CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-starlette-context

Middleware for Starlette that allows you to store and access the context data of a request.

Overview
Eval results
Files

context-management.mddocs/

Context Management

Core functionality for accessing and managing request-scoped context data. The context object provides a global dictionary-like interface that automatically manages request isolation using Python's contextvars.

Capabilities

Global Context Object

The main interface for accessing request-scoped data throughout your application.

context: _Context

The global context object behaves like a dictionary and is available anywhere in your request handling code:

from starlette_context import context

# Access like a dictionary
value = context["key"]
value = context.get("key", default_value)

# Store data
context["user_id"] = "12345"
context.update({"session": "abc", "role": "admin"})

# Check existence
if "user_id" in context:
    print("User ID exists")

# Get all data
all_data = context.data

Context Lifecycle Management

Manual context creation and management for testing or custom scenarios.

def request_cycle_context(initial_data: Optional[dict] = None) -> Iterator[None]:
    """
    Creates and resets a starlette-context context.
    
    Used in the Context and Raw middlewares, but can also be used to create a
    context out of a proper request cycle, such as in unit tests.
    
    Parameters:
    - initial_data: Optional dict of initial context data
    
    Returns:
    Context manager that creates isolated context scope
    """

Usage example:

from starlette_context import request_cycle_context, context

# Create context for testing
with request_cycle_context({"user_id": "123", "role": "admin"}):
    # Context is available here
    user_id = context["user_id"]
    context["additional_data"] = "value"
    
    # Do work that requires context
    process_user_request()
    
# Context is automatically cleaned up

Context Object Methods

The context object extends Python's UserDict and provides all standard dictionary methods plus additional context-specific functionality.

class _Context(UserDict):
    @property
    def data(self) -> dict:
        """
        Dump this to json. Object itself is not serializable.
        
        Returns:
        dict: Current context data
        
        Raises:
        ContextDoesNotExistError: If accessed outside request cycle
        """
    
    def exists(self) -> bool:
        """
        Check if context exists in current execution scope.
        
        Returns:
        bool: True if context is available, False otherwise
        """
    
    def copy(self) -> dict:
        """
        Read only context data.
        
        Returns:
        dict: Copy of current context data
        """

Standard dictionary methods available:

# Access methods
value = context["key"]
value = context.get("key", default)
keys = context.keys()
values = context.values()
items = context.items()

# Modification methods  
context["key"] = "value"
context.update({"key1": "value1", "key2": "value2"})
context.setdefault("key", "default_value")
del context["key"]
value = context.pop("key", default)
key, value = context.popitem()
context.clear()

# Info methods
length = len(context)
exists = "key" in context
for key in context:
    print(key, context[key])

Usage Examples

Basic Context Access

from starlette_context import context

async def my_handler(request):
    # Access data stored by middleware plugins
    request_id = context.get("X-Request-ID")
    correlation_id = context["X-Correlation-ID"]
    
    # Store custom data
    context["user_id"] = extract_user_id(request)
    context["processing_start"] = time.time()
    
    # Use context data in logging
    logger.info("Processing request", extra=context.data)
    
    return response

Testing with Manual Context

import pytest
from starlette_context import request_cycle_context, context

def test_my_function():
    test_data = {
        "X-Request-ID": "test-123",
        "user_id": "user-456"
    }
    
    with request_cycle_context(test_data):
        result = my_function_that_uses_context()
        assert result is not None
        
        # Verify context was used
        assert context["X-Request-ID"] == "test-123"

Context Existence Checking

from starlette_context import context

def safe_context_access():
    if context.exists():
        user_id = context.get("user_id")
        if user_id:
            return f"User: {user_id}"
    return "No context available"

Error Handling

class ContextDoesNotExistError(RuntimeError, StarletteContextError):
    """
    Raised when context is accessed outside of a request-response cycle.
    
    This occurs when:
    - Context is accessed before middleware has created it
    - Context is accessed after request processing is complete
    - Context is accessed in code not running within a request context
    """

Common scenarios that raise ContextDoesNotExistError:

from starlette_context import context, ContextDoesNotExistError

# This will raise an error - no middleware context
try:
    value = context["key"]
except ContextDoesNotExistError:
    print("Context not available outside request cycle")

# Safe access
if context.exists():
    value = context.get("key")

Install with Tessl CLI

npx tessl i tessl/pypi-starlette-context

docs

context-management.md

error-handling.md

index.md

middleware.md

plugins.md

tile.json