Skip to main content

Web App Scaling with Flask Blueprint and Namespaces



A real-world Flask-RESTX-based API may have multiple namespaces. The best practice for scaling a web application is to use a blueprint along with multiple namespace. The namespace is used to group a set of CRUD operations for a specific resource. Blueprint can be used to combine (mixing) multiple namespaces.

Here’s an example directory structure:
project\
├── app.py                     #  Application file
├── apis                       #
   ├── v20                     #  API directory
   │   ├── __init__.py            
   │   ├── specs.py            #  API namespaces and REST methods
   │   ├── steps.py            #  API namespaces and REST methods
   └── v20bp.py                #  API blueprint file

Here is an example app.py. Using a blue print allow you to mount your API on any url prefix.

from flask import Flask

from apis.v20bp import blueprint as api

app = Flask(__name__)
app.register_blueprint(api, url_prefix='/api/v20')
app.run(debug=True)

The following is an example of v20bp.py .
from flask import Blueprint

from flask_restx import Api

blueprint = Blueprint('api', __name__)

api = Api(blueprint)

api.add_namespace(ns1)
api.add_namespace(ns2)



The v20.__init__.py would aggregate all the namespace
from flask_restx import Api

from .specs import api as ns1
from .steps import api as ns2

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

api.add_namespace(ns1)
api.add_namespace(ns2)

Below is an example of a namespace.
from flask_restx import Namespace, Resource, fields

api = Namespace('steps', description='Steps related operations')

step = api.model('Step', {
    'id': fields.String(required=True, description='The identifier'),
    'name': fields.String(required=True, description='The name'),
})

STEPS = [
    {'id': 'felix', 'name': 'Felix'},
]

@api.route('/')
class StepList(Resource):
    @api.doc('list_steps')
    @api.marshal_list_with(step)
    def get(self):
        '''List all steps'''
        return STEPS

@api.route('/<id>')
@api.param('id', 'The step identifier')
@api.response(404, 'Step not found')
class Step(Resource):
    @api.doc('get_step')
    @api.marshal_with(step)
    def get(self, id):
        '''Fetch a step given its identifier'''
        for stp in STEPS:
            if stp['id'] == id:
                return stp
        api.abort(404)
References:


http://michal.karzynski.pl/blog/2016/06/19/building-beautiful-restful-apis-using-flask-swagger-ui-flask-restplus/



Comments

Popular posts from this blog