-
Notifications
You must be signed in to change notification settings - Fork 507
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
Swagger UI refers to http://localhost:5000/swagger.json #223
Comments
I think your issue is Flask related. Have a look at #132. |
I have the same issue, I've spent the whole day debugging it and hopefully got somewhere, my case: I have two flask-restplus apps running, one in localhost:5000 and other in localhost:5100. I am using the example on the README.md for both of them. I am deploying them behind nginx. My intention is that localhost/contacts proxies to localhost:5000 and localhost/notifications proxies to localhost:5100. With the below changes, things work almost as expected:
The solution was to follow http://flask.pocoo.org/snippets/35/ and add the following to nginx block:
And then call flask-restplus with
Needless to say I think it's an awful solution because something that should be solved in the web server layer has to be solved in a middleware / application layer. What if I don't have access to the flask-restplus server code? If swagger.json worked with nginx changes only life would be good. I think what I am trying to achieve is a very common case. Any thoughts @ziirish and @noirbizarre ? And thanks for the work on flask-restplus, it's a very good piece of software :) |
I did the worst fix ever but hopefully it can spark a better implementation. I've created a flask config called SWAGGER_BASEPATH which basically is concatenated to generate the swagger.json URL. So in my case:
And then everything works like a charm without needing to use ReverseProxied, CORS or anything else. My small implementations (happy to adapt or if the thing already existed please point me to it): in flask_restplus/api.py:
in flask_restplus/swagger.py:
And that's it. |
Useful to be able to get swagger URLs from other locations when using reverse a proxy. See I noirbizarre#223
I don't understand why you want to patch a framework when this should be handled by your application code. In this case, why won't you patch Flask directly? @rndrestore issue is typically handled by the Your issue is a bit different because you host your application behind a sub-root path. Again, the snippet you mentioned is probably the best answer you can get. Again, I don't understand why you want to patch the framework. The issue is related to your own environment. Most people won't care about this use-case. Besides, you can (and must) handle this at a different layer in your application stack. For the record, here is how I handle your use-case: This way you can either configure your reverse-proxy to send the appropriate header, or you can add a new option to your application. And I confirm it works with Flask-Restplus since my application heavily relies on this framework. |
I have played with what you mentioned @ziirish , the problem is that I have to duplicate the code (or add an extra lib) / call a reverse proxy on each micro service using flask restplus. It's also doing things in the middleware layer (slow - python) instead of nginx (fast). It's a framework that gives a swagger doc (which is amazing) but IMO it has to be configurable to work under reverse proxies without needing to change the application code or add boilerplate to every middleware running a flask-restplus application. e.g: say I have 500 microservices, with the configuration I can get that path from an environment variable and have it set with Ansible and be done at deployment. Without it I need to always remember to add a ReverseProxy when using flask restplus, add it in 500 places and make 500 services run slower. In the end, in my opinion, looks like an immense overkill to add a whole WSGI middlware just to be able to access the auto generated docs, everything else works perfectly fine just with NGINX and no changes in the application layer. |
I understand your situation, but I'm pretty sure Flask-Restplus is not the right place for your patch. Because this is something related to your own environment, I think it might be a good idea to write your own framework around Flask and Flask-Restplus which implements your fixes. That's how we always did at my past and current jobs. |
@ziirish having said that it wouldn't hurt to have some reverse proxy examples in the repo for apache/nginx/haproxy that are verified working with restplus. |
If users are repeatedly addressing similar issues, these should at minimum be added to the docs, even if they are deemed beyond the scope of a product. Otherwise every adopter is left to cobble a snowflake solution with no benefit from those that have addressed this.
Schedules don't allow for that. It'll remain proprietary code which everyone needs to maintain in isolation. I also find the docs here to stop short of the ideal which, IMO, should include some examples that do go beyond the hard line that defines the projects edge boundaries. |
I think I found some way instead of modifying the framework.
Wish good luck! |
@goodloop 's solution works (at least for ngrok). |
@goodloop - great stuff! Does work! |
@goodloop it works, great!! |
I redirected two nginx location. Everything works. location /swagger.json {
|
I am forking flask-restplus now to make this change to the main code. I plan to add a behind_proxy=True keyword parameter to the Api(...., behind_proxy=True) object. I need this feature to use an nginx reverse proxy to serve many REST+ APIs inside kubernetes. I think this will be a popular fix.
|
Hello, It's been a long time since this issue has been opened. We'll then be discussing how we could improve your experience. |
|
Can you reference the rest of the Flask code that you are using to get this to work? I am a little confused what object you pass to the Custom_API class. Edit: |
I did a solution for this in my project. Swagger gets the host information from SERVER_NAME env. But if you change the SERVER_NAME to a different name from your server, you'll not able to access it. So I've created a 'new' env named SWAGGER_HOST and changed the following line to get this new parameter instead SERVER_NAME and working as expected. flask-restplus/flask_restplus/swagger.py Line 226 in a7e363a
|
Is there any reason @goodloop's solution cannot be integrated into Flask-RestPlus? It works locally and behind a proxy. Would you accept a pull-request containing this fix, together with documentation on how to use Flask-RestPlus behind and nginx reverse-proxy with HTTPS? |
To clarify what @goodloop explained: DOCS_ROUTES = Blueprint('swagger', __name__)
class CustomAPI(Api):
@property
def specs_url(self):
'''
The Swagger specifications absolute url (ie. `swagger.json`)
:rtype: str
'''
return url_for(self.endpoint('specs'), _external=False)
API = CustomAPI(DOCS_ROUTES, title='My Flask API',
version='1.0',
description='My Flask API Project') It works with flask==1.1.1 and flask_restplus==0.13.0 behind a Nginx proxy with this example config:
|
For anyone who drops here, this project has been replaced by flask-restx as mentioned in #770. |
How do i import app in blueprints for swagger? api_service.py
service.py
|
1 - please open restx questions against flask-restx not flask-restplus 2 - if you're using flask-restx for swagger, you don't need flasgger's Swagger. Not really sure what is trying to be accomplished there. flask-restx (and flask-restplus) generate your swagger/openapi docs for you, and vendor in the swagger UI. |
You can follow this solution: https://stackoverflow.com/questions/47508257/serving-flask-restplus-on-https-server
Now when you run locally this hack won't be applied and swagger.json would be served through http and in your server it would be served via https. |
This solved the issue I was having. Thank you! |
I don't agree with have to configure my proxy to pass to /swaggerui, what about when I have multiple microservices behind the same proxy? Please considere use the prefix, to set /${prefix}/swaggerui, thank you! |
We deploy flask-restplus behind a proxying firewall.
Problem here is that the swagger.html generates this:
url: "http://127.0.0.1:5000/swagger.json"
This is fine for local deployments, but blocked when proxied through a firewall.
The problem come from api.py:
@Property
def specs_url(self):
'''
The Swagger specifications absolute url (ie.
swagger.json
)Using _external=False results in '/swagger.json' and solves this issue, and nicely serves swagger UI via the proxying firewall.
The text was updated successfully, but these errors were encountered: