Search code examples
python-3.xhttp-status-code-404fastapiuvicorn

FastAPI app results in 404 error response when it is started using uvicorn.run


New to FastAPI and uvicorn, but I'm wondering why when I run my "hello world" service by starting it using uvicorn from the command line, it works fine, but when using the "uvicorn.run" method from inside my service, the service starts, but when I send a GET I always get a 404 with a response body of {"detail": "Not Found"}?

Here is my code:

import uvicorn
from fastapi import FastAPI

app = FastAPI()
uvicorn.run(app, host="127.0.0.1", port=5049)


@app.get("/")
async def root():
    return {"message": "Hello World"}

That always returns with a 404 as follows:

# curl http://127.0.0.1:5049/
{"detail":"Not Found"}

The output from my service shows:

INFO:     Started server process [28612]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:5049 (Press CTRL+C to quit)
INFO:     127.0.0.1:55446 - "GET / HTTP/1.1" 404 Not Found

If I comment out the "uvicorn.run" line and then start the service from the command line with (running on Windows 10):

uvicorn.exe test:app --host=127.0.0.1 --port=5049

I get the correct response:

# curl http://127.0.0.1:5049/
{"message":"Hello World"}

Solution

  • Because, the statement uvicorn.run(app, host="127.0.0.1", port=5049) is executed before the root(...) function and the execution is never reaching to the root(...) function.

    But, when you run the app using the command line, the app is loaded in a lazy fashion, and hence the root(...) function is getting executed.

    Something like this would surely resolve the issue:

    import uvicorn
    from fastapi import FastAPI
    
    app = FastAPI()
    
    
    @app.get("/")
    async def root():
        return {"message": "Hello World"}
    
    
     # at last, the bottom of the file/module
    if __name__ == "__main__":
        uvicorn.run(app, host="127.0.0.1", port=5049)