Easy OpenAPI specs and Swagger UI for your Flask API

Overview

Flasgger

Easy Swagger UI for your Flask API

Build Status Code Health Coverage Status PyPI Donate with Paypal

flasgger

Flasgger is a Flask extension to extract OpenAPI-Specification from all Flask views registered in your API.

Flasgger also comes with SwaggerUI embedded so you can access http://localhost:5000/apidocs and visualize and interact with your API resources.

Flasgger also provides validation of the incoming data, using the same specification it can validates if the data received as as a POST, PUT, PATCH is valid against the schema defined using YAML, Python dictionaries or Marshmallow Schemas.

Flasgger can work with simple function views or MethodViews using docstring as specification, or using @swag_from decorator to get specification from YAML or dict and also provides SwaggerView which can use Marshmallow Schemas as specification.

Flasgger is compatible with Flask-RESTful so you can use Resources and swag specifications together, take a look at restful example.

Flasgger also supports Marshmallow APISpec as base template for specification, if you are using APISPec from Marshmallow take a look at apispec example.

Table of Contents

Created by gh-md-toc

Top Contributors

Examples and demo app

There are some example applications and you can also play with examples in Flasgger demo app

NOTE: all the examples apps are also test cases and run automatically in Travis CI to ensure quality and coverage.

Docker

The examples and demo app can also be built and run as a Docker image/container:

docker build -t flasgger .
docker run -it --rm -p 5000:5000 --name flasgger flasgger

Then access the Flasgger demo app at http://localhost:5000 .

Installation

under your virtualenv do:

Ensure you have latest setuptools

pip install -U setuptools

then

pip install flasgger

or (dev version)

pip install https://github.com/rochacbruno/flasgger/tarball/master

NOTE: If you want to use Marshmallow Schemas you also need to run pip install marshmallow apispec

How to run tests

(You may see the command in .travis.yml for "-before install" part) In your virtualenv:

pip install -r requirements.txt

pip requirements-dev.txt make test


# Getting started

## Using docstrings as specification

Create a file called for example `colors.py`

