Python a WSGI

Co je to WSGI

WSGI je standard definující komunikaci mezi webovou aplikací napsanou v pythonu a webserverem. Je založen na CGI standardu. Hlavním důvodem vzniku WSGI byla nejednotnost a chaos v rozhraní webových aplikací. Aplikace byly psány pro CGI, FastCGI, mod_python a další.

Struktura WSGI

Strana serveru

S webovým serverem může WSGI komunikovat libovolnou metodou. Existují implementace pro téměř všechny dnes používané rozhraní. Základem je wrapper pro CGI a FastCGI. Podporováno je ale i SCGI a AJP. Dá se najít dokonce i wrapper pro mod_python. Se serverem Microsoft IIS lze komunikovat prostřednictvím isapi-wsgi, PyISAPI a ASP brány.

Pro server Apache je doporučovaná volba modul - mod_wsgi.

Strana aplikace

Při přijetí HTTP požadavku, zavolá WSGI objekt application, který poskytuje strana aplikace.

Příklad volaného objektu:

def application(environ, start_response):
	start_response('200 OK', [('Content-Type', 'text/html')])
	yield '<h1>WSGI</h1>n'

Volaný objekt musí vždy přijímat objekt environ a ukazatel na funkci start_response. Jeho úkolem je pak zavolat funkci start_response a pomocí yield vrátit data jako iterátor.

Objekt environ je obdoba proměnných prostředí u CGI nebo superglobálního pole $_SERVER používaného v PHP.

Celý obsah lze zobrazit například takto:

response_body = ['%s: %s' % (key, value) for key, value in sorted(environ.items())]
response_body = 'n'.join(response_body)

Funkce start_response očekává dva parametry.

  1. String vyjadřující status odpovědi.
     200 OK 
  2. Seznam n-tic vyjadřující hlavičky odpovědi.
     [('Content-Type', 'text/html'), ('Content-Length', str(len(response_body)))] 

Naše funkce vrací tělo odpovědi a to ve formátu iterovatelného objektu (iterátor, seznam,…).

yield response_body

Middleware

WSGI umožňuje tvorbu takzvaného middleware (technicky něco jako man-in-the-middle). Funguje to tak, že místo aby WSGI wrapper volal náš objekt, zavolá tento middleware, který se pro server tváří jako aplikace. Middleware pak provede nějakou funkcionalitu (zparsuje URL, přidá něco do environu) a zavolá naši aplikaci. Pro naši aplikaci se pak middleware naopak tváří jako server. Vše probíhá transparentně a může se opakovat, čímž vzniká tzv. middleware zásobník.

Middleware se používá zejména pro routování, tedy překlad URL na vnitřní požadavek aplikace (volaný obejkt). Mezi další funkcionalitu patří rozložení zátěže mezi více serverů nebo postprocessing výstupu.

Middleware hojně využívají všechny pythonové webové frameworky.

Porovnání wrapperů

Použit nástroj Apache Bench s 10000 dotazy při 10 souběžných vláknech. Testovací aplikace je velmi podobná funkci phpinfo() známé z PHP.

Wrapper Dotazů za sec.
mod_wsgi 1274
wrapper pro FastCGI 304
wrapper pro mod_python 654

Z pohledu výkonu tedy jasně vítězí mod_wsgi. Velkou výhodou mod_wsgi je, že narozdíl od mod_python může Apache běžet jako worker MPM.

Mod_WSGI

Způsoby běhu

Základní způsob běhu mod_wsgi je tzv. embedded mód, který se velmi podobá fungování mod_python nebo mod_php. Kód aplikace je v tomto případě vykonáván přímo v child procesech Apache. Tento mód je doporučován především pro aplikace náročné na výkon. Druhým způsobem je daemon mód, který se podobá spíše FastCGI. Kód aplikace je pak spouštěn v dedikovaných procesech. Narozdíl od klasického FastCGI je zprovoznění daemon módu velmi jednoduché - stačí k tomu jediná direktiva, o vše se postará samotný modul. Dedikovaný proces může být spuštěn pod právy určitého uživatele, což výrazně zvyšuje bezpečnost serveru. Pokud aplikace nepotřebuje velmi vysoký výkon, je tento mód upřednostňovaným řešením.

