pythonsanic

Retrieving config from a blueprint in Sanic app


I have a Sanic application, and want to retrieve app.config from a blueprint as it holds MONGO_URL, and I will pass it to a repository class from the blueprint.

However, I could not find how to get app.config in a blueprint. I have also checked Flask solutions, but they are not applicable to Sanic.

My app.py:

from sanic import Sanic
from routes.authentication import auth_route
from routes.user import user_route

app = Sanic(__name__)
app.blueprint(auth_route, url_prefix="/auth")
app.blueprint(user_route, url_prefix="/user")

app.config.from_envvar('TWEETBOX_CONFIG')
app.run(host='127.0.0.1', port=8000, debug=True)

My auth blueprint:

import jwt
from sanic import Blueprint
from sanic.response import json, redirect
from domain.user import User
from repository.user_repository import UserRepository
...

auth_route = Blueprint('authentication')
mongo_url = ?????
user_repository = UserRepository(mongo_url)
...

@auth_route.route('/signin')
async def redirect_user(request):
    ...

Solution

  • I would suggest a slightly different approach, based on the 12 Factor App (very interesting read which, among others, provides a nice guideline on how to protect and isolate your sensitive info).

    The general idea is to place your sensitive and configuration variables in a file that is going to be gitignored and therefore will only be available locally.

    I will try to present the method I tend to use in order to be as close as possible to the 12 Factor guidelines:

    1. Create a .env file with your project variables in it:

      MONGO_URL=http://no_peeking_this_is_secret:port/
      SENSITIVE_PASSWORD=for_your_eyes_only
      CONFIG_OPTION_1=config_this
      DEBUG=True
      ...
      
    2. (Important) Add .env and .env.* on your .gitignore file, thus protecting your sensitive info from been uploaded to GitHub.

    3. Create an env.example (be careful not to name it with a . in the beginning, because it will get ignored).
      In that file, you can put an example of the expected configuration in order to be reproducible by simply copy, paste, rename to .env.

    4. In a file named settings.py, use decouple.config to read your config file into variables:

      from decouple import config
      
      
      MONGO_URL = config('MONGO_URL')
      CONFIG_OPTION_1 = config('CONFIG_OPTION_1', default='')
      DEBUG = config('DEBUG', cast=bool, default=True)
      ...
      
    5. Now you can use these variables wherever is necessary for your implementation:

      myblueprint.py:

      import settings
      
      ...
      auth_route = Blueprint('authentication')
      mongo_url = settings.MONGO_URL
      user_repository = UserRepository(mongo_url)
      ... 
      

    As a finisher, I would like to point out that this method is framework (and even language) agnostic so you can use it on Sanic as well as Flask and everywhere you need it!