PyconPL 2009

No, byłem. Co do konferencji jako takiej to wolę się nie wypowiadać, ale wnioskuję, że nie byłem jej targetem — był może jeden wykład, na którym dowiedziałem się czegoś nowego i jeden, który obejrzałem dla przyjemności. Aspekt społeczny w pewnym stopniu został zaspokojony przez bratanie się z kolegami z Allegro.pl. Infrastrukturę (dostęp do sieci, wyżywienie, zakwaterowanie, napoje, przekąski) pominę milczeniem. W końcu też w niedzielę dałem spicz i odniosłem wrażenie, że pomimo pewnych problemów technicznych się podobał. Czyli: pod względem merytorycznym niejaki sukces.

Dla uzupełnienia:

  • prezentacja do obejrzenia/ściągnięcia jest na SlideShare
  • kod w takiej wersji, jaka była prezentowana, jest na BitBucket

Jeżeli czas pozwoli, to skrobnę też jakiś artykuł na podstawie tego, co zostało powiedziane.

Autentykacja, podejście drugie

Ponownie brudzę sobie ręce w aplikacji zrobionej przy użyciu alternative stack (Werkzeug + Jinja2 + SQLAlchemy + WTForms), trochę przy okazji przygotowań do mojego nadchodzącego wystąpienia na PyconPL 2009. I ponownie wszystko szło gładko, dopóki nie musiałem zabrać do autentykacji uwierzytelniana (nie autoryzacji).

Krąży po mieście plotka, że najlepiej do tego użyć AuthKit lub repoze.who. Jak w każdej plotce, w tej także może być ziarno prawdy, więc kilka dni temu postanowiłem to sprawdzić. Już początki nie były zachęcające (każda z tych bibliotek doinstalowuje w zależnościach połowę Pylons), a potem było jeszcze gorzej.

AuthKit okazał się tak mocno związany z Pylons, że nawet nie ma własnej dokumentacji, tylko jakieś rozdziały w Pylons Book. Jedyne, co nadawało się do użycia bez Pylons, to kilka przykładów w repozytorium. Spróbowałem pokonać niechęć i zapoznać się bliżej z tą biblioteką, ale dałem za wygraną po godzinie zastanawiania się, jak do tego bydlaka podejść. Może jakoś niedługo przyjdzie mi do głowy idea, jak mógłbym z tego skorzystać bez Pylons (a może ktoś to opisze...).

Dokumentacja do repoze.who okazała się dużo lepsza, ale tym razem przerosła mnie idea tej biblioteki. Przeczytałem wprowadzenie i zagotowało mi się pod kopułą — jak to w ogóle działa? I najważniejsze, jak to podłączyć do istniejącego kodu? Jestem pewien, że dokumentacja dokładnie opisuje każdy aspekt działania tej biblioteki, ale ja tego zwyczajnie nie zrozumiałem. Może dlatego, że przez cały czas przed oczami miałem mój use case, który obejmuje jedynie mały fragmencik tego, do czego ta biblioteka została stworzona.

Na dzień 10 lipca 2009 roku konkluzja jest taka, że albo przysiądę fałdów i spróbuję użyć jednej z tych dwóch bibliotek, albo pójdę na skróty i użyję RPX (czy czegoś w tym stylu). Co biorąc pod uwagę obecny trend w branży nie wydaje się być takim głupim rozwiązaniem. Niestety, pomijając całkowite niedopasowanie tego rozwiązania do docelowej grupy użytkowników mojej aplikacji...

Zapraszam na PyconPL 2009

Jeżeli ktoś jeszcze się zastanawia, czy wybrać się na PyconPL do Ustronia w październiku, to może przekonam go tym, że będę tam trzymał spicz na temat przygód Adama Słodowego w krainie ramówek webowych — rozłożę na czynniki pierwsze jakąś ramówkę (pewnie będzie to najbliższe mi Django) i spróbuję złożyć coś podobnego używając zamienników.

Dawno nie dawałem żadnego występu publicznego (od ostatniego WarPY w październiku minie 2 lata...), więc trzeba przygotować lepszy show. :)

Setuptools to szajs