Práce s mod_wsgi

Postupy se vztahují k distribuci Ubuntu.

Instalace a základní konfigurace

Celá instalace sestává z instalace balíku libapache2-mod-wsgi.

Pokud se wsgi po restartu Apache nenačte, je ještě potřeba vytvořit symbolické odkazy.

cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/wsgi.conf
sudo ln -s ../mods-available/wsgi.load

K základní konfiguraci stačí přidat jeden řádek do VirtualHost kontejneru.

WSGIScriptAlias /wsgi/ /home/dundee/workspace/wsgi/

Nyní budou všechny soubory z adresáře /home.../wgsi/ předány ke zpracování mod_wsgi. Způsob běhu je embedded. Pokud chceme spouštět aplikace v módu daemon (což je pravděpodobné), přidáme ještě dva řádky:

WSGIDaemonProcess site1 user=dundee group=dundee processes=2 threads=25
WSGIProcessGroup site1

První parametr direktivy WSGIDaemonProcess označuje skupinu procesů. Toto označení musí být v rámci serveru jedinečné. Direktiva může být použita v jakémkoliv kontextu.

Direktiva WSGIProcessGroup je pak použita v rámci VirtualHostu a určuje v rámci jaké skupiny procesů se bude aplikace spouštět. Když není tato direktiva použita, dedikované procesy se nepoužijí.

Srovnání výkonu embedded vs. daemon módu

Mód Dotazů za sec.
Embedded 1594
Daemon 1499
PHP jako FastCGI 916

Z výsledku testu vyplývá, že daemon mód není o mnoho pomalejší než embedded mód, a je proto doporučovaným způsobem použití mod_wsgi. Daemon mód se dá přirovnat k dobře vyladěnému FastCGI se suexecem.

Závěr

V článku jsme se v krátkosti podívali na to, co je to WSGI, jakou má strukturu, jaké byly důvody vzniku a srovnali jsme výkon jeho nejběžnějších implementací. Dále jsme se zaměřili na doporučovanou implementaci WSGI - mod_wsgi - a podívali jsme se na módy běhu, základní konfiguraci a srovnání výkonu. Z celého článku jednoznačně vyplývá, že platforma PHP/FastCGI/Apache má proti sobě nového velmi ambiciózního a silného protivníka v podobě Python/WSGI/Apache. Vyzyvatel ve výkonovém testu překonal šampióna o celou jednu třetinu, což je nezanedbatelné. Objektovost a snadné spuštění pod právy uživatele pak činí z vyzyvatele jasného vítěze. Podle mého názoru je jen otázkou času, než Python na webových serverech přečíslí PHP.

Hodnocení

Komentáře

[1] veena
2009-01-15 15:11:57

Dobrej rozbor. Hned to posílám kámošovi z jednoho hostingu. To jsem zvědavý, co na to řekne.

Na tento komentář odpověděl [2] Dundee
[2] Dundee
2009-01-15 15:43:40

#1 veena: Taky mi to trvalo skoro dva dny :)

Byl to původně referát na předmět Administrace webového serveru.

[3] koubel
2009-01-22 14:50:47

Jojo, už aby to bylo, to, jak se u PHP při každém requestu znova "staví" celá aplikace je naprosto šílené. Je to jeden z důvodů, proč by se podle mě nemělo PHP nasazovat na projekty náročné na výkon, aplikační server - to bude asi ten middleware v tvém podání - je jiná liga. Ještě je ale asi důležitá otázka deploymentu takových projektů, jak to je u WSGI, musí se při nové verzi asi pořád něco restartovat ne?

Na tento komentář odpověděl [6] Dundee
[4] Messa
2009-01-22 15:26:39

