.. _swagger:

Swagger documentation
=====================


.. currentmodule:: flask_restx

Swagger API documentation is automatically generated and available from your API's root URL.  You can configure the documentation using the :meth:`@api.doc() <Api.doc>` decorator.


Documenting with the ``@api.doc()`` decorator
---------------------------------------------

The ``api.doc()`` decorator allows you to include additional information in the documentation.

You can document a class or a method:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.doc(params={'id': 'An ID'})
    class MyResource(Resource):
        def get(self, id):
            return {}

        @api.doc(responses={403: 'Not Authorized'})
        def post(self, id):
            api.abort(403)


Automatically documented models
-------------------------------

All models instantiated with :meth:`~Namespace.model`, :meth:`~Namespace.clone` and :meth:`~Namespace.inherit`
will be automatically documented in your Swagger specifications.

The :meth:`~Namespace.inherit` method will register both the parent and the child in the Swagger models definitions:

.. code-block:: python

    parent = api.model('Parent', {
        'name': fields.String,
        'class': fields.String(discriminator=True)
    })

    child = api.inherit('Child', parent, {
        'extra': fields.String
    })

The above configuration will produce these Swagger definitions:

.. code-block:: json

    {
        "Parent": {
            "properties": {
                "name": {"type": "string"},
                "class": {"type": "string"}
            },
            "discriminator": "class",
            "required": ["class"]
        },
        "Child": {
            "allOf": [
                {
                    "$ref": "#/definitions/Parent"
                }, {
                    "properties": {
                        "extra": {"type": "string"}
                    }
                }
            ]
        }
    }


The ``@api.marshal_with()`` decorator
-------------------------------------

This decorator works like the raw :func:`marshal_with` decorator
with the difference that it documents the methods.
The optional parameter ``code`` allows you to specify the expected HTTP status code (200 by default).
The optional parameter ``as_list`` allows you to specify whether or not the objects are returned as a list.

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>', endpoint='my-resource')
    class MyResource(Resource):
        @api.marshal_with(resource_fields, as_list=True)
        def get(self):
            return get_objects()

        @api.marshal_with(resource_fields, code=201)
        def post(self):
            return create_object(), 201


The :meth:`Api.marshal_list_with` decorator is strictly equivalent to :meth:`Api.marshal_with(fields, as_list=True)`.

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>', endpoint='my-resource')
    class MyResource(Resource):
        @api.marshal_list_with(resource_fields)
        def get(self):
            return get_objects()

        @api.marshal_with(resource_fields)
        def post(self):
            return create_object()


The ``@api.expect()`` decorator
-------------------------------

The ``@api.expect()`` decorator allows you to specify the expected input fields.
It accepts an optional boolean parameter ``validate`` indicating whether the payload should be validated.
The validation behavior can be customized globally either
by setting the ``RESTX_VALIDATE`` configuration to ``True``
or passing ``validate=True`` to the API constructor.

The following examples are equivalent:

* Using the ``@api.expect()`` decorator:

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        @api.expect(resource_fields)
        def get(self):
            pass

* Using the ``api.doc()`` decorator:

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        @api.doc(body=resource_fields)
        def get(self):
            pass


You can specify lists as the expected input:

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        @api.expect([resource_fields])
        def get(self):
            pass


You can use :exc:`~flask_restx.reqparse.RequestParser` to define the expected input:

.. code-block:: python

    parser = api.parser()
    parser.add_argument('param', type=int, help='Some param', location='form')
    parser.add_argument('in_files', type=FileStorage, location='files')


    @api.route('/with-parser/', endpoint='with-parser')
    class WithParserResource(restx.Resource):
        @api.expect(parser)
        def get(self):
            return {}


Validation can be enabled or disabled on a particular endpoint:

.. code-block:: python

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        # Payload validation disabled
        @api.expect(resource_fields)
        def post(self):
            pass

        # Payload validation enabled
        @api.expect(resource_fields, validate=True)
        def post(self):
            pass


An example of application-wide validation by config:

.. code-block:: python

    app.config['RESTX_VALIDATE'] = True

    api = Api(app)

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        # Payload validation enabled
        @api.expect(resource_fields)
        def post(self):
            pass

        # Payload validation disabled
        @api.expect(resource_fields, validate=False)
        def post(self):
            pass


An example of application-wide validation by constructor:

.. code-block:: python

    api = Api(app, validate=True)

    resource_fields = api.model('Resource', {
        'name': fields.String,
    })

    @api.route('/my-resource/<id>')
    class MyResource(Resource):
        # Payload validation enabled
        @api.expect(resource_fields)
        def post(self):
            pass

        # Payload validation disabled
        @api.expect(resource_fields, validate=False)
        def post(self):
            pass


Documenting with the ``@api.response()`` decorator
--------------------------------------------------

The ``@api.response()`` decorator allows you to document the known responses
and is a shortcut for ``@api.doc(responses='...')``.

The following two definitions are equivalent:

.. code-block:: python

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.response(200, 'Success')
        @api.response(400, 'Validation Error')
        def get(self):
            pass


    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.doc(responses={
            200: 'Success',
            400: 'Validation Error'
        })
        def get(self):
            pass

You can optionally specify a response model as the third argument:


.. code-block:: python

    model = api.model('Model', {
        'name': fields.String,
    })

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.response(200, 'Success', model)
        def get(self):
            pass

The ``@api.marshal_with()`` decorator automatically documents the response:

.. code-block:: python

    model = api.model('Model', {
        'name': fields.String,
    })

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.response(400, 'Validation error')
        @api.marshal_with(model, code=201, description='Object created')
        def post(self):
            pass

You can specify a default response sent without knowing the response code:

.. code-block:: python

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.response('default', 'Error')
        def get(self):
            pass


The ``@api.route()`` decorator
------------------------------

You can provide class-wide documentation using the ``doc`` parameter of ``Api.route()``. This parameter accepts the same values as the ``Api.doc()`` decorator.

For example, these two declarations are equivalent:


* Using ``@api.doc()``:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.doc(params={'id': 'An ID'})
    class MyResource(Resource):
        def get(self, id):
            return {}


* Using ``@api.route()``:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource', doc={'params':{'id': 'An ID'}})
    class MyResource(Resource):
        def get(self, id):
            return {}

Multiple Routes per Resource
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Multiple ``Api.route()`` decorators can be used to add multiple routes for a ``Resource``.
The ``doc`` parameter provides documentation **per route**.

For example, here the ``description`` is applied only to the ``/also-my-resource/<id>`` route:

.. code-block:: python

    @api.route("/my-resource/<id>")
    @api.route(
        "/also-my-resource/<id>",
        doc={"description": "Alias for /my-resource/<id>"},
    )
    class MyResource(Resource):
        def get(self, id):
            return {}

Here, the ``/also-my-resource/<id>`` route is marked as deprecated:

.. code-block:: python

    @api.route("/my-resource/<id>")
    @api.route(
        "/also-my-resource/<id>",
        doc={
            "description": "Alias for /my-resource/<id>, this route is being phased out in V2",
            "deprecated": True,
        },
    )
    class MyResource(Resource):
        def get(self, id):
            return {}

Documentation applied to the ``Resource`` using ``Api.doc()`` is `shared` amongst all
routes unless explicitly overridden:

.. code-block:: python

    @api.route("/my-resource/<id>")
    @api.route(
    "/also-my-resource/<id>",
    doc={"description": "Alias for /my-resource/<id>"},
    )
    @api.doc(params={"id": "An ID", description="My resource"})
    class MyResource(Resource):
    def get(self, id):
        return {}

Here, the ``id`` documentation from the ``@api.doc()`` decorator is present in both routes, 
``/my-resource/<id>`` inherits the ``My resource`` description from the ``@api.doc()`` 
decorator and  ``/also-my-resource/<id>`` overrides the description with ``Alias for /my-resource/<id>``.

