This project sets up the initial structure of a chatbot application using FastAPI for the backend. It currently includes:
- A health check route (
/health
) to monitor the application's status. - User Registration Endpoint (
/users/register
) to allow users to create accounts. - User Login Endpoint (
/users/login
) to enable users to authenticate. Authentication tokens are stored securely in HTTP-only cookies. - User Logout Endpoint (
/users/logout
) to allow users to log out by clearing authentication cookies. - User Info Endpoint (
/users/me
) to retrieve information about the currently authenticated user. - Protected
/messages
Endpoints (/messages
) to manage chatbot messages, accessible only to authenticated users. These endpoints allow users to:- List Messages (
GET /messages/
): Retrieve a list of messages sent and received. - Send a Message (
POST /messages/
): Send a new message to the chatbot. - Edit a Message (
PUT /messages/{id_message}
): Edit an existing user message. - Delete a Message (
DELETE /messages/{id_message}
): Delete a user message.
- List Messages (
Additionally, the project has been refactored to enhance maintainability and scalability by:
- Centralizing Configuration in a dedicated
config.py
module. - Separating Models into individual files within the
models
directory. - Organizing Utility Functions within the
utils
directory. - Implementing Comprehensive Logging within the authentication process for better monitoring and debugging.
This setup serves as a foundation for developing additional chatbot functionalities such as sending, editing, and deleting messages, as well as integrating more advanced chatbot logic.
-
Backend:
- Python 3.11.0
- FastAPI
- Uvicorn
- Pytest
- boto3
- python-dotenv
- python-jose
-
Containerization:
- Docker
-
Deployment:
- AWS App Runner
- AWS Elastic Container Registry (ECR)
-
Testing:
- pytest
-
Development Tools:
- Black
- pre-commit
async-chatbot-api/
βββ app/
β βββ __init__.py
β βββ auth.py
β βββ config.py
β βββ main.py
β βββ models/
β β βββ __init__.py
β β βββ messages.py
β β βββ users.py
β βββ routers/
β β βββ __init__.py
β β βββ health.py
β β βββ messages.py
β β βββ users.py
β βββ utils/
β βββ __init__.py
β βββ auth.py
βββ tests/
β βββ __init__.py
β βββ test_auth.py
β βββ test_health.py
β βββ test_messages.py
β βββ test_users.py
βββ .pre-commit-config.yaml
βββ requirements.txt
βββ Dockerfile
βββ .gitignore
- app/config.py: Centralized configuration module loading environment variables.
- app/main.py: Entry point of the FastAPI application with logging configuration.
- app/models/users.py: Contains Pydantic models for user registration and login.
- app/models/messages.py: Contains Pydantic models for message management.
- app/routers/users.py: Defines the user registration, login, logout, and user info endpoints.
- app/routers/messages.py: Defines protected endpoints for managing chatbot messages (list, send, edit, delete).
- app/routers/health.py: Defines the
/health
route for health checks. - app/utils/auth.py: Contains utility functions, including
get_secret_hash
for AWS Cognito and authentication dependencies. - tests/test_users.py: Unit tests for user registration, login, logout, and user info endpoints.
- tests/test_messages.py: Unit tests for message management endpoints.
- requirements.txt: Project dependencies.
- Dockerfile: Configuration for containerizing the application.
- .gitignore: Files and directories to be ignored by Git.
- .pre-commit-config.yaml: Configuration file for pre-commit hooks.
git clone https://github.com/YutaroNegi/async-chatbot-api.git
cd async-chatbot-api
python -m venv venv
source venv/bin/activate # For Linux/Mac
venv\Scripts\activate # For Windows
pip install -r requirements.txt
The application uses environment variables to manage sensitive configurations such as AWS Cognito settings. During development, these can be set using a .env
file.
Create a .env
file in the root directory with the following content:
COGNITO_USER_POOL_ID=your_user_pool_id
COGNITO_APP_CLIENT_ID=your_app_client_id
COGNITO_APP_CLIENT_SECRET=your_app_client_secret
COGNITO_ISSUER=https://cognito-idp.<region>.amazonaws.com/<user_pool_id>
DYNAMO_MESSAGES_TABLE=Messages
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
Ensure that the .env
file is not committed to version control by keeping it listed in .gitignore
.
Ensure that pre-commit is installed and configured to run automatically before commits.
pre-commit install
uvicorn app.main:app --reload
The application will be available at http://localhost:8000.
-
User Registration:
- Endpoint:
POST /users/register
- Payload:
{ "email": "newuser@example.com", "password": "Password123" }
- Response:
{ "message": "User created successfully" }
- Password Policy:
- Must be at least 8 characters long.
- Must contain at least one number.
- Endpoint:
-
User Login:
- Endpoint:
POST /users/login
- Payload:
{ "email": "newuser@example.com", "password": "Password123" }
- Response:
{ "message": "Login successful" }
- Note: Tokens are now stored in HTTP-only cookies. They are not returned in the response body for enhanced security.
- Endpoint:
-
User Logout:
- Endpoint:
POST /users/logout
- Response:
{ "message": "Logout successful" }
- Endpoint:
-
Get Current User:
- Endpoint:
GET /users/me
- Response:
{ "email": "newuser@example.com" }
- Endpoint:
-
List Messages:
- Endpoint:
GET /messages/
- Response:
{ "messages": [ { "id_message": "aee86f6d-26e0-4b77-a8be-44829d0e6e04", "id_user": "test-user-id", "content": "Hello!", "timestamp": "2024-10-07T07:33:21.023112", "is_bot": false }, { "id_message": "31101aad-c65f-41b4-8210-a27649aaa124", "id_user": "test-user-id", "content": "Hi there!", "timestamp": "2024-10-07T07:35:21.023112", "is_bot": true } // ... other messages ... ] }
- Endpoint:
-
Send a Message:
- Endpoint:
POST /messages/
- Payload:
{ "content": "Hello, chatbot!" }
- Response:
{ "user_message": { "id_message": "aee86f6d-26e0-4b77-a8be-44829d0e6e04", "id_user": "test-user-id", "content": "Hello, chatbot!", "timestamp": "2024-10-07T07:33:21.023112", "is_bot": false }, "bot_response": { "id_message": "31101aad-c65f-41b4-8210-a27649aaa124", "id_user": "test-user-id", "content": "This is a bot response.", "timestamp": "2024-10-07T07:35:21.023112", "is_bot": true } }
- Endpoint:
-
Edit a Message:
- Endpoint:
PUT /messages/{id_message}
- Payload:
{ "content": "Updated message content." }
- Response:
{ "id_message": "aee86f6d-26e0-4b77-a8be-44829d0e6e04", "content": "Updated message content." }
- Endpoint:
-
Delete a Message:
- Endpoint:
DELETE /messages/{id_message}
- Response:
{ "id_message": "aee86f6d-26e0-4b77-a8be-44829d0e6e04", "status": "deleted" }
- Endpoint:
Ensure all development dependencies are installed and run:
pytest tests/
This command will execute all unit tests for user registration, login, and protected message routes, ensuring the reliability of authentication and authorization mechanisms.
-
Authentication Tests:
- Accessing protected routes without a token.
- Accessing protected routes with an invalid token.
-
User Tests:
- Registering a new user.
- Logging in with valid credentials.
- Logging in with invalid credentials.
-
Message Tests:
- Listing messages for an authenticated user.
- Sending a new message.
- Editing an existing message.
- Deleting a message.
docker build -t async-chatbot-api .
docker run -d --name async-chatbot-api-container -p 8000:8000 --env-file .env async-chatbot-api
The application will be accessible at http://localhost:8000.
Ensure you have an AWS account and have configured the AWS CLI with appropriate permissions.
aws ecr create-repository --repository-name async-chatbot-api --region your-region
aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com
docker tag async-chatbot-api:latest your-account-id.dkr.ecr.your-region.amazonaws.com/async-chatbot-api:latest
docker push your-account-id.dkr.ecr.your-region.amazonaws.com/async-chatbot-api:latest
Navigate to the AWS App Runner console and create a new service:
- Source: Select "Container registry" and choose "Amazon ECR".
- Repository: Select your
async-chatbot-api
repository and thelatest
tag. - Service Settings: Configure the service name, CPU, memory, and other settings as needed.
- Environment Variables: Set the required environment variables as defined in your
.env
file. - Networking: Configure VPC, subnets, and security groups as necessary.
- Deployment: Review and create the service.
The service will be deployed and accessible via the provided App Runner URL.
Ensure all necessary environment variables are set in the App Runner console under the service settings. These should mirror those in your local .env
file but should be securely managed within AWS.
This project uses Black to ensure consistent code style.
Format all Python code in the project:
black app/ tests/
pre-commit is used to automatically run linting and formatting checks before each commit, ensuring code quality and consistency.
pre-commit install
Pre-commit hooks run automatically on git commit
. To manually run all hooks against all files:
pre-commit run --all-files
The tests utilize pytest and FastAPI's TestClient along with unittest.mock to simulate interactions with DynamoDB and the authentication process. This ensures that tests are isolated, fast, and do not depend on external services.
Ensure that pytest and unittest.mock are installed. These should already be included in your requirements.txt
, but verify:
pip install pytest
Execute all tests within the tests/
directory:
pytest tests/
- Development Environment: It's recommended to use a virtual environment to isolate project dependencies.
- Docker: Ensure Docker is installed on your machine to utilize containerization features.
- Endpoint Testing: Use tools like Postman or cURL to test API endpoints.
- Security:
- Never commit sensitive information such as AWS credentials or Cognito secrets. Always use environment variables and ensure
.env
is listed in.gitignore
. - In production, set
secure=True
for cookies to enforce HTTPS. - Consider implementing CSRF protection mechanisms since cookies are used for authentication.
- Never commit sensitive information such as AWS credentials or Cognito secrets. Always use environment variables and ensure
Below is the system design diagram for this project: