Announcing Blackfire middleware support for WSGI Python applications
Activating Blackfire on a WSGI application is now simplified by dedicated middleware.
WSGI is the Web Server Gateway Interface. It is a convention that describes how a web server communicates with web applications and how those can be organized to process one request.
Django, Flask, and many other popular Python frameworks are WSGI-based. Blackfire has dedicated support for Django, Flask, and Odoo. Our new custom middleware aims at easing the configuration of other WSGI applications
BlackfireWSGIMiddleware to the rescue
The Blackfire Middleware extends the framework scope by adding observability-related features. The
BlackfireWSGIMiddleware is provided with the Python SDK. The SDK itself is available with the Blackfire Python Package.
Let’s implement a middleware for a Bottle application by extending the
BlackfireWSGIMiddleware. Three elements need to be configured. The first mandatory step is to set the
FRAMEWORK constant as a class variable.
from blackfire.hooks.wsgi import BlackfireWSGIMiddleware class BlackfireBottleMiddleware(BlackfireWSGIMiddleware): FRAMEWORK = 'bottle' ...
Two methods could then be defined.
get_view_name would enable the monitoring of the WSGI application, while
build_blackfire_yml_response is required to trigger builds.
Both functions are required only for the monitoring and the synthetic monitoring of your application, respectively. Their definitions can be omitted if you are not considering one or the other.
Activating Blackfire Monitoring
To have the requests of your WSGI-based application instrumented by Blackfire Monitoring, the
get_view_name method must be defined.
get_view_name method retrieves the view name executing or handling the HTTP request. Blackfire Monitoring relies on this information to group requests in the monitoring dashboard.
Please check the documentation for a complete description of the function signature.
class BlackfireBottleMiddleware(BlackfireWSGIMiddleware): FRAMEWORK = 'bottle' def get_view_name(self, environ): return request.path
Keeping critical user journeys under control with Blackfire builds
Blackfire builds allow the performance assessment of a collection of scenarios that represent the various steps of critical user journeys. A
build_blackfire_yml_response method is required to trigger builds.
When a Build POST request is received, this function gets called to build a framework specific response that contains the
.blackfire.yaml file contents. It should return a framework specific HTTP response.
For more info, check the complete documentation of the
build_blackfire_yml_response function signature.
Here is the code of a Bottle application with Blackfire fully enabled:
from bottle import app, route, run, request, Response from blackfire.hooks.wsgi import BlackfireWSGIMiddleware class BlackfireBottleMiddleware(BlackfireWSGIMiddleware): FRAMEWORK = 'bottle' def get_view_name(self, environ): return request.path def build_blackfire_yml_response( self, blackfireyml_content, agent_response, environ, start_response ): # The .blackfire.yaml file should only be sent for authentified request if agent_response: return Response( body=blackfireyml_content or '', headers=[agent_response] )(environ, start_response) return Response()(environ, start_response) my_app = BlackfireBottleMiddleware(app()) @route('/') def home(): return 'hello world!' run(app=my_app)
Do you want to dig further to see the observability of Python applications?
Check theSümer Cip’s series of articles on the Challenges of Async Python Observability: part 1, part 2, and part 3.
Have you built a middleware for a WSGI framework? Reach out to us on Reddit or Twitter to contribute and share it with the Blackfire community.
And as always, Happy Python Performance Optimization!