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
Formatting of dates and times in Flask templates using moment.js.

Flask-Moment This extension enhances Jinja2 templates with formatting of dates and times using moment.js. Quick Start Step 1: Initialize the extension

Miguel Grinberg 358 Nov 28, 2022
API to get the details of the characters in the Money heist TV show.

Project Heist Description: Project Heist is a RESTful API made using Python and Flask. This API is inspired by the popular Spanish TV show Money Heist

Rahul V 5 Dec 19, 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
A clean and simple blog system based on Flask and MongoDB

CleanBlog A clean and simple blog system based on Flask and MongoDB You can access CleanBlog This is the source code of Flask Tutorial Pro,you can buy

shin 107 Oct 06, 2022
Python Flask API service, backed by DynamoDB, running on AWS Lambda using the traditional Serverless Framework.

Serverless Framework Python Flask API service backed by DynamoDB on AWS Python Flask API service, backed by DynamoDB, running on AWS Lambda using the

Andreu Jové 0 Apr 17, 2022
A Flask extension that enables or disables features based on configuration.

Flask FeatureFlags This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on

Rachel Greenfield 131 Sep 26, 2022
REST API with Flask and SQLAlchemy. I would rather not use it anymore.

Flask REST API Python 3.9.7 The Flask experience, without data persistence :D First, to install all dependencies: python -m pip install -r requirement

Luis Quiñones Requelme 1 Dec 15, 2021
Flask Boilerplate - Paper Kit Design | AppSeed

Flask Paper Kit Open-Source Web App coded in Flask Framework - Provided by AppSeed Web App Generator. App Features: SQLite database SQLAlchemy ORM Ses

App Generator 86 Nov 29, 2021
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
A gRpc server like Flask (像Flask一样的gRpc服务)

Mask A gRpc server just like Flask. Install Mask support pypi packages, you can simply install by: pip install mask Document Mask manual could be fou

吴东 16 Jun 14, 2022
Small flask based opds catalog designed to serve a directory via OPDS

teenyopds Small flask based opds catalog designed to serve a directory via OPDS, it has currently only been verified to work with KyBook 3 on iOS but

Adam Furbee 4 Jul 14, 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
Full text search for flask.

flask-msearch Installation To install flask-msearch: pip install flask-msearch # when MSEARCH_BACKEND = "whoosh" pip install whoosh blinker # when MSE

honmaple 197 Dec 29, 2022
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.3k Jan 03, 2023
docker-compose uWSGI nginx flask

docker-compose uWSGI nginx flask Note that this was tested on CentOS 7 Usage sudo yum install docker

Abdolkarim Saeedi 3 Sep 11, 2022
Flask-Rebar combines flask, marshmallow, and swagger for robust REST services.

Flask-Rebar Flask-Rebar combines flask, marshmallow, and swagger for robust REST services. Features Request and Response Validation - Flask-Rebar reli

PlanGrid 223 Dec 19, 2022
Another redis monitor by using flask, angular, socket.io

RedisPAPA we use redis info to monitor the redis usage. PAPA means a father who is monitoring the redis. accoding to the redis doc, it is be recommand

no13bus 393 Dec 30, 2022
Small and simple gravatar usage in Flask.

Flask Gravatar About This is small and simple integration gravatar into flask. Installation Flask-Gravatar is on PyPI so all you need is: pip install

Alexander Zelenyak 78 Sep 15, 2022
An flask app for fake image detector

fake_img_detector This is a ml based project: frameworks used:- Flask Google collab #Description: Here you can Upload two different looking image with

shivam kumar 7 Jun 29, 2022