# API

class oslo_middleware.BasicAuthMiddleware(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Middleware which performs HTTP basic authentication on requests

class oslo_middleware.CORS(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  CORS Middleware.

  This middleware allows a WSGI app to serve CORS headers for multiple configured domains.

  For more information, see http://www.w3.org/TR/cors/

  add_origin(allowed_origin: list[str], allow_credentials: bool = True, expose_headers: list[str] | None = None, max_age: int | None = None, allow_methods: list[str] | None = None, allow_headers: list[str] | None = None) → None

    Add another origin to this filter.

    Parameters:

      - allowed_origin – Protocol, host, and port for the allowed origin.

      - allow_credentials – Whether to permit credentials.

      - expose_headers – A list of headers to expose.

      - max_age – Maximum cache duration.

      - allow_methods – List of HTTP methods to permit.

      - allow_headers – List of HTTP headers to permit from the client.

    Returns:

  classmethod factory(global_conf: dict[str, Any] | None, **local_conf: Any) → Callable[[WSGIApplication], base.MiddlewareType]

    factory method for paste.deploy

    allowed_origin: Protocol, host, and port for the allowed origin. allow_credentials: Whether to permit credentials. expose_headers: A list of headers to expose. max_age: Maximum cache duration. allow_methods: List of HTTP methods to permit. allow_headers: List of HTTP headers to permit from the client.

  process_response(response: Response, request: Request | None = None) → Response

    Check for CORS headers, and decorate if necessary.

    Perform two checks. First, if an OPTIONS request was issued, let the application handle it, and (if necessary) decorate the response with preflight headers. In this case, if a 404 is thrown by the underlying application (i.e. if the underlying application does not handle OPTIONS requests, the response code is overridden.

    In the case of all other requests, regular request headers are applied.

class oslo_middleware.CatchErrors(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Middleware that provides high-level error handling.

  It catches all exceptions from subsequent applications in WSGI pipeline to hide internal errors from API response.

class oslo_middleware.CorrelationId(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Middleware that attaches a correlation id to WSGI request

  static process_request(req: webob.request.Request) → webob.response.Response | None

    Called on each request.

    If this returns None, the next application down the stack will be executed. If it returns a response then that response will be returned and execution will stop here.

class oslo_middleware.Debug(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Helper class that returns debug information.

  Can be inserted into any WSGI application chain to get information about the request and response.

  static print_generator(app_iter: Iterable[bytes]) → Iterator[bytes]

    Prints the contents of a wrapper string iterator when iterated.

class oslo_middleware.HTTPProxyToWSGI(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  HTTP proxy to WSGI termination middleware.

  This middleware overloads WSGI environment variables with the one provided by the remote HTTP reverse proxy.

  process_request(req: webob.request.Request) → webob.response.Response | None

    Called on each request.

    If this returns None, the next application down the stack will be executed. If it returns a response then that response will be returned and execution will stop here.

class oslo_middleware.Healthcheck(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Healthcheck application used for monitoring.

  It will respond 200 with “OK” as the body. Or a 503 with the reason as the body if one of the backends reports an application issue.

  This is useful for the following reasons:

  - Load balancers can ‘ping’ this url to determine service availability.

  - Provides an endpoint that is similar to ‘mod_status’ in apache which can provide details (or no details, depending on if configured) about the activity of the server.

  - (and more)

  Note

  This middleware indicates that the API is accessible but it does indicate that it is necessarily functional or that any other API request will actually work.

  Example requests/responses (not detailed mode):

      $ curl -i -X HEAD "http://0.0.0.0:8775/healthcheck"
      HTTP/1.1 204 No Content
      Content-Type: text/plain; charset=UTF-8
      Content-Length: 0
      Date: Fri, 11 Sep 2015 18:55:08 GMT

      $ curl -i -X GET "http://0.0.0.0:8775/healthcheck"
      HTTP/1.1 200 OK
      Content-Type: text/plain; charset=UTF-8
      Content-Length: 2
      Date: Fri, 11 Sep 2015 18:55:43 GMT

      OK

      $ curl -X GET -i -H "Accept: application/json" "http://0.0.0.0:8775/healthcheck"
      HTTP/1.0 200 OK
      Date: Wed, 24 Aug 2016 06:09:58 GMT
      Content-Type: application/json
      Content-Length: 63

      {
          "detailed": false,
          "reasons": [
              "OK"
          ]
      }

      $ curl -X GET -i -H "Accept: text/html" "http://0.0.0.0:8775/healthcheck"
      HTTP/1.0 200 OK
      Date: Wed, 24 Aug 2016 06:10:42 GMT
      Content-Type: text/html; charset=UTF-8
      Content-Length: 239

      <HTML>
      <HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
      <BODY>

      <H2>Result of 1 checks:</H2>
      <TABLE bgcolor="#ffffff" border="1">
      <TBODY>
      <TR>

      <TH>
      Reason
      </TH>
      </TR>
      <TR>
          <TD>OK</TD>
      </TR>
      </TBODY>
      </TABLE>
      <HR></HR>

      </BODY>

  Example requests/responses (detailed mode):

      $ curl -X GET -i -H "Accept: application/json" "http://0.0.0.0:8775/healthcheck"
      HTTP/1.0 200 OK
      Date: Wed, 24 Aug 2016 06:11:59 GMT
      Content-Type: application/json
      Content-Length: 3480

      {
          "detailed": true,
          "gc": {
              "counts": [
                  293,
                  10,
                  5
              ],
              "threshold": [
                  700,
                  10,
                  10
              ]
          },
          "greenthreads": [
             ...
          ],
          "now": "2016-08-24 06:11:59.419267",
          "platform": "Linux-4.2.0-27-generic-x86_64-with-Ubuntu-14.04-trusty",
          "python_version": "2.7.6 (default, Jun 22 2015, 17:58:13) \n[GCC 4.8.2]",
          "reasons": [
              {
                  "class": "HealthcheckResult",
                  "details": "Path '/tmp/dead' was not found",
                  "reason": "OK"
              }
          ],
          "threads": [
              ...
          ]
      }

      $ curl -X GET -i -H "Accept: text/html" "http://0.0.0.0:8775/healthcheck"
      HTTP/1.0 200 OK
      Date: Wed, 24 Aug 2016 06:36:07 GMT
      Content-Type: text/html; charset=UTF-8
      Content-Length: 6838

      <HTML>
      <HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
      <BODY>
      <H1>Server status</H1>
      <B>Server hostname:</B><PRE>...</PRE>
      <B>Current time:</B><PRE>2016-08-24 06:36:07.302559</PRE>
      <B>Python version:</B><PRE>2.7.6 (default, Jun 22 2015, 17:58:13)
      [GCC 4.8.2]</PRE>
      <B>Platform:</B><PRE>Linux-4.2.0-27-generic-x86_64-with-Ubuntu-14.04-trusty</PRE>
      <HR></HR>
      <H2>Garbage collector:</H2>
      <B>Counts:</B><PRE>(77, 1, 6)</PRE>
      <B>Thresholds:</B><PRE>(700, 10, 10)</PRE>

      <HR></HR>
      <H2>Result of 1 checks:</H2>
      <TABLE bgcolor="#ffffff" border="1">
      <TBODY>
      <TR>
      <TH>
      Kind
      </TH>
      <TH>
      Reason
      </TH>
      <TH>
      Details
      </TH>

      </TR>
      <TR>
      <TD>HealthcheckResult</TD>
          <TD>OK</TD>
      <TD>Path &#39;/tmp/dead&#39; was not found</TD>
      </TR>
      </TBODY>
      </TABLE>
      <HR></HR>
      <H2>1 greenthread(s) active:</H2>
      <TABLE bgcolor="#ffffff" border="1">
      <TBODY>
      <TR>
          <TD><PRE>  File &#34;oslo_middleware/healthcheck/__main__.py&#34;, line 94, in &lt;module&gt;
          main()
        File &#34;oslo_middleware/healthcheck/__main__.py&#34;, line 90, in main
          server.serve_forever()
        ...
      </PRE></TD>
      </TR>
      </TBODY>
      </TABLE>
      <HR></HR>
      <H2>1 thread(s) active:</H2>
      <TABLE bgcolor="#ffffff" border="1">
      <TBODY>
      <TR>
          <TD><PRE>  File &#34;oslo_middleware/healthcheck/__main__.py&#34;, line 94, in &lt;module&gt;
          main()
        File &#34;oslo_middleware/healthcheck/__main__.py&#34;, line 90, in main
          server.serve_forever()
        ....
      </TR>
      </TBODY>
      </TABLE>
      </BODY>
      </HTML>

  Example of paste configuration:

      [app:healthcheck]
      use = egg:oslo.middleware:healthcheck
      backends = disable_by_file
      disable_by_file_path = /var/run/nova/healthcheck_disable

      [pipeline:public_api]
      pipeline = healthcheck sizelimit [...] public_service

  Multiple app sections can be defined if it desired to have pipelines with different healthcheck configuration, example:

      [composite:public_api]
      use = egg:Paste#urlmap
      / = public_api_pipeline
      /healthcheck = healthcheck_public

      [composite:admin_api]
      use = egg:Paste#urlmap
      / = admin_api_pipeline
      /healthcheck = healthcheck_admin

      [pipeline:public_api_pipeline]
      pipeline = sizelimit [...] public_service

      [pipeline:admin_api_pipeline]
      pipeline = sizelimit [...] admin_service

      [app:healthcheck_public]
      use = egg:oslo.middleware:healthcheck
      backends = disable_by_file
      disable_by_file_path = /var/run/nova/healthcheck_public_disable

      [app:healthcheck_admin]
      use = egg:oslo.middleware:healthcheck
      backends = disable_by_file
      disable_by_file_path = /var/run/nova/healthcheck_admin_disable

  classmethod app_factory(global_conf: dict[str, Any] | None, **local_conf: Any) → Self

    Factory method for paste.deploy.

    Parameters:

      - global_conf – dict of options for all middlewares (usually the [DEFAULT] section of the paste deploy configuration file)

      - local_conf – options dedicated to this middleware (usually the option defined in the middleware section of the paste deploy configuration file)

  classmethod factory(global_conf: dict[str, Any] | None, **local_conf: Any) → Callable[[WSGIApplication], base.MiddlewareType]

    Factory method for paste.deploy.

    Parameters:

      - global_conf – dict of options for all middlewares (usually the `[DEFAULT]` section of the paste deploy configuration file)

      - local_conf – options dedicated to this middleware (usually the option defined in the middleware’s section of the paste deploy configuration file)

class oslo_middleware.RequestBodySizeLimiter(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Limit the size of incoming requests.

class oslo_middleware.RequestId(application: WSGIApplication | None, conf: dict[str, Any] | cfg.ConfigOpts | None = None)

  Middleware that ensures request ID.

  It ensures to assign request ID for each API request and set it to request environment. The request ID is also added to API response.

class oslo_middleware.TracingMiddleware(application: WSGIApplication | None, conf: dict[str, ty.Any] | cfg.ConfigOpts | None = None)

  WSGI middleware for OpenTelemetry distributed tracing.

  Creates a span for each incoming HTTP request with W3C TraceContext propagation.

  Usage in `api-paste.ini`:

      [filter:tracing]
      paste.filter_factory = oslo_middleware:TracingMiddleware.factory
      oslo_config_project = glance
      oslo_config_program = glance-api

  Or via entry point:

      [filter:tracing]
      paste.filter_factory = oslo_middleware#tracing

  process_request(req: webob.request.Request) → webob.response.Response | None

    Called on each request.

    If this returns None, the next application down the stack will be executed. If it returns a response then that response will be returned and execution will stop here.

  process_response(response: webob.response.Response, request: webob.request.Request | None = None) → webob.response.Response

    Do whatever you’d like to the response.

## Configuration Options

### RequestBodySizeLimiter

#### oslo_middleware

max_request_body_size
  Type:

    integer

  Default:

    `114688`

  The maximum body size for each request, in bytes.

### SSLMiddleware

this page last updated: 2026-07-14 20:24:58

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.

found an error? report a bug