Znám jen PHP. Jak napíšu webovou aplikaci v Pythonu?

python-logo-master-v3-TM

Jste otrávení z psaní webů v PHP a při posedávání v kavárnách slýcháte od svých kamarádek, že kdybyste se naučili Python, bude váš život krásnější, plnější, barevnější, prostě dokonalý od kořínků ke konečkům? Teď je ta pravá chvíle vykročit z komfortní zóny a zkusit to! Pojďme se podívat na to, jak v Pythonu začít s webem.

Následující text je volným překladem článku Python FAQ: Webdev, jehož autorem je Eevee a je zde zveřejněn se souhlasem autora. Článek jsem tu a tam aktualizoval, doplnil, nebo obohatil o nějakou tu větu.

Úplně nejjednodušší odpověď na otázku z nadpisu by bylo: “Přestaň číst tento článek, podívej se na Flask, a začni něco tvořit.” Někdy je ale lepší věci trochu rozvést.

Následující text však není návodem – předpokládám, že čtenář se zvládá učit z dokumentace. Je to přehled poměrů, jaké v současnosti vládnou ve webovém vývoji v Pythonu. Je to úvod pro někoho, kdo chce s Pythonem začít a nevyzná se.

Začínáme

Zcela zřejmě je k webovému vývoji v Pythonu potřeba mít nainstalovaný Python. Ujistěte se, že váš Python je verze 2, protože ve verzi 3 byly provedeny některé zpětně nekompatibilní změny a ne zcela všechny knihovny byly už přepsány tak, aby fungovaly na obou verzích.

Pro instalaci knihoven se používá pip. Na Linuxu si jej snadno pořídíte jako balíček – v Ubuntu třeba pomocí sudo apt-get install python-pip. pip je package manager pro Python – slouží k instalaci, odebírání a aktualizaci všech knihoven. Je to tedy ekvivalent nástroje Composer, jenž se používá ve světě PHP. Upřednostňujte pro instalaci Python knihoven pip před jakoukoliv jinou cestou, protože jen tak budete mít k dispozici jejich nejnovější verze.

Ve výchozím stavu instaluje pip knihovny přímo do systému, ale k tomu je např. v Linuxu potřeba sudo, neboli administrátorské oprávnění. Navíc, máte-li v systému nějaký program napsaný v Pythonu (a takových bývá na Linuxu hodně), můžete globálním zásahem nechtěně ovlivnit jeho závislosti a rozbít si jej. Je možné instalovat knihovny do vlastního domovského adresáře pomocí pip install --user ..., ale ještě lepší je mít knihovny nainstalované separátně pro každý projekt, na kterém pracujete – jen tak lze mít na různých projektech různé verze stejné knihovny a zabránit jakýmkoliv kolizím. Nástroj virtualenv přesně toto řeší – umožňuje jedním příkazem vytvářet izolované instalace Pythonu. Tento koncept je tak rozšířený a oblíbený, že už se stává přímo součástí nejnovější verze Pythonu.

Framework

První věc, kterou musíte vyřešit, je spojit nějak váš kód s prohlížečem. Začínáte-li s PHP, nejjednodušší cestou je nainstalovat Apache a předhodit mu nějaký adresář se soubory, které má servírovat do světa. V Pythonu, stejně jako ve větších PHP projektech, je řešením nějaký webový framework.

Frameworky mívají většinou podobné workflow:

  1. Nainstalujete framework jako knihovnu. Nejlépe přes pip.
  2. Vytvoříte skeleton nového projektu, tedy kostru adresářů a souborů. Složitost těchto skeletonů se různí. V již zaniklých Pylons člověk skončil se slušnou hromádkou jakéhosi záhadného kódu, který bylo potřeba manuálně aktualizovat novými verzemi frameworku. Flask je tak jednoduchý, že nepotřebuje vůbec žádný skeleton. Někde mezi nimi je Pyramid, kde kostru tvoří jen běžný startovní kód, jejž byste museli stejně napsat ručně, kdybyste skeleton nepoužili.
  3. Nakonfigurujete pár věcí, např. databázi.
  4. Spustíte vývojový server. Vývojový server je většinou jednoduchý konzolový program, který spustí vaši webovou aplikaci bez toho, že byste museli mít nějaký opravdový těžkotonážní HTTP server (jakým je třeba už onen zmiňovaný Apache). Vývojové servery umí detekovat změny ve vašem kódu a znova si jej načítat, vypisují do konzole nezachycené výjimky, logované zprávy a podobné informace vhodné pro debugování aplikace. Tato funkce se v PHP vyskytuje od verze 5.4.0 a skrývá se pod přepínačem php -S.
  5. Programujete!

