A comprehensive FastAPI-based service for the BI Assistant with stateful session management and streaming support.
bi_assistant/
├── api/ # API package
│ ├── __init__.py # Package initialization
│ ├── main.py # FastAPI application setup
│ ├── models/ # Pydantic models
│ │ ├── __init__.py
│ │ ├── session.py # Session-related models
│ │ ├── chat.py # Chat-related models
│ │ └── auth.py # Auth models (future)
│ ├── routes/ # API route handlers
│ │ ├── __init__.py
│ │ ├── session.py # Session endpoints
│ │ ├── chat.py # Chat endpoints
│ │ └── health.py # Health/utility endpoints
│ ├── services/ # Business logic services
│ │ ├── __init__.py
│ │ ├── session_manager.py # Session management
│ │ └── chat_service.py # Chat processing
│ └── middleware/ # Middleware components
│ ├── __init__.py
│ └── auth.py # Auth middleware (future)
├── src/ # Original BI Agent source
├── server.py # Main server entry point
├── api_client_example.py # Client usage example
├── docker-compose.yml # Docker deployment
└── Dockerfile # Container configuration
- Stateful Sessions: Persistent conversation sessions with automatic cleanup
- Streaming Support: Real-time streaming responses for better user experience
- RESTful API: Clean, well-documented REST endpoints
- Session Management: Create, manage, and track multiple user sessions
- Conversation History: Persistent conversation tracking per session
- Error Handling: Comprehensive error handling and logging
- Docker Support: Ready-to-deploy Docker configuration
- Production Ready: Nginx configuration and health checks included
The service is built around several key components:
- Session Manager: Manages user sessions, handles timeouts, and cleanup
- BI Agent Integration: Seamless integration with the existing BI Agent
- Streaming Handler: Manages real-time streaming responses
- State Management: Maintains conversation state across requests
POST /sessions- Create a new sessionGET /sessions- List all active sessionsGET /sessions/{session_id}- Get session informationDELETE /sessions/{session_id}- Delete a sessionGET /sessions/{session_id}/history- Get conversation historyGET /sessions/{session_id}/capabilities- Get available capabilities
POST /chat- Send message (non-streaming)POST /chat/stream- Send message (streaming)
GET /- Service informationGET /health- Health check
-
Install Dependencies
pip install -r api_requirements.txt
-
Set Environment Variables Create a
.envfile:# Database configuration POSTGRES_HOST=localhost POSTGRES_PORT=5432 POSTGRES_DB=your_database POSTGRES_USER=your_user POSTGRES_PASSWORD=your_password # LLM API keys OPENAI_API_KEY=your_openai_key GOOGLE_API_KEY=your_google_key # Optional: Qdrant configuration QDRANT_URL=your_qdrant_url QDRANT_API_KEY=your_qdrant_key
-
Run the Service
python server.py
The service will be available at
http://localhost:8888 -
View API Documentation
- Swagger UI:
http://localhost:8888/docs - ReDoc:
http://localhost:8888/redoc
- Swagger UI:
-
Build and Run with Docker Compose
docker-compose up -d
This will start:
- BI Assistant API service
- PostgreSQL database
- Nginx reverse proxy
-
Access the Service
- API:
http://localhost:8888 - Through Nginx:
http://localhost:80
- API:
-
Create a Session
curl -X POST "http://localhost:8888/sessions" \ -H "Content-Type: application/json" \ -d '{ "username": "Test User", "user_role": "BI", "preferred_language": "en", "streaming": true }'
-
Send a Chat Message (Non-streaming)
curl -X POST "http://localhost:8888/chat" \ -H "Content-Type: application/json" \ -d '{ "message": "Hello, what can you help me with?", "session_id": "your-session-id" }'
{"message":"tell me more","session_id":"6aab113e-771a-48c2-a8c1-62d6d96f6100"} 3. Send a Chat Message (Streaming)
curl -X POST "http://localhost:8888/chat/stream" \
-H "Content-Type: application/json" \
-d '{
"message": "Hello, what can you help me with?",
"session_id": "6aab113e-771a-48c2-a8c1-62d6d96f6100"
}'- Get Session Information
curl "http://localhost:8888/sessions/your-session-id"
// Create session
const createSession = async () => {
const response = await fetch('/sessions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'Web User',
user_role: 'Analyst',
streaming: true
})
});
return await response.json();
};
// Streaming chat
const streamingChat = async (sessionId, message) => {
const response = await fetch('/chat/stream', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: message,
session_id: sessionId
})
});
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
console.log('Stream data:', data);
}
}
}
};Sessions can be configured with the following parameters:
- username: Display name for the user
- user_role: User's role (affects prompt behavior)
- preferred_language: Language preference (en, vi, etc.)
- preferred_generation_format: Chart generation preferences
- streaming: Enable/disable streaming by default
Key configuration options in api_service.py:
# Session timeout (default: 2 hours)
session_timeout = timedelta(hours=2)
# Cleanup interval (default: 5 minutes)
cleanup_interval = 300
# CORS settings
allow_origins = ["*"] # Configure for production{
"session_id": "uuid",
"username": "John Doe",
"user_role": "Data Analyst",
"preferred_language": "en",
"created_at": "2024-01-01T10:00:00",
"last_activity": "2024-01-01T10:30:00",
"message_count": 5,
"streaming_enabled": true,
"status": "active"
}{
"session_id": "uuid",
"message_id": "uuid",
"response": "Generated response text",
"success": true,
"iterations": 2,
"exist_reason": "response_generated",
"error": null,
"timestamp": "2024-01-01T10:30:00"
}data: {"type": "start", "session_id": "uuid", "message_id": "uuid"}
data: {"type": "text", "text": "Hello, I can help you with..."}
data: {"type": "complete", "session_id": "uuid", "success": true, "iterations": 1}
The API returns appropriate HTTP status codes:
200: Success404: Session not found410: Session expired422: Validation error500: Internal server error
Error responses include detailed messages:
{
"detail": "Session not found"
}curl http://localhost:8888/healthResponse:
{
"status": "healthy",
"timestamp": "2024-01-01T10:30:00",
"active_sessions": 3
}Enable debug mode by setting:
uvicorn.run(
"api_service:app",
host="0.0.0.0",
port=8888,
reload=True,
log_level="debug" # Enable debug logging
)- Import Errors: Ensure the
srcdirectory is in the Python path - Database Connection: Check PostgreSQL credentials and connectivity
- Session Timeouts: Adjust
session_timeoutin SessionManager - Memory Usage: Monitor session cleanup and consider reducing timeout
- Streaming Issues: Check client implementation of Server-Sent Events
- Connection Pooling: Configure database connection pooling
- Async Processing: Use background tasks for heavy operations
- Caching: Implement Redis for session storage
- Load Balancing: Use multiple API instances with nginx
[Add your license information here]