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
A flask app that turn image into ASCII art

ASCII art A flask app that turn image into ASCII art. This app has been deployed to https://motmaytinh.herokuapp.com Getting Started These instruction

Trần Ngọc Quý 1 Jan 13, 2022
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
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 870 Jan 08, 2023
Boilerplate template formwork for a Python Flask application with Mysql,Build dynamic websites rapidly.

Overview English | 简体中文 How to Build dynamic web rapidly? We choose Formwork-Flask. Formwork is a highly packaged Flask Demo. It's intergrates various

aswallz 81 May 16, 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
Serve angular production application from python flask backend. Quick and Easy

Serve angular production application from python flask backend. Quick and Easy

mark 1 Dec 01, 2022
A web application that consists of a collection of board games

PyBoardGame About This website contains a collection of board games for users to enjoy, as well as various guides for the games. The web app is built

Larry Shi 0 Aug 11, 2021
An python flask app with webserver example

python-flask-example-keepalive How it works? Basically its just a python flask webserver which can be used to keep any repl/herokuapp or any other ser

KangersHub 2 Sep 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
Paid roles for discord using Stripe, Python, Flask & Docker

Welcome to Paycord Paid roles for discord using Stripe, Python, Flask & Docker. Setup Production On stripe dashboard, go Developers ➡️ Webhooks ➡️ Add

Ward 12 Dec 28, 2022
Flask RESTful Web services using API to communicate between client and server.

Welcome! Open up two terminals, one for client and for server each Terminal 1 Terminal 2 Now navigate to the CW2_code directory in both like so $ cd C

Sehra Elahi 1 Nov 23, 2021
iloveflask is a Python library to collect functions that help a flask developer generate reports, config files and repeat code.

I Love Flask iloveflask is a Python library to collect functions that help a flask developer generate reports, config files and repeat code. Installat

2 Dec 29, 2021
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
SQL Alchemy dialect for Neo4j

SQL Alchemy dialect for Neo4j This package provides the SQL dialect for Neo4j, using the official JDBC driver (the Neo4j "BI Connector" ) Installation

Beni Ben zikry 8 Jan 02, 2023
A fairly common feature in web applications to have links that open a popover when hovered

Add Popovers to Links in Flask App It is a fairly common feature in web applications to have links that open a popover when hovered. Twitter does this

Gitau Harrison 1 Jan 22, 2022
Are-You-OK is a Flask-based, responsive Web App to monitor whether the Internet Service you care about is still working.

Are-You-OK Are-You-OK is a Flask-based, responsive Web App to monitor whether the Internet Service you care about is still working. Demo-Preview Get S

Tim Qiu 1 Oct 28, 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 v

249 Jan 06, 2023
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
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
Full-Stack application that visualizes amusement park safety.

Amusement Park Ride Safety Analysis Project Proposal We have chosen to look into amusement park data to explore ride safety relationships visually, in

Michael Absher 0 Jul 11, 2021