Administrace webového serveru - ČVUT FEL? Ten předmět jsem nedělal, ale co jsem slyšel a viděl, tohle musel být jeden z těch lepších referátů :-)

WSGI je vlastně moc jednoduchá věc, žádná věda, jen lepidlo pro přilepení vaší aplikace k něčemu, co ji pustí do světa. Akorát není moc jasné, kde se mod_wsgi dozví, že má spouštět zrovna funkci app a jaký je životní cyklus aplikace (např. co když chci mezi požadavky udržovat data nebo databázové spojení, jak bude aplikace ukončena... vlastně deployment vůbec, jak zmínil Koubel). Odpovídat mi nemusíte, já si to zjistím sám, až to budu chtít vědět, jen jsem chtěl nastínit možné další otázky :-)

K tomu PHP - podle mě nebude "přečísleno" ještě aspoň 5 let. Přeci jen na to málo co se v něm obvykle dělá (nějaké to echo a připojení do db) je optimalizované dost a právě to, že po každém požadavku vše opět zmizí, ho umožňuje nasadit na mass hostingy o tisících webech na jednom stroji. Naopak mass hosting s tisíci Python procesy (když to chcete dělat "správně"), byť žijích jen když jsou potřeba, to už je trochu horší. Ale když už se webovka v Pythonu jednou spustí, pak už to lítá :-) a je to podle mě rychlejší, než když se o nějaké šablonování a podobné samozřejmosti někdo pokouší v PHP. No a taky nastavit hosting pro Python asi nebude sranda jak pro jeho správce, tak pro uživatele; nebude to tak snadné, jako přes FTP nahrát soubor s příponou .php. Osobně si ale myslím, že kdo to s weby myslí vážně, má vlastní server(y) a nasazení Pythonu nebo čehokoliv je pak sranda. Jde mi jen o to, že ty velká čísla okolo PHP jsou tvořena hlavně oněmi hostingy za dvacku měsíčně. Konec éry PHP - mě je to jedno, pro mě už skončila :-)

Ještě by se asi slušelo zmínit, že WSGI je specifikováno v PEP 333.

Na tento komentář odpověděl [6] Dundee
[5] vv
2009-01-22 17:22:26

Ne, ja uz tem vasim srovnanim proste neverim. :)

[6] Dundee
2009-01-22 18:29:41

#3 koubel: Nevím jak u frameworků nad WSGI, ale samotné WSGI funguje podobně jako FastCGI, takže se aplikace spouští vždy od znova a restartovat není potřeba.

#4 Messa: Přímo ve standardu WSGI jsem o tom, který objekt bude spuštěn, nenašel nic. Mod_wsgi (tedy jedna z implementací WSGI) vždy volá objekt application.

Životní koloběh aplikace se zdá být stejný jako u PHP.

Stejně jako u PHP může i Python běžet jako součást Apache (embedded mod). Na mnoha hostinzích běží PHP jako FastCGI, kde se také může vytvářet více procesů, takže v daemon módu bych problém také neviděl.

Rozchodit správně Python na hostingu, je daleko lehčí než PHP. Konfigurace PHP se suexecem a FastCGI je celkem zdlouhavá, u WSGI je to otázka jen 3 direktiv.

[7] Miloslav Ponkrác
2009-01-22 21:29:33

Bohužel škoda toho bulvárního nadpisu, jinak skvělý, opravdu vynikající článek.

Python nikdy nepřeválcuje PHP, to spíše Rossum převálcuje Python. Žádný jiný jazyk co znám neudělal tak radikální změnu syntaxe jako Python ve verzi 3 a přitom nechal programátory totálně na holičkách, protože neexistuje k dispozici žádný nástroj, který by převedl spolehlivě syntaxi z verze 2 na verzi 3.

Já osobně bych takovému jazyku žádný střední, ani větší projekt nesvěřil – jazyk, který po 17 letech přeorává radikálně syntaxi. A proto ani Python nepřeválcuje PHP, ba ani řadu jiných jazyků a technologií, kde by se hodil – jeho změny syntaxe a zvednutý nosánek nad zpětnou kompatibilitou mu podrazí nohy i před daleko horšími technologiemi.

