Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

middleware breaks behavior of background task #2215

Closed
jkh911208 opened this issue Oct 21, 2020 · 10 comments
Closed

middleware breaks behavior of background task #2215

jkh911208 opened this issue Oct 21, 2020 · 10 comments
Labels
question Question or problem question-migrate

Comments

@jkh911208
Copy link

First check

  • [x ] I added a very descriptive title to this issue.
  • [ x] I used the GitHub search to find a similar issue and didn't find it.
  • [ x] I searched the FastAPI documentation, with the integrated search.
  • [ x] I already searched in Google "How to X in FastAPI" and didn't find any information.
  • [ x] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [ x] I already checked if it is not related to FastAPI but to Pydantic.
  • [ x] I already checked if it is not related to FastAPI but to Swagger UI.
  • [ x] I already checked if it is not related to FastAPI but to ReDoc.
  • [ x] After submitting this, I commit to one of:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Example

import asyncio
import logging
import time

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from starlette.background import BackgroundTasks

app = FastAPI()


@app.get("/")
async def read_root():
    response_object = {"Hello": "World"}
    tasks = BackgroundTasks()
    tasks.add_task(bg_task)
    return JSONResponse(response_object, 202, background=tasks)


async def bg_task():
    logging.error("test1")
    await asyncio.sleep(10)
    logging.error("test2")


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    response.headers["X-Process-Time"] = str(time.time() - start_time)
    response.headers["address"] = request.client.host
    return response

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="0.0.0.0", port=8000,
                log_level="debug", reload=True)

Description

run the above code, make a request to "/"
you will see
Screen Shot 2020-10-21 at 8 50 42 AM
which logging is happening before return the object

but if you make only one request at a time this is fine, but if you make multiple request while background task is running

problem #1 the second request start after first background task finishes
problem #2 when background task of second request finishes, it throw error
Screen Shot 2020-10-21 at 8 52 39 AM

Environment

  • OS: [e.g. Linux / Windows / macOS]: macos and debian
  • FastAPI Version [e.g. 0.3.0]: 0.61.1
  • Python version: 3.8.5

Additional context

if i remove middleware code it works as expected
Screen Shot 2020-10-21 at 8 55 24 AM
all requests are handled and all background tasks are working fine no exception

@jkh911208 jkh911208 added the question Question or problem label Oct 21, 2020
@ycd
Copy link
Contributor

ycd commented Oct 21, 2020

I believe this is related to Starlette Issue 919: Background tasks don't work with middleware that subclasses BaseHTTPMiddleware

@jkh911208
Copy link
Author

thank you @ycd seems like work is still in progress

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Oct 25, 2020

@jkh911208 Could you close this issue, please?

@yingyingPengSAP
Copy link

yingyingPengSAP commented Sep 30, 2021

For those who are searching for how to call background tasks under FastAPI middleware, here is quick solution:

from starlette.background import BackgroundTask
from somewhere import functionA

@app.middleware("http")
async def middleware(request: Request, call_next):
........(do something)
response.background = BackgroundTask(functionA, arg)
return response

You can add a time.sleep(10) in function A to see the result better.
For tasks running in background, it will return the results of function A
very quickly and will not be affected by time.sleep().

Hope this helps someone!

@santigandolfo
Copy link

santigandolfo commented Apr 18, 2022

Hi @jkh911208 @Kludex , why is this issue Closed? Cause I'm trying to use background tasks and a middleware at the same time, and if I send a request to the endpoint through Postman, I receive my response but the request time doesn't finish until the background task does. But if I remove the middleware then it works as expected.

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Apr 18, 2022

What is the version of your FastAPI?

Oh sorry, yeah, this is still a thing. encode/starlette#1441

@santigandolfo
Copy link

What is the version of your FastAPI?

Oh sorry, yeah, this is still a thing. encode/starlette#1441

I'm on v0.75.2
Do you suggest a workaround until that PR is merged in Starlette and FastAPI bumps it's requirements?

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Apr 18, 2022

Yes, don't use BaseHTTPMiddleware.

@santigandolfo
Copy link

Yes, don't use BaseHTTPMiddleware.

In that case I couldn't add general before and after request actions, right?

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Apr 19, 2022

No, I'm saying to not use that class. You can have middlewares: https://pgjones.dev/blog/how-to-write-asgi-middleware-2021

@tiangolo tiangolo reopened this Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #7168 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

6 participants