2017-05-05 2 views
0

J'essaie de faire un appel API à partir de mon service et je cours dans les problèmes de boucle d'événements. Quelqu'un peut-il m'aider à comprendre ce que je fais de mal?aiohttp: appel asyncio à partir d'un web en cours d'exécution.Application: RuntimeError: Cette boucle d'événement est déjà en cours d'exécution

Fondamentalement je veux faire un service qui fait quelques calculs basés sur des données tirées d'un service différent.

Je peux appeler ce code ci-dessous d'un cli, mais pas quand je lance une application web (par exemple) frapper http://127.0.0.1:8080/add

loop = asyncio.get_event_loop() 
data = loop.run_until_complete(run_fetch(loop, 'http://google.com')) 

Exemple de code:

from aiohttp import web 
import aiohttp 
import asyncio 

async def add(request): 
    loop = asyncio.get_event_loop() 
    data = loop.run_until_complete(run_fetch(loop, 'http://google.com')) 
    return web.json_response(data) 


async def fetch(client, url): 
    async with client.get(url) as resp: 
     assert resp.status == 200 
     return await resp.text() 


async def run_fetch(loop, url): 
    async with aiohttp.ClientSession(loop=loop) as client: 
     html = await fetch(client, url) 
    return html 

app = web.Application() 
app.router.add_get('/add', add) 
web.run_app(app, host='127.0.0.1', port=8080) 

Exception:

Traitement des erreurs Traceback (dernier appel en dernier): Fichier ".../aiohttp/web_protocol.py", ligne 417, au début resp = rendement de self._request_handler (demande)

Fichier ".../aiohttp/web.py", à la ligne 289, en _handle resp = rendement du gestionnaire (demande)

Fichier » .. ./sample.py "ligne 11, en ajouter des données = loop.run_until_complete (run_fetch (boucle, 'http://google.com'))

fichier" .../python3.6/asyncio/base_events.py », la ligne 454 , dans run_until_complete self.run_forever()

Fichier ".../python3.6/asyncio/base_events.py", ligne 408, dans run_forever augmentation RuntimeError (« Cette boucle d'événement est en cours d'exécution »)

RuntimeError: Cette boucle d'événement est en cours d'exécution

Répondre

1

Le run_until_complete est le moyen d'exécuter un code async à partir du contexte de synchronisation. Sous le capot il ajoute le futur fourni à l'ioloop donné et appelle run_forever puis retourne le résultat ou renvoie l'exception (future résolu).

En fait, vous devez await run_fetch(loop, 'http://google.com'), car la fonction d'appelant est asynchrone.

+0

Cela a du sens, et a fonctionné! Je vous remercie! – user4445586