The Bolt Framework for Python - a comprehensive framework for building Slack applications with decorator-based API for handling events, actions, and interactive components
—
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.
Integrate Bolt apps with FastAPI for modern async web applications.
from slack_bolt.adapter.fastapi import SlackRequestHandler
class SlackRequestHandler:
"""FastAPI adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize FastAPI handler.
Args:
app: Bolt App or AsyncApp instance
"""
async def handle_async(self, request):
"""
Handle async FastAPI request.
Args:
request: FastAPI Request object
Returns:
Response: FastAPI Response object
"""
def handle(self, request):
"""
Handle sync FastAPI request.
Args:
request: FastAPI Request object
Returns:
Response: FastAPI Response object
"""Integrate Bolt apps with Flask for traditional web applications.
from slack_bolt.adapter.flask import SlackRequestHandler
class SlackRequestHandler:
"""Flask adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize Flask handler.
Args:
app: Bolt App instance
"""
def handle(self, request):
"""
Handle Flask request.
Args:
request: Flask Request object
Returns:
Response: Flask Response object
"""Integrate Bolt apps with Django web framework.
from slack_bolt.adapter.django import SlackRequestHandler
class SlackRequestHandler:
"""Django adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize Django handler.
Args:
app: Bolt App instance
"""
def handle(self, request):
"""
Handle Django request.
Args:
request: Django HttpRequest object
Returns:
HttpResponse: Django HttpResponse object
"""Generic ASGI adapter for async web applications.
from slack_bolt.adapter.asgi import SlackRequestHandler
class SlackRequestHandler:
"""ASGI adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize ASGI handler.
Args:
app: Bolt App or AsyncApp instance
"""
async def handle_async(self, scope, receive, send):
"""
Handle ASGI request.
Args:
scope: ASGI scope
receive: ASGI receive callable
send: ASGI send callable
"""Generic WSGI adapter for sync web applications.
from slack_bolt.adapter.wsgi import SlackRequestHandler
class SlackRequestHandler:
"""WSGI adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize WSGI handler.
Args:
app: Bolt App instance
"""
def handle(self, environ, start_response):
"""
Handle WSGI request.
Args:
environ: WSGI environ dict
start_response: WSGI start_response callable
Returns:
Iterable: WSGI response body
"""Deploy Bolt apps to AWS Lambda for serverless execution.
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
class SlackRequestHandler:
"""AWS Lambda adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize Lambda handler.
Args:
app: Bolt App instance configured with process_before_response=True
"""
def handle(self, event, context):
"""
Handle Lambda event.
Args:
event: Lambda event dict
context: Lambda context object
Returns:
dict: Lambda response format
"""
def clear_all_log_handlers(self):
"""Clear log handlers for Lambda environment."""Deploy Bolt apps to Google Cloud Functions.
from slack_bolt.adapter.google_cloud_functions import SlackRequestHandler
class SlackRequestHandler:
"""Google Cloud Functions adapter for Bolt applications."""
def __init__(self, app):
"""
Initialize Cloud Functions handler.
Args:
app: Bolt App instance configured with process_before_response=True
"""
def handle(self, request):
"""
Handle Cloud Functions request.
Args:
request: Flask Request object (Cloud Functions runtime)
Returns:
Response: Flask Response object
"""Support for other popular Python web frameworks.
# Starlette
from slack_bolt.adapter.starlette import SlackRequestHandler
# Bottle
from slack_bolt.adapter.bottle import SlackRequestHandler
# CherryPy
from slack_bolt.adapter.cherrypy import SlackRequestHandler
# Pyramid
from slack_bolt.adapter.pyramid import SlackRequestHandler
# Tornado
from slack_bolt.adapter.tornado import SlackRequestHandler
# Falcon
from slack_bolt.adapter.falcon import SlackResource
# Sanic (async)
from slack_bolt.adapter.sanic import AsyncSlackRequestHandlerfrom fastapi import FastAPI, Request
from slack_bolt import App
from slack_bolt.adapter.fastapi import SlackRequestHandler
import os
# Initialize Bolt app
bolt_app = App(
token=os.environ.get("SLACK_BOT_TOKEN"),
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)
@bolt_app.message("hello")
def say_hello(message, say):
say(f"Hi <@{message['user']}>!")
# Initialize FastAPI
fastapi_app = FastAPI()
handler = SlackRequestHandler(bolt_app)
@fastapi_app.post("/slack/events")
async def endpoint(request: Request):
return await handler.handle_async(request)
# Optional: Add OAuth endpoints
@fastapi_app.get("/slack/install")
async def install(request: Request):
return await handler.handle_async(request)
@fastapi_app.get("/slack/oauth_redirect")
async def oauth_redirect(request: Request):
return await handler.handle_async(request)
# Run with: uvicorn main:fastapi_app --host 0.0.0.0 --port 3000from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
import os
# Initialize Bolt app
bolt_app = App(
token=os.environ.get("SLACK_BOT_TOKEN"),
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)
@bolt_app.command("/weather")
def weather_command(ack, respond, command):
ack()
respond(f"Weather in {command.get('text', 'your location')}: Sunny! ☀️")
# Initialize Flask
flask_app = Flask(__name__)
handler = SlackRequestHandler(bolt_app)
@flask_app.route("/slack/events", methods=["POST"])
def slack_events():
return handler.handle(request)
# OAuth endpoints (if using OAuth)
@flask_app.route("/slack/install", methods=["GET"])
def install():
return handler.handle(request)
@flask_app.route("/slack/oauth_redirect", methods=["GET"])
def oauth_redirect():
return handler.handle(request)
if __name__ == "__main__":
flask_app.run(host="0.0.0.0", port=3000)# views.py
from django.http import HttpRequest
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from slack_bolt import App
from slack_bolt.adapter.django import SlackRequestHandler
import os
# Initialize Bolt app
bolt_app = App(
token=os.environ.get("SLACK_BOT_TOKEN"),
signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)
@bolt_app.event("app_mention")
def handle_mention(event, say):
say("Thanks for mentioning me!")
handler = SlackRequestHandler(bolt_app)
@csrf_exempt
@require_http_methods(["POST"])
def slack_events(request: HttpRequest):
return handler.handle(request)
@csrf_exempt
@require_http_methods(["GET"])
def slack_install(request: HttpRequest):
return handler.handle(request)
@csrf_exempt
@require_http_methods(["GET"])
def slack_oauth_redirect(request: HttpRequest):
return handler.handle(request)
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path("slack/events", views.slack_events, name="slack_events"),
path("slack/install", views.slack_install, name="slack_install"),
path("slack/oauth_redirect", views.slack_oauth_redirect, name="slack_oauth_redirect"),
]from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
import os
# Initialize Bolt app with FaaS mode
bolt_app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
process_before_response=True # Required for Lambda
)
@bolt_app.message("hello")
def say_hello(message, say):
say(f"Hi <@{message['user']}>!")
@bolt_app.command("/ping")
def ping_command(ack, respond):
ack()
respond("Pong! 🏓")
# Lambda handler
handler = SlackRequestHandler(bolt_app)
def lambda_handler(event, context):
"""AWS Lambda handler function."""
return handler.handle(event, context)
# Deploy with:
# - Package code and dependencies
# - Set environment variables SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET
# - Configure API Gateway to trigger Lambdafrom slack_bolt import App
from slack_bolt.adapter.google_cloud_functions import SlackRequestHandler
import os
# Initialize Bolt app
bolt_app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
process_before_response=True # Required for Cloud Functions
)
@bolt_app.shortcut("create_task")
def create_task_shortcut(ack, shortcut, client):
ack()
# Handle shortcut logic
client.chat_postEphemeral(
channel=shortcut["channel"]["id"],
user=shortcut["user"]["id"],
text="Task creation feature coming soon!"
)
# Cloud Functions handler
handler = SlackRequestHandler(bolt_app)
def slack_events(request):
"""Google Cloud Functions handler."""
return handler.handle(request)
# Deploy with:
# gcloud functions deploy slack-events \
# --runtime python39 \
# --trigger-http \
# --entry-point slack_events \
# --set-env-vars SLACK_BOT_TOKEN=xoxb-...,SLACK_SIGNING_SECRET=...from slack_bolt import AsyncApp
from slack_bolt.adapter.asgi import SlackRequestHandler
import os
# Initialize async Bolt app
bolt_app = AsyncApp(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
@bolt_app.message("hello")
async def say_hello(message, say):
await say(f"Hi <@{message['user']}>!")
# ASGI application
handler = SlackRequestHandler(bolt_app)
async def app(scope, receive, send):
"""ASGI application."""
if scope["type"] == "http" and scope["path"] == "/slack/events":
await handler.handle_async(scope, receive, send)
else:
# Handle other routes or return 404
await send({
"type": "http.response.start",
"status": 404,
})
await send({
"type": "http.response.body",
"body": b"Not Found",
})
# Run with: uvicorn main:app --host 0.0.0.0 --port 3000from fastapi import FastAPI, Request
from slack_bolt import App
from slack_bolt.adapter.fastapi import SlackRequestHandler
import os
bolt_app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
@bolt_app.event("app_mention")
def handle_mention(event, say):
say("Thanks for the mention!")
fastapi_app = FastAPI()
handler = SlackRequestHandler(bolt_app)
# Main events endpoint
@fastapi_app.post("/slack/events")
async def slack_events(request: Request):
return await handler.handle_async(request)
# Interactive components endpoint
@fastapi_app.post("/slack/interactive")
async def slack_interactive(request: Request):
return await handler.handle_async(request)
# Slash commands endpoint
@fastapi_app.post("/slack/commands")
async def slack_commands(request: Request):
return await handler.handle_async(request)
# OAuth endpoints
@fastapi_app.get("/slack/install")
async def slack_install(request: Request):
return await handler.handle_async(request)
@fastapi_app.get("/slack/oauth_redirect")
async def slack_oauth_redirect(request: Request):
return await handler.handle_async(request)
# Health check
@fastapi_app.get("/health")
async def health_check():
return {"status": "healthy"}from fastapi import FastAPI, Request, HTTPException
from slack_bolt import App
from slack_bolt.adapter.fastapi import SlackRequestHandler
import os
bolt_app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
# Custom Bolt middleware
@bolt_app.middleware
def log_requests(logger, body, next):
logger.info(f"Incoming request from team: {body.get('team_id')}")
next()
@bolt_app.message("hello")
def say_hello(message, say):
say("Hello from integrated app!")
fastapi_app = FastAPI()
handler = SlackRequestHandler(bolt_app)
# FastAPI middleware
@fastapi_app.middleware("http")
async def add_security_headers(request: Request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
return response
# Rate limiting middleware
async def rate_limit_middleware(request: Request, call_next):
# Implement rate limiting logic
client_ip = request.client.host
if is_rate_limited(client_ip):
raise HTTPException(status_code=429, detail="Rate limit exceeded")
response = await call_next(request)
return response
@fastapi_app.post("/slack/events")
async def slack_events(request: Request):
return await handler.handle_async(request)from flask import Flask, request, jsonify
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
from slack_bolt.error import BoltError
import logging
import os
bolt_app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
# Bolt error handler
@bolt_app.error
def global_error_handler(error, body, logger):
logger.exception(f"Error: {error}")
return {"status": "error", "message": "Internal server error"}
flask_app = Flask(__name__)
handler = SlackRequestHandler(bolt_app)
# Flask error handlers
@flask_app.errorhandler(BoltError)
def handle_bolt_error(error):
logging.exception("Bolt framework error")
return jsonify({"error": "Slack integration error"}), 500
@flask_app.errorhandler(500)
def handle_internal_error(error):
logging.exception("Internal server error")
return jsonify({"error": "Internal server error"}), 500
@flask_app.route("/slack/events", methods=["POST"])
def slack_events():
try:
return handler.handle(request)
except Exception as e:
logging.exception("Unhandled error in Slack events")
return jsonify({"error": "Processing failed"}), 500# Dockerfile for FastAPI + Bolt
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 3000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "3000"]# docker-compose.yml
version: '3.8'
services:
slack-bot:
build: .
ports:
- "3000:3000"
environment:
- SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
- SLACK_SIGNING_SECRET=${SLACK_SIGNING_SECRET}
volumes:
- ./data:/app/data# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: slack-bot
spec:
replicas: 2
selector:
matchLabels:
app: slack-bot
template:
metadata:
labels:
app: slack-bot
spec:
containers:
- name: slack-bot
image: your-registry/slack-bot:latest
ports:
- containerPort: 3000
env:
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
name: slack-secrets
key: bot-token
- name: SLACK_SIGNING_SECRET
valueFrom:
secretKeyRef:
name: slack-secrets
key: signing-secret
---
apiVersion: v1
kind: Service
metadata:
name: slack-bot-service
spec:
selector:
app: slack-bot
ports:
- port: 80
targetPort: 3000
type: LoadBalancerInstall with Tessl CLI
npx tessl i tessl/pypi-slack-bolt