Nu dobrá, jaký framework si však vybrat? Na výběr jsou stovky možností, ale jen několik je těch opravdu oblíbených a běžně používaných.

Já mám rád Pyramid, který se nachází někde ve zlatém řezu mezi minimalismem a plně vybaveným monolitem (batteries-included). Je to celkem mladý počin, ale vyvinul se ze dvou starších a používaných projektů. Výsledek je dobře navržený, dobře zdokumentovaný a poměrně přehledný. Jednoduchá aplikace nevyžaduje žádné velké psaní, k dispozici jsou skeletony, s nimiž lze práci rychle odstartovat. K tomu všemu je Pyramid snadno upravitelný a rozšiřitelný, díky čemuž roste i nabídka doplňků.

Pro ještě rychlejší start je vhodný Flask (pozn. překl. – ten mám rád zase já). Tento mikroframework je jednoduchý, jak jen to jde, ale přitom nabízí šílené množství doplňků a možností rozšíření, díky nimž na něm není problém vystavět i velmi komplikované aplikace. Flask je navržen tak, aby sice poskytoval poměrně rozumnou sadu nástrojů v základu, ale zároveň aby vám přitom nepřekážel a do ničeho vás příliš nenutil.

Bottle je podobný jako Flask, je však ještě jednodušší. Má jeden jediný soubor a nemá žádné závislosti na dalších knihovnách. Jestli je to dobře nebo špatně, to nechám na čtenáři. Chcete-li si vytvořit drobný, třístránkový web nebo toužíte-li si Python jen vyzkoušet, určitě stojí Bottle za vyzkoušení. Mnohdy se také objevuje jako výuková pomůcka v návodech pro úplné začátečníky.

Na druhé straně spektra se nachází Django, masivní bestie původně navržená pro backendy ve stylu CMS a podobně obsahově bohaté weby. Má obrovský ekosystém doplňků, přičemž už v základu poskytuje všechno možné od šablon až po ORM. Existují k němu hory dokumentace, článků, návodů, aj. komunitně tvořených informací. Často je Django považováno za ekvivalent Ruby on Rails. Nevýhodou je, že někdy nemusí být úplně příjemné nutit jej dělat věci, které se mu dělat nechtějí… Pro začátečníka to také může být možná až zbytečně těžké kladivo – učící křivka nemusí být úplně krátká.

web2py… existuje… Ehm, no – vlastně o něm ani nic dalšího nevím. Údajně sám od sebe vkládá proměnné do jmenných prostorů vašich modulů, což je dost prasárna. Takže pokud vám není jedno, že já si o něčem myslím, že je to prasárna, tak tento framework nepoužívejte. Anebo klidně… vždyť je to jedno.

Existují i další frameworky, třeba Twisted nebo Tornado, které jsou založené na asynchronních voláních a používají se například když chcete pracovat s mnoha paralelními požadavky, ale pro začátečníka přicházejícího z PHP to asi není úplně ono.

Dříve existoval a používal se mod_python, modul do Apache, který byl myšlenkou spřízněný s mod_perl, ale už se dávno nevyvíjí. Prosím, nepoužívejte jej.

Nakonec je také dobré se zmínit, že je možné napsat webovou aplikaci v Pythonu „ručně“, bez použití nějaké knihovny, ale pocit při psaní takového kódu se velmi blíží k něčemu jako je porod dikobrazích paterčat. Není to ani rychlejší, ani naučné, ani nijak moc užitečné. Netrapte se tím a nezkoušejte to.

Mé doporučení? Pokud si chcete jen vyzkoušet Python, chopte se Flasku a postupně si na něj přikládejte, co potřebujete, až když to potřebujete. Pokud máte už vymyšlený nějaký webík a chcete ho uvést rychle do provozu, použijte scaffolding v Pyramid a začtěte se do jeho výpravné dokumentace. Toužíte-li do měsíce dělat weby v Pythonu jako placenou práci, vrhněte se na Django.

Routing

Zatímco čisté PHP spouští na základě URL konkrétní soubor, webové aplikace napsané v Pythonu mají sklon „vlastnit“ celý adresář (nebo i celou doménu). Přiřazování konkrétních URL určitému kódu je tedy o něco pružnější a je obvykle spravováno tzv. routingem. Kdo pracuje s nějakými PHP frameworky, koncept routingu určitě zná, ale pojďme si jej připomenout.

„Routy“ (z anglického route, mn. č. routes) jsou parametrizovaná URL, jako například tato:

/users/{name}
/companies/{id}/products
/blog/{year:\d\d\d\d}/{month:\d\d}/{day:\d\d}/{title}

Když k té první routě připojíte funkci a v prohlížeči půjdete na /users/eevee, funkce se spustí a parametry pro ni budou k dispozici v podobě {"name": u"eevee"}.

