A swagger 2.0 spec extractor for flask

Related tags

Flask flask-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-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Joshua Carp 617 Dec 30, 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
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 282 Feb 11, 2021
Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development.

Flask-Starter Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development. It has all the r

Kundan Singh 259 Dec 26, 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 Project Template A full feature Flask project template.

Flask Project Template A full feature Flask project template. See also Python-Project-Template for a lean, low dependency Python app. HOW TO USE THIS

Bruno Rocha 96 Dec 23, 2022
A Fast API style support for Flask. Gives you MyPy types with the flexibility of flask

Flask-Fastx Flask-Fastx is a Fast API style support for Flask. It Gives you MyPy types with the flexibility of flask. Compatibility Flask-Fastx requir

Tactful.ai 18 Nov 26, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure.

Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure. All the required libraries are already installed easily to use in any big project.

Ajay kumar sharma 5 Jun 14, 2022
flask-reactize is a boostrap to serve any React JS application via a Python back-end, using Flask as web framework.

flask-reactize Purpose Developing a ReactJS application requires to use nodejs as back end server. What if you want to consume external APIs: how are

Julien Chomarat 4 Jan 11, 2022
Pf-flask-rest-com - Flask REST API Common Implementation by Problem Fighter Library

In the name of God, the Most Gracious, the Most Merciful. PF-Flask-Rest-Com Docu

Problem Fighter 3 Jan 15, 2022
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
Open-source Flask Sample built on top of flask-dance library

Open-source Flask Sample built on top of flask-dance library. The project implements the social login for Github and Twitter - Originally coded by TestDriven.IO.

App Generator 4 Jul 26, 2022
Flask-redmail - Email sending for Flask

Flask Red Mail: Email Sending for Flask Flask extension for Red Mail What is it?

Mikael Koli 11 Sep 23, 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

null 6 Jan 6, 2023
Flask-template - A simple template for make an flask api

flask-template By GaGoU :3 a simple template for make an flask api notes: you ca

GaGoU 2 Feb 17, 2022
SQLAlchemy database migrations for Flask applications using Alembic

Flask-Migrate Flask-Migrate is an extension that handles SQLAlchemy database migrations for Flask applications using Alembic. The database operations

Miguel Grinberg 2.2k Dec 28, 2022
Adds SQLAlchemy support to Flask

Flask-SQLAlchemy Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application. It aims to simplify using SQLAlchemy

The Pallets Projects 3.9k Dec 29, 2022
Cross Origin Resource Sharing ( CORS ) support for Flask

Flask-CORS A Flask extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible. This package has a simple philosoph

Cory Dolphin 803 Jan 1, 2023