A swagger 2.0 spec extractor for flask

Related tags

Flaskflask-swagger
Overview

flask-swagger

A Swagger 2.0 spec extractor for Flask

You can now specify base path for yml files:

app = Flask(__name__)

@app.route("/spec")
def spec():
    base_path = os.path.join(app.root_path, 'docs')
    return jsonify(swagger(app), from_file_keyword="swagger_from_file", base_path=base_path)

and use relative paths:

@app.route('/test', methods=['POST'])
def login():
    """
    swagger_from_file: test.yml
    """

Install:

pip install flask-swagger

Flask-swagger provides a method (swagger) that inspects the Flask app for endpoints that contain YAML docstrings with Swagger 2.0 Operation objects.

class UserAPI(MethodView):

    def post(self):
        """
        Create a new user
        ---
        tags:
          - users
        definitions:
          - schema:
              id: Group
              properties:
                name:
                 type: string
                 description: the group's name
        parameters:
          - in: body
            name: body
            schema:
              id: User
              required:
                - email
                - name
              properties:
                email:
                  type: string
                  description: email for user
                name:
                  type: string
                  description: name for user
                address:
                  description: address for user
                  schema:
                    id: Address
                    properties:
                      street:
                        type: string
                      state:
                        type: string
                      country:
                        type: string
                      postalcode:
                        type: string
                groups:
                  type: array
                  description: list of groups
                  items:
                    $ref: "#/definitions/Group"
        responses:
          201:
            description: User created
        """
        return {}

Flask-swagger supports docstrings in methods of MethodView classes (à la Flask-RESTful) and regular Flask view functions.

Following YAML conventions, flask-swagger searches for ---, everything preceding is provided as summary (first line) and description (following lines) for the endpoint while everything after is parsed as a swagger Operation object.

In order to support inline definition of Schema objects in Parameter and Response objects, flask-swagger veers a little off from the standard. We require an id field for the inline Schema which is then used to correctly place the Schema object in the Definitions object.

Schema objects can be defined in a definitions section within the docstrings (see group object above) or within responses or parameters (see user object above). We also support schema objects nested within the properties of other Schema objects. An example is shown above with the address property of User.

If you don't like to put YAML on docstrings you can put the same content in an external file.

file.yml

Create a new user
---
tags:
  - users
definitions:
  - schema:
      id: Group
      properties:
        name:
         type: string
         description: the group's name
parameters:
  - in: body
    name: body
    schema:
      id: User
      required:
        - email
        - name
      properties:
        email:
          type: string
          description: email for user
        name:
          type: string
          description: name for user
        address:
          description: address for user
          schema:
            id: Address
            properties:
              street:
                type: string
              state:
                type: string
              country:
                type: string
              postalcode:
                type: string
        groups:
          type: array
          description: list of groups
          items:
            $ref: "#/definitions/Group"
responses:
  201:
    description: User created

and point to it in your docstring.

class UserAPI(MethodView):

    def post(self):
        """
        Create a new user

        blah blah

        swagger_from_file: path/to/file.yml

        blah blah
        """
        return {}

Note that you can replace swagger_from_file by another keyword. Supply your chosen keyword as an argument to swagger.

To expose your Swagger specification to the world you provide a Flask route that does something along these lines

from flask import Flask, jsonify
from flask_swagger import swagger

app = Flask(__name__)

@app.route("/spec")
def spec():
    return jsonify(swagger(app))

Note that the Swagger specification returned by swagger(app) is as minimal as it can be. It's your job to override and add to the specification as you see fit.

@app.route("/spec")
def spec():
    swag = swagger(app)
    swag['info']['version'] = "1.0"
    swag['info']['title'] = "My API"
    return jsonify(swag)

Swagger-UI

Swagger-UI is the reason we embarked on this mission to begin with, flask-swagger does not however include Swagger-UI. Simply follow the awesome documentation over at https://github.com/swagger-api/swagger-ui and point your swaggerUi.url to your new flask-swagger endpoint and enjoy.

flaskswagger Command

