Het gemak en de veelzijdigheid van Python betekenen dat het wordt gebruikt om software te bouwen in bijna elke tak van het IT-leven. Een belangrijke niche is web services, waar Python’s snelheid van ontwikkelen en flexibele metaforen het makkelijk maken om websites snel in de lucht te krijgen.
En net zoals je misschien al raadt, geeft Python je veel keus en speelruimte in web frameworks, zowel klein als groot. Immers, niet elk webproject hoeft enterprise-schaal te zijn. De meeste moeten net groot genoeg zijn om de klus te klaren, en niet groter. Dit artikel geeft een overzicht van acht van de bekendste Python frameworks die de nadruk leggen op eenvoud, lichtgewicht levering en een strakke focus.
Bottle
Bottle zou kunnen worden beschouwd als een soort mini-Flask, omdat het nog compacter en beknopter is dan dat andere “microframework.” Door zijn minimale footprint is Bottle ideaal om op te nemen in andere projecten of om snel kleine projecten zoals REST API’s op te leveren. (Flask wordt hieronder besproken.)
De hele codebase voor Bottle past in een enkel bestand en heeft absoluut geen externe afhankelijkheden. Zelfs dan, Bottle is uitgerust met genoeg functionaliteit om veel voorkomende web apps te bouwen zonder afhankelijk te zijn van hulp van buitenaf.
Het routing systeem in Bottle, dat URL’s aan functies koppelt, heeft bijna exact dezelfde syntaxis als Flask. Je bent ook niet beperkt tot een vaste set paden; je kunt ze dynamisch aanmaken. Request en response data, cookies, query variabelen, formulier data van een POST actie, HTTP headers, en file uploads kunnen allemaal worden benaderd en gemanipuleerd door middel van objecten in Bottle.
Elke mogelijkheid is geïmplementeerd met veel aandacht voor detail. Met bestand uploads, bijvoorbeeld, hoef je niet om het bestand te hernoemen als de naamgeving conventie botst met het doel bestandssysteem (zoals schuine strepen in de naam op Windows). Bottle kan dat voor u doen.
Bottle bevat zijn eigen eenvoudige HTML templating engine. Nogmaals, hoewel minimaal, de templating engine heeft alle essentie. Variabelen in een sjabloon worden standaard weergegeven met veilige HTML; je moet zelf aangeven welke variabelen veilig zijn om letterlijk weer te geven. Als je liever Bottle’s template engine omruilt voor een andere, zoals Jinja2, laat Bottle je dat doen zonder gedoe. Ik geef de voorkeur aan het simple-template systeem dat met Bottle wordt meegeleverd; het is snel, de syntax is pretentieloos, en het stelt je in staat om code en template tekst te mengen zonder onnodige problemen.
Bottle ondersteunt zelfs meerdere server back ends. Het komt met zijn eigen ingebouwde miniserver voor snel testen, maar ondersteunt ook generieke WSGI, een breed scala van WSGI-compatibele HTTP-servers, en gewoon oude CGI indien nodig.
Bottle heeft niet zo veel documentatie nodig als andere frameworks, maar de docs zijn zeker niet bekrompen. Al het belangrijke past op een enkele (zij het lange) webpagina. Daarbuiten vindt u volledige documentatie voor elke API, voorbeelden voor het inzetten op verschillende infrastructuren, een uitleg van de ingebouwde templating taal, en een keur aan veelgebruikte recepten.
Net als bij Flask, kunt u de functionaliteit van Bottle handmatig of via plug-ins uitbreiden. Bottle plug-ins zijn lang niet zo talrijk als Flask’s, maar er zijn nuttige stukken, zoals integratie met verschillende database lagen en basis authenticatie van gebruikers. Voor async-ondersteuning kan Bottle een van de bestaande serveradapters gebruiken die asynchroon werken, zoals aiohttp/uvloop, maar async/await
wordt niet van nature ondersteund.
Een gevolg van het minimalisme van Bottle is dat sommige items er gewoon niet zijn. Formulier validatie, met inbegrip van functies zoals CSRF (cross-site request forgery) bescherming, is niet inbegrepen. Als je een web applicatie wilt bouwen die een hoge mate van gebruikersinteractie ondersteunt, zul je die ondersteuning zelf moeten toevoegen.
Een ander probleem met Bottle is dat de ontwikkeling is gestagneerd; de laatste point release, 0.12, kwam in 2013. Dat gezegd hebbende, Bottle wordt nog steeds onderhouden, en de ontwikkelingsversies blijven bruikbaar voor productie. De ontwikkelaars zijn van plan om nieuwe versies uit te brengen die ondersteuning voor oudere edities van Python overbodig maken.
CherryPy
CherryPy bestaat in een of andere vorm al bijna 20 jaar, maar heeft niet het minimalisme en de elegantie verloren die het vanaf het begin hebben onderscheiden.
Het doel achter CherryPy, afgezien van het bevatten van alleen de kale bits die nodig zijn om webpagina’s te serveren, is om te voelen, voor zover mogelijk, niet als een “web framework”, maar als elke andere vorm van Python-toepassing. Sites als Hulu en Netflix hebben CherryPy in productie gebruikt omdat het framework een zeer onopvallende basis biedt om op te bouwen. CherryPy maakt gebruik van gepoolde threads onder de motorkap, hoe beter om multithreaded server adapters te ondersteunen.
CherryPy laat u uw webapplicatie gescheiden houden van de core logica. Om de functies van uw applicatie te mappen naar URLs of routes geserveerd door CherryPy, maakt u een klasse waar de namespaces van de objecten direct mappen naar de URLs die u wilt serveren. Bijvoorbeeld, de root van de website wordt geleverd door een functie met de naam “index.” Parameters die aan die functies worden doorgegeven, worden gebruikt om variabelen af te handelen die door GET- of POST-methodes worden geleverd.
De bits die CherryPy bevat, zijn bedoeld om als bouwstenen op laag niveau te werken. Session identifiers en cookie handling zijn inbegrepen, maar HTML templating is dat niet. Net als Bottle, CherryPy biedt een manier om routes naar mappen op de schijf voor statische file serving.
CherryPy zal vaak afhangen van een bestaande third-party bibliotheek om een functie te ondersteunen in plaats van het zelf te bieden. WebSocket applicaties, bijvoorbeeld, worden niet direct ondersteund door CherryPy, maar via de ws4py bibliotheek.
De documentatie voor CherryPy bevat een handige tutorial walk-through van de verschillende aspecten van het programma. Het neemt je niet mee door een complete end-to-end applicatie, in tegenstelling tot sommige andere framework tutorials, maar het is nog steeds nuttig. De docs komen met handige notities over deployment in virtual hosts, reverse proxying via Apache en Nginx, en vele andere scenario’s.
Falcon
Als je REST-gebaseerde API’s bouwt en niets anders, dan is Falcon speciaal voor jou gemaakt. Lean en snel, met bijna geen afhankelijkheden buiten de standaard bibliotheek, Falcon biedt alles wat je nodig hebt voor REST API’s en niets meer. Falcon 2.0, uitgebracht in 2019, maakt een einde aan Python 2.x ondersteuning en vereist ten minste Python 3.5.
Een groot deel van de reden waarom Falcon het label “licht en slank” verdient, heeft weinig te maken met het aantal regels code in het framework. Het is omdat Falcon bijna geen eigen structuur oplegt aan applicaties. Het enige wat een Falcon applicatie moet doen is aangeven welke functies overeenkomen met welke API endpoints. JSON teruggeven van een endpoint impliceert weinig meer dan het opzetten van een route en de data teruggeven via de json.dumps
functie uit Python’s standaardbibliotheek. Ondersteuning voor async is nog niet geland in Falcon, maar er wordt aan gewerkt om dat mogelijk te maken in Falcon 3.0.
Falcon gebruikt ook verstandige out-of-the-box defaults, dus er is weinig knutselwerk nodig voor de setup. Bijvoorbeeld, 404’s worden standaard getoond voor elke route die niet expliciet is aangegeven. Als je fouten wilt terugsturen naar de client, kun je een van de standaard exceptions gebruiken die met het framework gebundeld zijn (zoals HTTPBadRequest
) of je kunt een generieke falcon.HTTPError
exception gebruiken. Als je preprocessing of postprocessing nodig hebt voor een route, biedt Falcon daar ook hooks voor.
Falcon’s focus op API’s betekent dat er hier weinig is voor het bouwen van web apps met conventionele HTML user interfaces. Verwacht bijvoorbeeld niet veel op het gebied van formulierverwerkingsfuncties en CSRF-beveiligingstools. Falcon biedt echter elegante opties om zijn functionaliteit uit te breiden, zodat meer gesofisticeerde items kunnen gebouwd worden. Naast het bovenvermelde hooking mechanisme, vindt u een interface voor het creëren van middleware die kan worden gebruikt om alle API’s van Falcon te omhullen.
De documentatie voor Falcon is slank in vergelijking met andere frameworks, maar alleen omdat er minder te behandelen valt. De gebruikershandleiding bevat een formele stap-voor-stap uitleg van alle belangrijke functies, samen met een quick-start sectie die u voorbeeldcode laat bekijken met of zonder annotatie.
FastAPI
FastAPI’s naam is een goede samenvatting van wat het doet. Het is gebouwd om snel API endpoints te maken, en het draait ook snel.
FastAPI maakt gebruik van het Starlette project voor zijn high-speed networking core, maar je hoeft niet te weten over Starlette’s internals om FastAPI te gebruiken. Je definieert eindpunten op vrijwel dezelfde manier als een Flask of Bottle app – gebruik decorators om aan te geven welke functies welke routes afhandelen – en retourneert dan woordenboeken die automatisch worden vertaald naar JSON.
Je kunt eenvoudig overriden hoe dingen worden geretourneerd. Bijvoorbeeld, als u HTML/XML van sommige eindpunten wilt retourneren, kunt u dat doen door eenvoudig een aangepast Response
-object te retourneren. Als u middleware op maat wilt toevoegen, kunt u er alles in stoppen dat de ASGI-standaard volgt.
FastAPI maakt gebruik van Python’s type hinting om beperkingen op te leggen aan het soort gegevens dat routes accepteren. Bijvoorbeeld, als u een route met het type Optional
heeft, zal FastAPI alle inzendingen behalve gehele getallen weigeren. U hoeft geen datavalidatiecode aan uw endpoints toe te voegen; u kunt gewoon type-hints gebruiken en FastAPI het werk laten doen.
Natuurlijk worden sommige dingen weggelaten. Er is geen native HTML template engine, bijvoorbeeld, maar er is geen tekort aan oplossingen van derden om dat gat te vullen. Hetzelfde geldt voor database connectiviteit, maar de documentatie bevat details over hoe je bepaalde ORMs (b.v. Peewee) kunt overhalen om met FastAPI’s async gedrag te werken.
Flask
Veel discussies over Python web frameworks beginnen met Flask, en dat is niet voor niets. Flask is een gevestigde, goed begrepen framework dat makkelijk te gebruiken is en behoorlijk stabiel. Het is bijna onmogelijk om de fout in te gaan met Flask voor een lichtgewicht web project of een basis REST API, maar je zult zwaar werk moeten verrichten als je iets groters probeert te bouwen.
Flask’s centrale aantrekkingskracht is de lage toetredingsdrempel. Een basis “hello world” app kan worden opgezet in minder dan 10 regels Python. Flask bevat een veelgebruikt HTML templating systeem, Jinja2, om het renderen van tekst eenvoudig te maken, maar Jinja2 kan worden verwisseld voor een willekeurig aantal andere template-engines (zoals Mustache) of u kunt uw eigen rollen.
In de naam van eenvoud, Flask weglaat niceties zoals een data layer of ORM, en biedt geen voorzieningen voor, zoals, formulier validatie. Echter, Flask kan worden uitgebreid door middel van extensies, waarvan er tientallen zijn, voor veel voorkomende use cases, zoals caching, formulier handling en validatie, en database connectiviteit. Dit lean-by-default ontwerp stelt je in staat om een Flask applicatie te bouwen met het absolute minimum aan functionaliteit, en dan alleen de onderdelen toe te voegen die je nodig hebt wanneer je ze nodig hebt.
Flask’s documentatie is geniaal en makkelijk te lezen. Het quick-start document doet uitstekend werk om je op weg te helpen, terwijl het ook het belang van de standaard keuzes voor een eenvoudige Flask applicatie uitlegt, en de API docs zitten vol met goede voorbeelden. Ook uitstekend is de verzameling Flask-snippets, die quick-and-dirty voorbeelden zijn van hoe specifieke taken te volbrengen, zoals hoe een object te retourneren als het bestaat of een 404-fout als het dat niet doet.
Flask raakte zijn mijlpaal 1.0-release in 2018, met Python 2.6 en Python 3.3 als de minimaal ondersteunde versies, en met veel van zijn gedragingen eindelijk in steen gebeiteld. Flask ondersteunt niet expliciet Python’s async syntaxis, maar een API-compatibele variant van Flask genaamd Quart is gesponsord om aan die vraag te voldoen.
Pyramid
Klein en licht, Pyramid is zeer geschikt voor taken zoals het blootstellen van bestaande Python-code als een REST API, of het leveren van de kern voor een webproject waarbij de ontwikkelaar het meeste zware werk doet.
“Pyramid stelt je in staat om snel productief te worden, en groeit met je mee,” zegt de documentatie. “Het zal je niet tegenhouden als je applicatie klein is, en het zal je niet in de weg zitten als je applicatie groot wordt.”
Een goede manier om het minimalisme van Pyramid te beschrijven zou “vrij van beleid” zijn, een term die wordt gebruikt in het gedeelte van de documentatie dat bespreekt hoe Pyramid zich verhoudt tot andere webframeworks. In principe betekent “vrij van beleid” dat welke database of welke templating taal je kiest te gebruiken niet de zorg van Pyramid is.
Er is zeer weinig werk nodig om een basis Pyramid applicatie te bouwen. Net als bij Bottle en Flask, kan een Pyramid applicatie bestaan uit een enkel Python bestand, afgezien van de bestanden voor het framework zelf. Een eenvoudige one-route API vereist niet meer dan een dozijn of zo regels code. Het meeste daarvan is boilerplate zoals from … import
statements en het opzetten van de WSGI server.
Standaard bevat Pyramid een aantal zaken die gebruikelijk zijn in web apps, maar ze worden geleverd als componenten die aan elkaar geplakt kunnen worden, niet als volledige oplossingen. Ondersteuning voor gebruikerssessies, bijvoorbeeld, wordt zelfs geleverd met CSRF-beveiliging. Maar ondersteuning voor gebruikersaccounts, zoals logins of accountbeheer, maakt geen deel uit van de overeenkomst. Die zult u zelf moeten inbouwen of via een plug-in moeten toevoegen. Hetzelfde geldt voor formulierafhandeling en databaseverbindingen.
Pyramid biedt zelfs een manier om sjablonen te maken van eerdere Pyramid projecten om eerder werk te hergebruiken. Deze templates, genaamd “scaffolds”, genereren een Pyramid app met eenvoudige routing en een aantal starter HTML / CSS templates. Gebundelde scaffolds bevatten een voorbeeld starter-project en een project dat verbinding maakt met databases via de populaire Python bibliotheek SQLAlchemy.
Pyramid’s slanke test- en debug-gereedschappen doen de truc. Bundel de debugtoolbar
extensie in een Pyramid app en je krijgt een aanklikbaar pictogram op elke webpagina dat details genereert over de uitvoering van de app, inclusief een gedetailleerde traceback in het geval van fouten. Logging en unit testing zijn ook aanwezig.
Pyramid’s documentatie is uitstekend. Naast een snelle rondleiding door de basis en een tutorial-achtige walk-through, vindt u een set van community-contributed tutorials en een kookboek van gemeenschappelijke recepten. De laatste bevat deployment technieken voor een keur aan doelomgevingen, van Google App Engine tot Nginx.
Pyramid ondersteunt zowel Python 2 als Python 3, maar maakt geen gebruik van Python 3’s async syntaxis. Als u async in Pyramid wilt gebruiken, zie het aiopyramid project, dat een scaffold bevat voor een async-gestuurde “hello world” applicatie.
Sanic
Ontworpen voor snelheid en eenvoud, Sanic werkt met Python 3.6 of hoger en maakt gebruik van Python’s async/await
syntaxis (beschikbaar vanaf Python 3.5) om u efficiënte web applicaties te laten maken.
Zoals met Flask of Bottle, een basis Sanic “hello world” loopt ongeveer 10 regels code, de meeste van het importeren en andere boilerplate. Het belangrijkste verschil is dat applicatieroutes moeten worden gedeclareerd als async def
-functies, en dat u await
moet gebruiken om deze functies binnen uw async-code aan te roepen. Als u al eerder async-gestuurde applicaties hebt geschreven, hebt u het moeilijkste deel al onder de knie.
Veel van de mechanismen die Sanic gebruikt voor het afhandelen van verbindingen en reacties zullen bekend zijn. Verzoeken en antwoorden zijn gewoon objecten met bekend ogende eigenschappen, zoals geüploade bestanden, formulieren, JSON-objecten, headers, enzovoort.
Applicaties met veel routes worden onhandelbaar om te beheren. Sanic pakt dit aan met “blueprints,” objecten die groepen routes kunnen beschrijven en u in staat stellen om ze te beheren via een high-level interface. In plaats van elke route expliciet te schrijven, of een overmaat aan routes met variabelen te gebruiken, kun je een paar blueprints schrijven om generiek te beschrijven hoe de routes werken in je app (bijv. /object/object_id/action
). Blueprints kunnen gemeenschappelijke middleware hebben, wat handig is als u beheerfunctionaliteit op sommige routes wilt toepassen, maar niet op andere.
Sanic werkt ook met andere protocollen dan HTTP. WebSocket endpoints vereisen slechts een andere decorator en een beetje meer interne logica (bijv. het wachten op en het afhandelen van reacties). Aangepaste netwerkprotocollen kunnen worden ondersteund door asyncio.protocol
te subclassen.
Sanic laat met opzet functionaliteit zoals database connectiviteit en HTML templating achterwege, terwijl het wel de mogelijkheden behoudt om die mogelijkheden in te bouwen: middleware, gecentraliseerde applicatie configuratie, enzovoort.
Tornado
Tornado is een ander klein framework gericht op een specifiek gebruik: asynchrone netwerk applicaties. Tornado is zeer geschikt voor het maken van diensten die een groot aantal netwerkverbindingen openen en deze in leven houden-dat wil zeggen, alles met WebSockets of lange polling. Tornado 6.0 vereist Python 3.5 of hoger, en laat Python 2 ondersteuning geheel achterwege.
Zoals Bottle of Falcon, laat Tornado functies weg die niet van belang zijn voor zijn centrale doel. Tornado heeft een ingebouwd templating systeem voor het genereren van HTML en andere output, en biedt mechanismen voor internationalisatie, formulier afhandeling, cookie instelling, authenticatie van gebruikers, en CSRF bescherming. Maar het laat functies weg, zoals formuliervalidatie en een ORM, die vooral voor gebruiker-facing web apps zijn.
Tornado blinkt uit in het bieden van infrastructuur aan apps die nauwe controle over asynchrone netwerken nodig hebben. Zo biedt Tornado niet alleen een ingebouwde asynchrone HTTP-server, maar ook een asynchrone HTTP-client. Dus, Tornado is zeer geschikt voor het bouwen van apps, zoals een web scraper of een bot, die query andere sites in parallel en handelen op de geretourneerde gegevens.
Als u wilt een app die gebruik maakt van andere protocollen dan HTTP te maken, Tornado heeft u gedekt. Tornado biedt toegang tot laag-niveau TCP verbindingen en sockets voor hulpprogramma’s zoals DNS resolvers, evenals voor authenticatiediensten van derden, en het ondersteunt interoperatie met andere frameworks via de WSGI standaard. De documentatie, die klein maar niet karig is, bevat voldoende voorbeelden om dit alles te bereiken.
Tornado maakt gebruik van en is een aanvulling op Python’s eigen functionaliteit voor asynchroon gedrag. Als je Python 3.5 gebruikt, ondersteunt Tornado de ingebouwde async
en await
keywords, die applicaties een snelheidsboost beloven te geven. Je kunt ook futures of callbacks gebruiken om reacties op events af te handelen.
Tornado biedt een bibliotheek van synchronisatie primitieven-semaphores, locks, enzovoort om events tussen asynchrone coroutines te coördineren. Merk op dat Tornado normaal gesproken single-threaded draait, dus deze primitieven zijn niet hetzelfde als hun threading naamgenoten. Echter, als je Tornado in parallelle processen wilt draaien om gebruik te maken van meerdere sockets en cores, zijn er tools beschikbaar om dit te doen.
Tornado’s documentatie behandelt elk belangrijk concept in het raamwerk en alle belangrijke API’s in het model. Hoewel het een voorbeeld applicatie bevat (een web crawler), is het voornamelijk voor het demonstreren van Tornado’s queuing module.