0
# Web Framework Integration
1
2
Middleware and integration components for popular Python web frameworks including Django, Flask, Bottle, and aiohttp. Provides automatic request tracing, HTTP metadata collection, and seamless integration with framework-specific features.
3
4
## Capabilities
5
6
### Django Integration
7
8
Complete Django integration with middleware, settings configuration, and automatic request tracing.
9
10
#### Django Middleware
11
12
```python { .api }
13
# Settings configuration
14
INSTALLED_APPS = [
15
'aws_xray_sdk.ext.django',
16
# ... other apps
17
]
18
19
MIDDLEWARE = [
20
'aws_xray_sdk.ext.django.middleware.XRayMiddleware',
21
# ... other middleware
22
]
23
24
# X-Ray configuration in settings
25
XRAY_RECORDER = {
26
'AWS_XRAY_TRACING_NAME': str, # Required: segment name for requests
27
'PLUGINS': tuple, # Optional: plugin names
28
'DAEMON_ADDRESS': str, # Optional: daemon address
29
'CONTEXT_MISSING': str, # Optional: context missing behavior
30
'SAMPLING': bool, # Optional: sampling enabled
31
'SAMPLING_RULES': str, # Optional: sampling rules file path
32
'PATCH_MODULES': list, # Optional: modules to patch
33
'IGNORE_MODULE_PATTERNS': list, # Optional: module patterns to ignore
34
'AUTO_PATCH_PARENT_SEGMENT_NAME': str, # Optional: parent segment for auto-patching
35
'STREAM_SQL': bool, # Optional: SQL streaming enabled
36
'AUTO_INSTRUMENT': bool, # Optional: auto-instrument Django ORM
37
'URLS_AS_ANNOTATION': str, # Optional: 'LAMBDA', 'ALL', or 'NONE'
38
}
39
```
40
41
#### Django Database Integration
42
43
```python { .api }
44
# Auto-instrument Django ORM
45
XRAY_RECORDER = {
46
'AUTO_INSTRUMENT': True, # Automatically patch Django database operations
47
'STREAM_SQL': True, # Enable SQL query streaming
48
}
49
50
# Manual database patching
51
from aws_xray_sdk.ext.django.db import patch_db
52
patch_db()
53
```
54
55
### Flask Integration
56
57
Flask middleware for automatic request tracing and X-Ray integration.
58
59
```python { .api }
60
class XRayMiddleware:
61
"""Flask middleware for X-Ray request tracing."""
62
63
def __init__(self, app: Flask, recorder: AWSXRayRecorder) -> None:
64
"""
65
Initialize Flask X-Ray middleware.
66
67
Args:
68
app (Flask): Flask application instance
69
recorder (AWSXRayRecorder): X-Ray recorder instance
70
"""
71
```
72
73
### Bottle Integration
74
75
Bottle plugin for X-Ray request tracing integration.
76
77
```python { .api }
78
class XRayMiddleware:
79
"""Bottle plugin for X-Ray request tracing."""
80
81
def __init__(self, recorder: AWSXRayRecorder) -> None:
82
"""
83
Initialize Bottle X-Ray plugin.
84
85
Args:
86
recorder (AWSXRayRecorder): X-Ray recorder instance
87
"""
88
```
89
90
### aiohttp Integration
91
92
Asynchronous web framework integration with middleware and client tracing.
93
94
#### aiohttp Middleware
95
96
```python { .api }
97
def middleware(request: web.Request, handler: Callable) -> web.Response:
98
"""
99
aiohttp middleware function for X-Ray request tracing.
100
101
Args:
102
request (web.Request): aiohttp request object
103
handler (Callable): Request handler function
104
105
Returns:
106
web.Response: Response object with X-Ray tracing
107
"""
108
```
109
110
#### aiohttp Client Tracing
111
112
```python { .api }
113
def aws_xray_trace_config() -> aiohttp.TraceConfig:
114
"""
115
Create aiohttp TraceConfig for client request tracing.
116
117
Returns:
118
aiohttp.TraceConfig: Configured trace config for X-Ray integration
119
"""
120
```
121
122
## Framework-Specific Usage
123
124
### Django Setup
125
126
#### Basic Django Configuration
127
128
```python
129
# settings.py
130
INSTALLED_APPS = [
131
'django.contrib.admin',
132
'django.contrib.auth',
133
'aws_xray_sdk.ext.django', # Add X-Ray Django extension
134
'myapp',
135
]
136
137
MIDDLEWARE = [
138
'aws_xray_sdk.ext.django.middleware.XRayMiddleware', # Add as first middleware
139
'django.middleware.security.SecurityMiddleware',
140
'django.contrib.sessions.middleware.SessionMiddleware',
141
# ... other middleware
142
]
143
144
# X-Ray configuration
145
XRAY_RECORDER = {
146
'AWS_XRAY_TRACING_NAME': 'My Django App', # Required
147
'PLUGINS': ('EC2Plugin', 'ECSPlugin'),
148
'DAEMON_ADDRESS': '127.0.0.1:2000',
149
'CONTEXT_MISSING': 'LOG_ERROR',
150
'SAMPLING': False, # Disable sampling for development
151
}
152
```
153
154
#### Advanced Django Configuration
155
156
```python
157
# settings.py
158
XRAY_RECORDER = {
159
'AWS_XRAY_TRACING_NAME': 'Django Production App',
160
'PLUGINS': ('EC2Plugin', 'ECSPlugin', 'ElasticBeanstalkPlugin'),
161
'DAEMON_ADDRESS': '127.0.0.1:2000',
162
'CONTEXT_MISSING': 'LOG_ERROR',
163
'SAMPLING': True,
164
'SAMPLING_RULES': '/path/to/sampling-rules.json',
165
166
# Automatic patching
167
'PATCH_MODULES': [
168
'boto3',
169
'requests',
170
'sqlalchemy_core',
171
'pymongo',
172
],
173
'IGNORE_MODULE_PATTERNS': [
174
'myapp.test.*',
175
'.*mock.*',
176
],
177
'AUTO_PATCH_PARENT_SEGMENT_NAME': 'Django App Initialization',
178
179
# Database integration
180
'AUTO_INSTRUMENT': True, # Auto-patch Django ORM
181
'STREAM_SQL': True, # Stream SQL queries
182
183
# Lambda-specific settings
184
'URLS_AS_ANNOTATION': 'LAMBDA', # Add URL as annotation for Lambda
185
}
186
```
187
188
#### Django Views with X-Ray
189
190
```python
191
# views.py
192
from django.http import JsonResponse
193
from aws_xray_sdk.core import xray_recorder
194
195
def user_profile(request, user_id):
196
# Request is automatically traced by middleware
197
198
with xray_recorder.in_subsegment('validate-user') as subsegment:
199
subsegment.put_annotation('user_id', user_id)
200
# Validate user logic
201
202
with xray_recorder.in_subsegment('fetch-profile') as subsegment:
203
subsegment.put_annotation('table', 'user_profiles')
204
# Database query - automatically traced if AUTO_INSTRUMENT=True
205
profile = UserProfile.objects.get(user_id=user_id)
206
207
return JsonResponse({'profile': profile.to_dict()})
208
209
# Class-based views
210
from django.views.generic import View
211
212
class UserAPIView(View):
213
@xray_recorder.capture('process-user-request')
214
def get(self, request, user_id):
215
# Method is automatically traced
216
return JsonResponse({'user_id': user_id})
217
```
218
219
### Flask Setup
220
221
#### Basic Flask Integration
222
223
```python
224
from flask import Flask
225
from aws_xray_sdk.core import xray_recorder
226
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
227
228
app = Flask(__name__)
229
230
# Configure X-Ray recorder
231
xray_recorder.configure(
232
service='My Flask App',
233
dynamic_naming='*.example.com*',
234
daemon_address='127.0.0.1:2000',
235
context_missing='LOG_ERROR'
236
)
237
238
# Add X-Ray middleware
239
XRayMiddleware(app, xray_recorder)
240
241
@app.route('/users/<user_id>')
242
def get_user(user_id):
243
# Request is automatically traced
244
245
with xray_recorder.in_subsegment('database-query') as subsegment:
246
subsegment.put_annotation('user_id', user_id)
247
# Database operation
248
user = fetch_user_from_db(user_id)
249
250
return {'user': user}
251
252
if __name__ == '__main__':
253
app.run()
254
```
255
256
#### Flask with Database Integration
257
258
```python
259
from flask import Flask
260
from flask_sqlalchemy import SQLAlchemy
261
from aws_xray_sdk.core import xray_recorder
262
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
263
from aws_xray_sdk.ext.flask_sqlalchemy.query import XRayFlaskSqlAlchemy
264
265
app = Flask(__name__)
266
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/db'
267
268
# Configure X-Ray
269
xray_recorder.configure(service='Flask App with DB')
270
XRayMiddleware(app, xray_recorder)
271
272
# Use X-Ray enabled SQLAlchemy
273
db = XRayFlaskSqlAlchemy(app)
274
275
class User(db.Model):
276
id = db.Column(db.Integer, primary_key=True)
277
username = db.Column(db.String(80), unique=True, nullable=False)
278
279
@app.route('/users/<int:user_id>')
280
def get_user(user_id):
281
# Database queries are automatically traced
282
user = User.query.get_or_404(user_id)
283
return {'id': user.id, 'username': user.username}
284
```
285
286
### Bottle Setup
287
288
```python
289
from bottle import Bottle, run, route
290
from aws_xray_sdk.core import xray_recorder
291
from aws_xray_sdk.ext.bottle.middleware import XRayMiddleware
292
293
app = Bottle()
294
295
# Configure X-Ray recorder
296
xray_recorder.configure(
297
service='My Bottle App',
298
dynamic_naming='*.example.com*'
299
)
300
301
# Install X-Ray plugin
302
app.install(XRayMiddleware(xray_recorder))
303
304
@app.route('/users/<user_id>')
305
def get_user(user_id):
306
# Request is automatically traced
307
308
with xray_recorder.in_subsegment('process-user') as subsegment:
309
subsegment.put_annotation('user_id', user_id)
310
# Process user logic
311
312
return {'user_id': user_id}
313
314
if __name__ == '__main__':
315
run(app, host='localhost', port=8080)
316
```
317
318
### aiohttp Setup
319
320
#### aiohttp Server Integration
321
322
```python
323
from aiohttp import web
324
from aws_xray_sdk.ext.aiohttp.middleware import middleware
325
from aws_xray_sdk.core import xray_recorder
326
from aws_xray_sdk.core.async_context import AsyncContext
327
328
# Configure recorder with async context
329
xray_recorder.configure(
330
service='aiohttp App',
331
context=AsyncContext()
332
)
333
334
async def hello_handler(request):
335
# Request is automatically traced
336
337
async with xray_recorder.in_subsegment_async('async-operation') as subsegment:
338
subsegment.put_annotation('operation', 'hello')
339
# Async operation
340
await asyncio.sleep(0.1)
341
342
return web.json_response({'message': 'Hello World'})
343
344
# Create application with X-Ray middleware
345
app = web.Application(middlewares=[middleware])
346
app.router.add_get('/', hello_handler)
347
348
if __name__ == '__main__':
349
web.run_app(app)
350
```
351
352
#### aiohttp Client Tracing
353
354
```python
355
import aiohttp
356
from aws_xray_sdk.ext.aiohttp.client import aws_xray_trace_config
357
from aws_xray_sdk.core import xray_recorder
358
359
async def make_http_requests():
360
# Create trace config for client requests
361
trace_config = aws_xray_trace_config()
362
363
async with aiohttp.ClientSession(trace_configs=[trace_config]) as session:
364
# Client requests are automatically traced
365
async with session.get('https://api.example.com/users') as response:
366
data = await response.json()
367
return data
368
369
# Use within a traced context
370
async def main():
371
async with xray_recorder.in_segment_async('http-client-demo') as segment:
372
data = await make_http_requests()
373
segment.put_metadata('response_data', data)
374
```
375
376
### Combined Framework and Database Integration
377
378
```python
379
from flask import Flask
380
from aws_xray_sdk.core import xray_recorder, patch_all
381
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
382
import requests
383
import boto3
384
385
app = Flask(__name__)
386
387
# Configure X-Ray
388
xray_recorder.configure(
389
service='Integrated Flask App',
390
plugins=('EC2Plugin',),
391
daemon_address='127.0.0.1:2000'
392
)
393
394
# Patch all supported libraries
395
patch_all()
396
397
# Add Flask middleware
398
XRayMiddleware(app, xray_recorder)
399
400
@app.route('/user-data/<user_id>')
401
def get_user_data(user_id):
402
# Request automatically traced by middleware
403
404
with xray_recorder.in_subsegment('fetch-user-profile') as subsegment:
405
subsegment.put_annotation('user_id', user_id)
406
# HTTP request - automatically traced via patching
407
response = requests.get(f'https://api.users.com/profile/{user_id}')
408
profile = response.json()
409
410
with xray_recorder.in_subsegment('fetch-user-preferences') as subsegment:
411
# AWS call - automatically traced via patching
412
dynamodb = boto3.resource('dynamodb')
413
table = dynamodb.Table('user_preferences')
414
preferences = table.get_item(Key={'user_id': user_id})
415
416
return {
417
'profile': profile,
418
'preferences': preferences.get('Item', {})
419
}
420
```
421
422
## Serverless Integration
423
424
### Lambda with Web Frameworks
425
426
X-Ray works seamlessly with web frameworks deployed on AWS Lambda, automatically creating subsegments within Lambda's managed segments.
427
428
#### Django on Lambda
429
430
```python
431
# serverless Django setup
432
import os
433
os.environ['AWS_XRAY_TRACING_NAME'] = 'Django Lambda'
434
435
# Django settings remain the same
436
# Middleware will create subsegments instead of segments in Lambda
437
```
438
439
#### Flask on Lambda
440
441
```python
442
from flask import Flask
443
from aws_xray_sdk.core import xray_recorder
444
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
445
446
app = Flask(__name__)
447
448
# Configure for Lambda environment
449
xray_recorder.configure(
450
service='Flask Lambda Function',
451
context_missing='LOG_ERROR'
452
)
453
454
# Middleware creates subsegments in Lambda
455
XRayMiddleware(app, xray_recorder)
456
457
def lambda_handler(event, context):
458
# Lambda integration handles this automatically
459
return app(event, context)
460
```
461
462
## Best Practices
463
464
### Middleware Ordering
465
466
```python
467
# Django - X-Ray middleware should be first
468
MIDDLEWARE = [
469
'aws_xray_sdk.ext.django.middleware.XRayMiddleware', # First
470
'django.middleware.security.SecurityMiddleware',
471
# ... other middleware
472
]
473
```
474
475
### Error Handling
476
477
```python
478
# Automatic error capture in web frameworks
479
@app.errorhandler(500)
480
def handle_error(error):
481
# Error automatically captured by X-Ray middleware
482
# Additional context can be added
483
xray_recorder.put_annotation('error_handler', 'custom_500')
484
return 'Internal Server Error', 500
485
```
486
487
### Performance Considerations
488
489
```python
490
# Use sampling for high-traffic applications
491
xray_recorder.configure(
492
sampling=True, # Enable sampling
493
sampling_rules='/path/to/sampling-rules.json'
494
)
495
496
# Conditional expensive operations
497
if xray_recorder.is_sampled():
498
# Only add expensive metadata for sampled requests
499
xray_recorder.put_metadata('detailed_request_info', expensive_operation())
500
```