Maison > Article > développement back-end > ASGI a expliqué : l'avenir du développement Web Python
Traducteur | Li Rui
Critique | Sun Shujuan
Les applications Web Python suivent depuis longtemps la norme WSGI (Web Server Gateway Interface), qui décrit la manière dont elles communiquent avec les serveurs Web. WSGI, initialement introduit en 2003 et mis à jour en 2010, s'appuie uniquement sur des fonctionnalités faciles à implémenter disponibles nativement dans Python 2.2. En conséquence, WSGI a été rapidement intégré à tous les principaux frameworks Web Python et est devenu la pierre angulaire du développement Web Python.
Avance rapide jusqu’en 2022. Python2 est obsolète et Python dispose désormais d'une syntaxe native pour gérer les opérations asynchrones telles que les appels réseau. WSGI et d'autres normes qui supposent un comportement synchrone par défaut ne parviennent pas à tirer parti des gains de performances et d'efficacité de l'asynchrone. Cela signifie que WSGI ne peut pas gérer efficacement les protocoles de haut niveau tels que WebSocket.
Entrez ASGI, qui est l'interface de passerelle de serveur asynchrone. Semblable à WSGI, ASGI décrit une interface commune entre les applications Web Python et les serveurs Web. Contrairement à WSGI, ASGI autorise plusieurs événements asynchrones par application. De plus, ASGI prend en charge les applications synchrones et asynchrones. Les développeurs peuvent migrer les anciennes applications Web WSGI synchrones vers ASGI ou créer de nouvelles applications Web asynchrones à l'aide d'ASGI.
WSGI fonctionne en exposant les fonctions Python à un serveur Web, généralement nommé application ou app. Cette fonction prend deux paramètres :
constituent le corps de la réponse.
Une fonction d'application simple pourrait ressembler à ceci :
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) return [b'Greetings universe']
Si vous utilisez un framework Web compatible WSGI (tel que Flask), alors le framework lui-même fournira une fonction d'application avec tous ses composants. connecté automatiquement.
WSGI présente deux inconvénients : Premièrement, WSGI ne gère qu'une seule demande et réponse à la fois et suppose que la réponse sera renvoyée immédiatement. Il n'existe aucun moyen de gérer les connexions de longue durée, telles que WebSocket ou les connexions HTTP à interrogation longue.
Deuxièmement, WSGI est uniquement synchrone. Même avec le regroupement de connexions multithread, chaque connexion se bloque jusqu'à ce qu'elle renvoie une réponse. De nombreuses configurations WSGI sont capables de gérer des pools de threads et des pools de processus, mais ceux-ci sont limités par la synchronisation de l'interface WSGI elle-même.
ASGI est similaire en apparence à WSGI. Comme WSGI, les développeurs peuvent définir un objet fonction d'application, mais il s'agit d'une fonction asynchrone avec trois paramètres au lieu de deux :
scope : Un dictionnaire contenant des informations sur la requête en cours, similaire à celui de WSGI environ, mais les détails de la convention de dénomination est légèrement différente.
send : fonction appelable asynchrone qui permet à l'application de renvoyer des messages au client.
receive : Fonction appelable asynchrone qui permet à l'application de recevoir des messages du client.
Une simple fonction d'application ASGI ressemble à ceci :
async def application(scope, receive, send): await send({ 'type': 'http.response.start', 'status': 200, 'headers': [ [b'content-type', b'text/plain'], ], }) await send({ 'type': 'http.response.body', 'body': b'Hello, world!', })
Comme le framework Web WSGI, le framework Web ASGI générera sa propre fonction application() et la câblera si nécessaire.
La différence la plus évidente par rapport à ASGI est l'utilisation de métaphores asynchrones tout au long de la fonction. La fonction elle-même est asynchrone, où les en-têtes HTTP et le corps de la réponse sont envoyés via deux commandes wait send() distinctes. De cette façon, les fonctions elles-mêmes et leurs commandes d'envoi ne bloquent rien ; elles peuvent être liées aux appels de l'application et envoyées simultanément depuis de nombreuses autres connexions.
receive n'est pas utilisé dans cet exemple, mais c'est aussi une fonction asynchrone. Il permet de recevoir le corps de la requête sans bloquer d'autres opérations. Les requêtes et les réponses peuvent être transmises de manière incrémentielle vers ou depuis le serveur de cette manière – ce qui ne peut pas être fait correctement, voire pas du tout, avec WSGI.
Lorsque vous utilisez ASGI, vous devez utiliser autant de fonctions asynchrones et de bibliothèques asynchrones que possible. Cela vaut la peine de prendre l'habitude d'utiliser l'asynchrone, car les problèmes liés à l'utilisation de code uniquement synchrone peuvent être sérieux. Tout appel long à une fonction synchrone bloquera toute la chaîne d'appels, rendant presque nuls les avantages de l'utilisation de l'async.
Si vous rencontrez des problèmes lors de l'utilisation d'appels synchrones de longue durée, vous devez utiliser asyncio.run_in_executor pour externaliser l'appel vers un pool de threads ou un pool de processus. Un pool de threads doit être utilisé chaque fois que vous attendez des événements externes ou des tâches non gourmandes en CPU. Le pool de processus doit être utilisé pour les tâches locales gourmandes en CPU.
Par exemple, s'il existe une route dans une application Web qui peut appeler un site Web distant, des threads doivent être utilisés. Ou mieux encore, utilisez la bibliothèque aiohttp qui effectue des requêtes HTTP asynchrones. Si vous souhaitez appeler la bibliothèque d'images Pillow pour redimensionner les images, vous devriez probablement utiliser run_in_executor avec un pool de processus. Bien qu'il y ait une légère surcharge liée au transfert de données entre les processus, l'utilisation de run_in_executor ne bloque pas les autres événements.
En implémentant l'objet application(), les applications Web ASGI peuvent être écrites manuellement. Mais dans la plupart des cas, il est plus simple d’utiliser un framework Web Python natif asynchrone et centré sur ASGI. Voici quelques frameworks Web courants compatibles ASGI :
Starlette et FastAPI : ces frameworks émergents (FastAPI est construit sur Starlette) sont d'abord asynchrones, il n'est donc pas surprenant qu'ils prennent tous en charge ASGI. Si vous développez des applications Web à partir de zéro, il s'agit des frameworks Web les plus modernes et les plus avancés pour Python.
Quart : Bien que Flask, le principal framework Web Python, prenne en charge ASGI, Flask n'est pas conçu pour exploiter les métaphores asynchrones de l'intérieur vers l'extérieur. Quart de GitLab utilise la syntaxe et les métaphores de Flask mais autorise les gestionnaires de routes asynchrones.
Django 3.0 et supérieur : À partir de Django3.0, le prestigieux framework web Django prend en charge ASGI. La prise en charge du code asynchrone dans les applications Django a été ajoutée dans Django 3.1, au lieu de simplement pouvoir monter Django sur des gestionnaires ASGI. Pour un framework peu connu pour sa vitesse d'exécution, la présence d'async apporte de meilleures performances à ceux qui choisissent d'en profiter.
Lien original : https://www.infoworld.com/article/3658336/asgi-explained-the-future-of-python-Web-development.html
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!