Routes with a ``doc`` parameter are given a `unique` Swagger ``operationId``. Routes without
``doc`` parameter have the same Swagger ``operationId`` as they are deemed the same operation.


Documenting the fields
----------------------

Every Flask-RESTX field accepts optional arguments used to document the field:

- ``required``: a boolean indicating if the field is always set (*default*: ``False``)
- ``description``: some details about the field (*default*: ``None``)
- ``example``: an example to use when displaying (*default*: ``None``)

There are also field-specific attributes:

* The ``String`` field accepts the following optional arguments:
    - ``enum``: an array restricting the authorized values.
    - ``min_length``: the minimum length expected.
    - ``max_length``: the maximum length expected.
    - ``pattern``: a RegExp pattern used to validate the string.

* The ``Integer``, ``Float`` and ``Arbitrary`` fields accept the following optional arguments:
    - ``min``: restrict the minimum accepted value.
    - ``max``: restrict the maximum accepted value.
    - ``exclusiveMin``: if ``True``, minimum value is not in allowed interval.
    - ``exclusiveMax``: if ``True``, maximum value is not in allowed interval.
    - ``multiple``: specify that the number must be a multiple of this value.

* The ``DateTime`` field accepts the ``min``, ``max``, ``exclusiveMin`` and ``exclusiveMax`` optional arguments.  These should be dates or datetimes (either ISO strings or native objects).

.. code-block:: python

    my_fields = api.model('MyModel', {
        'name': fields.String(description='The name', required=True),
        'type': fields.String(description='The object type', enum=['A', 'B']),
        'age': fields.Integer(min=0),
    })


Documenting the methods
-----------------------

Each resource will be documented as a Swagger path.

Each resource method (``get``, ``post``, ``put``, ``delete``, ``path``, ``options``, ``head``)
will be documented as a Swagger operation.

You can specify a unique Swagger ``operationId`` with the ``id`` keyword argument:

.. code-block:: python

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.doc(id='get_something')
        def get(self):
            return {}

You can also use the first argument for the same purpose:

.. code-block:: python

    @api.route('/my-resource/')
    class MyResource(Resource):
        @api.doc('get_something')
        def get(self):
            return {}

If not specified, a default ``operationId`` is provided with the following pattern::

    {{verb}}_{{resource class name | camelCase2dashes }}

In the previous example, the default generated ``operationId`` would be ``get_my_resource``.


You can override the default ``operationId`` generator by providing a callable for the ``default_id`` parameter.
This callable accepts two positional arguments:

* The resource class name
* The HTTP method (lower-case)

.. code-block:: python

    def default_id(resource, method):
        return ''.join((method, resource))

    api = Api(app, default_id=default_id)

In the previous example, the generated ``operationId`` would be ``getMyResource``.


Each operation will automatically receive the namespace tag.
If the resource is attached to the root API, it will receive the default namespace tag.


Method parameters
~~~~~~~~~~~~~~~~~

Parameters from the URL path are documented automatically.
You can provide additional information using the ``params`` keyword argument of the ``api.doc()`` decorator:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.doc(params={'id': 'An ID'})
    class MyResource(Resource):
        pass

or by using the ``api.param`` shortcut decorator:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.param('id', 'An ID')
    class MyResource(Resource):
        pass


Input and output models
~~~~~~~~~~~~~~~~~~~~~~~

You can specify the serialized output model using the ``model`` keyword argument of the ``api.doc()`` decorator.

For ``POST`` and ``PUT`` methods, use the ``body`` keyword argument to specify the input model.


.. code-block:: python

    my_model = api.model('MyModel', {
        'name': fields.String(description='The name', required=True),
        'type': fields.String(description='The object type', enum=['A', 'B']),
        'age': fields.Integer(min=0),
    })


    class Person(fields.Raw):
        def format(self, value):
            return {'name': value.name, 'age': value.age}


    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.doc(params={'id': 'An ID'})
    class MyResource(Resource):
        @api.doc(model=my_model)
        def get(self, id):
            return {}

        @api.doc(model=my_model, body=Person)
        def post(self, id):
            return {}