Wiele było już głosów, że setuptools jest pełne błędów i nie powinno być używane. W mojej praktyce na te błędy nie trafiałem, więc poprzestawałem na niechęci, a drobne wpadki powodowały jedynie wzrost przychylności wobec antagonistów setuptools. Tym razem w ciągu ostatnich dni zostałem doświadczony dwukrotnie przez poważne niedoróbki w setuptools, w tym jedna ma znaczenie krytyczne (nie instaluje się część zawartości pakietu):

Setuptools musi odejść!

Oko na RSS

Nie nie chodzi o żadne feedy, tylko o tzw. resident set aplikacji w Django. Obserwuję tę wartość od dłuższego czasu dla tej małej aplikacyjki i z pewnym niepokojem obserwuję jak rośnie, od ~15MB pod koniec 2007 roku przez ~17MB w okolicach wydania 1.0 do ~19MB z wersją 1.1-beta1 (przy wręcz zmniejszającym się feature secie aplikacji). A mój niepokój bierze się z mojej zadziwiająco dobrej pamięci, jak na mój podeszły wiek.

Kiedyś, w zamierzchłych czasach (okolice Slackware 9.0, czyli początek 2003 roku), była sobie fajna, mała przeglądarka WWW, która nazywała się Phoenix. Wyrosła z potrzeby istnienia po prostu przeglądarki i w swoich bebechach była Mozillą (tak się kiedyś nazywała przeglądarka wyrosła z Netscape Communicatora) bez wszystkiego tego, co nie służyło przeglądaniu stron WWW. Była szybka, miała małe wymagania i wszyscy ją pokochali od razu. Pokochali ją tak bardzo, że Mozilla Foundation postanowiła skupić na niej swoje wysiłki developerskie. W szybkim tempie (od wersji 0.4 Oceano z listopada 2002 do wersji 0.8 Royal Oak z lutego 2004) program zbliżył się apetytem na zasoby do swojego rodzica i przestał być postrzegany jako lekki i szybki. Po 7 latach istnienia Mozilla Firefox wciąż bohatersko zwalcza bloat, który był głównym powodem jego wypączkowania z projektu Mozilla Suite.

Na ile ostatnie develpmenta w Django przypominają to, co stało się z Phoeniksem? Na tyle, że nagle wszyscy pokochali Django i zaczęło ono obrastać w rzeczy, które już nie mieszczą się w legendarnych 80% (i django.contrib.gis to naprawdę mały pikuś w tym zestawie). Wygląda na to, że zadowalanie coraz większej rzeszy użytkowników daje w wyniku coraz większe zapotrzebowanie na zasoby...

Rekapitulując, ja też uważam, że martwię się na zapas. Sytuacja sama w sobie nie wygląda jeszcze na niepokojącą, niepokojący jedynie może być ten trend. Czy doprowadzi do tego, że Django przejdzie na ciemną stronę mocy, to się dopiero okaże.

Igranie z przyszłością

Zmiany się szykują... Wspominałem o planach przepisania silnika tego bloga przy użyciu narzędziówki, ale im dłużej nad tym siedzę, tym bardziej jestem przekonany, że nie ma to wielkiego sensu — zbyt wiele rzeczy wymagałoby ręcznej ingerencji, patchowania komponentów i rwania włosów z głowy, bo coś nie działa, jak na przykład odkrycie z wczoraj:

  • nie działa Beaker z powodu błędu w kodzie backendów sesyjnych wykorzystujących bazę danych i memcached (pliki działają OK, ale ich nie chcę);
  • w związku z tym, że nie działa Beaker, nie działa też AuthKit, więc nici z ułatwień autentykacji (np. po OpenID).

Oczywiście, byłbym w stanie naprawić Beaker'a, powstaje jedynie pytanie, czy to się w ogóle opłaca? Alternatywą jest przejrzenie i odchudzenie istniejącej aplikacji w Django, a przy okazji zoptymalizowanie jej nieco, wykorzystując doświadczenie, jakiego nabrałem w ciągu tych kilkunastu miesięcy. To też mogłoby być nienajgorsze rozwiązanie, a na pewno szybsze. Będę żałował Jinja2, ale jak mnie żal przyciśnie, to podłączę sobie ten silnik do Django, żeby stonować trochę ten żal...