Já osobně bych sám dal přednost horší technologii, ale se zaručenou jistotou, že jí nebudu muset překopávat – a tu mi Python nedá.

Aby nedošlo k omylu – i PHP mění syntaxi, ale ty změny jsou velmi velmi malé, téměř kosmetické. A i s nimi byl problém.

[8] Anonym
2009-01-23 09:02:25

Chtěl bych jen upozormit na to, že zdaleka ne všichni Python programátoři si o Pythonu myslí to, co pan Ponkrác.

Na tento komentář odpověděl [9] Dundee
Na tento komentář odpověděl [10] Miloslav Ponkrác
[9] Dundee
2009-01-23 12:29:49

#8 Anonym: Já sice zatím používám Python jen pro takové to "domácí programování", ale také většinu změn spíše vítám.

Jediné, co mi vadí, je, že print bude funkce a budu tedy muset psát o dva znaky víc. Ale chápu, že to asi pro zjednodušení složitého chování print bylo potřeba.

[10] Miloslav Ponkrác
2009-01-23 13:31:22

#8 Anonym: Mým cílem nebylo někomu říct, jak myslí všichni programátoři. Jen upozornit na velmi stinnou stránku Pythonu.

A lidé, kteří dělají velké, nebo opravdu důležité projekty myslí tak jak jsem to napsal já. Nelze myslet jinak.

Nejdůležitější a největší věci v programátorském světě byly psány v jazycích, které nemění svojí syntaxi. Byť můžeme pochybovat o tom, zda jsou to dobré programovací jazyky, ale fakt až puntičkářského zachovávání zpětné syntaktické kompatibility je nutnou podmínkou pro to, aby se jim svěřily důležité věci.

Proto se programuje v C, C++, Adě, Javě, Cobolu – a žádný jazyk ani technologie se nikdy nad ně nevyšvihne, dokud důsledně nezaručí zpětnou syntaktickou a knihovní kompatibilitu. To je totiž nutná záruka toho, aby programovací jazyk začaly brát vážně firmy, které vyvíjejí dlouhodobé projekty. Nehledě už od toho, že dobrý střední, nebo velký projekt nenapíšete za měsíc, takže silné záruky neměnnosti jazyka jsou nutné. A navíc tu hrají roli jako faktory typu spolehlivost, a jedna z věcí, která vám udělá z dlouhodobě odladěného programu s vychytanými chybami chybovou alfaverzi, kterou můžete znovu ladit je změna syntaxe jazyka.

U malých projektů možná (s trochou fanatismu) skousknete, když se vám jazyk, nebo knihovny mění pod rukou. Ale u středních a větších projektů z toho vznikají obrovské problémy, velké časové a finanční nároky. Proto se tam jazyk s proměnnou syntaxí nemá téměř šanci uplatnit – a to může být kvalitní jak chce.

Na tento komentář odpověděl [13] Dundee
Na tento komentář odpověděl [15] ehmo
[11] ehmo
2009-01-23 15:43:05

velmi pekne spracovane. skoda len, ze si nespomenul zakladne priklady spolocnosti, ktore standard pouzivaju. napr google a jeho app engine

Na tento komentář odpověděl [12] Dundee
2009-01-23 20:43:23

#11 ehmo: Díky. Jen to jen takové lehké seznámení se s WSGI, určitě by se dalo přidat mnoho dalších zajímavých informací. Třeba se podívat na Python frameworky podporující WSGI, rozebrat nejznámější middleware apod.

2009-01-23 20:47:57

#10 Miloslav Ponkrác: Chápu. Myslím, že není cílem Pythonu (aspoň zatím) nahrazovat bankovní software apod. Cítím ho jako moderní, dynamicky se vyvíjející jazyk, který spoluurčuje směr, jakým se budou programovací jazyky ubírat. Když chcete programování někam opravdu posunout, je zpětná kompatibilita oželitelná daň.

