7

I'm building a very complex microservice using Flask and Flask-Restplus.
It will have many endpoints, thus I'm organizing each endpoint into a separate Blueprint.

  • Currently, I'm struggling with the usage of Flask-Restplus and API using multiple Blueprints in combination with swagger
  • I want to be able to get all the endpoints of my blueprints into the built-in swagger of API, but this doesn't seem to work.
  • I can access my endpoints via postman, but the swagger-UI doesn't show anything. :(

The following example code and directory structure should give you a hint towards my idea:

.
├── endpoints
│   ├── endpointa.py
│   ├── endpointb.py
│   ├── endpointc.py
│   └── __init__.py
├── __init__.py
└── run.py

My main init.py looks like this:

from flask import Flask, Blueprint, logging, jsonify, request, Response
from flask_restplus import Resource, Api   


# create app and api
app = Flask(__name__)
api_prefix  = '/api/v1/'

# register Blueprints
from endpoints.endpointa import endpointa_api
app.register_blueprint(endpointa_api, url_prefix=api_prefix)

from endpoints.endpointb import endpointb_api
app.register_blueprint(endpointb_api, url_prefix=api_prefix)

from endpoints.endpointc import endpointc_api
app.register_blueprint(endpointc_api, url_prefix=api_prefix)


api = Api(app,
          version='1',
          title='Test Service REST-API',
          description='A REST-API for the Test Service, implemented in python')


if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=5060)

endpointa.py with the corresponding Blueprint:

from os import environ
import json, ast, syslog
import requests
import gc
from flask import Flask, Blueprint, logging, jsonify, request, Response
from flask_restplus import Resource, Api

endpointa_api = Blueprint('endpointa_api', __name__)

@endpointa_api.route('testa', methods=['GET'])
def testa():
    ...


@endpointa_api.route('testa/<string:testa_id>', methods=['GET', 'POST'])
def testa_id():
    ...

Again:

I can access my endpoints via postman, but the swagger-UI doesn't show anything:

enter image description here

Normally I would add endpoints to API using something like

api.add_resource(TestClass, api_prefix + 'test')

but this doesn't seem to be possible with multiple Blueprints.

Can anyone show me how to add/register these Blueprints (endpointa_api, endpointb_api and endpointc_api) with Api ?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
dacoda
  • 157
  • 1
  • 2
  • 10

1 Answers1

9

There are 2 possible solutions using Flask-Restplus:

  • Use Flask-RestPlus namespaces
  • Turn your blueprints into Flask-RestPlus Apis

You can read about both in the documentation: https://flask-restplus.readthedocs.io/en/stable/scaling.html

Namespaces

Flask-RESTPlus provides a way to use almost the same pattern as Flask’s blueprint. The main idea is to split your app into reusable namespaces.

from flask_restplus import Api

from .namespace1 import api as ns1
from .namespace2 import api as ns2
# ...
from .namespaceX import api as nsX

api = Api(
    title='My Title',
    version='1.0',
    description='A description',
    # All API metadatas
)

api.add_namespace(ns1)
api.add_namespace(ns2)
# ...
api.add_namespace(nsX)

Blueprint Apis

Here’s an example of how to link an Api up to a Blueprint.

from flask import Blueprint
from flask_restplus import Api

blueprint = Blueprint('api', __name__)
api = Api(blueprint)
# ...

Using a blueprint will allow you to mount your API on any url prefix and/or subdomain in you application:

from flask import Flask
from apis import blueprint as api

app = Flask(__name__)
app.register_blueprint(api, url_prefix='/api/1')
app.run(debug=True)
Robbe
  • 2,610
  • 1
  • 20
  • 31
  • 2
    Thank you. Blueprint Apis: This is the example of linking an Api to ONE Blueprint, but I want to be able to link an Api to multiple Blueprints. – dacoda Feb 25 '19 at 10:10
  • 1
    You can do the same for each blueprint. Just call `Api(blueprint)` for each and register them on your app. – Robbe Feb 25 '19 at 14:24
  • Thank you very much, I'll use namespaces, fits best for my purposes. :) – dacoda Mar 01 '19 at 08:13
  • 1
    Hi @dacoda, if this answer helped you, could you mark it as accepted so it's clear for other users that this worked? – Robbe Mar 07 '19 at 08:27
  • How can I just go to one endpoint to view all my swagger endpoints? With this I need to do `http://localhost:5000/` where before I did not need to define my namespace's URL prefix – frlzjosh Jul 06 '21 at 07:56
  • 1
    What's the benefit of using namespaces vs blueprints? – Teharez Jul 28 '21 at 06:57
  • Would have been nice if the examples were relevant to the question's code. This example shows nothing more than the docs. Where does the automated documentation come into play with the example given? – Dean Martin Nov 24 '21 at 16:26