{"id":3817,"library":"starlette-context","title":"Starlette Context","description":"Starlette Context is a middleware for Starlette that provides a request-scoped data store, allowing you to store and access context data throughout the request lifecycle. It is commonly used to enrich logs with request-specific identifiers like `x-request-id` or `x-correlation-id` without explicit parameter passing. The current version is 0.5.1, released on February 28, 2026, and the library maintains an active release cadence.","status":"active","version":"0.5.1","language":"en","source_language":"en","source_url":"https://github.com/tomwojcik/starlette-context","tags":["starlette","middleware","context","logging","request-id","correlation-id","fastapi"],"install":[{"cmd":"pip install starlette-context","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core framework dependency; requires >=0.27.0 since v0.4.0.","package":"starlette","optional":false},{"reason":"Requires Python 3.10+ since v0.5.0 (dropped Python 3.9 support).","package":"python","optional":false}],"imports":[{"symbol":"ContextMiddleware","correct":"from starlette_context.middleware import ContextMiddleware"},{"note":"Use RawContextMiddleware for streaming or file responses, or when avoiding BaseHTTPMiddleware limitations.","symbol":"RawContextMiddleware","correct":"from starlette_context.middleware import RawContextMiddleware"},{"note":"The context object is directly available from the top-level package.","wrong":"from starlette_context.context import context","symbol":"context","correct":"from starlette_context import context"},{"note":"Provides access to built-in plugins like RequestIdPlugin and CorrelationIdPlugin.","symbol":"plugins","correct":"from starlette_context import plugins"},{"note":"A context manager for manual context management, often used in tests or FastAPI dependencies.","symbol":"request_cycle_context","correct":"from starlette_context import request_cycle_context"}],"quickstart":{"code":"import uvicorn\nfrom starlette.applications import Starlette\nfrom starlette.middleware import Middleware\nfrom starlette.responses import JSONResponse\nfrom starlette.routing import Route\nfrom starlette_context import context, plugins\nfrom starlette_context.middleware import ContextMiddleware\n\nasync def homepage(request):\n    # Access and modify context data\n    context[\"user_id\"] = \"123\"\n    context[\"custom_data\"] = \"Hello from Starlette Context!\"\n    return JSONResponse(context.data)\n\nroutes = [\n    Route(\"/\", endpoint=homepage)\n]\n\nmiddleware = [\n    Middleware(\n        ContextMiddleware,\n        plugins=(\n            plugins.RequestIdPlugin(),\n            plugins.CorrelationIdPlugin(),\n        )\n    )\n]\n\napp = Starlette(routes=routes, middleware=middleware)\n\nif __name__ == \"__main__\":\n    # Run with `uvicorn example:app --port 8000`\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n","lang":"python","description":"This example demonstrates how to set up `ContextMiddleware` with basic plugins (`RequestIdPlugin`, `CorrelationIdPlugin`) and access/modify the `context` object within a Starlette route. When you access '/', the response will include the generated request and correlation IDs, along with any custom data added to the context. To run, save as `example.py` and execute `uvicorn example:app --port 8000`."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or higher.","message":"Python 3.9 and Python 3.8 support has been dropped in recent versions. Version 0.5.0 requires Python 3.10+, and v0.4.0 required Python 3.9+. Ensure your environment uses Python 3.10 or newer.","severity":"breaking","affected_versions":">=0.4.0, >=0.5.0"},{"fix":"Upgrade Starlette to version 0.27.0 or newer (e.g., `pip install 'starlette>=0.27.0'`).","message":"Support for Starlette versions below 0.27.0 was dropped in `starlette-context` v0.4.0. Ensure your Starlette installation is up-to-date.","severity":"breaking","affected_versions":">=0.4.0"},{"fix":"Review any code that explicitly converts `HeaderKeys` enum members to strings and ensure it expects the header key string (e.g., 'X-API-Key').","message":"In v0.5.1, the `HeaderKeys` enum was changed to `StrEnum` to ensure consistent `str()` behavior across Python versions (e.g., `str(HeaderKeys.api_key)` now consistently returns `'X-API-Key'`). Code relying on the prior inconsistent string representation (e.g., `'HeaderKeys.api_key'` on Python 3.11+) might break.","severity":"breaking","affected_versions":">=0.5.1"},{"fix":"Always use `if context.exists():` before accessing `context.data` or `context[...]` outside of a guaranteed request cycle. For tests or specific asynchronous tasks, wrap the code with `async with request_cycle_context():` to establish a temporary context.","message":"Accessing the `context` object outside of a request-response cycle (i.e., when no middleware is active or `request_cycle_context` is not used) will raise a `ContextDoesNotExistError`. This can happen during application startup or in background tasks not tied to a request.","severity":"gotcha","affected_versions":">=0.3.2"},{"fix":"Update exception handling for context access from `except RuntimeError` to `except ContextDoesNotExistError` where applicable.","message":"As of v0.3.2, attempting to access a non-existent context now raises `ContextDoesNotExistError` instead of a generic `RuntimeError`. While `ContextDoesNotExistError` inherits from `RuntimeError` for backward compatibility, specific `except RuntimeError` blocks might need to be updated to `except ContextDoesNotExistError:` for clearer exception handling.","severity":"breaking","affected_versions":">=0.3.2"},{"fix":"If migrating from versions older than 0.3.0 and using custom plugins or internal plugin imports, review the changelog and documentation for `v0.3.0` for necessary adjustments.","message":"Version 0.3.0 introduced a 'small refactor of the base plugin' which involved moving directories and removing a redundant method. This was noted as 'potentially breaking changes' for users upgrading from very early versions who might have custom plugins or direct imports to internal plugin modules.","severity":"breaking","affected_versions":">=0.3.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}