Na tento komentář odpověděl [14] Miloslav Ponkrác
[14] Miloslav Ponkrác
2009-01-23 21:23:45

#13 Dundee: Podle mě Python určil jeden směr – dokázal udělat geniálně jednoduchý, a přitom mocný a moderní jazyk. Všechny jazyky do té doby (snad s výjimkou Basicu) byly složité až vědecké, a nebo jednoduché, ale prasácké.

A potom se také Python stane laboratoří, která ukáže, zda zavedený jazyk přežije radikální změnu syntaxe. I v tom bude průkopníkem.

Všimněte si, že Python se začal skvěle šířit a nasazovat, mimo jiné také proto, že nikdo nepočítal se změnou syntaxe. Začaly ho nasazovat velké firmy, nastával obrovský rozmach Pythonu zejména ve web technologiích. Mluvilo se o něm jako o jazyku budoucnosti – to vše po Pythonu 3 ustalo. Je jaksi dosti ticho.

Podobný osud má Perl – ten je ovšem radikálnější, už roky slibuje Perl 6, který bude nekompatibilní se současným Perlem 5. Tím autor Perlu velmi efektivně utlumil jakýkoli vývoj Perlu i nástrojů pro Perl po několik let. A stačil na to pouhý slib.

Ruby se pokusil o to samé – radikální změnu syntaxe. Jenže Ruby je jiný svět – má velmi velmi loajální komunitu, až fanatickou, kterou jinde nenajdete. Podobnou věrnost, byť ne tak radikální najdete u příznivců Javy.

No a o to jaká bude cena za nekompatibilitu – to ukáže budoucnost. Podle mě to ale Python prohraje.

[15] ehmo
2009-01-23 21:26:55

#10 Miloslav Ponkrác: ja som si az teraz vsimol tvoj komentar a musim povedat ze je to totalna sprostost co si napisal. na preklenutie verzii sa na 90% da velmi dobre pouzit existujuce riesenie, zvysok nie, pretoze vypadli niektore funkcie. php urobilo mnohokrat taku upravu, ze zrazu prestal portal fungovat a nevedel si za boha najst dovod, lebo pani zmenili error kod vracany napr z -1 na false a pod.

to ze v tom nebudu napisane velke projekty neviem cim merias, ale napr google ma v pythone napisanych v priemere 85% vsetkych veci, len matematicky algorytmi su riesene cez ceckarske kniznice, cast searchu, praca s hw, mapreduce je napisany kombinovane c a python. ak chces porovnavat velke projekty, kludne sa do tohoto pustim s tebou, pretoze pochybujem, ze ktorykolvek tebou oznaceny projekt pracuje s 1 alebo 2 PB datami K zmenam syntaxe vobec nedoslo nahodou, malo to svoje zasadne dovody ktore guido s ludmi okolo py ohlasovali uz dost dlho.

ak sa bavime o bankovych systemoch, tak napriklad citi bank ma v pythone napisany kompletny backoffice, atd. mna by zaujimalo, kam chodis na tieto reci, ze vsetko velke je napisane len v c, c++ a cobole. ano, rozsirenost je urcite nizsia, ale co sa tyka velkych projektov, zabudni. v tych sa python minimalne vyrovna ostatnym tebou vypisanym jazykov.

a ci php niekto nahradi je otazka asi ustupkov. asi neexistuje jazyk, ktory robi tak neuveritelne ustupky ako php, vdaka comu existuje tak obrovske kvanta balastneho kodu a nijak sa to nelepsi, lebo sa kazdy den objavuju dalsi "amazing" programatori, ktori vcera otvorili kosekovu knihu a dnes uz vedia co to je oop.

preto sa na tuto uroven ostatne jazyky len tak nedostanu. dalsia vec je aj podpora u hostingov. tu ani nie je co riesit, vsetci vieme aka je podpora pre php, asp resp .net. prichod app engine sa to lepsi, no nijak vyrazne.

Na tento komentář odpověděl [16] Murphy
2009-02-09 21:57:57

#15 ehmo: Naporosto souhlasim. V PHP se uz nekolikrat stalo ze zmenily navratovou hodnotu funkce a pak si to hledejte. Zkusil si nekdy nekdo najit automaticky migracni skript z PH3->PHP4 nebo PHP4->PHP5 ? I kdyz se najit daji, nikdy nefungiovaly spravne. Ty zmeny v Pythonu byly diskutovany v diskusich hodne pred a tudiz jsou na ne vsichni pripraveni a tyto zmeny jsou navic spravne a logicke.

P.S.: programoval jsem v PHP, C, Java s Pythonem teprve zacinam, ale zda se mi, ze ma velky potencial proti Jave, prave kvuli Jave jsem zacal hledat novy moderni jazyk, ktery by mi vyhovoval. Java me moc nenadchla.

[17] Petr Mach
2009-09-14 00:44:26

Ponkrác je proslavený svou zaslepenou anymozitou vůči Pythonu. Vyčítá mu vlastnosti, které jsou vlastní snad všem skriptovacím jazykům. Líbí se mu Python 2 a vadí mu, že po 10 letech vzniknul Python 3, který čistí chlívek a odstraňuje chyby v návrhu, ke kterým došlo a které jsou Pythonu koulí na noze.

Je to pokrytecké, protože stejným způsobem vzniknul i Python 2, který je nekompatibilní s předchozí řadou. Ale ta holt nebyla tak pěkný a Python v té době nebyl moc rozšířený. Za to, že Python 2 je tak fajn vděčíme (včetně Ponkráce) právě tomu, na co Ponkrác neustále všude plive a nadává.

Je velmi smutné, že místo Pythonu Ponkrác doporučuje PHP, která je v tomto ohledu řádově horší.

Přitom nic nikomu nebrání i nadále používat Python 2 a tak se i děje. Krom toho změny ke kterým mezi Pythonem 2 a 3 došlo byly pečlivě naplánovány. Byl to několikaletý uvážený proces, na který se všichni mohli a stále mohou v klidu a beze spěchu připravit. Napomáhá tomu jak speciální verze Pythonu 2.6, která je co nejvíce kompatibilní s řadou 2 i 3 a upozorňuje na příslušná problematická místa, tak i převodní nástroj, který převádí rutinní změnu syntaxe z verze 2 na 3. Po jeho použití k ručnímu ošetření zbývá jen málo míst (snadno se vychytají za pomoci Pythonu 2.6), prakticky žádná, pokud byl programátor schopný a poučený a stihl se několik let předem seznámit s tím, co v Pythonu 3 bude jinak.

2009-09-18 22:22:05

Já osobně "trojkové" verzi Pythonu hodně fandím.
V Pythonu dělám už několik let a z přechodu aplikací z verze 2 na 3 mám trochu obavu, přeci jen to bude mravenčí práce. I přesto se mi rozhodnutí o zpětné nekompatibilitě líbí. Přesně to jazyk jednou za čas potřebujete, pořádně pročistit. Jen se podívejte na PHP. Tam se snaží kompatibilitu zachovat (ikdyž, jak už tu někdo psal, občas taky mění návratové hodnoty fcí, atd. - a to navíc docela zákeřně) a je z toho čím dál větší paskvil.

Beze změn by byl život nuda. Já zrovna hledám řešení jak inteligentně přepsat aplikace z mod_pythonu do mod_wsgi. Protože nejsem zastáncem velkých, nabubřelých frameworků, vytvořil jsem si nad mod_pythonem (hoooodně primitivní) framework. Jsou to spíš pravidla, než framework :-) Jenže mod_pythonu odzvonilo :-( takže je potřeba se zase posunout dál. Teď vytvářím podobný "framework" (pravidla) pod mod_wsgi. Taky bych mohl nadávat, že se mod_python už nevyvíjí a já to musím předělávat, ale to je prostě život. Stejně tak je to i s Py2 -> Py3

Komentáře již nelze přidávat