Skip to main content

Configure middleware

Warning

Manual middleware configuration is no longer recommended. Instead, you should run your application with the contrast-python-run command, which automatically detects and enables framework-specific instrumentation. See Contrast Runner for more information.

For rarer cases where manual middleware configuration is still required, instructions are listed below.

Middleware is a software component that is part of a web application and is capable of reading and modifying inbound requests and outbound responses.

The Python agent is implemented as a middleware for all of the frameworks that Contrast supports. To use the Python agent, you must configure the middleware for the framework that your application uses:

AIOHTTP

AIOHTTP middleware is a class-based middleware that should be passed into the aiohttp web.Application constructor as an argument. The following example shows a sample AIOHTTP application that uses the Contrast middleware class:

from aiohttp import web
from contrast.aiohttp import ContrastMiddleware


routes = web.RouteTableDef()

@routes.get("/")
def index(request):
    raise web.HTTPFound("/hello")


middlewares = [ContrastMiddleware(app_name="app name")]
app = web.Application(middlewares=middlewares)
app.add_routes(routes)

web.run_app(app)

Bottle

Contrast's Bottle middleware is a WSGI middleware, which operates by wrapping the Bottle application instance.

To configure the Python agent for Bottle:

  1. Find the Bottle application object in your application codebase. This will be an instance of bottle.Bottle.

    A sample Bottle application might look like this, where app is your Bottle application object:

    from bottle import Bottle, run
    
    app = Bottle(__name__)
    
    @app.route("/")
    def index():    
        return "hello world"
    
    <InstallContrastHere>
    
    run(app)
  2. Wrap the Bottle application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.bottle import ContrastMiddleware
    app = ContrastMiddleware(app)

Important

In rare cases, you may be required to pass the original bottle.Bottle application instance directly to the ContrastMiddleware in addition to your WSGI application object. If the application does not start, find your original Bottle application and pass it to Contrast's middleware. For example:

app = ContrastMiddleware(
    app,
    original_bottle_app,  # instance of bottle.Bottle
)

Django

New configuration steps: works with Contrast Python agent versions 4.6.0 and later

Contrast's Django middleware is a WSGI middleware, not a Django-style middleware.

  1. Find your WSGI application object. The WSGI_APPLICATION Django configuration option points to your project's WSGI app - this is often located in wsgi.py. You must set the WSGI_APPLICATION config option if it is not already set.

    A sample wsgi.py might look like this, where application is your WSGI application object:

    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    
    <InstallContrastHere>
  2. Wrap the WSGI application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.django import ContrastMiddleware
    application = ContrastMiddleware(application)

Old configuration steps: will not work with Contrast Python agent versions 5.0.0 and later

Django middleware is configured in the settings.py file.

  1. Find the settings.py file. This file isn't found in the same location for all applications, but it's generally near the top of the application source tree. Common locations include:

    • /settings.py

    • config/settings.py

    • app/settings.py

    Note

    When searching the source tree to find the settings.py, make sure to exclude any directories that correspond to Python virtual environments.

    Some applications have multiple settings.py files, which may correspond to different configurations of the application (for example, prod or test). In these cases, add the Contrast agent middleware to any and all of the configurations where it will be used.

  2. Add the Contrast agent module to the list.

    Include the Contrast middleware as early in the list as possible; although modifying the order may be necessary to get the application working in some circumstances.

    • Django 1.10 and later: Look for the MIDDLEWARE configuration variable, which is an array. Add the Contrast agent module to the list:

      MIDDLEWARE = [
        'contrast.agent.middlewares.django_middleware.DjangoMiddleware',
        # OTHER MIDDLEWARE,
      ]
    • Django 1.6 to 1.9: Look for the MIDDLEWARE_CLASSES configuration variable in settings.py and add the Contrast agent module to the list:

      MIDDLEWARE_CLASSES = [
        'contrast.agent.middlewares.legacy_django_middleware.DjangoMiddleware',
        # OTHER MIDDLEWARE
      ]

    See the Django documentation for more details on middleware inclusion.

Falcon (ASGI)

Falcon (ASGI) middleware is an ASGI middleware, which operates by wrapping the Falcon(ASGI) application instance.

The following example shows a sample Falcon(ASGI) application wrapped by the Contrast middleware class.

Note

If your Falcon (ASGI) application uses other middleware in addition to Contrast, Contrast must be the first middleware initialized in order for certain features to work.

import falcon.asgi
from contrast.falcon_asgi import ContrastMiddleware


class Home(object):
    async def on_get(self, req, resp):
        resp.status = falcon.HTTP_200
        resp.body = "Hello World"
        
def create():
    # This is where the example app is declared. Look for something similar in your
    # application since this instance needs to be wrapped by Contrast middleware
    _app = falcon.asgi.App()
    
    # Add routes to your app
    home = Home()
    _app.add_route("/home", home)
    
    # This line wraps the application instance with the Contrast middleware
    # NOTE: Contrast should be the first middleware if others are used
    _app = ContrastMiddleware(_app)
    return _app


app = create()

Falcon (WSGI)

Contrast's Falcon middleware is a WSGI middleware, not a Falcon-style middleware.

  1. Find your Falcon application object. This will be an instance of falcon.API or falcon.App depending on your version of Falcon.

    A sample Falcon application might look like this, where app is your Falcon application object:

    import falcon
    from views import Home
    
    app = falcon.API()
    
    home = Home()
    app.add_route('/home', home)
    
    <InstallContrastHere>
  2. Wrap the Falcon application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.falcon import ContrastMiddleware
    app = ContrastMiddleware(app)

    Important

    In rare cases, you may be required to pass the original falcon.App or falcon.API application instance directly to the ContrastMiddleware in addition to your WSGI application object. If the application does not start, find your original Falcon application and pass it to Contrast's middleware. For example:

    app = ContrastMiddleware(
      app,
      original_falcon_app,  # instance of falcon.App or falcon.API
    )

    Important

    You must wrap the Falcon instance after route registration is complete.

FastAPI

FastAPI middleware is a class-based ASGI middleware that relies on starlette.middleware.BaseHTTPMiddleware. Check Python supported technologies for the latest version of FastAPI supported by Contrast. The following example shows a sample FastAPI application that uses the Contrast middleware class:

from fastapi import FastAPI
from contrast.fastapi import ContrastMiddleware

app = FastAPI()
app.add_middleware(ContrastMiddleware, original_app=app)

@app.get("/")
def read_root():
    return RedirectResponse("/home")

If your FastAPI application uses other middleware in addition to Contrast, Contrast must be the first middleware initialized in order for certain features to work.

from fastapi import FastAPI
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
from contrast.fastapi import ContrastMiddleware

app = FastAPI()

# ContrastMiddleware must be the first middleware
app.add_middleware(ContrastMiddleware, original_app=app)
app.add_middleware(HTTPSRedirectMiddleware)

Adding middleware via the add_middleware method is the only supported way to add middleware at this time, because certain features require the FastAPI app to be passed in as the original_app keyword argument. Initializing middlewares by passing them in directly to the FastAPI class initialization is not currently supported by Contrast.

# Not currently supported.
app = FastAPI(middleware=[...])

Warning

Calling add_middleware multiple times is known to re-initialize all previous middleware.

Flask

Contrast’s Flask middleware is a WSGI middleware, which operates by wrapping the Flask application instance.

  1. Find your Flask application object. This will be an instance of flask.Flask.

    A sample Flask application might look like this, where app is your Flask application object:

    import Flask
    
    app = Flask(__name__)
    
    <InstallContrastHere>
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    app.run(...) 
    
  2. Wrap the Flask application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.flask import ContrastMiddleware
    app.wsgi_app = ContrastMiddleware(app)

    Note

    Contrast's Flask middleware requires an instance of flask.Flask as an argument, rather than flask.Flask.wsgi_app.

Pyramid

Old configuration steps: will not work with Contrast Python agent versions 5.0.0 and later

In Pyramid, middlewares are called "tweens".

  1. Find the configurator object in your application codebase. It might look like this:

    from pyramid.config import Configurator
    config = Configurator()
    
    <InstallContrastHere>
  2. Add Contrast's middleware to your config. In the example above, replace <InstallContrastHere> with:

    config.add_tween('contrast.agent.middlewares.pyramid_middleware.PyramidMiddleware')

    See the Pyramid documentation for additional details on tween configuration.

New configuration steps: works with Contrast Python agent versions 4.6.0 and later

Contrast's Pyramid middleware is a WSGI middleware, not a Pyramid-style "tween".

  1. Find your WSGI application object. This is often created by a call to Configurator.make_wsgi_app().

    For example, it might look like this:

    from pyramid.config import Configurator
    
    config = Configurator()
    app = config.make_wsgi_app()
    
    <InstallContrastHere>
  2. Wrap the WSGI application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.pyramid import ContrastMiddleware
    app = ContrastMiddleware(app)

    Important

    In rare cases, Contrast may require that you pass your application's Registry object to the middleware as well. The registry is commonly available as an attribute of both the Configurator instance and the Pyramid application object.

    If the application does not start, find your application Registry and pass it to Contrast's middleware, for example:

    app = ContrastMiddleware(app, config.registry)

Quart

The Quart middleware should wrap the Quart application object and be assigned to the asgi_app attribute. The following example shows a sample quart application that uses the Contrast middleware class:

from quart import Quart, redirect
from contrast.quart import ContrastMiddleware


app = Quart(__name__)
app.asgi_app = ContrastMiddleware(app)

@app.route("/")
async def index():
    return redirect("/home")

WSGI

Contrast provides a generic WSGI middleware that includes all core agent functionality. Framework-specific features such as route discovery are not implemented in the generic WSGI middleware.

To instrument any WSGI-compliant application with Contrast:

  1. Find the WSGI application object in your application codebase. For example, a WSGI app was created as follows:

    from example.module import make_app
    wsgi_app = make_app() 
    
    <InstallContrastHere>
  2. Wrap the WSGI application object with Contrast's middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.wsgi import ContrastMiddleware
    wsgi_app = ContrastMiddleware(wsgi_app)

See the WSGI specification for additional details on WSGI middleware.

ASGI

Contrast also provides a generic ASGI middleware. Like the generic WSGI middleware, the ASGI middleware includes core agent functionality but no framework-specific features.

To instrument an ASGI-compliant HTTP/HTTPS application:

  1. Find the ASGI application object in your codebase. For example, take the following ASGI app:

    from example.module import make_app
    asgi_app = make_app()
    
    <InstallContrastHere>
  2. Wrap the ASGI application object with Contrast’s middleware. In the example above, replace <InstallContrastHere> with:

    from contrast.asgi import ContrastMiddleware
    asgi_app = ContrastMiddleware(asgi_app)