This package now comes with a very simple command line interface: flaskswagger. This command can be used to build and update swagger specs for your flask apps from the command line or at build time.

flaskswagger -h
usage: flaskswagger [-h] [--template TEMPLATE] [--out-dir OUT_DIR]
                    [--definitions DEFINITIONS] [--host HOST]
                    [--base-path BASE_PATH] [--version VERSION]
                    app

positional arguments:
  app                   the flask app to swaggerify

optional arguments:
  -h, --help            show this help message and exit
  --template TEMPLATE   template spec to start with, before any other options
                        or processing
  --out-dir OUT_DIR     the directory to output to
  --definitions DEFINITIONS
                        json definitions file
  --host HOST
  --base-path BASE_PATH
  --version VERSION     Specify a spec version

For example, this can be used to build a swagger spec which can be served from your static directory. In the example below, we use the manually created swagger.json.manual as a template, and output to the static/ directory.

flaskswagger server:app --template static/swagger.json.manual --out-dir static/

Also, you can ask flaskswagger to add host and basePath to your swagger spec:

flaskswagger server:app --host localhost:5000 --base-path /v1

Acknowledgements

Flask-swagger builds on ideas and code from flask-sillywalk and flask-restful-swagger

Notable forks

Flasgger

Comments
  • Are Blueprint supported ?

    Are Blueprint supported ?

    Hi,

    I have a Flask app using Blueprints and would like to document the API using swagger. I love the idea of having a single source of truth when it comes to the API documentation and hence would like to use flask-swagger. Does it support Blueprint ? I must admit I didn't even try, I was hoping to first get some tips before messing around with my docstrings everywhere....

    thanks

    Brieuc

    opened by ghost 9
  • Method/route combinations appear in swagger documentation output that are not in the code

    Method/route combinations appear in swagger documentation output that are not in the code

    Permutations of routes and methods appear as documented operations in the swagger output that aren't present in the code. Other applications rely on the JSON output of swagger, and the superfluity of operations breaks that.

    mod.add_url_rule('/edges/', defaults={'annotation_id': None}, methods=['GET']) mod.add_url_rule('/edges/', methods=['POST']) mod.add_url_rule('/edges/<int:annotation_id>/', methods=['GET', 'PUT', 'PATCH', 'DELETE'])

    i.e. The code defines a route at /edges/ with "GET" and "POST" methods. The code also defines a route at /edges/<int:annotation_id>/ with "GET", "PUT", "PATCH", and "DELETE" methods. [This is a total of 2 routes and 5 method verbs.] The swagger output shows a list of 10 operations, which includes combinations of verbs and routes that don't exist in code (e.g. "POST" for the /edges/<int:annotation_id>/ route, and "PUT" for the /edges/ route).

    opened by JasonWWalton 7
  • Make docs processor more configurable

    Make docs processor more configurable

    To use markdown in my api docs, right now I use monkey patching like this:

    import flask_swagger
    import CommonMark
    
    def sanitize(text):
        parser = CommonMark.DocParser()
        renderer = CommonMark.HTMLRenderer()
        ast = parser.parse(text)
        return renderer.render(ast)
    
    flask_swagger._sanitize = sanitize
    

    But this could be made a configurable parameter like:

    def swagger(app, process_doc=_sanitize):
        ...
    
    opened by svetlyak40wt 5
  • base_path parameter and relative pathes

    base_path parameter and relative pathes

    You can now specify base path for yml files:

    app = Flask(__name__)
    
    @app.route("/spec")
    def spec():
        base_path = os.path.join(app.root_path, 'docs')
        return jsonify(swagger(app), from_file_keyword="swagger_from_file", base_path=base_path)
    

    and use relative pathes:

    @app.route('/test', methods=['POST'])
    def login():
        """
        swagger_from_file: test.yml
        """
    
    opened by NotJustPizza 4
  • Multiple path parameters and multiple endpoints

    Multiple path parameters and multiple endpoints

    Hi there,

    I currently have a flask_restful Resource with 2 path parameters: one compulsory, and one optional. I followed this recommendations of writing it this way:

    api.add_resource(ProductsResource, '/products/<string:slug>', '/products/<string:slug>/<string:color>')

    class ProductsResource(Resource):
          @marshal_with(products_fields)
          def get(self, slug, color=None):
               ....
    

    Then, i have the following YML documentation in the docstring regarding parameters:

    ...
    - name: slug
       in: path
       description: product's slug
       type: string
       required: true
    - name: color
       in: path
       description: product's color
       type: string
       required: true
    

    When I go to my project on http://localhost:5000/spec, I see that I have 2 endpoint generated:

    • http://localhost:5000/products/{slug}
    • http://localhost:5000/products/{slug}/{color}

    But, for both endpoints there are those 2 required parameters, resulting in a swagger error: Path parameter is defined but is not declared: color.

    Do you think it would be possible to filter the path parameters based on the endpoints used ? Here it would mean filter out 'color' for the first endpoint.

    Thanks, Pierre.

    opened by hnb2 3
  • Invalid path parameter

    Invalid path parameter

    • The following path is listed in docs as: https://api.getsling.com/#/timeclock/post_timeclock_clockin
    • This path is for clocking in for shifts, but it is wrong.
    • The valid path for proper documentation changes by the following:
    Old Path: /timeclock/clockin
    New path: /{org_id}/timeclock/clockin
    
    opened by cloudguruab 2
  • Avoid running twice from CLI

    Avoid running twice from CLI

    When running flaskswagger, the run() function would be invoked twice: One from the entrypoint and another by just importing build_swagger_spec.

    This ensures the spec is only dumped once to stdout.

    opened by ocaballeror 2
  • Pip source code is different from github master branch

    Pip source code is different from github master branch

    Hi, I installed flask-swagger using 'pip install flask-swagger' and I noticed the downloaded source code is different from the one published in the master branch. Notice "_parse_docstring" function on the left and "_find_from_file" on the right.

    screenshot 2016-09-30 14 38 50

    Maybe I'm doing something wrong and I haven't realize it, any thoughts?

    opened by jhonjairoroa87 2
  • Swagger from file

    Swagger from file

    Hi,

    This is a proposal to decode a special line in a docstring swagger_from_file: path.

    I think it could be useful sometimes to take the yaml swagger spec out of the docstring:

    • if you have other things to say in the docstring,
    • if it's easier to edit yaml code from a .yml file.

    In the pull request you'll find besides flask_swagger.py a modified example and README.md

    Please criticize as needed. Thanks.

    opened by ninit 2
  • Stringify `responses` to make validator happy

    Stringify `responses` to make validator happy

    If you will try to use jsonschema`s Draft4Validator to validate swagger.json, generated by flask-swagger, then will discover it is failing, trying to match numerical HTTP status codes from responses agains this piece of Swagger 2.0 spec:

    "responses": {
      "type": "object",
      "description": "Response objects names can either be any valid
      HTTP status code or 'default'.",
      "minProperties": 1,
      "additionalProperties": false,
      "patternProperties": {
        "^([0-9]{3})$|^(default)$": {
          "$ref": "#/definitions/responseValue"
        },
        "^x-": {
          "$ref": "#/definitions/vendorExtension"
        }
      }
    }
    

    This fix just coerse responses keys to strings.

    opened by svetlyak40wt 2
  • Add ability to define definitions within other definitions

    Add ability to define definitions within other definitions

    Currently it is not possible to define definitions within the properties or items (if within an array) of other definitions.

    This change recursively traverses the properties of definitions to find other schema defs. This is a deviation from the standard, but the cleanest way I could think to handle it.

    Also builds on the work by abhaga to handle multiple views for same route. Handles the case where definitions get overridden by separate view functions for the same verb.

    opened by brentthew 2
  • Embedded plantuml diagrams in docstrings

    Embedded plantuml diagrams in docstrings

    This PR adds an optional ability to embed plantuml diagrams in the description section of endpoint docstrings. Example:

    @app.route('/foo')
    def foo():
        """
        # Expected sequence
        @startuml
        client -> server: /foo
        server --> client: response {id}
        client -> server: /bar/{id}
        @enduml
        """
        return 'foobar'
    

    This relies on having a PlantUML server available. By default, it uses the public server available at http://www.plantuml.com/plantuml/img/ but this can be configured by setting FLASK_SWAGGER_PLANTUML_SERVER in the flask app config.

    The diagrams it generates go into a subdirectory of the app's static content directory. By default this subdirectory is called uml but it can be configured by setting FLASK_SWAGGER_PLANTUML_FOLDER in the flask app config.

    The diagram content is replaced with a GFM image tag. If an error occurs while generating the image, the image content is replaced with an error message. If the plantuml package is not available, swagger generation proceeds as normal.

    I've also added parameters to the swagger method for title, version and description. This is mostly so that the description content can be scanned for diagram content.

    Currently uses some Python 3.6+ syntax. Let me know if this is an obstacle to merging & I can fix.

    opened by tom-cook-pmev 0
  • Provide context for errors

    Provide context for errors

    This PR adds some logging so that errors in the YAML in a docstring give some indication of which method caused the problem. Several times now I've gone over a large codebase adding swagger docstrings then tried to view the documentation, only to find that there is an error - somewhere. The YAML parser will tell you which line of a docstring the error happened on, and might tell you what the offending content was, and that might be enough to find the error. Or it might not. This logs which object the docstring appeared on.

    opened by tom-cook-pmev 1
  • 'base_path' argument error

    'base_path' argument error

    I'm using flask-swagger-0.2.14 but when i ran the first example like in your README.md

    @app.route("/spec")
    def spec():
       base_path = os.path.join(app.root_path, 'docs')
       return jsonify(swagger(app), from_file_keyword="swagger_from_file", base_path=base_path)
    
    @app.route('/test', methods=['POST'])
    def login():
       """
       swagger_from_file: test.yml
       """
    

    I got this error

    swagger() got an unexpected keyword argument 'base_path'
    

    Could you tell me how to resolve it! Thank in advance!

    opened by lamhai1401 1
  • AttributeError: type object 'Create' has no attribute 'lower'

    AttributeError: type object 'Create' has no attribute 'lower'

    I am using Flask-Swagger with Flask-MongoRest. Last versions, with Python 3.8.2.

    I wanted to simply try this code from the README:

    from flask import Flask, jsonify
    from flask_swagger import swagger
    
    app = Flask(__name__)
    
    @app.route("/spec")
    def spec():
        return jsonify(swagger(app))
    

    then when I do GET http://127.0.0.1:5000/spec, the following error is displayed:

      File "/home/cedric/.cache/pypoetry/virtualenvs/stats-api-7Yf7ZOUq-py3.8/lib/python3.8/site-packages/flask_swagger.py", line 178, in <lambda>
        and verb in map(lambda m: m.lower(), endpoint.methods) \
    AttributeError: type object 'Create' has no attribute 'lower'
    

    I fixed my issue by changing this code: https://github.com/gangverk/flask-swagger/blob/master/flask_swagger.py#L177-L179

    to

    if hasattr(endpoint, 'methods') \
                        and verb in map(lambda m: m.method.lower(), endpoint.methods) \	
                        and hasattr(endpoint.view_class, verb):
    

    Since actually here m is an object, not a string. m.method is a string. It also works with str(m).lower().

    With this change, it works quite well.

    If you want I can create a fix which will works with m.lower() and m.method.lower() and make a pull request.

    Or do you thing the issue is on the side of Flask-MongoRest ?

    opened by cedricbonhomme 1
Releases(v0.2.11)
Owner
Sling
Sling
Flask 文档中文翻译

Flask 中文文档 这里是 Flask 文档中文翻译项目,欢迎参与! 在开始翻译之前,请务必阅读下面的 Contributing Guide 了解贡献流程,然后阅读这个 Issue 了解翻译要求,在这个 Discussion 投票选出你认为合适的翻译词汇,在这个 Discussion 投票选出你喜

Grey Li 93 Nov 28, 2022
Criando um Bot com PYAUTOGUI e utilizando o Flask para Interface para Usuário

Criando um Bot com PYAUTOGUI e utilizando o Flask para Interface para Usuário O pyautogui foi escolhido pela possibilidade de fazer a identificação do

Rodrigo Vital 2 Oct 20, 2021
flask extension for integration with the awesome pydantic package

Flask-Pydantic Flask extension for integration of the awesome pydantic package with Flask. Installation python3 -m pip install Flask-Pydantic Basics U

248 Dec 26, 2022
Flask Sitemapper is a small Python 3 package that generates XML sitemaps for Flask applications.

Flask Sitemapper Flask Sitemapper is a small Python 3 package that generates XML sitemaps for Flask applications. This allows you to create a nice and

6 Jan 06, 2023
A web application made with Flask that works with a weather service API to get the current weather from all over the world.

Weather App A web application made with Flask that works with a weather service API to get the current weather from all over the world. Uses data from

Christian Jairo Sarmiento 19 Dec 02, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication. For use with cookiecutter.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Dec 29, 2022
A template for Flask APIs.

FlaskAPITempate A template for a Flask API. Why tho? I just wanted an easy way to create a Flask API. How to setup First, use the template. You can do

TechStudent10 1 Dec 28, 2021
A simple FastAPI web service + Vue.js based UI over a rclip-style clip embedding database.

Explore CLIP Embeddings in a rclip database A simple FastAPI web service + Vue.js based UI over a rclip-style clip embedding database. A live demo of

18 Oct 15, 2022
Brandnew-flask is a CLI tool used to generate a powerful and mordern flask-app that supports the production environment.

Brandnew-flask is still in the initial stage and needs to be updated and improved continuously. Everyone is welcome to maintain and improve this CLI.

brandonye 4 Jul 17, 2022
flask extension for integration with the awesome pydantic package

Flask-Pydantic Flask extension for integration of the awesome pydantic package with Flask. Installation python3 -m pip install Flask-Pydantic Basics v

249 Jan 06, 2023
Flask-Discord-Bot-Dashboard - A simple discord Bot dashboard created in Flask Python

Flask-Discord-Bot-Dashboard A simple discord Bot dashboard created in Flask Pyth

Ethan 8 Dec 22, 2022
SqlAlchemy Flask-Restful Swagger Json:API OpenAPI

SAFRS: Python OpenAPI & JSON:API Framework Overview Installation JSON:API Interface Resource Objects Relationships Methods Custom Methods Class Method

Thomas Pollet 365 Jan 06, 2023
An extension to add support of Plugin in Flask.

An extension to add support of Plugin in Flask.

Doge Gui 31 May 19, 2022
Alexa Skills Kit for Python

Program the Amazon Echo with Python Flask-Ask is a Flask extension that makes building Alexa skills for the Amazon Echo easier and much more fun. Flas

John Wheeler 1.9k Dec 30, 2022
Python3🐍 webApp to display your current playing music on OBS Studio.

Spotify Overlay A Overlay to display on Obs Studio or any related video/stream recorder, the current music that is playing on your Spotify. Installati

carlitos 0 Oct 17, 2022
A python package for integrating ripozo with Flask

flask-ripozo This package provides a dispatcher for ripozo so that you can integrate ripozo with Flask. As with all dispatchers it is simply for getti

Vertical Knowledge 14 Dec 03, 2018
HTTP security headers for Flask

Talisman: HTTP security headers for Flask Talisman is a small Flask extension that handles setting HTTP headers that can help protect against a few co

Google Cloud Platform 853 Dec 19, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 310 Dec 14, 2022
Python web-app (Flask) to browse Tandoor recipes on the local network

RecipeBook - Tandoor Python web-app (Flask) to browse Tandoor recipes on the local network. Designed for use with E-Ink screens. For a version that wo

5 Oct 02, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021