Topp 5 asynkrona webbramverk för Python

Asynkron programmering är en förstklassig medborgare i Python nu. Om du är en webbutvecklare finns det fantastiska ramverk du kan välja mellan!

I skrivande stund är asynkron inte längre bara ett modeord i Python-communityt. Med utgivningen av sin asyncio bibliotek i 3.5-version, Python erkände effekten av Node.js på webbutveckling och introducerade två nya nyckelord i språket – asynkron och vänta. Detta var en mycket stor sak eftersom Python-språket är extremt försiktigt med att utöka kärnsyntaxen om det inte finns ett trängande behov, vilket bara indikerar hur fundamentalt viktigt Python-utvecklarna ansåg de asynkrona funktionerna.

Som ett resultat öppnades slussar för asynkron programmering: nya och gamla bibliotek började använda sig av coroutines-funktionen, asynkrona ramverk exploderade i popularitet och nya skrivs fortfarande idag. Prestanda i nivå med eller bättre än Node.js är inte ovanligt, och om inte dina laddningsmönster involverar massor av CPU-tunga uppgifter, finns det ingen anledning till varför du inte kan göra några tusen förfrågningar per sekund.

Men tillräckligt med motivation!

Låt oss undersöka det nuvarande Python-landskapet och kolla in några av de bästa asynkrona ramverken.

Innehållsförteckning

Tornado

Förvånande, Tornado är inte ett nytt ramverk alls. Dess första release var 2009 (exakt tio år sedan, i skrivande stund) och sedan dess har fokus legat på att tillhandahålla stensäker asynkron programmering med hög samtidighet.

Tornado är inte ett webbramverk i grunden. Det är en samling asynkrona moduler, som också används för att bygga webbrammodulen. Mer specifikt är dessa moduler:

  • Coroutiner och andra primitiver (tornado.gen, tornado.locks, tornado.queues, etc.)
  • Nätverksmoduler (tornado.ioloop, tornado.iostream, etc.)
  • Asynkrona servrar och klienter (tornado.httpserver, tornado.httpclient, etc.)

Dessa har kombinerats för att producera de slutliga ramverksmodulerna: tornado.web, tornado.routing, tornado.template, etc.

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado har en stark och engagerad följare i Python-communityt och används av erfarna arkitekter för att bygga mycket kapabla system. Det är ett ramverk som länge har haft svaret på problemen med samtidighet, men som kanske inte blev mainstream eftersom det inte stöder WSGI-standarden och var för mycket av ett inköp (kom ihåg att huvuddelen av Python-bibliotek fortfarande är synkrona ).

Sanic

Sanic är ett ”modernt” ramverk i ordets rätta bemärkelse: det stöder inte Python-versionen under 3.6, stöder den enkla och universella syntaxen för async/väntar ur lådan, och får dig som ett resultat inte att läsa massor av dokumentation och ha kantfall i ditt sinne innan du kan skriva din första HTTP-hanterare.

Som ett resultat är den resulterande syntaxen ganska trevlig (i alla fall enligt min mening); den liknar kod som du skulle skriva med vilken annan mikroram som helst (Till exempel Flask, CherryPy) med bara några få asynk sprinklade i:

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Sanic är utan tvekan det mest populära och mest älskade asynkrona ramverket i Python-världen. Den har nästan alla funktioner du vill ha för dina projekt – routing, mellanprogram, cookies, versionshantering, ritningar, klassbaserade vyer, statiska filer, streaming, sockets, etc. – och vad den inte erbjuder direkt. — mallar, databasstöd, fil-I/O, köer — kan läggas till eftersom det finns tillräckligt med asynkronbibliotek för dessa idag.

Vibora

Vibora är en nära kusin till Sanic, förutom att den är fixerad vid att bli den snabbaste Python-webbservern där ute. Faktum är att det allra första besöket på dess webbplats hälsar dig med en ramjämförelse:

Som du kan se säger sig Vibora vara flera gånger snabbare än de klassiska ramverken och vara mer än dubbelt så snabb som Sanic, dess närmaste konkurrent. Givetvis ska riktmärken tas med en nypa salt. 🙂

Även om Vibora i syntax och funktioner är jämförbar med Sanic (eller kanske till och med något bättre eftersom den paketerar populära bibliotek och saker som mallar är tillgängliga direkt), skulle jag anse Sanic vara mer mogen eftersom den har funnits längre och har en större gemenskap.

from vibora import Vibora, JsonResponse

app = Vibora()

@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

Men om du är en prestationsjunkie kan Vibora flyta din båt. Som sagt, i skrivande stund undergår Vibora en fullständig omskrivning för att bli ännu snabbare, och det länk till dess prestandaversion står det att den är under ”tung utveckling”. Det kommer att bli en besvikelse för dem som hämtade Vibora tidigare och snart måste möta brytande förändringar, men hej, det är tidiga dagar i Python async-världen, och ingen förväntar sig att saker och ting ska vara stabila.

