Chatbot API with AWS Chalice and AWS Bedrock: Part 1 - Setup and First Deploy
- Carlo Sansonetti
- Mar 27
- 3 min read
Welcome to the first installment of our three-part series on building a robust, serverless chatbot API using AWS Chalice. In this series, we'll go through the entire process of setting up a production-ready chatbot that leverages AWS Bedrock for AI capabilities and DynamoDB for chat history persistence.
Why Chalice for a Chatbot API?
When I started rebuilding CGCircuit's backend infrastructure, I needed a solution that was:
Serverless - to reduce infrastructure management overhead
Scalable - to handle variable traffic without performance issues
Cost-effective - to optimize for both development time and operational expenses
Python-based - to leverage our team's existing skills
AWS Chalice checked all these boxes, providing a Flask-like framework for serverless applications that abstracts away much of the complexity of working with AWS Lambda and API Gateway.
Prerequisites
Before we begin, make sure you have:
An AWS account with appropriate permissions
Python 3.8 or newer installed
AWS CLI configured with your credentials
A basic understanding of RESTful APIs
Setting Up Your Development Environment
First, let's create a new virtual environment and install Chalice:
# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install Chalice
pip install chalice
Creating a New Chalice Project
Now we'll create a new Chalice project specifically for our chatbot:
chalice new-project chatbot-api
cd chatbot-api
This creates a basic project structure that includes:
app.py - The main application file
.chalice/ - Configuration directory for Chalice
requirements.txt - Dependencies file
Configuring Your Chalice Project
Let's modify the default app.py file to create a simple endpoint that will verify our setup:
from chalice import Chalice
app = Chalice(app_name='chatbot-api')
@app.route('/')
def index():
return {'message': 'Welcome to the Chatbot API'}
@app.route('/health')
def health_check():
return {'status': 'healthy'}
Next, let's update our requirements.txt file to include dependencies we'll need throughout this series:
boto3>=1.28.0
Setting Up IAM Permissions
Chalice will create IAM roles for us, but we need to ensure our policy allows the necessary actions. Create a .chalice/policy.json file:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
Note: We'll expand this policy in later parts as we add Bedrock and DynamoDB capabilities.
Local Development and Testing
Before deploying to AWS, let's test our API locally:
chalice local
This starts a local development server, typically at http://127.0.0.1:8000. You can test the endpoints using curl, Postman, or your browser:
curl http://127.0.0.1:8000/
# Should return: {"message": "Welcome to the Chatbot API"}
curl http://127.0.0.1:8000/health
# Should return: {"status": "healthy"}
Deploying to AWS
When you're ready to deploy to AWS, it's as simple as:
chalice deploy
Chalice will:
Package your application
Create the necessary IAM roles
Set up an API Gateway REST API
Configure Lambda functions
Provide you with an endpoint URL
After successful deployment, you'll see output similar to:
Creating deployment package.
Creating IAM role: chatbot-api-dev
Creating lambda function: chatbot-api-dev
Creating Rest API
Resources deployed:
- Lambda ARN: arn:aws:lambda:us-east-1:123456789012:function:chatbot-api-dev
- Rest API URL: https://abcdefghij.execute-api.us-east-1.amazonaws.com/api/
You can now test your live API:
curl https://abcdefghij.execute-api.us-east-1.amazonaws.com/api/
# Should return: {"message": "Welcome to the Chatbot API"}
Structuring Your Project for a Chatbot
While the simple structure works for now, as we add more complexity in Parts 2 and 3, we'll want a more organized codebase. Let's create a better structure:
chatbot-api/
├── .chalice/
│ └── config.json
├── chalicelib/
│ ├── __init__.py
│ ├── bedrock.py # Will contain Bedrock integration (Part 2)
│ ├── dynamodb.py # Will contain DynamoDB integration (Part 3)
│ └── utils.py # Utility functions
├── app.py
└── requirements.txt
Create these files now, even though we'll populate them in the upcoming parts:
mkdir -p chalicelib
touch chalicelib/__init__.py chalicelib/bedrock.py chalicelib/dynamodb.py chalicelib/utils.py
Adding Configuration for Different Environments
Let's update .chalice/config.json to support different environments:
{
"version": "2.0",
"app_name": "chatbot-api",
"stages": {
"dev": {
"api_gateway_stage": "api",
"environment_variables": {
"STAGE": "dev"
}
},
"prod": {
"api_gateway_stage": "api",
"environment_variables": {
"STAGE": "prod"
}
}
}
}
Now you can deploy to different stages:
# Deploy to dev (default)
chalice deploy
# Deploy to production
chalice deploy --stage prod
Next Steps
In this first part, we've:
Set up a Chalice project
Created a basic API structure
Deployed to AWS
Prepared the codebase for future enhancements
In Part 2, we'll integrate AWS Bedrock to give our chatbot AI capabilities by creating a dedicated endpoint that can process user messages and generate responses.
Then in Part 3, we'll add chat history persistence using DynamoDB, allowing our chatbot to maintain context throughout conversations.
Stay tuned, and happy coding!
Want to learn more about building APIs with Chalice? Check out the official AWS Chalice documentation or leave a comment below with your questions.
Comments