Poważnie się zastanawiam i jeszcze nie podjąłem żadnej decyzji — na razie kod wykorzystujący narzędziówkę poszedł do oddzielnego brancha w repozytorium, a w trunku pojawił się kod wersji działającej obecnie, ale nie ma to jakiegoś symbolicznego znaczenia (tak sobie to tłumaczę). Uch, jak ja lubię mieć takie dylematy... :)

Nowe zabawki

W końcu się przemogłem i postanowiłem w celach edukacyjnych przemóc się i spróbować zrobić jakąś aplikację na Google AppEngine. Ponieważ chciałem mieć coś więcej, niż tylko naukę odpalania aplikacji pod Django na nowym środowisku, wybrałem sobie narzędziówkę z kosmosu: Werkzeug, Jinja2 i WTForms. I jak do tej pory psioczyłem na AppEngine, to teraz spodobało mi się to środowisko. Co prawda pod względem dołączonych baterii moja nowa narzędziówka jest bardzo uboga w porównaniu do wszystkiego tego, co przychodzi z Django, to jednak dzięki temu zorientowałem się, jak dużo rzeczy z Django tak naprawdę jest mi zupełnie niepotrzebne. Okazało się też, jak prosto można zaimplementować te rzeczy, które są mi potrzebne lub ułatwiają życie.

Więcej na ten temat wkrótce.

What would Brian Boitano do?

Przesiadam się teraz dość regularnie z komputera z desktopem GNOME na Mac OS X 10.5 i mam kilka pomysłów, które mogłyby stać się killer-aplikacjami, gdyby tylko były. Innymi słowy, jest to lista tego, czego brakuje mi w GNOME lub w OS X (albo i w jednym i w drugim).

W GNOME najbardziej brakuje mi czegoś, co działa jak Spotlight w OS X. Celowo napisałem "co działa", bo podobne launchery i dodatki oczywiście istnieją, ale do działania Spotlighta im daleko (są wolne i żrą masę zasobów). Poproszę o coś takiego w najbliższym wydaniu.

I jest coś, czego nie ma ani GNOME, ani OS X — instalator tematów. Coś, co ma Firefox i Opera, ale sam desktop nie. Chciałbym móc otworzyć sobie okienko, przejrzeć listę tematów z gnome-look.org (albo z innego serwisu), nacisnąć guzik "install theme" i już.

Eureka!

Pomimo tego, że robię w Django od paru lat, wciąż zdarzają mi się odkrycia na miarę archimedejskiej eureki. Dziś właśnie zauważyłem, że skrót render_to_response może przyjmować jako pierwszy argument nie tylko nazwę szablonu, ale także listę nazw szablonów. Dzięki temu wiekopomnemu odkryciu kod, który wyglądał dość marnie:

templates = [
    'flagging/%s_flagging_form.html' % obj._meta.module_name,
    'flagging/flagging_form.html',
]
template = loader.select_template(templates)
return HttpResponse(template.render(ctx))

teraz może wyglądać trochę ładniej:

templates = [
    'flagging/%s_flagging_form.html' % obj._meta.module_name,
    'flagging/flagging_form.html',
]
return render_to_response(templates, ctx)

Świadomie używam określeń ładnie i brzydko, bo chodzi tu jedynie o estetykę (obydwa warianty robią dokładnie to samo pod spodem).

Na swoje usprawiedliwienie mogę powiedzieć tylko tyle, że takie zachowanie render_to_response jest obecnie nieudokumentowane (ale zgłosiłem odpowiedniego patcha).

Introducing django-confirmation

I'm pleased to announce my first (hopefully) reusable app for Django: django-confirmation. The idea for this app came from my personal need to handle confirming object's creation on one of my sites. I found few apps performing similar tasks, but both are targeting single classes of objects, while I needed more generic approach (I hate this word...) — there are several classes of objects that need to be confirmed separately but using the same mechanism.

The use case for this app is as follows:

  • non-registered/not-logged-in user creates an object;
  • application sends an email asking user to click (within configurable period of time) on provided link to make the object "active";
  • user clicks a link and makes the object "active" or
  • key expires after specified amount of time.

The implementation is based on what I found in other apps, specially django-registration and django-email-confirmation, but with added support for confirming generic Django model instances (as long as they can have different activity states, that is).

Ładowanie...