Possible to execute a function after returning a response inside a route?
See original GitHub issueFirst Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
try:
return {"message": "Hello World"}
except Exception:
pass
else:
print("I'm executing after successfully returning a response")
finally:
print("I'm executing after a successful or failed response")
Description
I would like to execute a particular action after a response has been successfully returned. My use case is that the end user attempts to retrieve an object via FastAPI from my in memory database. Only if the response succeeds, then I’d like to remove the object from the database. I only want to remove the item after successfully returning a response, as responses may fail due to idiosyncrasies in the user’s connection.
Is there a “FastAPI” way to do this? It seems straightforward but I can’t find anything related to this in the documentation after searching the docs for the words “finally” and “except”.
If there’s not a “FastAPI” way to do this, any other more general approach to achieve this you might recommend?
Much thanks! 🙏🏼
Operating System
Linux
Operating System Details
No response
FastAPI Version
0.65.1
Python Version
3.9.8
Additional Context
No response
Issue Analytics
- State:
- Created 2 years ago
- Comments:10
Top GitHub Comments
you can use Background Tasks for this - https://fastapi.tiangolo.com/tutorial/background-tasks/ - they do exactly what you require - execute code just after successful return
@jacksbox yes I’d like to really check that the response arrives at the client! Otherwise I won’t want to delete the data they are requesting.
Turns out the
BackgroundTask
does this perfectly. If the request is prematurely terminated by the client (say for a connection issue, or timeout) theBackgroundTask
does not execute. And theBackgroundTask
does not start execution until after the successful return of the response. The following code show a working example:And on the client side:
The same correct behavior will occur is the client manually terminates the connection with a
ctrl + c
while the response is in flight.@yinziyan1206 Thanks for the suggestions on the middleware. The middleware doesn’t follow the same paradigm for execution: the
finally
clause will execute no matter the success/failure of the request and middleware appears to not supporttry/except/else/finally
clauses beyondtry/finally
. Here’s an example that demonstrates this:If you do the same requests noted above with the
httpx
client you will never reach theelse
orexcept
blocks of the middleware. However thefinally
block will always execute after a request, so this seems like a great way to cleanup any state that is associated with a request; however, it cannot trigger different behaviors for when a request succeeds and when it fails. Let me know if I’m missing anything here and thank you for your thoughtful feedback and suggestions.The
BackgroundTask
meets the specs I was looking for:If I’ve inaccurately summarized your suggestions or findings please let me know and I’ll update my response. Thanks to you both very much!