0
# Web Framework Integration
1
2
Adapters for integrating Bolt apps with popular Python web frameworks and deployment platforms. Supports FastAPI, Flask, Django, ASGI/WSGI, and cloud platforms like AWS Lambda and Google Cloud Functions.
3
4
## Capabilities
5
6
### FastAPI Integration
7
8
Integrate Bolt apps with FastAPI for modern async web applications.
9
10
```python { .api }
11
from slack_bolt.adapter.fastapi import SlackRequestHandler
12
13
class SlackRequestHandler:
14
"""FastAPI adapter for Bolt applications."""
15
16
def __init__(self, app):
17
"""
18
Initialize FastAPI handler.
19
20
Args:
21
app: Bolt App or AsyncApp instance
22
"""
23
24
async def handle_async(self, request):
25
"""
26
Handle async FastAPI request.
27
28
Args:
29
request: FastAPI Request object
30
31
Returns:
32
Response: FastAPI Response object
33
"""
34
35
def handle(self, request):
36
"""
37
Handle sync FastAPI request.
38
39
Args:
40
request: FastAPI Request object
41
42
Returns:
43
Response: FastAPI Response object
44
"""
45
```
46
47
### Flask Integration
48
49
Integrate Bolt apps with Flask for traditional web applications.
50
51
```python { .api }
52
from slack_bolt.adapter.flask import SlackRequestHandler
53
54
class SlackRequestHandler:
55
"""Flask adapter for Bolt applications."""
56
57
def __init__(self, app):
58
"""
59
Initialize Flask handler.
60
61
Args:
62
app: Bolt App instance
63
"""
64
65
def handle(self, request):
66
"""
67
Handle Flask request.
68
69
Args:
70
request: Flask Request object
71
72
Returns:
73
Response: Flask Response object
74
"""
75
```
76
77
### Django Integration
78
79
Integrate Bolt apps with Django web framework.
80
81
```python { .api }
82
from slack_bolt.adapter.django import SlackRequestHandler
83
84
class SlackRequestHandler:
85
"""Django adapter for Bolt applications."""
86
87
def __init__(self, app):
88
"""
89
Initialize Django handler.
90
91
Args:
92
app: Bolt App instance
93
"""
94
95
def handle(self, request):
96
"""
97
Handle Django request.
98
99
Args:
100
request: Django HttpRequest object
101
102
Returns:
103
HttpResponse: Django HttpResponse object
104
"""
105
```
106
107
### ASGI Integration
108
109
Generic ASGI adapter for async web applications.
110
111
```python { .api }
112
from slack_bolt.adapter.asgi import SlackRequestHandler
113
114
class SlackRequestHandler:
115
"""ASGI adapter for Bolt applications."""
116
117
def __init__(self, app):
118
"""
119
Initialize ASGI handler.
120
121
Args:
122
app: Bolt App or AsyncApp instance
123
"""
124
125
async def handle_async(self, scope, receive, send):
126
"""
127
Handle ASGI request.
128
129
Args:
130
scope: ASGI scope
131
receive: ASGI receive callable
132
send: ASGI send callable
133
"""
134
```
135
136
### WSGI Integration
137
138
Generic WSGI adapter for sync web applications.
139
140
```python { .api }
141
from slack_bolt.adapter.wsgi import SlackRequestHandler
142
143
class SlackRequestHandler:
144
"""WSGI adapter for Bolt applications."""
145
146
def __init__(self, app):
147
"""
148
Initialize WSGI handler.
149
150
Args:
151
app: Bolt App instance
152
"""
153
154
def handle(self, environ, start_response):
155
"""
156
Handle WSGI request.
157
158
Args:
159
environ: WSGI environ dict
160
start_response: WSGI start_response callable
161
162
Returns:
163
Iterable: WSGI response body
164
"""
165
```
166
167
### AWS Lambda Integration
168
169
Deploy Bolt apps to AWS Lambda for serverless execution.
170
171
```python { .api }
172
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
173
174
class SlackRequestHandler:
175
"""AWS Lambda adapter for Bolt applications."""
176
177
def __init__(self, app):
178
"""
179
Initialize Lambda handler.
180
181
Args:
182
app: Bolt App instance configured with process_before_response=True
183
"""
184
185
def handle(self, event, context):
186
"""
187
Handle Lambda event.
188
189
Args:
190
event: Lambda event dict
191
context: Lambda context object
192
193
Returns:
194
dict: Lambda response format
195
"""
196
197
def clear_all_log_handlers(self):
198
"""Clear log handlers for Lambda environment."""
199
```
200
201
### Google Cloud Functions Integration
202
203
Deploy Bolt apps to Google Cloud Functions.
204
205
```python { .api }
206
from slack_bolt.adapter.google_cloud_functions import SlackRequestHandler
207
208
class SlackRequestHandler:
209
"""Google Cloud Functions adapter for Bolt applications."""
210
211
def __init__(self, app):
212
"""
213
Initialize Cloud Functions handler.
214
215
Args:
216
app: Bolt App instance configured with process_before_response=True
217
"""
218
219
def handle(self, request):
220
"""
221
Handle Cloud Functions request.
222
223
Args:
224
request: Flask Request object (Cloud Functions runtime)
225
226
Returns:
227
Response: Flask Response object
228
"""
229
```
230
231
### Additional Framework Adapters
232
233
Support for other popular Python web frameworks.
234
235
```python { .api }
236
# Starlette
237
from slack_bolt.adapter.starlette import SlackRequestHandler
238
239
# Bottle
240
from slack_bolt.adapter.bottle import SlackRequestHandler
241
242
# CherryPy
243
from slack_bolt.adapter.cherrypy import SlackRequestHandler
244
245
# Pyramid
246
from slack_bolt.adapter.pyramid import SlackRequestHandler
247
248
# Tornado
249
from slack_bolt.adapter.tornado import SlackRequestHandler
250
251
# Falcon
252
from slack_bolt.adapter.falcon import SlackResource
253
254
# Sanic (async)
255
from slack_bolt.adapter.sanic import AsyncSlackRequestHandler
256
```
257
258
## Usage Examples
259
260
### FastAPI Integration
261
262
```python
263
from fastapi import FastAPI, Request
264
from slack_bolt import App
265
from slack_bolt.adapter.fastapi import SlackRequestHandler
266
import os
267
268
# Initialize Bolt app
269
bolt_app = App(
270
token=os.environ.get("SLACK_BOT_TOKEN"),
271
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
272
)
273
274
@bolt_app.message("hello")
275
def say_hello(message, say):
276
say(f"Hi <@{message['user']}>!")
277
278
# Initialize FastAPI
279
fastapi_app = FastAPI()
280
handler = SlackRequestHandler(bolt_app)
281
282
@fastapi_app.post("/slack/events")
283
async def endpoint(request: Request):
284
return await handler.handle_async(request)
285
286
# Optional: Add OAuth endpoints
287
@fastapi_app.get("/slack/install")
288
async def install(request: Request):
289
return await handler.handle_async(request)
290
291
@fastapi_app.get("/slack/oauth_redirect")
292
async def oauth_redirect(request: Request):
293
return await handler.handle_async(request)
294
295
# Run with: uvicorn main:fastapi_app --host 0.0.0.0 --port 3000
296
```
297
298
### Flask Integration
299
300
```python
301
from flask import Flask, request
302
from slack_bolt import App
303
from slack_bolt.adapter.flask import SlackRequestHandler
304
import os
305
306
# Initialize Bolt app
307
bolt_app = App(
308
token=os.environ.get("SLACK_BOT_TOKEN"),
309
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
310
)
311
312
@bolt_app.command("/weather")
313
def weather_command(ack, respond, command):
314
ack()
315
respond(f"Weather in {command.get('text', 'your location')}: Sunny! โ๏ธ")
316
317
# Initialize Flask
318
flask_app = Flask(__name__)
319
handler = SlackRequestHandler(bolt_app)
320
321
@flask_app.route("/slack/events", methods=["POST"])
322
def slack_events():
323
return handler.handle(request)
324
325
# OAuth endpoints (if using OAuth)
326
@flask_app.route("/slack/install", methods=["GET"])
327
def install():
328
return handler.handle(request)
329
330
@flask_app.route("/slack/oauth_redirect", methods=["GET"])
331
def oauth_redirect():
332
return handler.handle(request)
333
334
if __name__ == "__main__":
335
flask_app.run(host="0.0.0.0", port=3000)
336
```
337
338
### Django Integration
339
340
```python
341
# views.py
342
from django.http import HttpRequest
343
from django.views.decorators.csrf import csrf_exempt
344
from django.views.decorators.http import require_http_methods
345
from slack_bolt import App
346
from slack_bolt.adapter.django import SlackRequestHandler
347
import os
348
349
# Initialize Bolt app
350
bolt_app = App(
351
token=os.environ.get("SLACK_BOT_TOKEN"),
352
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
353
)
354
355
@bolt_app.event("app_mention")
356
def handle_mention(event, say):
357
say("Thanks for mentioning me!")
358
359
handler = SlackRequestHandler(bolt_app)
360
361
@csrf_exempt
362
@require_http_methods(["POST"])
363
def slack_events(request: HttpRequest):
364
return handler.handle(request)
365
366
@csrf_exempt
367
@require_http_methods(["GET"])
368
def slack_install(request: HttpRequest):
369
return handler.handle(request)
370
371
@csrf_exempt
372
@require_http_methods(["GET"])
373
def slack_oauth_redirect(request: HttpRequest):
374
return handler.handle(request)
375
376
# urls.py
377
from django.urls import path
378
from . import views
379
380
urlpatterns = [
381
path("slack/events", views.slack_events, name="slack_events"),
382
path("slack/install", views.slack_install, name="slack_install"),
383
path("slack/oauth_redirect", views.slack_oauth_redirect, name="slack_oauth_redirect"),
384
]
385
```
386
387
### AWS Lambda Deployment
388
389
```python
390
from slack_bolt import App
391
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
392
import os
393
394
# Initialize Bolt app with FaaS mode
395
bolt_app = App(
396
token=os.environ["SLACK_BOT_TOKEN"],
397
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
398
process_before_response=True # Required for Lambda
399
)
400
401
@bolt_app.message("hello")
402
def say_hello(message, say):
403
say(f"Hi <@{message['user']}>!")
404
405
@bolt_app.command("/ping")
406
def ping_command(ack, respond):
407
ack()
408
respond("Pong! ๐")
409
410
# Lambda handler
411
handler = SlackRequestHandler(bolt_app)
412
413
def lambda_handler(event, context):
414
"""AWS Lambda handler function."""
415
return handler.handle(event, context)
416
417
# Deploy with:
418
# - Package code and dependencies
419
# - Set environment variables SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET
420
# - Configure API Gateway to trigger Lambda
421
```
422
423
### Google Cloud Functions Deployment
424
425
```python
426
from slack_bolt import App
427
from slack_bolt.adapter.google_cloud_functions import SlackRequestHandler
428
import os
429
430
# Initialize Bolt app
431
bolt_app = App(
432
token=os.environ["SLACK_BOT_TOKEN"],
433
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
434
process_before_response=True # Required for Cloud Functions
435
)
436
437
@bolt_app.shortcut("create_task")
438
def create_task_shortcut(ack, shortcut, client):
439
ack()
440
# Handle shortcut logic
441
client.chat_postEphemeral(
442
channel=shortcut["channel"]["id"],
443
user=shortcut["user"]["id"],
444
text="Task creation feature coming soon!"
445
)
446
447
# Cloud Functions handler
448
handler = SlackRequestHandler(bolt_app)
449
450
def slack_events(request):
451
"""Google Cloud Functions handler."""
452
return handler.handle(request)
453
454
# Deploy with:
455
# gcloud functions deploy slack-events \
456
# --runtime python39 \
457
# --trigger-http \
458
# --entry-point slack_events \
459
# --set-env-vars SLACK_BOT_TOKEN=xoxb-...,SLACK_SIGNING_SECRET=...
460
```
461
462
### ASGI Application
463
464
```python
465
from slack_bolt import AsyncApp
466
from slack_bolt.adapter.asgi import SlackRequestHandler
467
import os
468
469
# Initialize async Bolt app
470
bolt_app = AsyncApp(
471
token=os.environ["SLACK_BOT_TOKEN"],
472
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
473
)
474
475
@bolt_app.message("hello")
476
async def say_hello(message, say):
477
await say(f"Hi <@{message['user']}>!")
478
479
# ASGI application
480
handler = SlackRequestHandler(bolt_app)
481
482
async def app(scope, receive, send):
483
"""ASGI application."""
484
if scope["type"] == "http" and scope["path"] == "/slack/events":
485
await handler.handle_async(scope, receive, send)
486
else:
487
# Handle other routes or return 404
488
await send({
489
"type": "http.response.start",
490
"status": 404,
491
})
492
await send({
493
"type": "http.response.body",
494
"body": b"Not Found",
495
})
496
497
# Run with: uvicorn main:app --host 0.0.0.0 --port 3000
498
```
499
500
### Multiple Endpoint Handling
501
502
```python
503
from fastapi import FastAPI, Request
504
from slack_bolt import App
505
from slack_bolt.adapter.fastapi import SlackRequestHandler
506
import os
507
508
bolt_app = App(
509
token=os.environ["SLACK_BOT_TOKEN"],
510
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
511
)
512
513
@bolt_app.event("app_mention")
514
def handle_mention(event, say):
515
say("Thanks for the mention!")
516
517
fastapi_app = FastAPI()
518
handler = SlackRequestHandler(bolt_app)
519
520
# Main events endpoint
521
@fastapi_app.post("/slack/events")
522
async def slack_events(request: Request):
523
return await handler.handle_async(request)
524
525
# Interactive components endpoint
526
@fastapi_app.post("/slack/interactive")
527
async def slack_interactive(request: Request):
528
return await handler.handle_async(request)
529
530
# Slash commands endpoint
531
@fastapi_app.post("/slack/commands")
532
async def slack_commands(request: Request):
533
return await handler.handle_async(request)
534
535
# OAuth endpoints
536
@fastapi_app.get("/slack/install")
537
async def slack_install(request: Request):
538
return await handler.handle_async(request)
539
540
@fastapi_app.get("/slack/oauth_redirect")
541
async def slack_oauth_redirect(request: Request):
542
return await handler.handle_async(request)
543
544
# Health check
545
@fastapi_app.get("/health")
546
async def health_check():
547
return {"status": "healthy"}
548
```
549
550
### Custom Middleware with Framework Integration
551
552
```python
553
from fastapi import FastAPI, Request, HTTPException
554
from slack_bolt import App
555
from slack_bolt.adapter.fastapi import SlackRequestHandler
556
import os
557
558
bolt_app = App(
559
token=os.environ["SLACK_BOT_TOKEN"],
560
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
561
)
562
563
# Custom Bolt middleware
564
@bolt_app.middleware
565
def log_requests(logger, body, next):
566
logger.info(f"Incoming request from team: {body.get('team_id')}")
567
next()
568
569
@bolt_app.message("hello")
570
def say_hello(message, say):
571
say("Hello from integrated app!")
572
573
fastapi_app = FastAPI()
574
handler = SlackRequestHandler(bolt_app)
575
576
# FastAPI middleware
577
@fastapi_app.middleware("http")
578
async def add_security_headers(request: Request, call_next):
579
response = await call_next(request)
580
response.headers["X-Content-Type-Options"] = "nosniff"
581
response.headers["X-Frame-Options"] = "DENY"
582
return response
583
584
# Rate limiting middleware
585
async def rate_limit_middleware(request: Request, call_next):
586
# Implement rate limiting logic
587
client_ip = request.client.host
588
if is_rate_limited(client_ip):
589
raise HTTPException(status_code=429, detail="Rate limit exceeded")
590
591
response = await call_next(request)
592
return response
593
594
@fastapi_app.post("/slack/events")
595
async def slack_events(request: Request):
596
return await handler.handle_async(request)
597
```
598
599
### Framework-Specific Error Handling
600
601
```python
602
from flask import Flask, request, jsonify
603
from slack_bolt import App
604
from slack_bolt.adapter.flask import SlackRequestHandler
605
from slack_bolt.error import BoltError
606
import logging
607
import os
608
609
bolt_app = App(
610
token=os.environ["SLACK_BOT_TOKEN"],
611
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
612
)
613
614
# Bolt error handler
615
@bolt_app.error
616
def global_error_handler(error, body, logger):
617
logger.exception(f"Error: {error}")
618
return {"status": "error", "message": "Internal server error"}
619
620
flask_app = Flask(__name__)
621
handler = SlackRequestHandler(bolt_app)
622
623
# Flask error handlers
624
@flask_app.errorhandler(BoltError)
625
def handle_bolt_error(error):
626
logging.exception("Bolt framework error")
627
return jsonify({"error": "Slack integration error"}), 500
628
629
@flask_app.errorhandler(500)
630
def handle_internal_error(error):
631
logging.exception("Internal server error")
632
return jsonify({"error": "Internal server error"}), 500
633
634
@flask_app.route("/slack/events", methods=["POST"])
635
def slack_events():
636
try:
637
return handler.handle(request)
638
except Exception as e:
639
logging.exception("Unhandled error in Slack events")
640
return jsonify({"error": "Processing failed"}), 500
641
```
642
643
## Cloud Platform Deployment Patterns
644
645
### Containerized Deployment
646
647
```dockerfile
648
# Dockerfile for FastAPI + Bolt
649
FROM python:3.9-slim
650
651
WORKDIR /app
652
653
COPY requirements.txt .
654
RUN pip install -r requirements.txt
655
656
COPY . .
657
658
EXPOSE 3000
659
660
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000"]
661
```
662
663
```yaml
664
# docker-compose.yml
665
version: '3.8'
666
services:
667
slack-bot:
668
build: .
669
ports:
670
- "3000:3000"
671
environment:
672
- SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
673
- SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET}
674
volumes:
675
- ./data:/app/data
676
```
677
678
### Kubernetes Deployment
679
680
```yaml
681
# k8s-deployment.yaml
682
apiVersion: apps/v1
683
kind: Deployment
684
metadata:
685
name: slack-bot
686
spec:
687
replicas: 2
688
selector:
689
matchLabels:
690
app: slack-bot
691
template:
692
metadata:
693
labels:
694
app: slack-bot
695
spec:
696
containers:
697
- name: slack-bot
698
image: your-registry/slack-bot:latest
699
ports:
700
- containerPort: 3000
701
env:
702
- name: SLACK_BOT_TOKEN
703
valueFrom:
704
secretKeyRef:
705
name: slack-secrets
706
key: bot-token
707
- name: SLACK_SIGNING_SECRET
708
valueFrom:
709
secretKeyRef:
710
name: slack-secrets
711
key: signing-secret
712
---
713
apiVersion: v1
714
kind: Service
715
metadata:
716
name: slack-bot-service
717
spec:
718
selector:
719
app: slack-bot
720
ports:
721
- port: 80
722
targetPort: 3000
723
type: LoadBalancer
724
```
725
726
## Related Topics
727
728
- [App Configuration & Setup](./app-configuration.md) - Basic app initialization and framework-agnostic setup
729
- [OAuth & Multi-Workspace Installation](./oauth-and-installation.md) - OAuth integration with web frameworks
730
- [Context Objects & Utilities](./context-and-utilities.md) - Using Bolt utilities in different frameworks