Confortul și versatilitatea lui Python înseamnă că este folosit pentru a construi software în aproape fiecare etapă a vieții IT. O nișă majoră este cea a serviciilor web, unde viteza de dezvoltare și metaforele flexibile ale lui Python facilitează punerea în funcțiune rapidă a site-urilor web.
Și, așa cum ați putea bănui, Python vă oferă o mulțime de opțiuni și latitudine în ceea ce privește cadrele web, atât mici cât și mari. La urma urmei, nu orice proiect web trebuie să fie la scară de întreprindere. Cele mai multe ar trebui să fie doar suficient de mari pentru a face treaba, și nu mai mari. Acest articol trece în revistă opt dintre cele mai cunoscute cadre Python care pun accentul pe simplitate, livrare ușoară și o concentrare strânsă.
Bottle
Bottle ar putea fi considerat un fel de mini-Flask, deoarece este chiar mai compact și mai succint decât acel alt „microframework”. Datorită amprentei sale minime, Bottle este ideal pentru a fi inclus în alte proiecte sau pentru a livra rapid proiecte mici, cum ar fi API-urile REST. (Flask este discutat mai jos.)
Întreaga bază de cod pentru Bottle încape într-un singur fișier și nu are absolut nicio dependență externă. Chiar și așa, Bottle vine echipat cu suficiente funcționalități pentru a construi tipuri comune de aplicații web fără a se baza pe ajutor extern.
Sistemul de rutare din Bottle, care mapează URL-urile către funcții, are aproape exact aceeași sintaxă ca Flask. De asemenea, nu sunteți limitat la un set de rute cablate; le puteți crea dinamic. Datele de cerere și de răspuns, cookie-urile, variabilele de interogare, datele de formular de la o acțiune POST, anteturile HTTP și încărcările de fișiere pot fi accesate și manipulate prin intermediul obiectelor din Bottle.
Care capacitate a fost implementată cu o bună atenție la detalii. În cazul încărcărilor de fișiere, de exemplu, nu trebuie să redenumiți fișierul în cazul în care convenția de denumire a acestuia intră în conflict cu sistemul de fișiere țintă (cum ar fi slashes în nume pe Windows). Bottle poate face acest lucru pentru dvs.
Bottle include propriul motor de modelare HTML simplu. Din nou, deși minimalist, motorul de modelare are toate elementele esențiale. Variabilele incluse într-un șablon sunt redate în mod implicit cu HTML sigur; trebuie să indicați ce variabile sunt sigure pentru a le reproduce literal. Dacă preferați să schimbați motorul de șabloane al lui Bottle cu un altul, cum ar fi Jinja2, Bottle vă permite să faceți acest lucru fără probleme. Eu prefer sistemul de șabloane simple inclus în Bottle; este rapid, sintaxa sa este nepretențioasă și vă permite să amestecați codul și textul șablonului fără dificultăți nejustificate.
Bottle suportă chiar și mai multe back-end-uri de server. Vine cu propriul miniserver încorporat pentru teste rapide, dar va suporta și WSGI generic, o mare varietate de servere HTTP compatibile cu WSGI și vechiul CGI, dacă este necesar.
Bottle nu are nevoie de atât de multă documentație ca alte cadre, dar documentele nu sunt deloc zgârcite. Toate lucrurile cruciale încap pe o singură pagină web (deși lungă). Dincolo de aceasta, veți găsi documentație completă pentru fiecare API, exemple de implementare pe diverse infrastructuri, o explicație a limbajului de modelare încorporat și o mulțime de rețete comune.
Ca și în cazul Flask, puteți extinde funcționalitatea lui Bottle manual sau prin intermediul unor plug-in-uri. Plug-in-urile Bottle nu sunt nici pe departe la fel de numeroase ca cele de la Flask, dar există piese utile, cum ar fi integrarea cu diverse straturi de baze de date și autentificarea de bază a utilizatorilor. Pentru suportul asincron, Bottle poate folosi unul dintre adaptorii de server existenți care rulează asincron, cum ar fi aiohttp/uvloop, dar async/await
nu este suportat nativ.
O consecință a minimalismului lui Bottle este că unele elemente pur și simplu nu există. Validarea formularelor, inclusiv caracteristici precum protecția CSRF (cross-site request forgery), nu este inclusă. Dacă doriți să construiți o aplicație web care să susțină un grad ridicat de interacțiune cu utilizatorul, va trebui să adăugați singur acest suport.
O altă problemă cu Bottle este că dezvoltarea a stagnat; ultima versiune punctuală, 0.12, a sosit în 2013. Acestea fiind spuse, Bottle continuă să fie întreținut, iar versiunile sale de dezvoltare rămân utilizabile pentru producție. Dezvoltatorii intenționează să livreze noi versiuni care să renunțe la suportul pentru edițiile vechi de Python.
CherryPy
CherryPy există într-o formă sau alta de aproape 20 de ani, dar nu și-a pierdut minimalismul și eleganța care l-au distins de la început.
Obiectivul din spatele CherryPy, pe lângă faptul că nu conține decât strictul necesar pentru a servi pagini web, este să se simtă, pe cât posibil, nu ca un „cadru web”, ci ca orice alt tip de aplicație Python. Site-uri precum Hulu și Netflix au folosit CherryPy în producție deoarece cadrul oferă o bază extrem de discretă pe care se poate construi. CherryPy folosește fire de execuție grupate sub capotă, cu atât mai bine pentru a suporta adaptoare de server cu mai multe fire de execuție.
CherryPy vă permite să vă păstrați aplicația web separat de logica de bază. Pentru a mapa funcțiile aplicației dvs. către URL-uri sau rute servite de CherryPy, creați o clasă în care spațiile de nume ale obiectelor se corelează direct cu URL-urile pe care doriți să le serviți. De exemplu, rădăcina site-ului web este furnizată de o funcție numită „index”. Parametrii trecuți către aceste funcții sunt utilizați pentru a gestiona variabilele furnizate de metodele GET sau POST.
Biturile pe care CherryPy le include sunt menite să funcționeze ca blocuri de construcție de nivel scăzut. Identificatorii de sesiune și manipularea cookie-urilor sunt incluse, dar nu și modelarea HTML. La fel ca Bottle, CherryPy oferă o modalitate de a mapa rutele către directoare pe disc pentru servirea fișierelor statice.
CherryPy se va referi adesea la o bibliotecă terță parte existentă pentru a susține o caracteristică, mai degrabă decât să o furnizeze nativ. Aplicațiile WebSocket, de exemplu, nu sunt suportate de CherryPy în mod direct, ci prin intermediul bibliotecii ws4py.
Documentația pentru CherryPy include un tutorial practic de prezentare a diferitelor aspecte ale programului. Acesta nu vă va conduce printr-o aplicație completă de la un capăt la altul, spre deosebire de alte tutoriale pentru framework-uri, dar este totuși util. Documentația vine cu note utile despre implementarea în gazde virtuale, proxy invers prin Apache și Nginx și multe alte scenarii.
Falcon
Dacă construiți API-uri bazate pe REST și nimic altceva, Falcon a fost creat doar pentru dumneavoastră. Slab și rapid, fără aproape nicio dependență în afară de biblioteca standard, Falcon oferă tot ce aveți nevoie pentru API-uri REST și nimic mai mult. Falcon 2.0, lansat în 2019, renunță la suportul pentru Python 2.x și necesită cel puțin Python 3.5.
O mare parte din motivul pentru care Falcon își merită eticheta de „ușor și subțire” are puțin de-a face cu numărul de linii de cod din framework. Aceasta se datorează faptului că Falcon nu impune aproape nicio structură proprie aplicațiilor. Tot ce trebuie să facă o aplicație Falcon este să indice ce funcții corespund la ce puncte finale API. Returnarea JSON de la un endpoint implică puțin mai mult decât configurarea unei rute și returnarea datelor prin intermediul funcției json.dumps
din biblioteca standard Python. Suportul pentru async nu a aterizat încă în Falcon, dar se lucrează pentru ca acest lucru să se întâmple în Falcon 3.0.
Falcon folosește, de asemenea, valori implicite sănătoase out-of-the-box, astfel încât este nevoie de puține modificări pentru configurare. De exemplu, 404s sunt ridicate în mod implicit pentru orice rută care nu este declarată în mod explicit. Dacă doriți să returnați erori către client, puteți ridica una dintre numeroasele excepții de stoc incluse în cadru (cum ar fi HTTPBadRequest
) sau puteți utiliza o excepție generică falcon.HTTPError
. Dacă aveți nevoie de preprocesare sau postprocesare pentru o rută, Falcon oferă și cârlige pentru acestea.
Concentrarea lui Falcon pe API-uri înseamnă că nu există prea multe aici pentru construirea de aplicații web cu interfețe utilizator HTML convenționale. Nu vă așteptați la prea multe în ceea ce privește funcțiile de procesare a formularelor și instrumentele de protecție CSRF, de exemplu. Acestea fiind spuse, Falcon oferă opțiuni elegante pentru a-și extinde funcționalitatea, astfel încât pot fi construite elemente mai sofisticate. În afară de mecanismul de agățare menționat mai sus, veți găsi o interfață pentru crearea de middleware care poate fi folosită pentru a îngloba toate API-urile lui Falcon.
Documentația pentru Falcon este subțire în comparație cu alte framework-uri, dar numai pentru că este mai puțin de acoperit. Ghidul utilizatorului include o prezentare formală, pas cu pas, a tuturor caracteristicilor majore, împreună cu o secțiune de pornire rapidă care vă permite să vizualizați exemple de cod cu sau fără adnotări.
FastAPI
Numele lui FastAPI este un bun rezumat a ceea ce face. Este construit pentru a crea rapid puncte finale de API și, de asemenea, rulează rapid.
FastAPI utilizează proiectul Starlette pentru nucleul său de rețea de mare viteză, dar nu trebuie să cunoașteți elementele interne ale Starlette pentru a utiliza FastAPI. Definiți punctele finale în același mod ca într-o aplicație Flask sau Bottle – folosiți decoratori pentru a indica ce funcții gestionează ce rute – și apoi returnați dicționare care sunt traduse automat în JSON.
Puteți suprascrie cu ușurință modul în care sunt returnate lucrurile. De exemplu, dacă doriți să returnați HTML/XML de la unele puncte finale, puteți face acest lucru prin simpla returnare a unui obiect personalizat Response
. Dacă doriți să adăugați middleware personalizat, puteți introduce orice lucru care respectă standardul ASGI.
FastAPI utilizează indicarea tipurilor din Python pentru a oferi constrângeri asupra tipurilor de date pe care rutele le acceptă. De exemplu, dacă aveți o rută cu tipul Optional
, FastAPI va respinge orice transmitere cu excepția numerelor întregi. Nu trebuie să adăugați cod de validare a datelor la punctele finale; puteți folosi doar indicii de tip și să lăsați FastAPI să facă treaba.
Natural, unele lucruri sunt lăsate pe dinafară. Nu există un motor de șabloane HTML nativ, de exemplu, dar nu lipsesc soluțiile de la terți pentru a umple acest gol. Același lucru cu conectivitatea bazelor de date, dar documentația conține detalii despre cum să convingi anumite ORM-uri (de exemplu Peewee) să lucreze cu comportamentele asincrone ale FastAPI.
Flask
Multe discuții despre cadrele web Python încep cu Flask, și pe bună dreptate. Flask este un cadru bine stabilit, bine înțeles, care este ușor de utilizat și destul de stabil. Este aproape imposibil să greșiți folosind Flask pentru un proiect web ușor sau un API REST de bază, dar vă veți confrunta cu greutăți mari dacă încercați să construiți ceva mai mare.
Atractivitatea centrală a lui Flask este bariera sa redusă la intrare. O aplicație de bază „hello world” poate fi configurată în mai puțin de 10 linii de Python. Flask include un sistem de șabloane HTML utilizat pe scară largă, Jinja2, pentru a ușura redarea textului, dar Jinja2 poate fi înlocuit cu orice număr de alte motoare de șabloane (cum ar fi Mustache) sau vă puteți crea propriul șablon.
În numele simplității, Flask omite subtilitățile, cum ar fi un strat de date sau ORM, și nu oferă prevederi pentru validarea formularelor. Cu toate acestea, Flask poate fi extins prin extensii, dintre care există zeci, care acoperă multe cazuri comune de utilizare, cum ar fi memoria cache, manipularea și validarea formularelor și conectivitatea bazei de date. Această concepție „lean-by-default” vă permite să începeți ingineria unei aplicații Flask cu un minim absolut de funcționalitate, apoi să adăugați doar piesele de care aveți nevoie atunci când aveți nevoie.
Documentația lui Flask este genială și ușor de citit. Documentul de pornire rapidă face o treabă excelentă pentru a vă pune pe picioare, explicând în același timp semnificația alegerilor implicite pentru o aplicație Flask simplă, iar documentele API sunt pline de exemple bune. De asemenea, excelentă este și colecția de fragmente Flash, care sunt exemple rapide și murdare de realizare a unor sarcini specifice, cum ar fi modul în care se returnează un obiect dacă există sau o eroare 404 dacă nu există.
Flask a ajuns la versiunea sa de referință 1.0 în 2018, cu Python 2.6 și Python 3.3 fiind versiunile minime acceptate și cu multe dintre comportamentele sale stabilite în sfârșit în piatră. Flask nu suportă în mod explicit sintaxa asincronă a lui Python, dar o variantă compatibilă cu API a lui Flask numită Quart a fost desprinsă pentru a satisface această cerere.
Pyramid
Primul și ușor, Pyramid este potrivit pentru sarcini precum expunerea codului Python existent ca API REST sau furnizarea nucleului pentru un proiect web în care dezvoltatorul face cea mai mare parte din munca grea.
„Pyramid vă va permite să deveniți productiv rapid și va crește odată cu dumneavoastră”, spune documentația. „Nu vă va reține atunci când aplicația dvs. este mică și nu vă va sta în cale atunci când aplicația dvs. devine mare.”
O modalitate bună de a descrie minimalismul lui Pyramid ar fi „lipsit de politici”, un termen folosit în secțiunea din documentație care discută modul în care Pyramid se poziționează față de alte cadre web. Practic, „free of policy” înseamnă că ce bază de date sau ce limbaj de modelare alegeți să folosiți nu este o preocupare a Pyramid.
Este nevoie de foarte puțină muncă pentru a construi o aplicație Pyramid de bază. Ca și în cazul Bottle și Flask, o aplicație Pyramid poate consta dintr-un singur fișier Python, în afară de fișierele pentru framework-ul propriu-zis. O simplă API cu o singură rută nu necesită mai mult de o duzină sau mai multe linii de cod. Cea mai mare parte din acestea sunt elemente de tip boilerplate, cum ar fi declarațiile from … import
și configurarea serverului WSGI.
În mod implicit, Pyramid include mai multe elemente care sunt comune în aplicațiile web, dar acestea sunt furnizate ca și componente care pot fi asamblate împreună, nu ca soluții complete. Suportul pentru sesiunile de utilizator, de exemplu, vine chiar și cu protecție CSRF. Dar suportul pentru conturile de utilizator, cum ar fi logările sau gestionarea conturilor, nu face parte din afacere. Va trebui să îl dezvoltați singur sau să îl adăugați prin intermediul unui plug-in. Același lucru este valabil și pentru gestionarea formularelor și conexiunile la bazele de date.
Pyramid oferă chiar și o modalitate de a crea șabloane din proiecte Pyramid anterioare pentru a reutiliza munca anterioară. Aceste șabloane, numite „scaffolds”, generează o aplicație Pyramid cu o rutare simplă și câteva șabloane HTML/CSS de pornire. Eșantioanele incluse în pachet includ un exemplu de proiect de pornire și un proiect care se conectează la baze de date prin intermediul popularei biblioteci Python SQLAlchemy.
Instrumentele subțiri de testare și de depanare ale Pyramid fac treaba. Adăugați extensia debugtoolbar
într-o aplicație Pyramid și veți obține o pictogramă pe care se poate face clic pe fiecare pagină web, care generează detalii despre execuția aplicației, inclusiv o urmărire detaliată în caz de erori. Logging-ul și testarea unitară sunt, de asemenea, prezente.
Documentația Pyramid este excelentă. În plus față de un tur rapid al elementelor de bază și de o prezentare în stil tutorial, veți găsi un set de tutoriale contribuită de comunitate și o carte de bucate cu rețete comune. Aceasta din urmă include tehnici de implementare pentru o serie de medii țintă, de la Google App Engine la Nginx.
Pyramid suportă atât Python 2 cât și Python 3, dar nu folosește sintaxa asincronă a lui Python 3. Dacă doriți să valorificați async în Pyramid, consultați proiectul aiopyramid, care include un eșafodaj pentru o aplicație „hello world” alimentată cu async.
Sanic
Conceput pentru viteză și simplitate, Sanic funcționează cu Python 3.6 sau o versiune mai recentă și utilizează sintaxa async/await
a Python (disponibilă începând cu Python 3.5) pentru a vă permite să creați aplicații web eficiente.
Ca și în cazul Flask sau Bottle, un „hello world” Sanic de bază rulează aproximativ 10 linii de cod, majoritatea fiind importuri și alte elemente de tip boilerplate. Diferența esențială este că rutele aplicației trebuie să fie declarate ca funcții async def
și trebuie să utilizați await
pentru a invoca aceste funcții în cadrul codului asincron. Dacă ați mai scris înainte aplicații cu funcționare asincronă, aveți deja cea mai grea parte sub control.
Multe dintre mecanismele pe care Sanic le folosește pentru gestionarea conexiunilor și răspunsurilor vă vor fi familiare. Cererile și răspunsurile sunt doar obiecte cu proprietăți cu aspect familiar, cum ar fi fișiere încărcate, formulare, obiecte JSON, anteturi și așa mai departe.
Aplicațiile cu multe rute devin greu de gestionat. Sanic abordează acest aspect cu „planuri”, obiecte care pot descrie grupuri de rute și care vă permit să le gestionați prin intermediul unei interfețe de nivel înalt. În loc să scrieți fiecare rută în mod explicit sau să folosiți un exces de rute cu variabile, puteți scrie câteva blueprints pentru a descrie în mod generic modul în care rutele funcționează în aplicația dumneavoastră (de exemplu, /object/object_id/action
). Blueprints pot avea middleware comun, ceea ce este util dacă doriți să aplicați funcționalitatea de management la unele rute, dar nu și la altele.
Sanic funcționează și cu alte protocoale decât HTTP. Punctele finale WebSocket necesită doar un decorator diferit și un pic mai multă logică internă (de exemplu, așteptarea și gestionarea răspunsurilor). Protocoalele de rețea personalizate pot fi suportate prin subclasarea asyncio.protocol
.
Sanic lasă în mod deliberat la o parte funcționalități cum ar fi conectivitatea bazelor de date și modelarea HTML, păstrând în același timp caracteristicile pe care cineva le-ar folosi pentru a conecta aceste capacități: middleware, configurarea centralizată a aplicației și așa mai departe.
Tornado
Tornado este un alt cadru mic care vizează un caz de utilizare specific: aplicații de rețea asincrone. Tornado este foarte potrivit pentru crearea de servicii care deschid un număr mare de conexiuni de rețea și le mențin în viață – adică orice implică WebSockets sau interogări lungi. Tornado 6.0 necesită Python 3.5 sau o versiune mai recentă și renunță complet la suportul pentru Python 2.
Ca și Bottle sau Falcon, Tornado omite caracteristicile străine scopului său central. Tornado are un sistem de modelare încorporat pentru a genera HTML și alte ieșiri și oferă mecanisme de internaționalizare, de gestionare a formularelor, de setare a cookie-urilor, de autentificare a utilizatorilor și de protecție CSRF. Dar omite caracteristici, cum ar fi validarea formularelor și un ORM, care sunt destinate în principal aplicațiilor web orientate către utilizator.
Tornado excelează în furnizarea de infrastructură pentru aplicațiile care au nevoie de un control strâns asupra rețelelor asincrone. De exemplu, Tornado oferă nu numai un server HTTP asincron încorporat, ci și un client HTTP asincron. Astfel, Tornado este foarte potrivit pentru crearea de aplicații, cum ar fi un web scraper sau un bot, care interoghează alte site-uri în paralel și acționează în funcție de datele returnate.
Dacă doriți să creați o aplicație care utilizează alte protocoale decât HTTP, Tornado vă acoperă. Tornado oferă acces la conexiuni TCP de nivel scăzut și la socket-uri pentru utilități precum rezolvatoare DNS, precum și la servicii de autentificare de la terți și suportă interoperarea cu alte cadre prin intermediul standardului WSGI. Documentația, care este mică, dar nu săracă, include exemple ample pentru a realiza toate acestea.
Tornado utilizează și completează atât funcționalitatea nativă a lui Python pentru comportamente asincrone. Dacă utilizați Python 3.5, Tornado suportă cuvintele cheie încorporate async
și await
, care promit să ofere aplicațiilor un impuls de viteză. De asemenea, puteți utiliza futures sau callback-uri pentru a gestiona răspunsurile la evenimente.
Tornado oferă o bibliotecă de primitive de sincronizare – semafoare, încuietori și așa mai departe – pentru a coordona evenimentele între corutinele asincrone. Rețineți că Tornado rulează în mod normal cu un singur fir de execuție, astfel încât aceste primitive nu sunt identice cu omonimele lor cu fir de execuție. Cu toate acestea, dacă doriți să rulați Tornado în procese paralele pentru a profita de mai multe socket-uri și nuclee, sunt disponibile instrumente pentru a face acest lucru.
Documentația Tornado acoperă fiecare concept major din cadrul și toate API-urile majore din model. Deși include o aplicație de probă (un web crawler), aceasta servește în principal la demonstrarea modulului de coadă de așteptare al Tornado.
.