Oslo Middleware Library
Oslo.middleware is an OpenStack library that provides a collection of WSGI middleware components for web service development. It allows developers to inject functionality into WSGI pipelines to intercept and modify request/response flows, offering features like HTTP header manipulation, request body size limiting, CORS support, and error handling. It is an actively maintained project within the OpenStack ecosystem, with regular releases aligning with OpenStack development cycles.
Common errors
-
ModuleNotFoundError: No module named 'oslo.middleware'
cause The package name is `oslo-middleware` (with a hyphen) for installation, but the Python import path uses an underscore: `oslo_middleware`.fixChange your import statement to `from oslo_middleware import ...`. -
TypeError: 'module' object is not callable (when trying to use `oslo_middleware.CORS` directly)
cause Many `oslo_middleware` components are classes that need to be instantiated, or they provide a factory function (e.g., `CORS.factory()`) for `paste.deploy` integration, not directly callable as a module.fixInstantiate the middleware class: `app = cors.CORS(your_app, ...)` or use its `factory` method if integrating with `paste.deploy`. Refer to specific middleware documentation for correct usage. -
KeyError: 'openstack.request_id' (or similar env var not found)
cause Attempting to access a request environment variable (like `openstack.request_id`) that has not been set by its corresponding middleware.fixEnsure the relevant middleware (e.g., `RequestId` for `openstack.request_id`) is properly included and ordered in your WSGI pipeline before your application attempts to access its values.
Warnings
- breaking Import paths for middleware components were standardized under the `oslo_middleware` namespace. Older projects might still reference `openstack.common.middleware`.
- gotcha Incorrect middleware order can lead to unexpected behavior. For instance, `CatchErrors` should typically wrap your application and other middleware that might raise exceptions, while `RequestId` often comes early in the pipeline.
- deprecated The `CatchErrors` middleware, in older versions, had an information-disclosure flaw (CVE-2017-2592) where sensitive values could be included in traceback error messages, potentially exposing tokens or other data.
Install
-
pip install oslo-middleware
Imports
- CORS
from oslo.middleware import cors
from oslo_middleware import cors
- CatchErrors
from oslo.middleware import catch_errors
from oslo_middleware import catch_errors
- RequestId
from openstack.common.middleware import request_id
from oslo_middleware import request_id
Quickstart
import webob.dec
import webob.exc
from oslo_middleware import catch_errors
from oslo_middleware import request_id
@webob.dec.wsgify
def simple_app(req):
if req.path_info == '/hello':
return f"Hello, Request ID: {req.environ.get('openstack.request_id', 'N/A')}"
elif req.path_info == '/error':
raise ValueError('Something went wrong!')
return webob.exc.HTTPNotFound()
# Order matters: RequestId first to ensure ID is generated,
# then CatchErrors to handle subsequent exceptions.
app = request_id.RequestId(simple_app)
app = catch_errors.CatchErrors(app)
# To run this with a WSGI server (e.g., Gunicorn or uWSGI):
# Save as app.py and run 'gunicorn app:app'
# Test with curl:
# curl http://127.0.0.1:8000/hello
# curl http://127.0.0.1:8000/error