Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
82
82%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
Complete guide for building AWS Lambda functions with the AWS Chalice framework.
AWS Chalice is a Python serverless microframework that lets you quickly create and deploy applications that use AWS Lambda. It provides:
# Install Chalice
pip install chalice
# Verify installation
chalice --version
# Create new project
chalice new-project my-api
cd my-apimy-chalice-project/
├── app.py # Main application file
├── requirements.txt # Python dependencies
├── .chalice/
│ ├── config.json # Stage configuration
│ └── deploy/ # Deployment artifacts (auto-generated)
├── chalicelib/ # Additional Python modules
│ ├── __init__.py
│ └── services.py
└── tests/
└── test_app.py# app.py
from chalice import Chalice
app = Chalice(app_name='hello-world')
@app.route('/')
def index():
return {'hello': 'world'}from chalice import Chalice
app = Chalice(app_name='my-api')
@app.route('/users', methods=['GET'])
def list_users():
return {'users': []}
@app.route('/users', methods=['POST'])
def create_user():
user = app.current_request.json_body
return {'user': user, 'created': True}
@app.route('/users/{user_id}', methods=['GET'])
def get_user(user_id):
return {'user_id': user_id}
@app.route('/users/{user_id}', methods=['PUT'])
def update_user(user_id):
updates = app.current_request.json_body
return {'user_id': user_id, 'updated': updates}
@app.route('/users/{user_id}', methods=['DELETE'])
def delete_user(user_id):
return {'user_id': user_id, 'deleted': True}@app.route('/orders/{order_id}/items/{item_id}')
def get_order_item(order_id, item_id):
return {
'order_id': order_id,
'item_id': item_id
}from urllib.parse import parse_qs
@app.route('/search')
def search():
# Access query parameters
query_params = app.current_request.query_params or {}
search_term = query_params.get('q')
page = int(query_params.get('page', 1))
limit = int(query_params.get('limit', 10))
return {
'search_term': search_term,
'page': page,
'limit': limit
}@app.route('/data', methods=['POST'])
def process_data():
request = app.current_request
# Request properties
return {
'method': request.method, # POST
'path': request.path, # /data
'query_params': request.query_params,
'headers': dict(request.headers),
'json_body': request.json_body, # Parsed JSON body
'raw_body': request.raw_body, # Raw bytes
'context': request.context, # Lambda context
'stage_vars': request.stage_vars, # API Gateway stage variables
}from chalice import Response
import json
@app.route('/custom-response')
def custom_response():
return Response(
body=json.dumps({'message': 'Custom response'}),
status_code=201,
headers={
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
}
)
@app.route('/binary-data')
def binary_data():
return Response(
body=b'binary content',
status_code=200,
headers={'Content-Type': 'application/octet-stream'}
)from chalice import Chalice, CORSConfig
# Global CORS configuration
cors_config = CORSConfig(
allow_origin='https://example.com',
allow_headers=['Content-Type', 'Authorization'],
allow_credentials=True,
max_age=600
)
app = Chalice(app_name='my-api')
app.api.cors_config = cors_configfrom chalice import CORSConfig
# Simple CORS
@app.route('/public', cors=True)
def public_endpoint():
return {'data': 'public'}
# Custom CORS per route
custom_cors = CORSConfig(
allow_origin='https://specific-domain.com',
allow_headers=['X-Custom-Header']
)
@app.route('/restricted', cors=custom_cors)
def restricted_endpoint():
return {'data': 'restricted'}from chalice import (
Chalice,
BadRequestError,
UnauthorizedError,
ForbiddenError,
NotFoundError,
ConflictError,
UnprocessableEntityError,
TooManyRequestsError,
ChaliceViewError
)
app = Chalice(app_name='my-api')
@app.route('/users/{user_id}')
def get_user(user_id):
user = find_user(user_id)
if user is None:
raise NotFoundError(f'User {user_id} not found')
return user
@app.route('/users', methods=['POST'])
def create_user():
data = app.current_request.json_body
if not data or 'email' not in data:
raise BadRequestError('Email is required')
if user_exists(data['email']):
raise ConflictError('User already exists')
return create_new_user(data)from chalice import ChaliceViewError
@app.errorhandler(ChaliceViewError)
def handle_errors(error):
return Response(
body=json.dumps({
'error': error.__class__.__name__,
'message': str(error)
}),
status_code=error.STATUS_CODE if hasattr(error, 'STATUS_CODE') else 500,
headers={'Content-Type': 'application/json'}
)import boto3
from botocore.exceptions import ClientError
# Initialize at module level for connection reuse
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('my-table')
@app.route('/items/{item_id}')
def get_item(item_id):
try:
response = table.get_item(Key={'id': item_id})
item = response.get('Item')
if not item:
raise NotFoundError(f'Item {item_id} not found')
return item
except ClientError as e:
app.log.error(f"DynamoDB error: {e}")
raise ChaliceViewError('Database error')
@app.route('/items', methods=['POST'])
def create_item():
item = app.current_request.json_body
try:
table.put_item(Item=item)
return item
except ClientError as e:
app.log.error(f"DynamoDB error: {e}")
raise ChaliceViewError('Failed to create item')import boto3
import json
s3 = boto3.client('s3')
BUCKET_NAME = 'my-bucket'
@app.route('/files/{key}')
def get_file(key):
try:
response = s3.get_object(Bucket=BUCKET_NAME, Key=key)
content = response['Body'].read()
return Response(
body=content,
status_code=200,
headers={'Content-Type': response['ContentType']}
)
except s3.exceptions.NoSuchKey:
raise NotFoundError(f'File {key} not found')
@app.route('/files', methods=['POST'])
def upload_file():
request = app.current_request
key = request.query_params.get('key')
if not key:
raise BadRequestError('Key parameter required')
s3.put_object(
Bucket=BUCKET_NAME,
Key=key,
Body=request.raw_body,
ContentType=request.headers.get('content-type', 'application/octet-stream')
)
return {'key': key, 'uploaded': True}import boto3
import json
sqs = boto3.client('sqs')
QUEUE_URL = 'https://sqs.us-east-1.amazonaws.com/123456789/my-queue'
@app.route('/messages', methods=['POST'])
def enqueue_message():
message = app.current_request.json_body
response = sqs.send_message(
QueueUrl=QUEUE_URL,
MessageBody=json.dumps(message),
MessageAttributes={
'Type': {
'StringValue': message.get('type', 'default'),
'DataType': 'String'
}
}
)
return {
'message_id': response['MessageId'],
'status': 'queued'
}{
"version": "2.0",
"app_name": "my-api",
"stages": {
"dev": {
"api_gateway_stage": "api",
"environment_variables": {
"DEBUG": "true",
"TABLE_NAME": "dev-table"
},
"lambda_functions": {
"api_handler": {
"lambda_timeout": 10,
"lambda_memory_size": 256
}
},
"tags": {
"Environment": "dev",
"Project": "my-api"
}
},
"prod": {
"api_gateway_stage": "api",
"environment_variables": {
"DEBUG": "false",
"TABLE_NAME": "prod-table"
},
"lambda_functions": {
"api_handler": {
"lambda_timeout": 30,
"lambda_memory_size": 512,
"reserved_concurrent_executions": 100
}
},
"tags": {
"Environment": "prod",
"Project": "my-api"
}
}
}
}import os
# Access environment variables
DEBUG = os.environ.get('DEBUG', 'false').lower() == 'true'
TABLE_NAME = os.environ.get('TABLE_NAME', 'default-table')
SECRET_KEY = os.environ.get('SECRET_KEY')
@app.route('/config')
def get_config():
return {
'debug': DEBUG,
'table_name': TABLE_NAME,
'has_secret': SECRET_KEY is not None
}# Start local development server
chalice local
# With specific port
chalice local --port 8080
# With stage configuration
chalice local --stage dev# Test local endpoints
curl http://localhost:8000/
curl -X POST http://localhost:8000/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'# Deploy to default stage (dev)
chalice deploy
# Deploy to specific stage
chalice deploy --stage prod
# Get deployment info
chalice url --stage dev
chalice logs --stage dev# Generate SAM/CloudFormation template
chalice package --stage prod ./out
# Output:
# ./out/sam.json # CloudFormation template
# ./out/deployment.zip # Lambda deployment packagefrom chalice import Chalice
app = Chalice(app_name='my-api')
@app.middleware('http')
def auth_middleware(event, get_response):
# Run before handler
auth_header = event.headers.get('Authorization')
if not auth_header and event.path != '/':
return Response(
body=json.dumps({'error': 'Unauthorized'}),
status_code=401
)
# Call the actual handler
response = get_response(event)
# Run after handler
response.headers['X-Request-ID'] = event.request_context['requestId']
return responsefrom chalice import Chalice, Cron
app = Chalice(app_name='scheduled-tasks')
@app.schedule(Cron(0, 12, '*', '*', '?', '*'))
def daily_report(event):
"""Run every day at 12:00 PM UTC"""
app.log.info("Running daily report")
generate_daily_report()
return {'status': 'completed'}
@app.schedule('rate(1 hour)')
def hourly_cleanup(event):
"""Run every hour"""
app.log.info("Running hourly cleanup")
cleanup_old_data()
return {'status': 'completed'}@app.on_s3_event(bucket='my-bucket', events=['s3:ObjectCreated:*'])
def handle_s3_upload(event):
app.log.info(f"File uploaded: {event.key}")
process_file(event.bucket, event.key)
return {'status': 'processed'}@app.on_sns_message(topic='my-topic')
def handle_sns_message(event):
app.log.info(f"Received SNS message: {event.subject}")
app.log.info(f"Message body: {event.message}")
process_notification(event.message)
return {'status': 'processed'}@app.on_sqs_message(queue='my-queue', batch_size=10)
def handle_sqs_message(event):
for record in event:
app.log.info(f"Processing message: {record.body}")
process_message(record.body)
return {'status': 'processed'}chalicelib/ for additional modules to keep app.py cleanapp.log for CloudWatch integrationchalice package for CI/CD pipelines# chalicelib/users_service.py
import boto3
from botocore.exceptions import ClientError
from chalice import NotFoundError, BadRequestError
class UsersService:
def __init__(self, table_name):
self.table = boto3.resource('dynamodb').Table(table_name)
def get_user(self, user_id):
response = self.table.get_item(Key={'id': user_id})
user = response.get('Item')
if not user:
raise NotFoundError(f'User {user_id} not found')
return user
def create_user(self, user_data):
if 'id' not in user_data:
raise BadRequestError('id is required')
self.table.put_item(Item=user_data)
return user_data
# app.py
from chalicelib.users_service import UsersService
users_service = UsersService(os.environ.get('TABLE_NAME'))
@app.route('/users/{user_id}')
def get_user(user_id):
return users_service.get_user(user_id)
@app.route('/users', methods=['POST'])
def create_user():
return users_service.create_user(app.current_request.json_body)@app.route('/users')
def list_users():
query_params = app.current_request.query_params or {}
limit = int(query_params.get('limit', 20))
cursor = query_params.get('cursor')
kwargs = {'Limit': limit}
if cursor:
kwargs['ExclusiveStartKey'] = {'id': cursor}
response = table.scan(**kwargs)
result = {
'users': response.get('Items', []),
'count': response.get('Count', 0)
}
if 'LastEvaluatedKey' in response:
result['next_cursor'] = response['LastEvaluatedKey']['id']
return resultplugins
developer-kit-ai
skills
chunking-strategy
prompt-engineering
developer-kit-aws
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
references
aws-cloudformation-bedrock
references
aws-cloudformation-cloudfront
references
aws-cloudformation-cloudwatch
references
aws-cloudformation-dynamodb
references
aws-cloudformation-ec2
aws-cloudformation-ecs
references
aws-cloudformation-elasticache
aws-cloudformation-iam
references
aws-cloudformation-lambda
references
aws-cloudformation-rds
aws-cloudformation-s3
references
aws-cloudformation-security
references
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
developer-kit-core
skills
developer-kit-java
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
graalvm-native-image
langchain4j
langchain4j-mcp-server-patterns
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
references
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
unit-test-controller-layer
unit-test-exception-handler
unit-test-json-serialization
unit-test-mapper-converter
unit-test-parameterized
unit-test-scheduled-async
unit-test-service-layer
unit-test-utility-methods
unit-test-wiremock-rest-api
developer-kit-php
skills
aws-lambda-php-integration
developer-kit-python
skills
aws-lambda-python-integration
developer-kit-tools
developer-kit-typescript
skills
aws-lambda-typescript-integration
better-auth
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
scripts
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
references
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
references
shadcn-ui
tailwind-css-patterns
references
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities