# Blueprints

# Overview

Blueprints are objects that can be used for sub-routing within an application. Instead of adding routes to the application instance, blueprints define similar methods for adding routes, which are then registered with the application in a flexible and pluggable manner.

Blueprints are especially useful for larger applications, where your application logic can be broken down into several groups or areas of responsibility.

# Creating and registering

First, you must create a blueprint. It has a very similar API as the Sanic() app instance with many of the same decorators.

# ./my_blueprint.py
from sanic.response import json
from sanic import Blueprint

bp = Blueprint("my_blueprint")

async def bp_root(request):
    return json({"my": "blueprint"})

Next, you register it with the app instance.

from sanic import Sanic
from my_blueprint import bp

app = Sanic(__name__)

Blueprints also have the same websocket() decorator and add_websocket_route method for implementing websockets.

# Blueprint groups

Blueprints may also be registered as part of a list or tuple, where the registrar will recursively cycle through any sub-sequences of blueprints and register them accordingly. The Blueprint.group method is provided to simplify this process, allowing a ‘mock’ backend directory structure mimicking what’s seen from the front end. Consider this (quite contrived) example:

│ ├──authors.py
│ ├──static.py
│ └──__init__.py

# First blueprint

# api/content/authors.py
from sanic import Blueprint

authors = Blueprint("content_authors", url_prefix="/authors")

# Second blueprint

# api/content/static.py
from sanic import Blueprint

static = Blueprint("content_static", url_prefix="/static")

# Blueprint group

# api/content/__init__.py
from sanic import Blueprint
from .static import static
from .authors import authors

content = Blueprint.group(static, authors, url_prefix="/content")

# Third blueprint

# api/info.py
from sanic import Blueprint

info = Blueprint("info", url_prefix="/info")

# Another blueprint group

# api/__init__.py
from sanic import Blueprint
from .content import content
from .info import info

api = Blueprint.group(content, info, url_prefix="/api")

# Main server

All blueprints are now registered

# app.py
from sanic import Sanic
from .api import api

app = Sanic(__name__)

# Middleware

Blueprints can also have middleware that is specifically registered for its endpoints only.

async def print_on_request(request):
    print("I am a spy")

async def halt_request(request):
    return text("I halted the request")

async def halt_response(request, response):
    return text("I halted the response")

Similarly, using blueprint groups, it is possible to apply middleware to an entire group of nested blueprints.

bp1 = Blueprint("bp1", url_prefix="/bp1")
bp2 = Blueprint("bp2", url_prefix="/bp2")

async def bp1_only_middleware(request):
    print("applied on Blueprint : bp1 Only")

async def bp1_route(request):
    return text("bp1")

async def bp2_route(request, param):
    return text(param)

group = Blueprint.group(bp1, bp2)

async def group_middleware(request):
    print("common middleware applied for both bp1 and bp2")

# Register Blueprint group under the app

# Exceptions

Just like other exception handling, you can define blueprint specific handlers.

def ignore_404s(request, exception):
    return text("Yep, I totally found the page: {}".format(request.url))

# Static files

Blueprints can also have their own static handlers

bp = Blueprint("bp", url_prefix="/bp")
bp.static("/web/path", "/folder/to/serve")
bp.static("/web/path", "/folder/to/server", name="uploads")

Which can then be retrieved using url_for(). See routing for more information.

>>> print(app.url_for("static", name="bp.uploads", filename="file.txt"))

# Listeners

Blueprints can also implement listeners.

async def before_server_start(app, loop):

async def after_server_stop(app, loop):

# Versioning

As discussed in the versioning section, blueprints can be used to implement different versions of a web API.

The version will be prepended to the routes as /v1 or /v2, etc.

auth1 = Blueprint("auth", url_prefix="/auth", version=1)
auth2 = Blueprint("auth", url_prefix="/auth", verison=2)

When we register our blueprints on the app, the routes /v1/auth and /v2/auth will now point to the individual blueprints, which allows the creation of sub-sites for each API version.

from auth_blueprints import auth1, auth2

app = Sanic(__name__)

# Generating a URL

When generating a url with url_for(), the endpoint name will be in the form:

MIT Licensed | Copyright © 2018-present Sanic Community Organization