Skip to content

Commit

Permalink
Add option to exclude OPTIONS requests
Browse files Browse the repository at this point in the history
These changes add a new optional parameter called `document_options`
to the FlaskApiSpec constructor that will exclude OPTIONS requests
from the swagger specification if set to `False`.

Flask automatically generates OPTIONS requests for each route. There are
cases, such as when using CORS, where one would want these OPTIONS
requests to be generated but do not want to have them in their swagger
docs.

My line of reasoning for wanting to exclude these is: My API users
will never explicitly make an OPTIONS request. The browser will
automatically send a pre-flight OPTIONS request when making a
cross-origin request, and I want to have OPTIONS endpoints in order
to support that, but I don't want to have this functionality adding
a bunch of endpoints to my swagger docs which will largely be ignored
by users.
  • Loading branch information
Brcrwilliams committed Oct 21, 2018
1 parent 535fc9d commit d0cbe1a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
8 changes: 6 additions & 2 deletions flask_apispec/apidoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@

class Converter(object):

def __init__(self, app, spec):
def __init__(self, app, spec, document_options):
self.app = app
self.spec = spec
self.document_options = document_options
try:
self.marshmallow_plugin = next(
plugin for plugin in self.spec.plugins
Expand All @@ -39,13 +40,16 @@ def convert(self, target, endpoint=None, blueprint=None, **kwargs):
def get_path(self, rule, target, **kwargs):
operations = self.get_operations(rule, target)
parent = self.get_parent(target, **kwargs)
excluded_methods = {'head'}
if not self.document_options:
excluded_methods.add('options')
return {
'view': target,
'path': rule_to_path(rule),
'operations': {
method.lower(): self.get_operation(rule, view, parent=parent)
for method, view in six.iteritems(operations)
if method.lower() in (set(VALID_METHODS) - {'head'})
if method.lower() in (set(VALID_METHODS) - excluded_methods)
},
}

Expand Down
11 changes: 8 additions & 3 deletions flask_apispec/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@ def get_pet(pet_id):
:param Flask app: App associated with API documentation
:param APISpec spec: apispec specification associated with API documentation
:param bool document_options: Whether or not to include
OPTIONS requests in the specification
"""

def __init__(self, app=None):
def __init__(self, app=None, document_options=True):
self._deferred = []
self.app = app
self.view_converter = None
self.resource_converter = None
self.spec = None
self.document_options = document_options

if app:
self.init_app(app)
Expand All @@ -53,8 +56,10 @@ def init_app(self, app):
make_apispec(self.app.config.get('APISPEC_TITLE', 'flask-apispec'),
self.app.config.get('APISPEC_VERSION', 'v1'))
self.add_swagger_routes()
self.resource_converter = ResourceConverter(self.app, spec=self.spec)
self.view_converter = ViewConverter(app=self.app, spec=self.spec)
self.resource_converter = ResourceConverter(self.app,
self.spec,
self.document_options)
self.view_converter = ViewConverter(self.app, self.spec, self.document_options)

for deferred in self._deferred:
deferred()
Expand Down

0 comments on commit d0cbe1a

Please sign in to comment.