fastapi icon indicating copy to clipboard operation
fastapi copied to clipboard

Typer/Fastapi/asyncio interaction bug

Open eprparadocs opened this issue 2 years ago • 6 comments

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.

Commit to Help

  • [X] I commit to help with one of those options 👆

Example Code

import os
import asyncio


from fastapi import FastAPI
import uvicorn


app = FastAPI()

@app.on_event("startup")
async def on_startup() -> None:
    
    # WHEN YOU GET HERE YOU WILL FIND THE state.invisible IS GONE!!!!
    foo = 2


@app.on_event("shutdown")
async def on_shutdown() -> None:
    # When the system is shutdown
    pass



async def serverapp(appname:str, serverip:str, ctrlport:int):
    config = uvicorn.Config(appname, host=serverip, port=ctrlport)
    server = uvicorn.Server(config)
    # state.invisible IS STILL PRESENT!!!!
    await server.serve()


if __name__ == "__main__":
    import asyncio
    import typer
    import sys
    import os
    
 
    def main(serverip:str = typer.Argument(..., help="IP address of server", metavar='IPaddress'), 
             ctrlport:int = typer.Argument(..., help="PORT of control message server", metavar='int')):
        
        # Create the special name passed into uvicorn!
        mainName = os.path.basename(sys.argv[0]).split('.')[0] + ':app'
        
        # Spin up the server!
        app.state.invisible = 'This will be gone when you get to on_start!'
        asyncio.run(serverapp(mainName, serverip, ctrlport ))
 
        
    typer.run(main)

Description

If you run the code you will find that app.state is no longer available in on_start() though it was set in main().

Set a breakpoint at foo = 2 in on_start() and examine app.start - you wlll see it has disappeared.

It turns out, stepping through the code you see the original module containing 'app' is reloaded!!!

Operating System

Linux

Operating System Details

Linux slickus 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

FastAPI Version

0.75.0

Python Version

3.10.6

Additional Context

None

eprparadocs avatar Sep 12 '22 16:09 eprparadocs

I don’t get it. You are telling Uvicorn to load “filename:app” and that is what is happening. It doesn’t take the “app” from the current file but Uvicorn imports it based on the “filename:app” bit of the run command.

Not a bug I think, but intended behavior.

JarroVGIT avatar Sep 12 '22 16:09 JarroVGIT

Not completely sure (and I am on my phone) but I thought you could just pass an ASGI object (like FastAPI) to Uvicorn, rather than the string with filename:app. It should work then.

note that reload is not availble when passing an app object rather than a string.

JarroVGIT avatar Sep 12 '22 16:09 JarroVGIT

Excuse me? Here is the snippet from the uvicorn site:

import asyncioimport uvicorn async def app(scope, receive, send): ... async def main(): config = uvicorn.Config("main:app", port=5000, log_level="info") server = uvicorn.Server(config) await server.serve() if name == "main": asyncio.run(main())

And per the FastAPI docs I create app this way: app = FastAPI().

So how do I fix this problem, since it isn't in my code - it works as it is supposed to EXCEPT there is no state passed intoe on_start!!!

On Mon, Sep 12, 2022 at 12:31 PM Jarro van Ginkel @.***> wrote:

I don’t get it. You are telling Uvicorn to load “filename:app” and that is what is happening. It doesn’t take the “app” from the current file but Uvicorn imports it based on the “filename:app” bit of the run command.

Not a bug I think, but intended behavior.

— Reply to this email directly, view it on GitHub https://github.com/tiangolo/fastapi/issues/5383#issuecomment-1243992874, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAATQTMEXDTJVSOBAG4BC7DV55LH5ANCNFSM6AAAAAAQKUH6FE . You are receiving this because you authored the thread.Message ID: @.***>

eprparadocs avatar Sep 12 '22 16:09 eprparadocs

Okay, I'll try it.

C.

On Mon, Sep 12, 2022 at 12:34 PM Jarro van Ginkel @.***> wrote:

Not completely sure (and I am on my phone) but I thought you could just pass an ASGI object (like FastAPI) to Uvicorn, rather than the string with filename:app. It should work then.

— Reply to this email directly, view it on GitHub https://github.com/tiangolo/fastapi/issues/5383#issuecomment-1243995545, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAATQTLIN6J75V2X2FLYF5TV55LQTANCNFSM6AAAAAAQKUH6FE . You are receiving this because you authored the thread.Message ID: @.***>

eprparadocs avatar Sep 12 '22 16:09 eprparadocs

That did it! I followed the examples too carefully without reading the API docs. Thanks.

C.

On Mon, Sep 12, 2022 at 12:40 PM Charles Wegrzyn @.***> wrote:

Okay, I'll try it.

C.

On Mon, Sep 12, 2022 at 12:34 PM Jarro van Ginkel < @.***> wrote:

Not completely sure (and I am on my phone) but I thought you could just pass an ASGI object (like FastAPI) to Uvicorn, rather than the string with filename:app. It should work then.

— Reply to this email directly, view it on GitHub https://github.com/tiangolo/fastapi/issues/5383#issuecomment-1243995545, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAATQTLIN6J75V2X2FLYF5TV55LQTANCNFSM6AAAAAAQKUH6FE . You are receiving this because you authored the thread.Message ID: @.***>

eprparadocs avatar Sep 12 '22 16:09 eprparadocs

Screaming (using multiple exclamation marks) and things like "Excuse me?" really doesn't work in your favour when coming to a public place to get help for free from volunteers. Just saying, do with it what you will :)

JarroVGIT avatar Sep 12 '22 16:09 JarroVGIT