Open fithisux opened 2 years ago
My init
def init():
app = Flask(__name__)
app.config["JSON_SORT_KEYS"] = False
app.config.update(settings)
app.errorhandler(Exception)(exceptions_handler)
metrics = GunicornInternalPrometheusMetrics.for_app_factory(defaults_prefix=NO_PREFIX)
metrics.init_app(app)
app.before_request(log_request_start)
app.after_request(log_request_end)
app.add_url_rule(rule="/actuator/health", endpoint="healthcheck", view_func=healthcheck, methods=["GET"])
app.add_url_rule(rule="/v1/additive_decomposition/summary", endpoint="/v1/additive_decomposition/summary", view_func=additive_decomposition_v1_proxy, methods=["POST"])
logging.config.dictConfig(app.config.get("LOGGING"))
spec = APISpec(title="Additive Decomposition API", version="0.0.1", openapi_version="3.0.2", plugins=[FlaskPlugin(), MarshmallowPlugin()])
with app.test_request_context():
spec.path(view=additive_decomposition_v1_proxy)
spec.path(view=healthcheck)
with open(DOC_DIR, "w") as f:
json.dump(spec.to_dict(), f, indent=2)
api_doc(app, config_path=DOC_DIR, url_prefix="/api/doc", title="API doc")
return app
@fithisux It seems that a proxy is added before calling the api_doc
function, and its uri is /insight/additive-decomposition
, but this proxy does not work for /api/doc/static/swagger-ui.css
.
Thank you @PWZER. So, this issue is outside my application. Correct?
@fithisux I'm guessing you might need to use like this
api_doc(app, config_path=DOC_DIR, url_prefix="/insight/additive-decomposition/api/doc", title="API doc")
@fithisux Could be the problem caused by this
spec.path(view=additive_decomposition_v1_proxy)
@fithisux were you able to resolve this issue?
I went to a different solution @dulanthaf . I used apispec. https://apispec.readthedocs.io/en/latest/
Even there I had a poblem since routes were not rewritten correctly. So I downloaded in a separate folder, called "static"
the contents of https://github.com/swagger-api/swagger-ui.
Also there I added an empty "init.py"
Now I did in my code:
spec = APISpec(title="Additive Decomposition API", version="0.0.1", openapi_version="3.0.2", plugins=[FlaskPlugin(), MarshmallowPlugin()])
with app.test_request_context():
spec.path(view=xxx1)
spec.path(view=xxx2)
spec.path(view=healthcheck)
with open(OPENAPI_FILE, "w") as f:
json.dump(spec.to_dict(), f, indent=2)
where (I actually dumped the json in the static folder with the rest of swagger ui js)
STATIC_DIR = os.path.dirname(static.__file__)
OPENAPI_FILE = f"{STATIC_DIR}/swagger.json"
now flask can add a route to static as
app = Flask(__name__, static_url_path="/static", static_folder=STATIC_DIR)
I'm not sure if it's the same setup, but we use nginx
for the proxy setup. So what worked for me was, add the proxy path, in your case probably url_prefix="/insight/additive-decomposition/api/doc"
that includes the proxy subdirectory, and then in the nginx
config, add a new location
entry for the server:
location ^~ /insight/additive-decomposition/api/doc/ {
proxy_pass http://something:port/insight/additive-decomposition/api/doc/;
}
Thank you @dulanthaf this is exactly what I suspected, but our SREs did not like this solution. Thank you anyway.
@fithisux any particular reason why the SRE's did not like the solution? I would assume it's one more entry into the existing proxy pass configuration?
@fithisux any particular reason why the SRE's did not like the solution? I would assume it's one more entry into the existing proxy pass configuration?
Because it's workaround, which need to be described and supported. So really good SRE should avoid this solution
@fithisux it happens, since template uses prefix as an absolute path
I.e. paths are looks like /api/doc/static/swagger-ui.css
Any external path override will cause this issue:
Making static path relative to current swagger-ui location should help to avoid this behaviour and be independent from any location overrides
<head>
<meta charset="UTF-8">
<title> {{ title }} </title>
<link rel="stylesheet" type="text/css" href="{{ relative_prefix }}/static/swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="{{ relative_prefix }}/static/index.css" />
<link rel="icon" type="image/png" href="{{ relative_prefix }}/static/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="{{ relative_prefix }}/static/favicon-16x16.png" sizes="16x16" />
</head>
So it should be rendered like this
<head>
<meta charset="UTF-8">
<title> {{ title }} </title>
<link rel="stylesheet" type="text/css" href="doc/static/swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="doc/static/index.css" />
<link rel="icon" type="image/png" href="doc/static/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="doc/static/favicon-16x16.png" sizes="16x16" />
</head>
@fithisux ,
I've made my suggestions with PR mentioned above.
But if you want workaround right now:
class ApplicationDocumentRelative(ApplicationDocument):
@property
def doc_html(self):
doc_location_split = self.url_prefix.split("/")
static_relative_location = doc_location_split.pop()
self.set_relative_swagger_url()
return self.env.get_template("doc.html").render(
url_prefix=static_relative_location,
title=self.title,
config_url=self.swagger_json_uri_absolute,
parameters=self.parameters,
oauth2_config=self.oauth2_config,
)
def set_relative_swagger_url(self):
split_path = self.swagger_json_uri_absolute.split("/")
swagger_url_relative = "/".join(split_path[-2:])
self.parameters["url"] = f'"{swagger_url_relative}"'
def api_doc(app, **kwargs):
doc = ApplicationDocumentRelative(app, **kwargs)
handler = doc.match_handler()
if not handler:
raise RuntimeError("No match application isinstance type!")
if not callable(handler):
raise RuntimeError("handler is callable required!")
return handler(doc)
Result:
Thank you very much. I do not work in this project anymore.
I use swagger-ui-py==21.12.8 and locally Openapi documentation is created without problems and I can enjoy it at
http://localhost:8005/api/doc (8005 is custom).
We deploy in our preview envs, and this url works fine
https://preview-newe-2253-a9wd53-debug.preview.gfknewron.com/insight/additive-decomposition/api/doc/swagger.json
But htis one
https://preview-newe-2253-a9wd53-debug.preview.gfknewron.com/insight/additive-decomposition/api/doc/
has problems with resources
GET https://preview-newe-2253-a9wd53-debug.preview.gfknewron.com/api/doc/static/swagger-ui.css net::ERR_ABORTED 404
it should have been
https://preview-newe-2253-a9wd53-debug.preview.gfknewron.com/insight/additive-decomposition/api/doc/static/swagger-ui.css
The urls are generated from our deployment scripts.
Is there something I can do? Is this a misuse of the library on my part?
Any idea what is missing?
Python 3.10.3 on MacOS Big sur, x86-64, installed through pyenv. flask==2.1.0