Как использовать фоновые задачи со Starlette, когда нет фонового объекта? - PullRequest
0 голосов
/ 27 мая 2020

Я надеюсь, что сейчас не буду использовать сельдерей. В документах Starlette они предоставляют два способа добавления фоновых задач:

Через Graphene: https://www.starlette.io/graphql/

class Query(graphene.ObjectType):
    user_agent = graphene.String()

    def resolve_user_agent(self, info):
        """
        Return the User-Agent of the incoming request.
        """
        user_agent = request.headers.get("User-Agent", "<unknown>")
        background = info.context["background"]
        background.add_task(log_user_agent, user_agent=user_agent)
        return user_agent

Через JSON ответ: https://www.starlette.io/background/

async def signup(request):
    data = await request.json()
    username = data['username']
    email = data['email']
    task = BackgroundTask(send_welcome_email, to_address=email)
    message = {'status': 'Signup successful'}
    return JSONResponse(message, background=task)

Кто-нибудь знает, как добавить задачи в фон Старлетты с помощью Ариадны? Я не могу вернуть ответ JSONResponse в моем преобразователе, и у меня нет доступа к info.context ["background"]. Единственное, что я прикрепил к своему контексту, - это объект запроса.

1 Ответ

0 голосов
/ 02 июня 2020

Решено!

Промежуточное ПО Starlette:

class BackgroundTaskMiddleware(BaseHTTPMiddleware):
    async def dispatch(
            self, request: Request, call_next: RequestResponseEndpoint
    ) -> Response:
        request.state.background = None
        response = await call_next(request)
        if request.state.background:
            response.background = request.state.background
        return response

Резолвер Ariadne:

@query.field("getUser")
@check_authentication
async def resolve_get_user(user, obj, info):
    task = BackgroundTasks()
    task.add_task(test_func)
    task.add_task(testing_func_two, "I work now")
    request = info.context["request"]
    request.state.background = task
    return True


async def test_func():
    await asyncio.sleep(10)
    print("once!!")


async def testing_func_two(message: str):
    print(message)

Функции по-прежнему выполняются синхронно, но потому что они это фоновые задачи. Я не слишком беспокоюсь.

Подробнее об этом здесь.

...