Skip to main content

Flask-Injector

Build status

Adds Injector support to Flask.

Injector is a dependency-injection framework for Python, inspired by Guice.

This way there’s no need to use global Flask objects, which makes testing simpler.

Flask-Injector is compatible with CPython 2.5-2.6, 3.3+ and PyPy 1.9+.

Example application using flask_injector

Create your Flask application:

import sqlite3
from flask import Flask, Config
from flask.views import View
from flask_injector import init_app, post_init_app
from injector import Injector, inject

app = Flask(__name__)

Update the Flask app configuration as normal, additionally passing in any configuration for modules:

app.config.update(
    DB_CONNECTION_STRING=':memory:',
)

In the Injector world, all dependency configuration and initialization is performed in modules. The same is true with Flask-Injector. You can see some examples of configuring Flask extensions through modules below.

Accordingly, the next step is to create modules for any objects we want made available to the application. Note that in this example we also use the injector to gain access to the flask.Config:

# Configure our SQLite connection object
@inject(config=Config)
def configure(binder, config):
    binder.bind(
        sqlite3.Connection,
        to=sqlite3.Connection(config['DB_CONNECTION_STRING']),
        scope=request,
    )

Now perform Injector Flask application integration initialization. This needs to be run before any views, handlers, etc. are configured for the application:

injector = init_app(app=app, modules=[configure])

You can also provide already existing Injector instance:

injector = your_initialization_code()
# ...
init_app(app=app, injector=injector)

Configure your application by attaching views, handlers, context processors etc.:

# Putting all views configuration in a function is an example of how can
# you stop depending on global app object
def configure_views(app):
    @app.route("/bar")
    def bar():
        return render("bar.html")


    # Route with injection
    @app.route("/foo")
    @inject(db=sqlite3.Connection)
    def foo(db):
        users = db.execute('SELECT * FROM users').all()
        return render("foo.html")


    # Class-based view with injected constructor
    class Waz(View):
        @inject(db=sqlite3.Connection)
        def __init__(self, db):
            self.db = db

        def dispatch_request(self, key):
            users = self.db.execute('SELECT * FROM users WHERE name=?', (key,)).all()
            return 'waz'

    app.add_url_rule('/waz/<key>', view_func=Waz.as_view('waz'))

configure_views(app)

Run the post-initialization step. This needs to be run only after you attached all views, handlers etc.:

post_init_app(app=app, injector=injector)

Run the Flask application as normal:

app.run()

See example.py for a more complete example, including Flask-SQLAlchemy and Flask-Cache integration.

Supporting Flask Extensions

Typically, Flask extensions are initialized at the global scope using a pattern similar to the following.

app = Flask(__name__)
ext = ExtClass(app)

@app.route(...)
def view():
    # Use ext object here...

As we don’t have these globals with Flask-Injector we have to configure the extension the Injector way - through modules. Modules can either be subclasses of injector.Module or a callable taking an injector.Binder instance.

@inject(app=Flask)
def configure_ext(binder, app):
    binder.bind(ExtClass, to=ExtClass(app), scope=singleton)

def main():
    app = Flask(__name__)
    app.config.update(
        EXT_CONFIG_VAR='some_value',
    )

    injector = init_app(app=app, modules=[configure_ext])
    # attach your views etc. here
    post_init_app(app=app, injector=injector)

    app.run()

Make sure to bind extension objects as singletons.

Working Example 1: Flask-SQLAlchemy integration

This is a full working example of integrating Flask-SQLAlchemy.

We use standard SQLAlchemy models rather than the Flask-SQLAlchemy magic.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String

Base = declarative_base()


class KeyValue(Base):
    __tablename__ = 'data'

    key = Column(String, primary_key=True)
    value = Column(String)

    def __init__(self, key, value):
        self.key = key
        self.value = value

And to register the Flask-SQLAlchemy extension.

from flast.ext.sqlalchemy import SQLAlchemy

@inject(app=Flask)
class FlaskSQLAlchemyModule(Module):
    def configure(self, binder):
        db = self.configure_db(self.app)
        binder.bind(SQLAlchemy, to=db, scope=singleton)

    def configure_db(self, app):
        db = SQLAlchemy(app)
        Base.metadata.create_all(db.engine)
        db.session.add_all([
            KeyValue('hello', 'world'),
            KeyValue('goodbye', 'cruel world'),
        ])
        db.session.commit()
        return db

Working Example 2: Flask-Cache integration

@inject(app=Flask)
class CacheModule(Module):
    """Configure the application."""
    def configure(self, binder):
        binder.bind(Cache, to=Cache(self.app), scope=singleton)

Metadata

Release files for Flask-Injector 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Flask-Injector 0.3.2
File Size Uploaded Provenance
Flask-Injector-0.3.2.tar.gz 5.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for Flask-Injector 0.3.2
File Interpreter ABI Platform
Flask_Injector-0.3.2-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 13.8 kB

Release files / Flask-Injector-0.3.2.tar.gz

Download URL Flask-Injector-0.3.2.tar.gz
Size 5.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d808a98a4e9706bfa1d0003363de0efbbc9a88f2406745acf3fc18629afca9a0
BLAKE2b-256 checksum
How to use checksums
0ba696764cd600d25fb5a5af772762fa1b930675126fdc7a774c921c28da2a9a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / Flask_Injector-0.3.2-py2.py3-none-any.whl

Download URL Flask_Injector-0.3.2-py2.py3-none-any.whl
Size 8.3 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
ef86b665e18bb511bb8067b37c0c6d5e6810e87d5f33d6ed5f101a7155ed2009
BLAKE2b-256 checksum
How to use checksums
5344e44e61eabea25a049d1e940951687412a0ee1d62736f0d41629fc2e04563
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for Flask-Injector 0.3.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page