Skip to content

Added specs-url-scheme option for Api. #238

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

Merged
merged 7 commits into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ doc/_build/
# Specifics
flask_restx/static
node_modules

# pyenv
.python-version

# Jet Brains
.idea
23 changes: 17 additions & 6 deletions flask_restx/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class Api(object):
:param FormatChecker format_checker: A jsonschema.FormatChecker object that is hooked into
the Model validator. A default or a custom FormatChecker can be provided (e.g., with custom
checkers), otherwise the default action is to not enforce any format validation.
:param url_scheme: If set to a string (e.g. http, https), then the specs_url and base_url will explicitly use this
scheme regardless of how the application is deployed. This is necessary for some deployments behind a reverse
proxy.
"""

def __init__(
Expand Down Expand Up @@ -123,6 +126,7 @@ def __init__(
catch_all_404s=False,
serve_challenge_on_401=False,
format_checker=None,
url_scheme=None,
**kwargs
):
self.version = version
Expand Down Expand Up @@ -178,6 +182,7 @@ def __init__(
api=self,
path="/",
)
self.url_scheme = url_scheme
if app is not None:
self.app = app
self.init_app(app)
Expand All @@ -198,7 +203,9 @@ def init_app(self, app, **kwargs):
:param str contact: A contact email for the API (used in Swagger documentation)
:param str license: The license associated to the API (used in Swagger documentation)
:param str license_url: The license page URL (used in Swagger documentation)

:param url_scheme: If set to a string (e.g. http, https), then the specs_url and base_url will explicitly use
this scheme regardless of how the application is deployed. This is necessary for some deployments behind a
reverse proxy.
"""
self.app = app
self.title = kwargs.get("title", self.title)
Expand All @@ -209,6 +216,7 @@ def init_app(self, app, **kwargs):
self.contact_email = kwargs.get("contact_email", self.contact_email)
self.license = kwargs.get("license", self.license)
self.license_url = kwargs.get("license_url", self.license_url)
self.url_scheme = kwargs.get("url_scheme", self.url_scheme)
self._add_specs = kwargs.get("add_specs", True)

# If app is a blueprint, defer the initialization
Expand All @@ -220,7 +228,6 @@ def init_app(self, app, **kwargs):
else:
self.blueprint = app


def _init_app(self, app):
"""
Perform initialization actions with the given :class:`flask.Flask` object.
Expand Down Expand Up @@ -261,7 +268,6 @@ def _init_app(self, app):
DeprecationWarning
)


def __getattr__(self, name):
try:
return getattr(self.default_namespace, name)
Expand Down Expand Up @@ -515,11 +521,16 @@ def endpoint(self, name):
@property
def specs_url(self):
"""
The Swagger specifications relative url (ie. `swagger.json`)
The Swagger specifications relative url (ie. `swagger.json`). If
the spec_url_scheme attribute is set, then the full url is provided instead
(e.g. http://localhost/swaggger.json).

:rtype: str
"""
return url_for(self.endpoint("specs"))
external = None if self.url_scheme is None else True
return url_for(
self.endpoint("specs"), _scheme=self.url_scheme, _external=external
)

@property
def base_url(self):
Expand All @@ -528,7 +539,7 @@ def base_url(self):

:rtype: str
"""
return url_for(self.endpoint("root"), _external=True)
return url_for(self.endpoint("root"), _scheme=self.url_scheme, _external=True)

@property
def base_path(self):
Expand Down
10 changes: 10 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,13 @@ class TestResource(restx.Resource):
assert decorator1.called is True
assert decorator2.called is True
assert decorator3.called is True

def test_specs_url(self, app):
api = restx.Api(app)
specs_url = api.specs_url
assert specs_url == "/swagger.json"

def test_url_scheme(self, app):
api = restx.Api(app, url_scheme="https")
assert api.specs_url == "https://localhost/swagger.json"
assert api.base_url == "https://localhost/"