Některé frameworky (jako Pyramid) jdou v tomto směru ještě o kousek dál – místo propojování routy přímo s funkcí musíte dát routě nejdříve název a ten teprve spojit s funkcí. Je to práce navíc, ale výhodou je centrální seznam všech stránek v aplikaci. Také se potom dá URL vytvořit i zpětně z názvu routy a parametrů, díky čemuž lze všechna URL měnit na jediném místě v aplikaci bez toho, aby to ovlivnilo cokoliv dalšího. Překlep při vývoji navíc místo „stránky 404“, kterou objeví až uživatel, rovnou způsobí chybu.

Každý webový framework v Pythonu využívá nějakou obměnu takovéhoto routingu, ačkoliv konkrétní syntax a implementace se vždy trochu liší. Některé v určitých ohledech zjednodušují práci, např. předpřipravenými nástroji pro vytváření RESTful rout, nebo umožňují napsat si routy od základů úplně podle svých představ.

Životní cyklus HTTP požadavku

HTTP požadavek obvykle volá nějakou funkci (vybranou routingem) a předává jí objekt request.

Rozhraní takového objektu závisí na konkrétním frameworku, ale jeho obsah je vždy podobný – data z dotazu, cookies, hlavičky, atd. Vezměme například Request objekt z knihovny webob, který zahrnuje následující:

  • request.GET a request.POST jsou „multislovníky“ s daty z dotazu. (Multislovník vrátí jednu hodnotu pro request.GET['foo'], ale přes metodu getall() umožní dostat se ke všem hodnotám pod stejným klíčem. Takové chování se hodí např. pro uložení dat, jež měly v URL tvar ?foo=42&foo=69.)
  • request.params je multislovník kombinující obojí z předchozího bodu.
  • request.cookies je slovník s cookies.
  • request.headers je slovník s HTTP hlavičkami, ale s klíči, které nejsou citlivé na velikost písmen.
  • request.is_xhr podává informaci o tom, zda je přítomna hlavička X-Requested-With: XMLHttpRequest, jíž se běžně identifikují AJAXové požadavky z knihoven jako je např. jQuery.

Popis chování request objektů bývá zpravidla důkladný, takže většinou stačí nakouknout do dokumentace příslušného frameworku a najít si to důležité, co zrovna potřebujete.

Když je vaše aplikace hotova s tím úžasným něčím, co měla na práci, potřebujete nějak odeslat HTTP odpověď. Obvykle máme možnost buďto si sami sestrojit nějaký Response objekt (včetně HTTP hlaviček a dalších ručních serepetiček), nebo můžete rovnou vrátit kus HTML a zbytek nechat na výchozích hodnotách. Velice zřídkakdy však potřebujete tvořit odpověď sami, protože pro všechny obvyklé potřeby (jako např. i odesílání JSON) mají frameworky nějakou zkratku nebo pomocný dekorátor.

Šablony

Seskládávání HTML se běžně řeší přes šablony. Mako a Jinja2 jsou dva hlavní kandidáti pro většinu projektů, Django má pak své vlastní Templates.

Mám opravdu rád Mako. Velmi, velmi, velmi rád. Jděte a použijte ho. Používá pro svou syntax prostý Python a dělá to velice přirozeně. Lze dokonce psát celé úseky čistého Python kódu přímo v šablonách, ačkoliv tedy existence zrovna této vlastnosti by pro vás měla být spíše „kursem sebeovládání“ a měli byste ji využívat co nejméně. :-)

Jinja2 je celkem v pořádku. Má jednu nepříjemnou vadu: foo.bar se bere jako foo['bar'], pokud foo vypadá jako slovník. Já si myslím, že je to opravdu velice špatný nápad a v šablonovacích systémech se stejnou „vlastností“ mě potkala spousta drobných, nepříjemných problémů. (Navíc ta syntax {% %} je fakt nic moc, ale to už je vyloženě argumentace banalitami.) Kromě toho je však Jinja2 velice pěkná knihovna a určitě byste mohli vybrat hůř. Mnohem, mnohem hůř.

(Pozn. překl.: Ve výběru šablon se s autorem malinko rozcházím. Opravdu jsem si zamiloval Jinju2 – její syntax navazuje na šablony z Djanga a třeba Twig, šablonovací systém v PHP frameworku Symfony ji prakticky okopíroval. Je podobná i jiným běžně používaným – srovnejte s Latte. No a s onou popisovanou „vlastností“ jsem já osobně nikdy žádný problém neměl, ostatně je i v Djangu.)

Mako i Jinja2 jsou obě poměrně rychlé, automaticky se na pozadí kompilují do Python modulů, mají excelentní nástroje pro ladění (s šílenými hacky, které umožňují, aby uměly výjimky probublat hezky až z vašeho kódu v šabloně) a měly by být dost mocné na to, aby vám umožnily cokoliv si budete přát. Proleťte dokumentaci k oběma těmto knihovnám, jednu si vyberte a hotovo. Pokud si neumíte vybrat, použijte Mako. Flask tedy v základu používá Jinju2, ale je poměrně jednoduché ji vyměnit.

Existují samozřejmě i další projekty: Na třetím místě by se pravděpodobně umístila Genshi, ale ta je tak neskutečně komplikovaná, že už její homepage začíná vývojovým diagramem. Jak bylo už zmíněno, Django má své vlastní šablony, jež se velice úzkostlivě snaží oddělit logiku aplikace od HTML (podle mě ke své škodě). Bottle má rovněž své šablony, ale tak jednoduché, že by velice brzy způsobovaly akorát větší a větší potíže. Pyramid má kromě Mako ještě svůj vlastní systém, Chameleon. Ten ale pro cykly a další logiku používá atributy ve stylu HTML, což je tedy – fanoušci n:maker v Latte prominou – pěkně praštěné.

Možná se vám budou některé z těch dalších šablonovacích systémů líbit – já jsem je ale nepoužíval pro žádné netriviální věci. Ať už si ovšem vyberete cokoliv, nechť to proboha není Cheetah. NEPOUŽÍVEJTE knihovnu Cheetah. Je to zvrácená ohavnost. Už o ní nikdy nemluvme.

Logika v šablonách

Možná jste nikdy předtím šablony nepoužili. Pokud ano, určitě jste si někdy položili otázku, zda by měl nějaký složitý vykreslovací kód ležet spíše v šablonách, nebo raději v Pythonu.

Je to starý a hloupý argument, ale podám to takto: Stejně jako u mnoha jiných rozhodování o architektuře programů nejvíce záleží na tom, jak moc se budete později za výsledek nenávidět. Pokud můžete, vyhněte se komplexním konstrukcím v šablonách, ale pokud nemůžete, nesnažte se drbat levou nohou za pravým uchem jen pro samotnou čistotu řešení. Pamatujte, že vždy můžete napsat pár prostých Python funkcí v prostých Python modulech a importovat je. Silný šablonovací systém by mohl mít dokonce už v základu nějaké pěkné kreativní řešení pro to, co se snažíte docílit – zatímco přemýšlíte nad problémem, proleťte si raději znova dokumentaci.

Pokračování příště

Druhá a poslední část překladu vyjde příští týden.

Honza je programátor. Od roku 2011 buduje českou komunitu kolem jazyka Python. V současnosti pomáhá hlavně s propagací aktivit, jako jsou PyLadies, Pyvo, nebo PyCon CZ. Přes den jej najdete v Apiary, kde se stará o Dredd, framework na testování API. Občas taky radí lidem jak mají API dělat a přednáší o tom na konferencích.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 49

Přehled komentářů

Ondřej Mirtes Otázky
starenka Re: Otázky
Patrik Šíma Re: Otázky
viktor.stiskala Re: Otázky
Honza Javorek Re: Otázky
Ondřej Mirtes Re: Otázky
Honza Javorek Re: Otázky
Honza Javorek Re: Otázky
Martin Kuchař Re: Otázky
Jan Bednařík Re: Otázky
Ondřej Melkes Re: Otázky
vaclav.sir Re: Otázky
roman grok
Honza Javorek Re: grok
W. Re: grok
Čelo e
LH Python vedle PHP?
michal.wiglasz Re: Python vedle PHP?
Ondřej Böhm Re: Python vedle PHP?
LH Re: Python vedle PHP?
Ondra Re: Python vedle PHP?
LH Re: Python vedle PHP?
rikiless Odesíláte komentáře moc rychle po sobě. Zpomalte prosím.
Petr Stanislav web2py
diverman Cheetah
Jakub Kulhan Skvělý článek!
Hmm
LH Re:
Martin Kuchař Re:
Michal Wiglasz Re:
Honza Javorek Re:
Martin Kuchař Re:
Foo pekne
Honza Javorek Re: pekne
Jaroslav Kubíček Re: pekne
Jaroslav Kubíček
Josef Skladanka Re:
Honza Kral Framework pro zacatecniky
radek.zilka.3 Free Hosting
Honza Javorek Re: Free Hosting
Huge Re: Free Hosting
J. Namornici
Martin Putniorz Re: Namornici
sveta.margetova Python
jbub Re: Python
JackHat Werkzeug
Honza Javorek Re: Werkzeug
Kaacz
Kaacz Re:
Zdroj: https://www.zdrojak.cz/?p=8979