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
Boilerplate code for basic flask web apps

Flask Boilerplate This repository contains boilerplate code to start a project instantly It's mainly for projects which you plan to ship in less than

Abhishek 6 Sep 27, 2021
A caching extension for Flask

Flask-Caching Adds easy cache support to Flask. This is a fork of the Flask-Cache extension. Flask-Caching also includes the cache module from werkzeu

Peter Justin 774 Jan 02, 2023
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
Set up a modern flask web server by running one command.

Build Flask App · Set up a modern flask web server by running one command. Installing / Getting started pip install build-flask-app Usage build-flask-

Kushagra Bainsla 5 Jul 16, 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
This repo contains the Flask API to expose model and get predictions.

Tea Leaf Quality Srilanka Chapter This repo contains the Flask API to expose model and get predictions. Expose Model As An API Model Trainig will happ

DuKe786 2 Nov 12, 2021
Source code for backpainfree.org - a Q&A platform similar to StackOverFlow

Source code for backpainfree.org - a Q&A platform similar to StackOverFlow, which is designed specifically for people with back pain problems. Users can ask questions, post answers and comments, vote

Olzhas Arystanov 8 Dec 11, 2022
A multi-container docker application. Implemented and dockerized a web-based service leveraging Flask

Flask-based-web-service-with-Docker-compose A multi-container docker application. Implemented and dockerized a web-based service leveraging Flask. Des

Jayshree Rathi 1 Jan 15, 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
Telegram bot + Flask API ( Make Introduction pages )

Introduction-Page-Maker Setup the api Upload the flask api on your host Setup requirements Make pages file on your host and upload the css and js and

Plugin 9 Feb 11, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
Search users in Github. Created with Flask, PipEnv, Heroku and free time.

Search in Github Here search for users in Github and other stuff! This app is working with, Data Github API BackEnd Flask Language Python Package mana

AmirHossein Mohammadi 12 Jan 16, 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
Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Ahmed khémiri 22 Sep 08, 2021
Analytics snippets generator extension for the Flask framework.

Flask-Analytics Flask Analytics is an extension for Flask which generates analytics snippets for inclusion in templates. Installation $ pip install Fl

Mihir 80 Nov 30, 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
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
This is a simple web application using Python Flask and MySQL database.

Simple Web Application This is a simple web application using Python Flask and MySQL database. This is used in the demonstration of development of Ans

Alaaddin Tarhan 1 Nov 16, 2021
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
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