Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detail not found error using FastAPI's APIRouter

Tags:

python

fastapi

I have a directory structure as follows:

app
  >routers
   >items.py
  __init__.py
  main.py

Inside main I have the following code:

from typing import Union
import uvicorn
from fastapi import FastAPI, APIRouter
from routers import items



app = FastAPI()
app.include_router(items.router, prefix='/items', tags=['items'])

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

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Within items.py I have the following:

from fastapi import APIRouter

router = APIRouter(
    prefix="/items",
    tags=["items"]
)

@router.api_route("/items")
async def items():
    return {"test": "items"}

When I run the code, I can go to my url http:127.0.0.0:8000/ and I get the Hello world message. But when i go to http:127.0.0.0:8000/items I'm seeing an error:

{"detail": "not found"}

How do I fix this? I tried debugging this but when I hit my debugger, and type items.router it tells me that I'm correctly importing from the right path.

like image 588
turtle_in_mind Avatar asked Oct 28 '25 13:10

turtle_in_mind


1 Answers

You prefixed the route with /items three times!

router = APIRouter(prefix="/items", tags=["items"])
#                         ^^^^^^^^
...
@router.api_route("/items")
#                 ^^^^^^^^
...
app.include_router(items.router, prefix='/items', tags=['items'])
#                                       ^^^^^^^^

This means the endpoint is available at http://127.0.0.1:8000/items/items/items. For that matter you also added the same tag twice, which is unnecessary.

You also would have seen this by opening up the docs page to view the route specs exported by the openapi.json

enter image description here

You only need to specify the route once and tags once per endpoint/routing rule. Try this:

router = APIRouter(prefix="/items", tags=["items"])
...
@router.api_route("/")
...
app.include_router(items.router)

Full example:

import uvicorn
from fastapi import FastAPI, APIRouter

router = APIRouter(prefix="/items", tags=["items"])


@router.api_route("/")
async def items():
    return {"test": "items"}


app = FastAPI()
app.include_router(router)


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


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
like image 63
flakes Avatar answered Oct 30 '25 13:10

flakes