Describe the bug
There is a bug when API is organized with different versions (FastAPI apps) which mounted via global app.mount.
ReDoc duplicates mount's prefix. For example, http://127.0.0.1:8000/v1/v1/test.
It works well in default OpenAPI Docs.
Environment:
Additional context
import fastapi
from fastapi import APIRouter
app = fastapi.FastAPI(docs_url=None, redoc_url=None)
router = APIRouter()
@router.get("/users/", tags=["users"])
async def read_users():
return [{"username": "Foo"}, {"username": "Bar"}]
apiV1 = fastapi.FastAPI(openapi_prefix="/v1", version="1.0.0")
apiV1.include_router(router)
app.mount("/v1", apiV1)

Well, isn't it because you are adding a prefix to openapi? I see 2 prefixes: a v1 in the mount and another v1 in openapi_prefix.
It does not work at all if I omit openapi_prefix or app.mount("/v1"
I can't reproduce the issue :S (fastapi v0.40.0):
fastapi_test.py:
import fastapi
app = fastapi.FastAPI(docs_url=None, redoc_url=None)
apiV1 = fastapi.FastAPI(openapi_prefix="/v1", version="1.0.0")
app.mount("/v1", apiV1)
uvicorn --reload fastapi_test:app

I mean "readoc". As I mentioned above, classic openAPI docs works well. See the updated example above in the initial comment.
Same:

It's weird, is that all of your code? Maybe it's something else?
As a side note, going to /v1/v1/... returns 404
Please try the code in the example how to reproduce it. See https://github.com/tiangolo/fastapi/issues/594#issue-503005145
Done, and it works as expected:
import fastapi from fastapi import APIRouter app = fastapi.FastAPI(docs_url=None, redoc_url=None) router = APIRouter() @router.get("/users/", tags=["users"]) async def read_users(): return [{"username": "Foo"}, {"username": "Bar"}] apiV1 = fastapi.FastAPI(openapi_prefix="/v1", version="1.0.0") apiV1.include_router(router) app.mount("/v1", apiV1)
uvicorn --reload fastapi_test:app





Try cleaning your environment, recreating and reinstalling dependencies and run again.
Oh shit, I got it!

Gonna check it out in the code
I've inspected FastAPI code and I can say that this bug is in the redoc JS lib: it's building the URLs using the current URL (http://127.0.0.1/v1) + the URL pointed in openapi.json (/v1/users/), whereas SwaggerUI is building them correctly (using the host + the openapi.json URLs).
I don't see it possible to fix from the FastAPI project :(
Gonna see if I can dig some more to report it to the other project
@HacKanCuBa thank you so much for your research!
It could be related to https://github.com/Redocly/redoc/issues/926
Should I close this issue?
Not sure, I'm not a maintainer, just trying to help :)
I would leave it opened given that everybody using mount will encounter this issue.
YES! I got it. It's certainly related to it.
I tried serving a special openapi.json file for redoc that contained the servers definition with a URL being http://127.0.0.1:8000. With it, the ReDoc JS reads the server definition from there instead of getting it from the current URL and works :)
Here's how to replicate it:
output = {"openapi": openapi_version, "info": info, "servers": [{"url": "http://127.0.0.1:8000"}]}
For some reason it still says null instead of retrieving from the users api.
This is of course totally a hack and NOT a solution.
The bug does belong to the redoc js lib. However, the interesting thing is that indicating the server definition in the openapi.json file could be a good thing to add to the openapi definition generator (maybe even with a setting). Or maybe not, I really don't know. What do you think @tiangolo ?
Thanks for all the help @HacKanCuBa !
@ivankravets Yeah, that's an issue with ReDoc, not with FastAPI. If you want to modify the OpenAPI and try to add the servers or anything else, you can do that too, here are the docs: https://fastapi.tiangolo.com/advanced/extending-openapi/
Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.