A production-ready Flask-based chatbot backend powered by Azure OpenAI, featuring comprehensive security, monitoring, and containerization.
- Real-time chat with Azure OpenAI
- Session-based conversation management
- Streaming responses for better UX
- Conversation history and analytics
- Multiple export formats (JSON, Markdown, TXT)
- API key authentication
- JWT token support for enhanced features
- Input validation and sanitization
- Rate limiting with Redis backend
- Security headers (CSP, HSTS, X-Frame-Options)
- Non-root container execution
- Security scanning ready (Bandit, Safety)
- Application Insights integration
- Structured JSON logging
- Health check endpoint
- Retry logic with exponential backoff
- Comprehensive error handling
- Conversation analytics
- Clean separation of concerns
- Configuration management
- Docker containerization
- Azure Container Apps ready
- Multi-stage Docker builds
GET /healthResponse:
{
"status": "healthy",
"service": "chatbot-backend",
"version": "1.0.0",
"environment": "production"
}POST /chat
Headers:
X-API-Key: your-api-key
Content-Type: application/json
Body:
{
"message": "What is machine learning?",
"session_id": "user123",
"system_message": "You are a helpful AI assistant",
"temperature": 0.7
}POST /chat/stream
Headers:
X-API-Key: your-api-key
Content-Type: application/json
Body:
{
"message": "Tell me a story",
"session_id": "user123"
}GET /conversations/{session_id}
Headers:
X-API-Key: your-api-keyGET /conversations/{session_id}/export?format=markdown
Headers:
X-API-Key: your-api-keyFormats: json, markdown, txt
DELETE /conversations/{session_id}
Headers:
X-API-Key: your-api-keyGET /conversations
Headers:
X-API-Key: your-api-keyGET /conversations/stats
Headers:
X-API-Key: your-api-key- Python 3.9+
- Docker Desktop
- Azure OpenAI access
- Redis (via Docker)
- Clone and setup virtual environment
cd chatbot-backend
python3 -m venv venv
source venv/bin/activate- Install dependencies
pip install -r requirements.txt
pip install -r requirements-dev.txt # For development- Configure environment
cp .env.example .env
# Edit .env with your Azure credentials- Run with Docker Compose (Recommended)
docker-compose up --build- Or run locally
# Start Redis
docker run -d -p 6379:6379 redis:7-alpine
# Start application
python src/app.py# Health check
curl http://localhost:5000/health
# Chat (with API key)
curl -X POST http://localhost:5000/chat \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"message": "Hello!",
"session_id": "test123"
}'
# Get conversation
curl http://localhost:5000/conversations/test123 \
-H "X-API-Key: your-api-key"
# Export as markdown
curl http://localhost:5000/conversations/test123/export?format=markdown \
-H "X-API-Key: your-api-key" \
-o conversation.mddocker build -t chatbot-backend:latest .docker run -d \
-p 8000:8000 \
-e AZURE_OPENAI_ENDPOINT="your-endpoint" \
-e AZURE_OPENAI_API_KEY="your-key" \
-e AZURE_OPENAI_DEPLOYMENT_NAME="your-deployment" \
-e API_KEY="your-api-key" \
chatbot-backend:latest# Azure Container Registry
az acr build --registry myregistry \
--image chatbot-backend:latest .The deployment requires Azure credentials which should be configured separately. Below is the deployment process:
Step 1: Set up environment variables
# PLACEHOLDER: Set your Azure credentials
export AZURE_OPENAI_ENDPOINT="<YOUR_AZURE_OPENAI_ENDPOINT>"
export AZURE_OPENAI_API_KEY="<YOUR_AZURE_OPENAI_KEY>"
export AZURE_OPENAI_DEPLOYMENT_NAME="<YOUR_DEPLOYMENT_NAME>"
# Generate secure API keys
export API_KEY=$(openssl rand -hex 32)
export JWT_SECRET_KEY=$(openssl rand -hex 32)
echo "Generated API Key: $API_KEY"
echo "Generated JWT Secret: $JWT_SECRET_KEY"
echo "SAVE THESE KEYS - You'll need them to access your API"Step 2: Azure Container Registry Setup
# PLACEHOLDER: Configure your ACR details
RESOURCE_GROUP="chatbot-rg"
LOCATION="eastus"
ACR_NAME="chatbotacr$(date +%s)"
# Create resources
az group create --name $RESOURCE_GROUP --location $LOCATION
az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Basic --admin-enabled true
az acr build --registry $ACR_NAME --image chatbot-backend:latest .Step 3: Deploy to Azure Container Apps
# Get ACR credentials
ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --query loginServer -o tsv)
ACR_USERNAME=$(az acr credential show --name $ACR_NAME --query username -o tsv)
ACR_PASSWORD=$(az acr credential show --name $ACR_NAME --query passwords[0].value -o tsv)
# Create Container Apps environment
CONTAINER_APP_ENV="chatbot-env"
CONTAINER_APP_NAME="chatbot-backend"
az containerapp env create \
--name $CONTAINER_APP_ENV \
--resource-group $RESOURCE_GROUP \
--location $LOCATION
# Deploy container app
az containerapp create \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP \
--environment $CONTAINER_APP_ENV \
--image $ACR_LOGIN_SERVER/chatbot-backend:latest \
--registry-server $ACR_LOGIN_SERVER \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--target-port 8000 \
--ingress external \
--min-replicas 1 \
--max-replicas 10 \
--env-vars \
"AZURE_OPENAI_ENDPOINT=secretref:azure-openai-endpoint" \
"AZURE_OPENAI_API_KEY=secretref:azure-openai-key" \
"AZURE_OPENAI_DEPLOYMENT_NAME=secretref:azure-deployment-name" \
"API_KEY=secretref:api-key" \
"JWT_SECRET_KEY=secretref:jwt-secret" \
"ENVIRONMENT=production" \
--secrets \
"azure-openai-endpoint=${AZURE_OPENAI_ENDPOINT}" \
"azure-openai-key=${AZURE_OPENAI_API_KEY}" \
"azure-deployment-name=${AZURE_OPENAI_DEPLOYMENT_NAME}" \
"api-key=${API_KEY}" \
"jwt-secret=${JWT_SECRET_KEY}"
# Get app URL
APP_URL=$(az containerapp show --name $CONTAINER_APP_NAME --resource-group $RESOURCE_GROUP --query properties.configuration.ingress.fqdn -o tsv)
echo "App URL: https://$APP_URL"Step 4: Test Deployment
# Health check
curl https://$APP_URL/health
# Test chat
curl -X POST https://$APP_URL/chat \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-d '{"message": "Hello from Azure!", "session_id": "test"}'pytest tests/ --cov=src --cov-report=htmlblack src/flake8 src/
pylint src/bandit -r src/
safety checkmypy src/Configure APPINSIGHTS_INSTRUMENTATION_KEY in environment variables.
All logs are in JSON format for easy parsing:
{
"asctime": "2024-01-02T10:30:00Z",
"name": "src.app",
"levelname": "INFO",
"message": "Processing chat request for session: user123"
}- API Key Authentication: Required for all endpoints
- Input Validation: Pydantic models with sanitization
- Rate Limiting: Configurable per-minute limits
- Security Headers: CSP, HSTS, X-Frame-Options
- Non-root Container: Runs as unprivileged user
- Secrets Management: Environment variables, Azure Key Vault support
- HTTPS Only: Enforced in production
- CORS Protection: Configurable allowed origins
- Streaming Responses: Real-time token-by-token output
- Multiple Export Formats: JSON, Markdown, Plain Text
- Conversation Analytics: Message counts, timestamps, statistics
- System Message Customization: Per-session AI personality
- Temperature Control: Adjustable response creativity
- Conversation History Limits: Automatic trimming for context windows
- Retry Logic: Exponential backoff for API failures
- Health Monitoring: Kubernetes-ready health checks
chatbot-backend/
├── src/
│ ├── models/ # Data models
│ │ └── conversation.py
│ ├── services/ # Business logic
│ │ ├── azure_client.py
│ │ └── chat_service.py
│ ├── middleware/ # Request/response processing
│ │ ├── auth.py
│ │ ├── rate_limiter.py
│ │ └── security.py
│ ├── utils/ # Utilities
│ │ ├── logger.py
│ │ └── validators.py
│ ├── app.py # Main application
│ └── config.py # Configuration
├── tests/ # Test suite
├── Dockerfile # Container definition
├── docker-compose.yml # Local development
├── requirements.txt # Production dependencies
└── requirements-dev.txt # Development dependencies
Default: 10 requests per minute per IP
Configure in .env:
RATE_LIMIT_PER_MINUTE=10
RATE_LIMIT_ENABLED=trueAll configuration via environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
| AZURE_OPENAI_ENDPOINT | Yes | - | Azure OpenAI endpoint |
| AZURE_OPENAI_API_KEY | Yes | - | Azure OpenAI API key |
| AZURE_OPENAI_DEPLOYMENT_NAME | Yes | - | Model deployment name |
| API_KEY | Yes | - | API authentication key |
| JWT_SECRET_KEY | No | dev-secret | JWT signing key |
| REDIS_URL | No | redis://localhost:6379/0 | Redis connection URL |
| RATE_LIMIT_PER_MINUTE | No | 10 | Rate limit threshold |
| MAX_CONVERSATION_HISTORY | No | 20 | Max messages in context |
| LOG_LEVEL | No | INFO | Logging level |
MIT License - feel free to use in your projects!
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
For issues or questions, please open a GitHub issue.