If both ``body`` and ``formData`` parameters are used, a :exc:`~flask_restx.errors.SpecsError` will be raised.

Models can also be specified with a :class:`~flask_restx.reqparse.RequestParser`.

.. code-block:: python

    parser = api.parser()
    parser.add_argument('param', type=int, help='Some param', location='form')
    parser.add_argument('in_files', type=FileStorage, location='files')

    @api.route('/with-parser/', endpoint='with-parser')
    class WithParserResource(restx.Resource):
        @api.expect(parser)
        def get(self):
            return {}


.. note:: The decoded payload will be available as a dictionary in the payload attribute
          in the request context.

          .. code-block:: python

            @api.route('/my-resource/')
            class MyResource(Resource):
                def get(self):
                    data = api.payload

.. note::

    Using :class:`~flask_restx.reqparse.RequestParser` is preferred over the ``api.param()`` decorator
    to document form fields as it also perform validation.

Headers
~~~~~~~

You can document response headers with the ``@api.header()`` decorator shortcut.

.. code-block:: python

    @api.route('/with-headers/')
    @api.header('X-Header', 'Some class header')
    class WithHeaderResource(restx.Resource):
        @api.header('X-Collection', type=[str], collectionType='csv')
        def get(self):
            pass

If you need to specify an header that appear only on a given response,
just use the `@api.response` `headers` parameter.

.. code-block:: python

    @api.route('/response-headers/')
    class WithHeaderResource(restx.Resource):
        @api.response(200, 'Success', headers={'X-Header': 'Some header'})
        def get(self):
            pass


Documenting expected/request headers is done through the `@api.expect` decorator

.. code-block:: python

    parser = api.parser()
    parser.add_argument('Some-Header', location='headers')

    @api.route('/expect-headers/')
    @api.expect(parser)
    class ExpectHeaderResource(restx.Resource):
        def get(self):
            pass

Cascading
---------

Method documentation takes precedence over class documentation,
and inherited documentation takes precedence over parent documentation.

For example, these two declarations are equivalent:

* Class documentation is inherited by methods:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.params('id', 'An ID')
    class MyResource(Resource):
        def get(self, id):
            return {}


* Class documentation is overridden by method-specific documentation:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.param('id', 'Class-wide description')
    class MyResource(Resource):
        @api.param('id', 'An ID')
        def get(self, id):
            return {}

You can also provide method-specific documentation from a class decorator.
The following example will produce the same documentation as the two previous examples:

.. code-block:: python

    @api.route('/my-resource/<id>', endpoint='my-resource')
    @api.params('id', 'Class-wide description')
    @api.doc(get={'params': {'id': 'An ID'}})
    class MyResource(Resource):
        def get(self, id):
            return {}


Marking as deprecated
---------------------

You can mark resources or methods as deprecated with the ``@api.deprecated`` decorator:

.. code-block:: python

    # Deprecate the full resource
    @api.deprecated
    @api.route('/resource1/')
    class Resource1(Resource):
        def get(self):
            return {}

    # Deprecate methods
    @api.route('/resource4/')
    class Resource4(Resource):
        def get(self):
            return {}

        @api.deprecated
        def post(self):
            return {}

        def put(self):
            return {}



Hiding from documentation
-------------------------

You can hide some resources or methods from documentation using any of the following:

.. code-block:: python

    # Hide the full resource
    @api.route('/resource1/', doc=False)
    class Resource1(Resource):
        def get(self):
            return {}

    @api.route('/resource2/')
    @api.doc(False)
    class Resource2(Resource):
        def get(self):
            return {}

    @api.route('/resource3/')
    @api.hide
    class Resource3(Resource):
        def get(self):
            return {}

    # Hide methods
    @api.route('/resource4/')
    @api.doc(delete=False)
    class Resource4(Resource):
        def get(self):
            return {}

        @api.doc(False)
        def post(self):
            return {}

        @api.hide
        def put(self):
            return {}

        def delete(self):
            return {}

.. note::

   Namespace tags without attached resources will be hidden automatically from the documentation.


