or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mderror-handling.mdindex.mdmiddleware.mdplugins.md

context-management.mddocs/

0

# Context Management

1

2

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.

3

4

## Capabilities

5

6

### Global Context Object

7

8

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

9

10

```python { .api }

11

context: _Context

12

```

13

14

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

15

16

```python

17

from starlette_context import context

18

19

# Access like a dictionary

20

value = context["key"]

21

value = context.get("key", default_value)

22

23

# Store data

24

context["user_id"] = "12345"

25

context.update({"session": "abc", "role": "admin"})

26

27

# Check existence

28

if "user_id" in context:

29

print("User ID exists")

30

31

# Get all data

32

all_data = context.data

33

```

34

35

### Context Lifecycle Management

36

37

Manual context creation and management for testing or custom scenarios.

38

39

```python { .api }

40

def request_cycle_context(initial_data: Optional[dict] = None) -> Iterator[None]:

41

"""

42

Creates and resets a starlette-context context.

43

44

Used in the Context and Raw middlewares, but can also be used to create a

45

context out of a proper request cycle, such as in unit tests.

46

47

Parameters:

48

- initial_data: Optional dict of initial context data

49

50

Returns:

51

Context manager that creates isolated context scope

52

"""

53

```

54

55

Usage example:

56

57

```python

58

from starlette_context import request_cycle_context, context

59

60

# Create context for testing

61

with request_cycle_context({"user_id": "123", "role": "admin"}):

62

# Context is available here

63

user_id = context["user_id"]

64

context["additional_data"] = "value"

65

66

# Do work that requires context

67

process_user_request()

68

69

# Context is automatically cleaned up

70

```

71

72

### Context Object Methods

73

74

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

75

76

```python { .api }

77

class _Context(UserDict):

78

@property

79

def data(self) -> dict:

80

"""

81

Dump this to json. Object itself is not serializable.

82

83

Returns:

84

dict: Current context data

85

86

Raises:

87

ContextDoesNotExistError: If accessed outside request cycle

88

"""

89

90

def exists(self) -> bool:

91

"""

92

Check if context exists in current execution scope.

93

94

Returns:

95

bool: True if context is available, False otherwise

96

"""

97

98

def copy(self) -> dict:

99

"""

100

Read only context data.

101

102

Returns:

103

dict: Copy of current context data

104

"""

105

```

106

107

Standard dictionary methods available:

108

109

```python

110

# Access methods

111

value = context["key"]

112

value = context.get("key", default)

113

keys = context.keys()

114

values = context.values()

115

items = context.items()

116

117

# Modification methods

118

context["key"] = "value"

119

context.update({"key1": "value1", "key2": "value2"})

120

context.setdefault("key", "default_value")

121

del context["key"]

122

value = context.pop("key", default)

123

key, value = context.popitem()

124

context.clear()

125

126

# Info methods

127

length = len(context)

128

exists = "key" in context

129

for key in context:

130

print(key, context[key])

131

```

132

133

## Usage Examples

134

135

### Basic Context Access

136

137

```python

138

from starlette_context import context

139

140

async def my_handler(request):

141

# Access data stored by middleware plugins

142

request_id = context.get("X-Request-ID")

143

correlation_id = context["X-Correlation-ID"]

144

145

# Store custom data

146

context["user_id"] = extract_user_id(request)

147

context["processing_start"] = time.time()

148

149

# Use context data in logging

150

logger.info("Processing request", extra=context.data)

151

152

return response

153

```

154

155

### Testing with Manual Context

156

157

```python

158

import pytest

159

from starlette_context import request_cycle_context, context

160

161

def test_my_function():

162

test_data = {

163

"X-Request-ID": "test-123",

164

"user_id": "user-456"

165

}

166

167

with request_cycle_context(test_data):

168

result = my_function_that_uses_context()

169

assert result is not None

170

171

# Verify context was used

172

assert context["X-Request-ID"] == "test-123"

173

```

174

175

### Context Existence Checking

176

177

```python

178

from starlette_context import context

179

180

def safe_context_access():

181

if context.exists():

182

user_id = context.get("user_id")

183

if user_id:

184

return f"User: {user_id}"

185

return "No context available"

186

```

187

188

## Error Handling

189

190

```python { .api }

191

class ContextDoesNotExistError(RuntimeError, StarletteContextError):

192

"""

193

Raised when context is accessed outside of a request-response cycle.

194

195

This occurs when:

196

- Context is accessed before middleware has created it

197

- Context is accessed after request processing is complete

198

- Context is accessed in code not running within a request context

199

"""

200

```

201

202

Common scenarios that raise `ContextDoesNotExistError`:

203

204

```python

205

from starlette_context import context, ContextDoesNotExistError

206

207

# This will raise an error - no middleware context

208

try:

209

value = context["key"]

210

except ContextDoesNotExistError:

211

print("Context not available outside request cycle")

212

213

# Safe access

214

if context.exists():

215

value = context.get("key")

216

```