Обрабатывать вызовы API асинхронно - PullRequest
0 голосов
/ 11 октября 2019

ОБНОВЛЕНИЕ об этом: я не понимал, что эту проблему можно решить тривиально, добавив threadaded = True в функцию app.run. Спасибо за предложение другого сервера. Я вижу, что встроенный сервер не самый лучший.

Я использую Flask-Restful, и некоторые из моих маршрутов затем используют asyncio / aiohttp для получения и обработки данных. Однако это делается только внутри маршрутов. Несмотря на то, что это ускоряет время выполнения маршрута (как и предполагалось), мне интересно, может ли мой API обрабатывать другие запросы, пока этот запрос уже выполняется. Вроде как цикл обработки событий для самих маршрутов

Мои вопросы на данный момент таковы:

  • Возможно ли это вообще
  • Я использую неправильную структуру(s) для этого
  • есть хороший ресурс для выполнения такой работы

Простой пример:

Пользователь A отправляет запрос в /api / long, обработка которого занимает более 5 секунд. Пока он работает, пользователь B вызывает маршрут / api / quick (это займет меньше секунды). Таким образом, пользователь B должен дождаться завершения «long», прежде чем его запрос может быть запущен.

Вы можете игнорировать весь этот код ниже, если вы понимаете вопрос, но я добавил его, если кто-то знает конкретныеизменения, которые я мог бы реализовать.

flask-restful_api.py

from flask import Flask
from flask_restful import Api

app = Flask(__name__)
api = Api(app)

api.add_resource(myresource.long, '/long')
api.add_resource(myresource.quick, '/quick') 

if __name__ == '__main__':
    app.run(debug=True)

myresource.py

from flask_restful import Resource
from code import longCode, quickCode

class long(Resource):
    def post():
        response = longCode()
        return response, 200

class quick(Resource)
    def post():
        response = quickCode()
        return response, 200

code.py

import asyncio

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

def longCode():
    list = [1,2,3,4,5]
    itemList = loop.run_until_complete(Task(list))
    return itemList


def quickCode()
    list = [1]
    itemList = loop.run_until_complete(Task(list))
    return itemList


async def Task(list)
    async with aiohttp.ClientSession() as client
        listItem = await asyncio.gather(*asyncio.ensure_future(getItem(client, item) for item in list])


async def getItem(client, item)
    url = 'https://someUrl/api/foo/' + item
    async with client.get(url) as resp
        assert resp.status = 200
        html = await resp.json
        html.update("item":item)
        return html

Я попытался импортировать asyncio в myresource.py и сделать асинхронные функции def post (), но это не получится, потому что «TypeError: Объект типа« сопрограмма »не сериализуем в JSON». Кроме того, поскольку в потоке событий нет циклического события, я чувствую, что этот подход в целом кажется необоснованным, и я не чувствую, что могу решить его самостоятельно. Поэтому любые советы приветствуются!

...