Quart

Om du gillar att utveckla i Flask men beklagar bristen på asynkront stöd, kommer du att trivas Quart mycket.

Quart är kompatibel med ASGI standard, som är en efterföljare till den berömda WSGI-standarden och erbjuder asynkstöd. Det intressanta med Quart är att det inte bara liknar Flask utan faktiskt är kompatibelt med Flask API! Författaren till detta ramverk ville bevara Flask-känslan och bara lägga till async, WebSockets och HTTP 2-stöd till den. Som ett resultat kan du lära dig Quart direkt från Flask-dokumentationen, bara tänk på att funktioner i Quart är asynkrona.

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

Känns (nästan) precis som Flask, eller hur?!

Eftersom Quart är en utveckling av Flask är alla funktioner i Flask tillgängliga: routing, middleware, sessioner, mallar, ritningar och så vidare. Faktum är att du till och med kan använda Flask-tillägg direkt inuti Quart. En hake är att Python 3.7+ bara stöds, men om du inte kör den senaste versionen av Python kanske asynkronisering inte är rätt väg. 🙂

Dokumentationen är verkligen efterlängtad om du inte har tidigare erfarenhet av Flask, men jag kan rekommendera Quart eftersom det förmodligen är det enda asynkrona ramverket som närmar sig sin 1.0 release snart.

FastAPI

Det sista (men mest imponerande) ramverket på denna lista är FastAPI. Nej, det är inte bara ett API-ramverk; Faktum är att FastAPI verkar vara det mest funktionsrika och dokumentationsrika ramverket som jag stötte på när jag undersökte asynkrona Python-ramverk.

Det är intressant att notera att ramverksförfattaren studerade flera andra ramverk på djupet, från de samtida som Django till moderna som Sanic, samt tittade över teknologier i NestJS (ett Node.js, Typescript webbramverk). Deras utvecklingsfilosofi och omfattande jämförelser går att läsa här.

Syntaxen är ganska trevlig; man kan till och med hävda att det är mycket roligare än de andra ramverken vi har stött på:

rom fastapi import FastAPI

app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}

@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

Och nu, listan över mördande funktioner som får FastAPI att överglänsa andra ramverk:

Automatisk generering av API-dokument: Så snart dina slutpunkter har skrivits kan du spela med API:t med ett standardkompatibelt användargränssnitt. SwaggerUI, ReDoc och andra stöds.

Ramverket gör också automatisk datamodelldokumentation med JSON Schema.

Modern utveckling: Ja, ordet ”modern” slängs runt mycket, men jag fann att FastAPI faktiskt talade. Beroendeinjektion och typtips är förstklassiga medborgare, som inte bara upprätthåller bra kodningsprinciper utan förhindrar buggar och förvirring i det långa loppet.

Omfattande dokumentation: Jag vet inte hur det är med dig, men jag är totalt sugen på bra dokumentation. Och på det här området vinner FastAPI hand-down. Den har sidor på sidor med dokument som förklarar nästan varje liten subtilitet och ”se upp!” ögonblick för utvecklare på alla nivåer. Jag känner ett tydligt ”hjärta och själ” i dokumenten här, och den enda jämförelse jag kan hitta är Django-dokumenten (ja, FastAPI-dokumenten är så bra!).

Utöver grunderna: FastAPI har stöd för WebSockets, Streaming, såväl som GraphQL, förutom att ha alla traditionella hjälpare som CORS, sessioner, cookies och så vidare.

Och hur är det med prestationen? FastAPI är byggt på det fantastiska Starlette-biblioteket, vilket resulterar i prestanda som matchar Node, och i vissa fall även Go! Sammantaget har jag verkligen en känsla av att FastAPI kommer att tävla vidare som det bästa asynkrona ramverket för Python.

Slutsats

Det händer mycket i Python async-landskapet nu för tiden. Nya ramverk dyker upp, gamla skrivs om och biblioteken utvecklas för att matcha asynkront beteende. Medan Python har inbyggt stöd för en evenemangsslinga och det är möjligt att göra delar av din applikation asynkron, kan du välja att gå all-in och bygga vidare på ett av ramverken här. Se bara till att ha det långsiktiga i åtanke: flera av Python asynkrona ramverk där ute är i tidiga skeden och utvecklas snabbt, vilket kommer att skada din utvecklingsprocess och höja affärskostnaderna. Försiktighet är nyckeln!

Men allt sagt och gjort; Python är produktionsfärdigt för att leverera lätta prestanda när det kommer till webbramverk. Om du så länge har funderat på att migrera till Node, nu behöver du inte göra det! 🙂

Låter coolt? Master Python idag!