Flasgger lets you write Swagger documentation directly in your Flask application’s code, turning your API endpoints into living, self-documenting entities.

Here’s a simple Flask app with a /hello endpoint:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def hello():
    return jsonify({'message': 'Hello, world!'})

if __name__ == '__main__':
    app.run(debug=True)

Now, let’s add Flasgger to it. First, install it:

pip install flasgger

Then, integrate it into your app:

from flask import Flask, jsonify
from flasgger import Swagger

app = Flask(__name__)
swagger = Swagger(app) # Initialize Swagger with your Flask app

@app.route('/hello', methods=['GET'])
def hello():
    """A simple greeting endpoint.
    ---
    responses:
      200:
        description: A friendly greeting.
        schema:
          type: object
          properties:
            message:
              type: string
              example: Hello, world!
    """
    return jsonify({'message': 'Hello, world!'})

if __name__ == '__main__':
    app.run(debug=True)

The key is the docstring format. The """A simple greeting endpoint.\n---\nresponses:\n 200:\n description: A friendly greeting.\n schema:\n type: object\n properties:\n message:\n type: string\n example: Hello, world!\n""" is where the magic happens.

The --- separates the human-readable description from the machine-readable Swagger specification. Under responses, you define what your endpoint returns. Here, we specify a 200 OK response, describing its schema (a JSON object with a message property of type string, with an example).

When you run this Flask app and navigate to /apidocs (the default Swagger UI endpoint), you’ll see your documentation. You can even try out the endpoint directly from the UI.

Let’s add another endpoint, this time with a parameter:

from flask import Flask, jsonify, request
from flasgger import Swagger

app = Flask(__name__)
swagger = Swagger(app)

@app.route('/hello', methods=['GET'])
def hello():
    """A simple greeting endpoint.
    ---
    responses:
      200:
        description: A friendly greeting.
        schema:
          type: object
          properties:
            message:
              type: string
              example: Hello, world!
    """
    return jsonify({'message': 'Hello, world!'})

@app.route('/greet/<name>', methods=['GET'])
def greet(name):
    """Greets a specific person by name.
    ---
    parameters:
      - name: name
        in: path
        type: string
        required: true
        description: The name of the person to greet.
    responses:
      200:
        description: A personalized greeting.
        schema:
          type: object
          properties:
            greeting:
              type: string
              example: Hello, Alice!
    """
    return jsonify({'greeting': f'Hello, {name}!'})

if __name__ == '__main__':
    app.run(debug=True)

In the /greet/<name> endpoint, we introduced parameters. This section describes the name parameter:

  • name: name: The name of the parameter.
  • in: path: It’s part of the URL path. Other options include query, header, formData, and body.
  • type: string: The data type of the parameter.
  • required: true: This parameter must be provided.
  • description: A human-readable explanation.

The responses section now describes a greeting property.

Flasgger supports much more than just basic responses and parameters. You can define request bodies for POST/PUT requests, security schemes, external documentation links, and even custom Swagger extensions. The documentation for Flasgger provides a comprehensive look at all the available directives you can use in your docstrings.

A common pattern is to define reusable response schemas or parameter definitions at the top level of your Swagger initialization. This is done using the template or specs arguments when creating the Swagger object. For instance, you can define a components section in your Swagger template to hold common schema definitions, which can then be referenced by your individual endpoints using $ref.

Consider this: when you define a type: object in a schema, you’re not just saying it’s an object; you’re implicitly defining a schema where the keys are the property names and the values are the property types. This maps directly to JSON schema specifications, allowing for detailed validation and clear data structure definitions within your API documentation.

If you want to automatically generate Swagger specs from your Marshmallow schemas, you can use Flasgger’s integration with Marshmallow. This avoids duplicating schema definitions and keeps your API contract consistent.

The next step is to explore how to handle authentication and authorization within your Swagger documentation, which Flasgger supports through various security scheme definitions.

Want structured learning?

Take the full Flask course →