Documenting authorizations
--------------------------

You can use the ``authorizations`` keyword argument to document authorization information.
See `Swagger Authentication documentation <https://swagger.io/docs/specification/2-0/authentication/>`_
for configuration details.
- ``authorizations`` is a Python dictionary representation of the Swagger ``securityDefinitions`` configuration.

.. code-block:: python

    authorizations = {
        'apikey': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'X-API-KEY'
        }
    }
    api = Api(app, authorizations=authorizations)

Then decorate each resource and method that requires authorization:

.. code-block:: python

    @api.route('/resource/')
    class Resource1(Resource):
        @api.doc(security='apikey')
        def get(self):
            pass

        @api.doc(security='apikey')
        def post(self):
            pass

You can apply this requirement globally with the ``security`` parameter on the ``Api`` constructor:

.. code-block:: python

    authorizations = {
        'apikey': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'X-API-KEY'
        }
    }
    api = Api(app, authorizations=authorizations, security='apikey')


You can have multiple security schemes:

.. code-block:: python

    authorizations = {
        'apikey': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'X-API'
        },
        'oauth2': {
            'type': 'oauth2',
            'flow': 'accessCode',
            'tokenUrl': 'https://somewhere.com/token',
            'authorizationUrl': 'https://somewhere.com/auth',
            'scopes': {
                'read': 'Grant read-only access',
                'write': 'Grant read-write access',
            }
        }
    }
    api = Api(self.app, security=['apikey', {'oauth2': 'read'}], authorizations=authorizations)

Security schemes can be overridden for a particular method:

.. code-block:: python

    @api.route('/authorizations/')
    class Authorized(Resource):
        @api.doc(security=[{'oauth2': ['read', 'write']}])
        def get(self):
            return {}

You can disable security on a given resource or method by passing ``None`` or an empty list as the ``security`` parameter:

.. code-block:: python

    @api.route('/without-authorization/')
    class WithoutAuthorization(Resource):
        @api.doc(security=[])
        def get(self):
            return {}

        @api.doc(security=None)
        def post(self):
            return {}


Expose vendor Extensions
------------------------

Swaggers allows you to expose custom `vendor extensions`_ and you can use them
in Flask-RESTX with the `@api.vendor` decorator.

It supports both extensions as `dict` or `kwargs` and perform automatique `x-` prefix:

.. code-block:: python

    @api.route('/vendor/')
    @api.vendor(extension1='any authorized value')
    class Vendor(Resource):
        @api.vendor({
            'extension-1': {'works': 'with complex values'},
            'x-extension-3': 'x- prefix is optional',
        })
        def get(self):
            return {}


Export Swagger specifications
-----------------------------

You can export the Swagger specifications for your API:

.. code-block:: python

    from flask import json

    from myapp import api

    print(json.dumps(api.__schema__))


.. _swaggerui:

Swagger UI
----------

By default ``flask-restx`` provides Swagger UI documentation, served from the root URL of the API.


.. code-block:: python

    from flask import Flask
    from flask_restx import Api, Resource, fields

    app = Flask(__name__)
    api = Api(app, version='1.0', title='Sample API',
        description='A sample API',
    )

    @api.route('/my-resource/<id>')
    @api.doc(params={'id': 'An ID'})
    class MyResource(Resource):
        def get(self, id):
            return {}

        @api.response(403, 'Not Authorized')
        def post(self, id):
            api.abort(403)


    if __name__ == '__main__':
        app.run(debug=True)


If you run the code below and visit your API's root URL (http://localhost:5000)
you can view the automatically-generated Swagger UI documentation.

.. image:: _static/screenshot-apidoc-quickstart.png


Customization
~~~~~~~~~~~~~

You can control the Swagger UI path with the ``doc`` parameter (defaults to the API root):

.. code-block:: python

    from flask import Flask, Blueprint
    from flask_restx import Api

    app = Flask(__name__)
    blueprint = Blueprint('api', __name__, url_prefix='/api')
    api = Api(blueprint, doc='/doc/')

    app.register_blueprint(blueprint)

    assert url_for('api.doc') == '/api/doc/'


You can specify a custom validator URL by setting ``config.SWAGGER_VALIDATOR_URL``:

.. code-block:: python

    from flask import Flask
    from flask_restx import Api

    app = Flask(__name__)
    app.config.SWAGGER_VALIDATOR_URL = 'http://domain.com/validator'

    api = Api(app)


You can enable [OAuth2 Implicit Flow](https://oauth.net/2/grant-types/implicit/) for retrieving an
authorization token for testing api endpoints interactively within Swagger UI.
The ``config.SWAGGER_UI_OAUTH_CLIENT_ID`` and ``authorizationUrl`` and ``scopes``
will be specific to your OAuth2 IDP configuration.
The realm string is added as a query parameter to authorizationUrl and tokenUrl.
These values are all public knowledge. No *client secret* is specified here.
.. Using PKCE instead of Implicit Flow depends on https://github.com/swagger-api/swagger-ui/issues/5348

.. code-block:: python

    from flask import Flask
    from flask_restx import Api
    
    app = Flask(__name__)

    app.config.SWAGGER_UI_OAUTH_CLIENT_ID = 'MyClientId'
    app.config.SWAGGER_UI_OAUTH_REALM = '-'
    app.config.SWAGGER_UI_OAUTH_APP_NAME = 'Demo'

    api = Api(
        app,
        title=app.config.SWAGGER_UI_OAUTH_APP_NAME,
        security={'OAuth2': ['read', 'write']},
        authorizations={
            'OAuth2': {
                'type': 'oauth2',
                'flow': 'implicit',
                'authorizationUrl': 'https://idp.example.com/authorize?audience=https://app.example.com',
                'clientId': app.config.SWAGGER_UI_OAUTH_CLIENT_ID,
                'scopes': {
                    'openid': 'Get ID token',
                    'profile': 'Get identity',
                }
            }
        }
    )

You can also specify the initial expansion state with the ``config.SWAGGER_UI_DOC_EXPANSION``
setting (``'none'``, ``'list'`` or ``'full'``):

.. code-block:: python

    from flask import Flask
    from flask_restx import Api

    app = Flask(__name__)
    app.config.SWAGGER_UI_DOC_EXPANSION = 'list'

    api = Api(app)

By default, operation ID is hidden as well as request duration, you can enable them respectively with:

.. code-block:: python

    from flask import Flask
    from flask_restx import Api

    app = Flask(__name__)
    app.config.SWAGGER_UI_OPERATION_ID = True
    app.config.SWAGGER_UI_REQUEST_DURATION = True

    api = Api(app)


If you need a custom UI,
you can register a custom view function with the :meth:`~Api.documentation` decorator:

.. code-block:: python

    from flask import Flask
    from flask_restx import Api, apidoc

    app = Flask(__name__)
    api = Api(app)

    @api.documentation
    def custom_ui():
        return apidoc.ui_for(api)

Configuring "Try it Out"
~~~~~~~~~~~~~~~~~~~~~~~~~

By default, all paths and methods have a "Try it Out" button for performing API requests in the browser.
These can be disable **per method** with the ``SWAGGER_SUPPORTED_SUBMIT_METHODS`` configuration option, 
supporting the same values as the ``supportedSubmitMethods`` `Swagger UI parameter <https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#network/>`_.

.. code-block:: python

    from flask import Flask
    from flask_restx import Api

    app = Flask(__name__)

    # disable Try it Out for all methods
    app.config.SWAGGER_SUPPORTED_SUBMIT_METHODS = []

    # enable Try it Out for specific methods
    app.config.SWAGGER_SUPPORTED_SUBMIT_METHODS = ["get", "post"]

    api = Api(app)

Disabling the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~~

To disable Swagger UI entirely, set ``doc=False``:

.. code-block:: python

    from flask import Flask
    from flask_restx import Api

    app = Flask(__name__)
    api = Api(app, doc=False)


.. _vendor extensions: https://swagger.io/specification/#specification-extensions