```python
from flask import Flask, jsonify
from flasgger import Swagger

app = Flask(__name__)
swagger = Swagger(app)

@app.route('/colors/<palette>/')
def colors(palette):
    """Example endpoint returning a list of colors by palette
    This is using docstrings for specifications.
    ---
    parameters:
      - name: palette
        in: path
        type: string
        enum: ['all', 'rgb', 'cmyk']
        required: true
        default: all
    definitions:
      Palette:
        type: object
        properties:
          palette_name:
            type: array
            items:
              $ref: '#/definitions/Color'
      Color:
        type: string
    responses:
      200:
        description: A list of colors (may be filtered by palette)
        schema:
          $ref: '#/definitions/Palette'
        examples:
          rgb: ['red', 'green', 'blue']
    """
    all_colors = {
        'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
        'rgb': ['red', 'green', 'blue']
    }
    if palette == 'all':
        result = all_colors
    else:
        result = {palette: all_colors.get(palette)}

    return jsonify(result)

app.run(debug=True)

Now run:

python colors.py

And go to: http://localhost:5000/apidocs/

You should get:

colors

Using external YAML files

Save a new file colors.yml

Example endpoint returning a list of colors by palette
In this example the specification is taken from external YAML file
---
parameters:
  - name: palette
    in: path
    type: string
    enum: ['all', 'rgb', 'cmyk']
    required: true
    default: all
definitions:
  Palette:
    type: object
    properties:
      palette_name:
        type: array
        items:
          $ref: '#/definitions/Color'
  Color:
    type: string
responses:
  200:
    description: A list of colors (may be filtered by palette)
    schema:
      $ref: '#/definitions/Palette'
    examples:
      rgb: ['red', 'green', 'blue']

lets use the same example changing only the view function.

from flasgger import swag_from

@app.route('/colors/<palette>/')
@swag_from('colors.yml')
def colors(palette):
    ...

If you do not want to use the decorator you can use the docstring file: shortcut.

@app.route('/colors/<palette>/')
def colors(palette):
    """
    file: colors.yml
    """
    ...

Using dictionaries as raw specs

Create a Python dictionary as:

specs_dict = {
  "parameters": [
    {
      "name": "palette",
      "in": "path",
      "type": "string",
      "enum": [
        "all",
        "rgb",
        "cmyk"
      ],
      "required": "true",
      "default": "all"
    }
  ],
  "definitions": {
    "Palette": {
      "type": "object",
      "properties": {
        "palette_name": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Color"
          }
        }
      }
    },
    "Color": {
      "type": "string"
    }
  },
  "responses": {
    "200": {
      "description": "A list of colors (may be filtered by palette)",
      "schema": {
        "$ref": "#/definitions/Palette"
      },
      "examples": {
        "rgb": [
          "red",
          "green",
          "blue"
        ]
      }
    }
  }
}

Now take the same function and use the dict in the place of YAML file.

@app.route('/colors/<palette>/')
@swag_from(specs_dict)
def colors(palette):
    """Example endpoint returning a list of colors by palette
    In this example the specification is taken from specs_dict
    """
    ...

Using Marshmallow Schemas

FIRST: pip install marshmallow apispec

USAGE #1: SwaggerView

from flask import Flask, jsonify
from flasgger import Swagger, SwaggerView, Schema, fields


class Color(Schema):
    name = fields.Str()

class Palette(Schema):
    pallete_name = fields.Str()
    colors = fields.Nested(Color, many=True)

class PaletteView(SwaggerView):
    parameters = [
        {
            "name": "palette",
            "in": "path",
            "type": "string",
            "enum": ["all", "rgb", "cmyk"],
            "required": True,
            "default": "all"
        }
    ]
    responses = {
        200: {
            "description": "A list of colors (may be filtered by palette)",
            "schema": Palette
        }
    }

    def get(self, palette):
        """
        Colors API using schema
        This example is using marshmallow schemas
        """
        all_colors = {
            'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
            'rgb': ['red', 'green', 'blue']
        }
        if palette == 'all':
            result = all_colors
        else:
            result = {palette: all_colors.get(palette)}
        return jsonify(result)

app = Flask(__name__)
swagger = Swagger(app)

app.add_url_rule(
    '/colors/<palette>',
    view_func=PaletteView.as_view('colors'),
    methods=['GET']
)

app.run(debug=True)

USAGE #2: Custom Schema from flasgger

  • Body - support all fields in marshmallow
  • Query - support simple fields in marshmallow (Int, String and etc)
  • Path - support only int and str
from flask import Flask, abort
from flasgger import Swagger, Schema, fields
from marshmallow.validate import Length, OneOf

app = Flask(__name__)
Swagger(app)

swag = {"swag": True,
        "tags": ["demo"],
        "responses": {200: {"description": "Success request"},
                      400: {"description": "Validation error"}}}


class Body(Schema):
    color = fields.List(fields.String(), required=True, validate=Length(max=5), example=["white", "blue", "red"])

    def swag_validation_function(self, data, main_def):
        self.load(data)

    def swag_validation_error_handler(self, err, data, main_def):
        abort(400, err)


class Query(Schema):
    color = fields.String(required=True, validate=OneOf(["white", "blue", "red"]))

    def swag_validation_function(self, data, main_def):
        self.load(data)

    def swag_validation_error_handler(self, err, data, main_def):
        abort(400, err)

    swag_in = "query"


@app.route("/color/<id>/<name>", methods=["POST"], **swag)
def index(body: Body, query: Query, id: int, name: str):
    return {"body": body, "query": query, "id": id, "name": name}

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

NOTE: take a look at examples/validation.py for a more complete example.

NOTE: when catching arguments in path rule always use explicit types, bad: /api/<username> good: /api/<string:username>

Using Flask RESTful Resources

Flasgger is compatible with Flask-RESTful you only need to install pip install flask-restful and then:

from flask import Flask
from flasgger import Swagger
from flask_restful import Api, Resource

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

class Username(Resource):
    def get(self, username):
        """
        This examples uses FlaskRESTful Resource
        It works also with swag_from, schemas and spec_dict
        ---
        parameters:
          - in: path
            name: username
            type: string
            required: true
        responses:
          200:
            description: A single user item
            schema:
              id: User
              properties:
                username:
                  type: string
                  description: The name of the user
                  default: Steven Wilson
        """
        return {'username': username}, 200


api.add_resource(Username, '/username/<username>')

app.run(debug=True)

Auto-parsing external YAML docs and MethodViews

Flasgger can be configured to auto-parse external YAML API docs. Set a doc_dir in your app.config['SWAGGER'] and Swagger will load API docs by looking in doc_dir for YAML files stored by endpoint-name and method-name. For example, 'doc_dir': './examples/docs/' and a file ./examples/docs/items/get.yml will provide a Swagger doc for ItemsView method get.

Additionally, when using Flask RESTful per above, by passing parse=True when constructing Swagger, Flasgger will use flask_restful.reqparse.RequestParser, locate all MethodViews and parsed and validated data will be stored in flask.request.parsed_data.

Handling multiple http methods and routes for a single function

You can separate specifications by endpoint or methods

from flasgger.utils import swag_from

@app.route('/api/<string:username>', endpoint='with_user_name', methods=['PUT', 'GET'])
@app.route('/api/', endpoint='without_user_name')
@swag_from('path/to/external_file.yml', endpoint='with_user_name')
@swag_from('path/to/external_file_no_user_get.yml', endpoint='without_user_name', methods=['GET'])
@swag_from('path/to/external_file_no_user_put.yml', endpoint='without_user_name', methods=['PUT'])
def fromfile_decorated(username=None):
    if not username:
        return "No user!"
    return jsonify({'username': username})

And the same can be achieved with multiple methods in a MethodView or SwaggerView by registering the url_rule many times. Take a look at examples/example_app

Use the same data to validate your API POST body.

Setting swag_from's validation parameter to True will validate incoming data automatically:

from flasgger import swag_from

@swag_from('defs.yml', validation=True)
def post():
    # if not validate returns ValidationError response with status 400
    # also returns the validation message.

Using swagger.validate annotation is also possible:

from flasgger import Swagger

swagger = Swagger(app)

@swagger.validate('UserSchema')
def post():
    '''
    file: defs.yml
    '''
    # if not validate returns ValidationError response with status 400
    # also returns the validation message.

Yet you can call validate manually:

from flasgger import swag_from, validate

@swag_from('defs.yml')
def post():
    validate(request.json, 'UserSchema', 'defs.yml')
    # if not validate returns ValidationError response with status 400
    # also returns the validation message.

It is also possible to define validation=True in SwaggerView and also use specs_dict for validation.

Take a look at examples/validation.py for more information.

All validation options can be found at http://json-schema.org/latest/json-schema-validation.html

Custom validation

By default Flasgger will use python-jsonschema to perform validation.

Custom validation functions are supported as long as they meet the requirements:

  • take two, and only two, positional arguments:
    • the data to be validated as the first; and
    • the schema to validate against as the second argument
  • raise any kind of exception when validation fails.

Any return value is discarded.

Providing the function to the Swagger instance will make it the default:

from flasgger import Swagger

swagger = Swagger(app, validation_function=my_validation_function)

Providing the function as parameter of swag_from or swagger.validate annotations or directly to the validate function will force it's use over the default validation function for Swagger:

from flasgger import swag_from

@swag_from('spec.yml', validation=True, validation_function=my_function)
...
from flasgger import Swagger

swagger = Swagger(app)

@swagger.validate('Pet', validation_function=my_function)
...
from flasgger import validate

...

    validate(
        request.json, 'Pet', 'defs.yml', validation_function=my_function)

Validation Error handling

By default Flasgger will handle validation errors by aborting the request with a 400 BAD REQUEST response with the error message.

A custom validation error handling function can be provided to supersede default behavior as long as it meets the requirements:

  • take three, and only three, positional arguments:
    • the error raised as the first;
    • the data which failed validation as the second; and
    • the schema used in to validate as the third argument

Providing the function to the Swagger instance will make it the default:

from flasgger import Swagger

swagger = Swagger(app, validation_error_handler=my_handler)

Providing the function as parameter of swag_from or swagger.validate annotations or directly to the validate function will force it's use over the default validation function for Swagger:

from flasgger import swag_from

@swag_from(
    'spec.yml', validation=True, validation_error_handler=my_handler)
...
from flasgger import Swagger

swagger = Swagger(app)

@swagger.validate('Pet', validation_error_handler=my_handler)
...
from flasgger import validate

...

    validate(
        request.json, 'Pet', 'defs.yml',
        validation_error_handler=my_handler)

Examples of use of a custom validation error handler function can be found at example validation_error_handler.py

Get defined schemas as python dictionaries

You may wish to use schemas you defined in your Swagger specs as dictionaries without replicating the specification. For that you can use the get_schema method:

from flask import Flask, jsonify
from flasgger import Swagger, swag_from

app = Flask(__name__)
swagger = Swagger(app)

@swagger.validate('Product')
def post():
    """
    post endpoint
    ---
    tags:
      - products
    parameters:
      - name: body
        in: body
        required: true
        schema:
          id: Product
          required:
            - name
          properties:
            name:
              type: string
              description: The product's name.
              default: "Guarana"
    responses:
      200:
        description: The product inserted in the database
        schema:
          $ref: '#/definitions/Product'
    """
    rv = db.insert(request.json)
    return jsonify(rv)

...

product_schema = swagger.get_schema('product')

This method returns a dictionary which contains the Flasgger schema id, all defined parameters and a list of required parameters.

HTML sanitizer

By default Flasgger will try to sanitize the content in YAML definitions replacing every \n with <br> but you can change this behaviour setting another kind of sanitizer.

from flasgger import Swagger, NO_SANITIZER

app =Flask()
swagger = Swagger(app, sanitizer=NO_SANITIZER)

You can write your own sanitizer

swagger = Swagger(app, sanitizer=lambda text: do_anything_with(text))

There is also a Markdown parser available, if you want to be able to render Markdown in your specs description use MK_SANITIZER

Swagger UI and templates

You can override the templates/flasgger/index.html in your application and this template will be the index.html for SwaggerUI. Use flasgger/ui2/templates/index.html as base for your customization.

Flasgger supports Swagger UI versions 2 and 3, The version 3 is still experimental but you can try setting app.config['SWAGGER']['uiversion'].

app = Flask(__name__)
app.config['SWAGGER'] = {
    'title': 'My API',
    'uiversion': 3
}
swagger = Swagger(app)

OpenAPI 3.0 Support

There is experimental support for OpenAPI 3.0 that should work when using SwaggerUI 3. To use OpenAPI 3.0, set app.config['SWAGGER']['openapi'] to a version that the current SwaggerUI 3 supports such as '3.0.2'.

For an example of this that uses callbacks and requestBody, see the callbacks example.

Externally loading Swagger UI and jQuery JS/CSS

Starting with Flasgger 0.9.2 you can specify external URL locations for loading the JavaScript and CSS for the Swagger and jQuery libraries loaded in the Flasgger default templates. If the configuration properties below are omitted, Flasgger will serve static versions it includes - these versions may be older than the current Swagger UI v2 or v3 releases.

The following example loads Swagger UI and jQuery versions from unpkg.com:

swagger_config = Swagger.DEFAULT_CONFIG
swagger_config['swagger_ui_bundle_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js'
swagger_config['swagger_ui_standalone_preset_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js'
swagger_config['jquery_js'] = '//unpkg.com/[email protected]/dist/jquery.min.js'
swagger_config['swagger_ui_css'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui.css'
Swagger(app, config=swagger_config)

Initializing Flasgger with default data.

You can start your Swagger spec with any default data providing a template:

template = {
  "swagger": "2.0",
  "info": {
    "title": "My API",
    "description": "API for my data",
    "contact": {
      "responsibleOrganization": "ME",
      "responsibleDeveloper": "Me",
      "email": "[email protected]",
      "url": "www.me.com",
    },
    "termsOfService": "http://me.com/terms",
    "version": "0.0.1"
  },
  "host": "mysite.com",  # overrides localhost:500
  "basePath": "/api",  # base bash for blueprint registration
  "schemes": [
    "http",
    "https"
  ],
  "operationId": "getmyData"
}

swagger = Swagger(app, template=template)

And then the template is the default data unless some view changes it. You can also provide all your specs as template and have no views. Or views in external APP.

Getting default data at runtime

Sometimes you need to get some data at runtime depending on dynamic values ex: you want to check request.is_secure to decide if schemes will be https you can do that by using LazyString.

from flask import Flask
from flasgger import, Swagger, LazyString, LazyJSONEncoder

app = Flask(__init__)

# Set the custom Encoder (Inherit it if you need to customize)
app.json_encoder = LazyJSONEncoder


template = dict(
    info={
        'title': LazyString(lambda: 'Lazy Title'),
        'version': LazyString(lambda: '99.9.9'),
        'description': LazyString(lambda: 'Hello Lazy World'),
        'termsOfService': LazyString(lambda: '/there_is_no_tos')
    },
    host=LazyString(lambda: request.host),
    schemes=[LazyString(lambda: 'https' if request.is_secure else 'http')],
    foo=LazyString(lambda: "Bar")
)
Swagger(app, template=template)

The LazyString values will be evaluated only when jsonify encodes the value at runtime, so you have access to Flask request, session, g, etc.. and also may want to access a database.

Behind a reverse proxy

Sometimes you're serving your swagger docs behind an reverse proxy (e.g. NGINX). When following the Flask guidance, the swagger docs will load correctly, but the "Try it Out" button points to the wrong place. This can be fixed with the following code:

from flask import Flask, request
from flasgger import Swagger, LazyString, LazyJSONEncoder

app = Flask(__name__)
app.json_encoder = LazyJSONEncoder

template = dict(swaggerUiPrefix=LazyString(lambda : request.environ.get('HTTP_X_SCRIPT_NAME', '')))
swagger = Swagger(app, template=template)

Customize default configurations

Custom configurations such as a different specs route or disabling Swagger UI can be provided to Flasgger:

swagger_config = {
    "headers": [
    ],
    "specs": [
        {
            "endpoint": 'apispec_1',
            "route": '/apispec_1.json',
            "rule_filter": lambda rule: True,  # all in
            "model_filter": lambda tag: True,  # all in
        }
    ],
    "static_url_path": "/flasgger_static",
    # "static_folder": "static",  # must be set by user
    "swagger_ui": True,
    "specs_route": "/apidocs/"
}

swagger = Swagger(app, config=swagger_config)

Extracting Definitions

Definitions can be extracted when id is found in spec, example:

from flask import Flask, jsonify
from flasgger import Swagger

app = Flask(__name__)
swagger = Swagger(app)

@app.route('/colors/<palette>/')
def colors(palette):
    """Example endpoint returning a list of colors by palette
    ---
    parameters:
      - name: palette
        in: path
        type: string
        enum: ['all', 'rgb', 'cmyk']
        required: true
        default: all
    responses:
      200:
        description: A list of colors (may be filtered by palette)
        schema:
          id: Palette
          type: object
          properties:
            palette_name:
              type: array
              items:
                schema:
                  id: Color
                  type: string
        examples:
          rgb: ['red', 'green', 'blue']
    """
    all_colors = {
        'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
        'rgb': ['red', 'green', 'blue']
    }
    if palette == 'all':
        result = all_colors
    else:
        result = {palette: all_colors.get(palette)}

    return jsonify(result)

app.run(debug=True)

In this example you do not have to pass definitions but need to add id to your schemas.

Python2 Compatibility

Version 0.9.5.* will be the last verison that supports Python2. Please direct discussions to #399.

Comments
  • AttributeError: 'function' object has no attribute 'root_path'

    AttributeError: 'function' object has no attribute 'root_path'

    Issue introduced between 0.5.14 and 0.6.1:

    Traceback (most recent call last):
      File "/usr/local/bin/cci", line 7, in <module>
        from cci.main import start
      File "/usr/local/lib/python2.7/dist-packages/cci/main.py", line 13, in <module>
        from api import app
      File "/usr/local/lib/python2.7/dist-packages/cci/api/__init__.py", line 33, in <module>
        import views  # noqa
      File "/usr/local/lib/python2.7/dist-packages/cci/api/views.py", line 80, in <module>
        @swag_from(swag_file('api_versions.yml'))
      File "/usr/local/lib/python2.7/dist-packages/flasgger/utils.py", line 72, in decorator
        'root': function.root_path
    AttributeError: 'function' object has no attribute 'root_path'
    

    Our code:

    def swag_file(yml):
        return pkg_resources.resource_filename('cci', os.path.join("api/swag", yml))
    
    @app.route('/api/versions/', methods=['GET'])
    @swag_from(swag_file('api_versions.yml'))
    def get_version():
       // ...
    
    bug help wanted 
    opened by njarvis 15
  • Can't send formData with GET requests.

    Can't send formData with GET requests.

    I'm trying to make a GET request to my api, using flasgger-ui. But I get the response:

    {
      "status": "400 BAD REQUEST",
      "type": "error",
      "description": {
        "name": "Provide valid name."
      }
    }
    

    As the endpoint expects a parameter in formBody and data is not parsed properly by flasgger-ui, I get this response. Another important point is the CURL request command generated at flasgger-ui , if run directly from terminal. Gives the expected results. And I can even send data in formBody with GET request if I use python requests module. I can't figure out whats wrong.

    Please explain.

    hacktoberfest 
    opened by rhythmize 14
  • /package_example/apidocs/ fails with INTERNAL SERVER ERROR /package_example/apispec_1.json

    /package_example/apidocs/ fails with INTERNAL SERVER ERROR /package_example/apispec_1.json

    Navigating to http://flasgger.pythonanywhere.com/package_example/apidocs/ (as linked from index page) produces:

    Failed to load API definition.
    Fetch error
    INTERNAL SERVER ERROR /package_example/apispec_1.json
    
    hacktoberfest 
    opened by javabrett 12
  • HTTPS  is not supported in the current flasgger version

    HTTPS is not supported in the current flasgger version

    it seems that there is an issue regarding the HTTPS for swagger ui that was solved in more advanced version https://github.com/swagger-api/swagger-ui/issues/3166

    so currently flasgger also does not support the HTTPS api requests .

    bug 
    opened by ghost 12
  • This project is looking for new mantainers

    This project is looking for new mantainers

    Hi,

    I don't have enough time to dedicate to this project, also I am now working focused on Quality Engineering and test automation, web dev and API development with Flask is no more part of my daily work.

    There are many people/companies relying on this project to serve API and I don't want to disappoint them.

    We need new maintainers

    We need 2 more people to be included as maintainers of this project, currently it is only me and @javabrett but we are not able to handle all the work needed to do here.

    I'll still be here as maintainer, to ensure I can help with important decisions and setups and that the project is going on the right direction.

    What we need?

    • Move this project to an organization?
    • Work to have proper dicummentation in place
    • Review Pull Requests and Issues (there is a lot of issues in need of triage, labeling, answer)
    • Keep an eye open for OPenApi Spec updates
    • Keep eye open for Swagger UI updates

    Who can be a maintainer?

    The preference is for people that is already on this list, (but if you want to be a maintainer and are not on that list you can comment here anyway, we will see) https://github.com/rochacbruno/flasgger/graphs/contributors

    If you are on that list and wants to be added as a maintainer (rights on this repo and pypi for releases) please comment on this thread.

    What is your benefits of being a maintainer

    • You are going to be features in https://github.com/rochacbruno/flasgger#top-contributors
    • You will be added on the new file/section MAINTAINERS.md
    • You will help open-source
    • You will be praised as one of the people that will not let this project die
    • You will have the satisfaction of having this project (which I assume you use) in a good shape!

    What next?

    1. I am waiting for comments on this thread from people that wants to become a maintainer
    2. I'll add people to the team and we will try to put this project in a good shape (updates, docs and issues resolved)
    3. If I can't find new maintainers in 3 months from now (Aug, 4, 2019), then, I'll try to move this project to an organization like https://github.com/jazzband
    4. If I am not able to find new maintainers neither accepted on Jazzband or similar project in 4 months from now (Sept, 2019 )then, I'll archive this project (make it read-only), include a note on github and pypi, a deprecation warning on installation and let it available for fork only, I dont wanna do that!

    Thanks! I hope we can continue this project together!

    :+1:

    opened by rochacbruno 9
  • Flasgger 0.9.1 does not reflect changes without restarting app

    Flasgger 0.9.1 does not reflect changes without restarting app

    I'm using latest flasgger==0.9.1 and create documentation in Yaml files using swag_from decorator. Whenever I change something in Yaml file (major or very minor change, whatever) I need to restart Python app in order to get changes reflected on Flasgger UI. I think it's quite inconvenient - I see it worked well in flasgger==0.8.3 without reloading.

    Here is my init:

    def create_swagger(app):
        template = {
            "openapi": '3.0.0',
            "info": {
                "title": "my title",
                "description": "my description",
                "contact": {
                    "responsibleOrganization": "my org",
                    "email": "my mail",
                    "url": "my url"
                },
                "version": "1.0"
            },
            "basePath": "/",
            "schemes": [
                "http",
                "https"
            ],
            "operationId": "getmyData"
        }
    
        config = {
                "headers": [
            ],
            "specs": [
                {
                    "endpoint": 'api',
                    "route": '/api.json',
                    "rule_filter": lambda rule: True,  # all in
                    "model_filter": lambda tag: True,  # all in
                }
            ],
            "static_url_path": "/flasgger_static",
            "swagger_ui": True,
            "specs_route": "/docs"        
        }    
    
        return Swagger(app, template=template, config=config)
    
    0.9.2 
    opened by ab-gissupport 9
  • swagger config after init

    swagger config after init

    I want to generate my host and schemes in swagger dynamically by using request.

    for example

    host=request.host,
    schemes=['https' if request.is_secure else 'http'
    
    

    Is it possible after Swagger(app) ?

    enhancement question 
    opened by wobeng 9
  • Compatibility with FlaskRestless

    Compatibility with FlaskRestless

    Hey, I tested flasgger with Flask alone and work pretty well, good work!

    I'm working with a flask proyect and we are using FlaskRestless extension, how can I make it work with preprocessors using swag_from directive??

    opened by laranicolas 9
  • First stab at testing all the examples

    First stab at testing all the examples

    So, here's the big picture of what I was trying to do:

    • [x] Remove all app.run(debug=True) from the examples (for importing later)
    • [x] Programmatically import all example modules in conftest.py fixture
    • [x] Import every app from every module and request the swagger spec and validate

    The final step failed because the examples don't work :) Hence, we are getting somewhere.

    ~~You'd have to enable the Travis build since you are the admin of the project.~~ Already up, nice!

    Code is kinda messy as I hacked it together, but this could give you an idea. Feel free to remix/remove anything that you don't want. No ego here :)

    I've enabled Tox and Travis (via the configuration files (.travis.yml and tox.ini) which can automate tedious testing of python projects).

    I think we can use http://flex-swagger.readthedocs.io/en/latest/ for validation?

    Follows from https://github.com/rochacbruno/flasgger/issues/64#issuecomment-289791411.

    opened by decentral1se 9
  • Fix openapi3 request parse validation

    Fix openapi3 request parse validation

    This is a fix for #357. It's a problem caused by extracting schemas in a location which is changed by openapi3.

    This is a PR depends on #504 but it's not very hard to merge without it. Only last two commits are related to this PR

    Fix request parse for openapi3. 8e731d5
    Add tests for parse openapi3 request 5d16c30
    

    Please let me know your decision.

    opened by Lounarok 8
  • The imp module is deprecated in favour of importlib;

    The imp module is deprecated in favour of importlib;

    It seems this line needs to be updated:

    https://github.com/flasgger/flasgger/blob/ce98b046cbec2b2eb8c6de6df4b5409c06a8e539/flasgger/utils.py#L5

      File "/usr/local/Cellar/[email protected]/3.8.2/Frameworks/Python.framework/Versions/3.8/lib/python3.8/imp.py", line 31, in <module>
        warnings.warn("the imp module is deprecated in favour of importlib; "
    DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
    

    produced using: PYTHONWARNINGS=error in a flask project that uses flasgger.

    opened by kamyar 8
  • https://localhost:5000/apidocs not working

    https://localhost:5000/apidocs not working

    I wanted to use Swagger api to create a UI interface for my flask app. After I run the app and tried to open the server by adding /apidocs to the link. It generated URL error.

    I typed http://127.0.0.1:5000/apidocs but generated the URL error.

    issue

    Below is my code :

    from flask import Flask, request 
    import numpy as np
    import pandas as pd
    import pickle
    from flasgger import Swagger # For frontend stuff
    
    ## These two lines very important
    app = Flask(__name__)
    Swagger(app)
    
    pickle_in = open('Random_forest.pkl', 'rb')
    rfc = pickle.load(pickle_in)
    
    @app.route("/")
    def welcome():
        return 'Welcome All'
    
    @app.route('/predict')
    def predict_note_authentication():
    
        """Let's Authenticate the Banks Note
        This is using docstrings for specifications
        --- 
        parameters:
          - name: variance 
            in: query
            type: number 
            required: true 
          - name: skewness
            in: query
            type: number 
            required: true 
          - name: curtosis
            in: query
            type: number 
            required: true 
          - name: entropy
            in: query
            type: number 
            required: true 
        responses:
            200:
                description : The output values
        """
    
        variance = request.args.get('variance')
        skewness = request.args.get('skewness')
        curtosis = request.args.get('curtosis')
        entropy = request.args.get('entropy')
        prediction = rfc.predict([[variance, skewness, curtosis, entropy]])
        return f'The predicted value is {prediction}'
    
    @app.route('/predict_file', methods=["POST"])
    def predict_note_file():
        """Let's Authenticate the Banks Note
        This is using docstrings for specification .
        ---
        parameters:
          - name: file 
            in: formData
            type: file 
            required: true
        responses:
            200:
                description : The output values
    
        """
        df_test = pd.read_csv(request.files.get('file'))
        prediction = rfc.predict(df_test)
        return f'The predicted values are {list(prediction)}'
    
    if __name__ == '__name__':
        app.run(hosts='0.0.0.0', port=8000)
    
    opened by Blessing988 1
  • Missing support for handling multiple http methods and routes for single function when specs are from dictionary

    Missing support for handling multiple http methods and routes for single function when specs are from dictionary

    Hello team!

    Great job for the package! Playing around with it these days I've noticed a lack of support for handling multiple http methods and routes for specs that are coming from python dictionary

    Could a line like this be implemented in the future? @swag_from(SwaggerDocs.UserResourceSwagger.BlockUserResource, methods=['DELETE'])

    opened by cristiangabor 0
  • older flassger required package incompatibility

    older flassger required package incompatibility

    Hi Team, thanks for the great package! We came across an issue where flassger 0.9.5 imports a flask/jinja version that in turn imports a version of markupsafe that has a breaking change (soft_unicode was removed, soft_str replaced it), which causes a hard fail. A current workaround for this is manually importing an older version of markupsafe, but we wanted to suggest a specific version being specified in requirements for flask/jinja2, to avoid the package breaking for apps using older versions.

    Thanks in advance for your help!

    opened by adamb910 0
  • put 'POST', 'GET', 'PUT', 'DELETE' in one file

    put 'POST', 'GET', 'PUT', 'DELETE' in one file

    @api.route('/release', methods=['POST', 'GET', 'PUT', 'DELETE'])
    @swag_from('../swagger/release.yml')
    def api_mop():
        if request.method == 'POST':
            pass
        if request.method == 'GET':
            pass
         if request.method == 'PUT':
            pass
         if request.method == 'DELETE':
            pass
    

    Hi Team, thanks for your plugin, it is a great tool!! And I have a question, can you share how to write release.yml about this request, I don't know how to write it

    opened by SincerelyUnique 0
  • Invalid character in header when using jwt bearer auth

    Invalid character in header when using jwt bearer auth

    apostrophe are added as urlencode in the header which is wrong: ... -H "&#39;Authorization&#39;: Bearer ...

    image

    do you know what causes it and how to solve it ?

    opened by sosafe-bastian-bretagne 0
Releases(0.9.5)
  • 0.9.5(Aug 1, 2020)

    NOTE: 0.9.5.* is the last version that supports Python 2

    • 'swag_from' supports 'pathlib.Path'
    • Added support for OpenAPI3 parameter schema parsing #390
    • Enable optional OpenAPI3 fields #366
    • Fix access to local $ref definition #367
    • Add support for custom validation_function and error_handler
    • Accept pathlib.Path objects as path specification for swag_from
    • Delay RuntimeError for not installing apispec marshmallow in Schema #384
    • Ensure downward compatibility for werkzeug #391
    • Support default configuration merging #383
    • Update swagger-ui to 3.28.0 (improves safety)
    Source code(tar.gz)
    Source code(zip)
    flasgger-0.9.5.tar.gz(3.72 MB)
  • 0.9.4(Jan 20, 2020)

    • Changed apispec version supported to 2.0.2
    • Added support for OpenAPI3 callback field
    • Changed jsonschema version supported to jsonschema>=3.0.1
    • Changed json data to be parsed from request directly
    • Changed swagger-ui 3 version to 3.23.1
    • Added support for JWT_AUTH_HEADER_NAME
    • Changed to yaml.safe_load
    • Added support for docExpansion in swagger-ui 2
    • Fixed bug for apispec_to_template definition #301
    • Added support for using external yml file to specify parameter commit by @isaacfi
    • Changed flask-restful abort call to abort(code, e.message)
    • Added definitions to parsed_data validation [#330] (https://github.com/flasgger/flasgger/commit/8310196821ed61374581bb99d2be7739661b3afa)
    • Added support for Marshmallow Schema in Function Based View [#341] (https://github.com/flasgger/flasgger/commit/fbaa7a12859823137c485f9f6fb5591325dc90da)
    • Changed status code for no data to validate from 500 to 400
    • Added require_data kwarg to validate() to make data optional #340
    • Added support for importing OpenAPI3 spec components from config
    • Enable "import:" syntax in template.yml
    • Forward validation_error_handler in Marshmallow APIspec #352
    Source code(tar.gz)
    Source code(zip)
  • 0.9.4.dev1(Sep 3, 2019)

  • 0.9.3-beta(Sep 3, 2019)

  • 0.9.2(Nov 15, 2018)

    • Fixed packaging issue caused by the inclusion of examples #242
    • Enhancement allowing swagger-ui and static js to be loaded from external URLs #245
    • Added ui_params_text to allow raw text to be added to ui_params #244
    • Auto-disable Flasgger caching when running Flask in debug mode #250
    Source code(tar.gz)
    Source code(zip)
  • 0.9.1(Sep 13, 2018)

    • Updated support for apispec >=0.39.0 #205
    • Added install of etc/flasgger_package in requirements-dev.txt #208
    • repaired key error thrown when a path is given instead of in the func #210
    • fixed static file paths in demo app #213
    • removed pre-compile/cache *.pyc files from dist #137
    • auto-detect unicode charset-encoding in YAML files #156
    • bug fix, use getattr instead of dict get #226
    • added dev support for Docker (for demo app)
    • added support for parsed MethodView (flask_restful) #222
    Source code(tar.gz)
    Source code(zip)
  • 0.8.3(Sep 11, 2018)

  • 0.8.2(Sep 11, 2018)

    • Update index.html
    • Update index.html
    • Merge pull request #180 from anilpai/anilpai-patch-1
    • Update jwt_auth.py
    • Merge pull request #182 from anilpai/patch-1
    • Avoid inclusion of empty definition dict
    • Merge pull request #184 from mmichaels01/master
    • Fix README.md error
    • Merge pull request #186 from phylee/master
    • Fix get_schema exception message
    • Merge pull request #187 from boris-42/fix_get_schema_exc_message
    • Fix erroneous extra definitions objects
    • adding support for requestBody
    • fixing python 2.7 incompliant syntax
    • Merge pull request #191 from zrayn/add-requestBody-support
    • Merge pull request #190 from abstiles/fix-extra-definitions
    • Validate examples according to Swagger spec
    • Correct example's declaration as OpenAPI 3.0
    • Correct reference of invalid type int32
    • Make example python filter more strict
    • Fall back to simpler validation for OpenAPI 3
    • Skip validation of intentionally invalid example
    • Merge pull request #193 from abstiles/enhance-tests
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Jun 2, 2018)

    See examples/changelog_090.py

    • Updated Swagger UI 3.x
    • uiversion now defaults to 3
    • 'hide_top_bar' config option to remove the green top bar
    • 'fotter_text' added to customize the footer text (allows html and