Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to correctly reverse proxy FastAPI #1294

Closed
ybizeul opened this issue Apr 20, 2020 · 11 comments
Closed

Unable to correctly reverse proxy FastAPI #1294

ybizeul opened this issue Apr 20, 2020 · 11 comments

Comments

@ybizeul
Copy link

ybizeul commented Apr 20, 2020

Describe the bug

When using FastAPI behind a proxy that adds path elements like /api/1.0/, there is no way to correctly display the swagger

To Reproduce

  1. Configure a reverse proxy to send /api/1.0/ to your FastAPI server
  2. access swagger for the API
  3. Observe that all your objects are prefixed with /api/1.0

See screenshot

Expected behavior

/api/1.0 should not be part of API documentation.

OpenAPI documents this here

There should be a way to configure Server URL to /api/1.0 like indicated in the examples.

Screenshots

image

Environment

  • OS: alpine docker image
  • FastAPI Version 0.54.1
  • Python version 3.7.3

Additional context

Using Traefik as reverse proxy. Traefik like other proxies, has the ability to either :
Pass the request as-is with /api/1.0/, or strip the part from the URL and put it in the X-Forwarded-Prefix header. Maybe that could be used as the server URL for Swagger.

@ybizeul ybizeul added the bug Something isn't working label Apr 20, 2020
@esomir
Copy link

esomir commented May 7, 2020

You can use openapi_prefix (https://fastapi.tiangolo.com/advanced/sub-applications-proxy/) but that's not really viable when the application doesn't know under which prefix it's running from.

Ideally, it should be resolved dynamically based on the X-Forwarded-Prefix. We are using Traefik and having the same problem. We are having a PathPrefix on our route, and using the StripPrefix middleware, which will strip the prefix, and pass it to the X-Forwarded-Prefix header.

@ybizeul
Copy link
Author

ybizeul commented May 10, 2020

That's exactly my situation. Traefik passes all the information but they are not leveraged by fastapi. I switched to Connexion since then

@sm-Fifteen
Copy link
Contributor

Related to #829. @ybizeul raises a good point that the application's root path should probably be included in a server object in the generated OpenAPI documentation and omitted from the routes in the API.

FastAPI's current behavior (not specifying a servers array) falls back to the specification's default, which is this:

If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of /.

So equivalent to:

servers:
  - url: '/'
@tiangolo
Copy link
Owner

tiangolo commented Jun 11, 2020

Passing the root_path was addressed in #1199 🚀

Available in FastAPI 0.56.0.

Here are new docs on running FastAPI Behind a Proxy with a Traefik example.

It could be passed to Uvicorn as:

$ uvicorn app:main --root-path=/api/1.0

About reading the X-Forwarded-Prefix, that would be a feature request to Uvicorn, to read it when using --proxy-headers and set the root_path in the ASGI scope with it.

If it is implemented there, it will be automatically supported here.

@ybizeul
Copy link
Author

ybizeul commented Jun 11, 2020

From what I see in the documentation you point me to, it's not fixed at all and /api/blah is still part of the path for every path

@github-actions github-actions bot removed the answered label Jun 11, 2020
@tiangolo
Copy link
Owner

Ah, you are right, I didn't interpret your original issue description correctly.

You expected it to not contain the prefix and still work.

I have to investigate how the servers would interact with the rest.

@tiangolo
Copy link
Owner

This was fixed/implemented by @rkbeatss in #1596. 🎉

Available in FastAPI version 0.59.0. 🚀

New docs here: https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers

@github-actions
Copy link
Contributor

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

@trungswat
Copy link

Hi,

I am still stuck in FastAPI behind Reverse Proxy Nginx.
Everything running smoothly in local query, ROOT_PATH automatically add to every endpoint:

INFO: 172.29.0.5:45328 - "GET /ge_api/ArtistPerformance HTTP/1.1" 200 OK

But when running FastAPI behind the proxy, the ROOT_PATH is double before the endpoint which causes the query to be wrongly directed.

INFO: 172.29.0.9:45668 - "GET /ge_api/ge_api/ArtistPerformance HTTP/1.0" 404 Not Found

Here is FastAPI app config

app = FastAPI(
    root_path = "/ge_api",
    description = desc,
    openapi_tags = tags_metadata,
    version = "0.0.1",
    docs_url = '/ge_api/docs',
    redoc_url = '/ge_api/redoc',
    openapi_url = '/ge_api/openapi.json',
)

Nginx config:

location /ge_api {
			#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			#proxy_set_header X-Forwarded-Prefix /ge_api/api;
			#proxy_set_header Host $http_host;
			#proxy_http_version 1.1;
			proxy_pass http://ge_api:8080;	
		}

Is there any fixed for the issue? Thanks

@dontsovcmc
Copy link

Is there any fixed for the issue? Thanks

I solved same issue using subapi:
root_path doesn't work for me. openapi_prefix is deprecated.

from fastapi import FastAPI

app = FastAPI()

@app.get("/app")
def read_main():
    return {"message": "Hello World from main app"}

subapi = FastAPI()

@subapi.get("/sub")
def read_sub():
    return {"message": "Hello World from sub API"}

app.mount("/subapi", subapi)
@sm-Fifteen
Copy link
Contributor

Is there any fixed for the issue? Thanks

I solved same issue using subapi: root_path doesn't work for me. openapi_prefix is deprecated.

@dontsovcmc: root_path is intended to be passed to the root app by Uvicorn (and to Uvicorn using the --root-path CLI argument).

Hi,

I am still stuck in FastAPI behind Reverse Proxy Nginx. Everything running smoothly in local query, ROOT_PATH automatically add to every endpoint:

INFO: 172.29.0.5:45328 - "GET /ge_api/ArtistPerformance HTTP/1.1" 200 OK

But when running FastAPI behind the proxy, the ROOT_PATH is double before the endpoint which causes the query to be wrongly directed.

INFO: 172.29.0.9:45668 - "GET /ge_api/ge_api/ArtistPerformance HTTP/1.0" 404 Not Found

Here is FastAPI app config

app = FastAPI(
    root_path = "/ge_api",
    description = desc,
    openapi_tags = tags_metadata,
    version = "0.0.1",
    docs_url = '/ge_api/docs',
    redoc_url = '/ge_api/redoc',
    openapi_url = '/ge_api/openapi.json',
)

Nginx config:

location /ge_api {
			#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			#proxy_set_header X-Forwarded-Prefix /ge_api/api;
			#proxy_set_header Host $http_host;
			#proxy_http_version 1.1;
			proxy_pass http://ge_api:8080;	
		}

Is there any fixed for the issue? Thanks

@trungswat: I'm almost a year late on this, but the mistake you're making here is specifying /ge_api/docs for your ressource URLs, while root_path is automatically going to be prefixed to everything, so the final URL is something like root_path + docs_url == "/ge_api" + '/ge_api/docs'.

@tiangolo tiangolo added question Question or problem reviewed and removed bug Something isn't working labels Feb 22, 2023
@tiangolo tiangolo changed the title [BUG] Unable to correctly reverse proxy FastAPI Feb 24, 2023
@tiangolo tiangolo reopened this Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #7541 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →