Maison >développement back-end >Tutoriel Python >Comment puis-je éviter « H11._util.LocalProtocolError » lors de l'exécution de requêtes HTTP en aval dans une application FastAPI/Uvicorn simultanée ?

Comment puis-je éviter « H11._util.LocalProtocolError » lors de l'exécution de requêtes HTTP en aval dans une application FastAPI/Uvicorn simultanée ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-07 19:25:17260parcourir

How Can I Avoid `H11._util.LocalProtocolError` When Making Downstream HTTP Requests in a Concurrent FastAPI/Uvicorn Application?

Gestion des requêtes HTTP en aval dans Uvicorn/FastAPI

Lors de la création d'un point de terminaison d'API à l'aide de FastAPI/Uvicorn, il est courant d'effectuer des requêtes HTTP en aval. Cependant, lors du traitement de plusieurs requêtes simultanées, les développeurs peuvent rencontrer une erreur :

H11._util.LocalProtocolError: can't handle event type ConnectionClosed when role=SERVER and state=SEND_RESPONSE

Cette erreur se produit car la session de requête par défaut de FastAPI n'est pas entièrement thread-safe. Pour surmonter ce défi, nous devons adopter une approche alternative.

Utiliser Httpx pour les requêtes HTTP asynchrones

Une solution consiste à utiliser la bibliothèque httpx, qui fournit un API. Au lieu de request.Session(), nous pouvons utiliser httpx.AsyncClient(). Ce client permet des requêtes simultanées vers le même hôte, car la connexion TCP sous-jacente est réutilisée.

Dans FastAPI, nous pouvons définir notre gestionnaire de durée de vie pour initialiser l'AsyncClient au démarrage et le fermer à l'arrêt. Par exemple :

@asynccontextmanager
async def lifespan(app: FastAPI):
    async with httpx.AsyncClient() as client:
        yield {'client': client}  # Add the client to the app state

Dans nos points de terminaison, nous pouvons accéder au client en utilisant request.state.client. Nous pouvons faire une demande en aval comme suit :

@app.get('/')
async def home(request: Request):
    client = request.state.client
    req = client.build_request('GET', 'https://www.example.com')
    r = await client.send(req, stream=True)
    return StreamingResponse(r.aiter_raw(), background=BackgroundTask(r.aclose))

Réponses en streaming ou sans streaming

Nous pouvons envoyer la réponse en aval au client de différentes manières. Si nous souhaitons diffuser la réponse, nous pouvons créer un StreamingResponse qui utilise un générateur pour parcourir de manière asynchrone les données de réponse. Sinon, nous pouvons utiliser r.json(), PlainTextResponse ou une réponse personnalisée.

Avantages de l'utilisation de Httpx

L'utilisation de httpx offre plusieurs avantages :

  • API Async pour un traitement efficace des requêtes simultanées.
  • Connexion persistante pool pour des performances améliorées.
  • Contrôle de la taille du pool de connexions.
  • Intégration facile avec les gestionnaires de durée de vie et les points de terminaison de FastAPI.

En tirant parti de httpx, les développeurs peuvent efficacement créer des liens en aval Requêtes HTTP au sein de leurs applications FastAPI/Uvicorn sans rencontrer de problèmes de sécurité des threads. Cela garantit un comportement API fiable et évolutif.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn