Spaces:
Runtime error
Chat Agent API Documentation
This document describes the REST API endpoints for the multi-language chat agent.
Base URL
All API endpoints are prefixed with /api/v1/chat
Authentication
All endpoints (except health check and supported languages) require authentication via one of the following methods:
Header-based Authentication (Development)
X-User-ID: your-user-id
Token-based Authentication (Production)
Authorization: Bearer your-session-token
Rate Limiting
The API implements rate limiting to prevent abuse:
- Default: 200 requests per day, 50 requests per hour
- Session creation: 10 requests per minute
- Session deletion: 5 requests per minute
- Other endpoints: 20-30 requests per minute
Rate limit exceeded responses return HTTP 429 with retry information.
Endpoints
1. Get Supported Languages
Get a list of all supported programming languages.
Endpoint: GET /api/v1/chat/languages
Authentication: Not required
Response:
{
"languages": [
{
"code": "python",
"name": "Python",
"syntax_highlighting": "python",
"file_extensions": [".py", ".pyw"]
},
{
"code": "javascript",
"name": "JavaScript",
"syntax_highlighting": "javascript",
"file_extensions": [".js", ".mjs"]
}
],
"default_language": "python",
"total_count": 8
}
2. Create Chat Session
Create a new chat session for a user.
Endpoint: POST /api/v1/chat/sessions
Authentication: Required
Request Body:
{
"language": "python",
"metadata": {
"source": "web_app",
"user_preferences": {}
}
}
Response (201 Created):
{
"session_id": "uuid-string",
"user_id": "user-123",
"language": "python",
"created_at": "2023-01-01T00:00:00",
"message_count": 0,
"metadata": {
"source": "web_app"
}
}
Error Responses:
400 Bad Request: Invalid language or missing required fields401 Unauthorized: Missing or invalid authentication429 Too Many Requests: Rate limit exceeded
3. Get Chat Session
Retrieve information about a specific chat session.
Endpoint: GET /api/v1/chat/sessions/{session_id}
Authentication: Required (must own the session)
Response (200 OK):
{
"session_id": "uuid-string",
"user_id": "user-123",
"language": "python",
"created_at": "2023-01-01T00:00:00",
"last_active": "2023-01-01T01:00:00",
"message_count": 5,
"is_active": true,
"metadata": {}
}
Error Responses:
403 Forbidden: Session belongs to different user404 Not Found: Session does not exist410 Gone: Session has expired
4. List User Sessions
Get all sessions for the authenticated user.
Endpoint: GET /api/v1/chat/sessions
Authentication: Required
Query Parameters:
active_only(boolean, default: true): Only return active sessions
Response (200 OK):
{
"sessions": [
{
"session_id": "uuid-string",
"language": "python",
"created_at": "2023-01-01T00:00:00",
"last_active": "2023-01-01T01:00:00",
"message_count": 5,
"is_active": true,
"metadata": {}
}
],
"total_count": 1,
"active_only": true
}
5. Delete Chat Session
Delete a chat session and all associated data.
Endpoint: DELETE /api/v1/chat/sessions/{session_id}
Authentication: Required (must own the session)
Response (200 OK):
{
"message": "Session deleted successfully",
"session_id": "uuid-string",
"messages_deleted": 10
}
Error Responses:
403 Forbidden: Session belongs to different user404 Not Found: Session does not exist
6. Get Chat History
Retrieve chat history for a session.
Endpoint: GET /api/v1/chat/sessions/{session_id}/history
Authentication: Required (must own the session)
Query Parameters:
page(integer, default: 1): Page number for paginationpage_size(integer, default: 50, max: 100): Messages per pagerecent_only(boolean, default: false): Get only recent messageslimit(integer, default: 10, max: 50): Number of recent messages (when recent_only=true)
Response (200 OK):
{
"messages": [
{
"id": "uuid-string",
"role": "user",
"content": "Hello, can you help me with Python?",
"language": "python",
"timestamp": "2023-01-01T00:00:00",
"metadata": {}
},
{
"id": "uuid-string",
"role": "assistant",
"content": "Of course! I'd be happy to help you with Python.",
"language": "python",
"timestamp": "2023-01-01T00:01:00",
"metadata": {
"tokens": 15
}
}
],
"session_id": "uuid-string",
"total_count": 2,
"page": 1,
"page_size": 50,
"total_pages": 1
}
7. Search Chat History
Search messages within a session.
Endpoint: GET /api/v1/chat/sessions/{session_id}/history/search
Authentication: Required (must own the session)
Query Parameters:
q(string, required, min: 3 chars): Search querylimit(integer, default: 20, max: 50): Maximum results
Response (200 OK):
{
"messages": [
{
"id": "uuid-string",
"role": "user",
"content": "How do I use Python lists?",
"language": "python",
"timestamp": "2023-01-01T00:00:00",
"metadata": {}
}
],
"session_id": "uuid-string",
"query": "Python",
"result_count": 1
}
Error Responses:
400 Bad Request: Query too short or missing
8. Get Language Context
Get the current language context for a session.
Endpoint: GET /api/v1/chat/sessions/{session_id}/language
Authentication: Required (must own the session)
Response (200 OK):
{
"session_id": "uuid-string",
"language": "python",
"prompt_template": "You are a helpful Python programming assistant...",
"syntax_highlighting": "python",
"language_info": {
"name": "Python",
"syntax_highlighting": "python",
"file_extensions": [".py", ".pyw"],
"prompt_template": "..."
},
"updated_at": "2023-01-01T00:00:00"
}
9. Update Language Context
Change the programming language for a session.
Endpoint: PUT /api/v1/chat/sessions/{session_id}/language
Authentication: Required (must own the session)
Request Body:
{
"language": "javascript"
}
Response (200 OK):
{
"session_id": "uuid-string",
"language": "javascript",
"prompt_template": "You are a helpful JavaScript programming assistant...",
"syntax_highlighting": "javascript",
"language_info": {
"name": "JavaScript",
"syntax_highlighting": "javascript",
"file_extensions": [".js", ".mjs"],
"prompt_template": "..."
},
"updated_at": "2023-01-01T01:00:00"
}
Error Responses:
400 Bad Request: Unsupported language
10. Health Check
Check the health status of the API and its dependencies.
Endpoint: GET /api/v1/chat/health
Authentication: Not required
Response (200 OK):
{
"status": "healthy",
"timestamp": "2023-01-01T00:00:00",
"services": {
"database": "connected",
"redis": "connected"
}
}
Response (503 Service Unavailable):
{
"status": "unhealthy",
"timestamp": "2023-01-01T00:00:00",
"error": "Database connection failed"
}
Error Responses
All error responses follow a consistent format:
{
"error": "Error type",
"message": "Detailed error message"
}
Common HTTP Status Codes
200 OK: Request successful201 Created: Resource created successfully400 Bad Request: Invalid request data401 Unauthorized: Authentication required403 Forbidden: Access denied404 Not Found: Resource not found410 Gone: Resource expired429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server error503 Service Unavailable: Service temporarily unavailable
Security Considerations
- Authentication: All endpoints require valid authentication
- Authorization: Users can only access their own sessions
- Rate Limiting: Prevents abuse and manages API costs
- Input Validation: All inputs are validated and sanitized
- Error Handling: Errors don't expose sensitive information
Usage Examples
Create a Session and Send Messages
# Create session
curl -X POST http://localhost:5000/api/v1/chat/sessions \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{"language": "python"}'
# Get session info
curl -X GET http://localhost:5000/api/v1/chat/sessions/{session_id} \
-H "X-User-ID: user-123"
# Change language
curl -X PUT http://localhost:5000/api/v1/chat/sessions/{session_id}/language \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{"language": "javascript"}'
# Get chat history
curl -X GET http://localhost:5000/api/v1/chat/sessions/{session_id}/history \
-H "X-User-ID: user-123"
# Delete session
curl -X DELETE http://localhost:5000/api/v1/chat/sessions/{session_id} \
-H "X-User-ID: user-123"
JavaScript/TypeScript Example
const API_BASE = 'http://localhost:5000/api/v1/chat';
const USER_ID = 'user-123';
// Create session
const response = await fetch(`${API_BASE}/sessions`, {
method: 'POST',
headers: {
'X-User-ID': USER_ID,
'Content-Type': 'application/json'
},
body: JSON.stringify({
language: 'python',
metadata: { source: 'web_app' }
})
});
const session = await response.json();
console.log('Created session:', session.session_id);
// Get chat history
const historyResponse = await fetch(
`${API_BASE}/sessions/${session.session_id}/history`,
{
headers: { 'X-User-ID': USER_ID }
}
);
const history = await historyResponse.json();
console.log('Messages:', history.messages);
WebSocket API Documentation
The chat agent also supports real-time communication via WebSocket for interactive chat sessions.
WebSocket Connection
Endpoint: ws://localhost:5000/socket.io/
Authentication: Include user ID in connection query parameters or headers
Connection Example:
const socket = io('http://localhost:5000', {
query: { user_id: 'user-123' },
transports: ['websocket']
});
WebSocket Events
1. Connect Event
Automatically triggered when client connects.
Client sends:
// Connection is automatic, but you can send auth data
socket.emit('authenticate', {
user_id: 'user-123',
session_token: 'optional-token'
});
Server responds:
socket.on('connected', (data) => {
console.log(data);
// {
// "status": "connected",
// "user_id": "user-123",
// "timestamp": "2023-01-01T00:00:00Z"
// }
});
2. Send Message Event
Send a chat message to the assistant.
Client sends:
socket.emit('message', {
session_id: 'session-uuid',
content: 'How do I create a Python list?',
language: 'python',
metadata: {
source: 'web_chat',
timestamp: new Date().toISOString()
}
});
Server responds:
socket.on('message_response', (data) => {
console.log(data);
// {
// "session_id": "session-uuid",
// "message_id": "msg-uuid",
// "content": "To create a Python list, you can use square brackets...",
// "language": "python",
// "timestamp": "2023-01-01T00:01:00Z",
// "metadata": {
// "tokens": 45,
// "response_time": 0.85
// }
// }
});
3. Streaming Response Event
For real-time streaming responses.
Client sends:
socket.emit('message_stream', {
session_id: 'session-uuid',
content: 'Explain Python functions in detail',
language: 'python'
});
Server responds with multiple events:
socket.on('stream_start', (data) => {
// { "session_id": "session-uuid", "message_id": "msg-uuid" }
});
socket.on('stream_chunk', (data) => {
// { "session_id": "session-uuid", "chunk": "A Python function is..." }
});
socket.on('stream_end', (data) => {
// { "session_id": "session-uuid", "complete_response": "..." }
});
4. Language Switch Event
Change the programming language context.
Client sends:
socket.emit('language_switch', {
session_id: 'session-uuid',
language: 'javascript'
});
Server responds:
socket.on('language_switched', (data) => {
// {
// "session_id": "session-uuid",
// "previous_language": "python",
// "new_language": "javascript",
// "timestamp": "2023-01-01T00:02:00Z"
// }
});
5. Typing Indicator Events
Show when user or assistant is typing.
Client sends:
socket.emit('typing_start', {
session_id: 'session-uuid'
});
socket.emit('typing_stop', {
session_id: 'session-uuid'
});
Server responds:
socket.on('assistant_typing', (data) => {
// { "session_id": "session-uuid", "typing": true }
});
socket.on('assistant_typing_stop', (data) => {
// { "session_id": "session-uuid", "typing": false }
});
6. Error Events
Handle various error conditions.
Server sends:
socket.on('error', (data) => {
console.error(data);
// {
// "error": "session_not_found",
// "message": "Session does not exist or has expired",
// "session_id": "session-uuid",
// "timestamp": "2023-01-01T00:03:00Z"
// }
});
Complete WebSocket Example
<!DOCTYPE html>
<html>
<head>
<title>Chat Agent WebSocket Example</title>
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
</head>
<body>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="Type your message...">
<select id="languageSelect">
<option value="python">Python</option>
<option value="javascript">JavaScript</option>
<option value="java">Java</option>
</select>
<button onclick="sendMessage()">Send</button>
<script>
const socket = io('http://localhost:5000', {
query: { user_id: 'demo-user' }
});
let currentSessionId = null;
// Create session first
fetch('/api/v1/chat/sessions', {
method: 'POST',
headers: {
'X-User-ID': 'demo-user',
'Content-Type': 'application/json'
},
body: JSON.stringify({ language: 'python' })
})
.then(response => response.json())
.then(data => {
currentSessionId = data.session_id;
console.log('Session created:', currentSessionId);
});
// Handle connection
socket.on('connected', (data) => {
console.log('Connected to chat agent:', data);
});
// Handle messages
socket.on('message_response', (data) => {
addMessage('Assistant', data.content);
});
// Handle streaming
let streamBuffer = '';
socket.on('stream_chunk', (data) => {
streamBuffer += data.chunk;
updateStreamingMessage(streamBuffer);
});
socket.on('stream_end', (data) => {
addMessage('Assistant', data.complete_response);
streamBuffer = '';
});
// Handle language switches
socket.on('language_switched', (data) => {
console.log('Language switched:', data);
addMessage('System', `Language changed to ${data.new_language}`);
});
// Handle errors
socket.on('error', (data) => {
console.error('Chat error:', data);
addMessage('Error', data.message);
});
function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (message && currentSessionId) {
addMessage('You', message);
socket.emit('message', {
session_id: currentSessionId,
content: message,
language: document.getElementById('languageSelect').value
});
input.value = '';
}
}
function addMessage(sender, content) {
const messages = document.getElementById('messages');
const messageDiv = document.createElement('div');
messageDiv.innerHTML = `<strong>${sender}:</strong> ${content}`;
messages.appendChild(messageDiv);
messages.scrollTop = messages.scrollHeight;
}
// Language switching
document.getElementById('languageSelect').addEventListener('change', (e) => {
if (currentSessionId) {
socket.emit('language_switch', {
session_id: currentSessionId,
language: e.target.value
});
}
});
// Enter key to send message
document.getElementById('messageInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
</script>
</body>
</html>
Advanced Usage Examples
Error Handling and Retry Logic
class ChatAPIClient {
constructor(baseURL, userID) {
this.baseURL = baseURL;
this.userID = userID;
this.maxRetries = 3;
this.retryDelay = 1000; // 1 second
}
async makeRequest(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`;
const config = {
...options,
headers: {
'X-User-ID': this.userID,
'Content-Type': 'application/json',
...options.headers
}
};
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
try {
const response = await fetch(url, config);
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = response.headers.get('Retry-After') || this.retryDelay / 1000;
await this.sleep(retryAfter * 1000);
continue;
}
if (!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${error.message}`);
}
return await response.json();
} catch (error) {
if (attempt === this.maxRetries) {
throw error;
}
console.warn(`Attempt ${attempt} failed, retrying...`, error.message);
await this.sleep(this.retryDelay * attempt);
}
}
}
async createSession(language = 'python') {
return await this.makeRequest('/api/v1/chat/sessions', {
method: 'POST',
body: JSON.stringify({ language })
});
}
async getChatHistory(sessionId, page = 1, pageSize = 50) {
return await this.makeRequest(
`/api/v1/chat/sessions/${sessionId}/history?page=${page}&page_size=${pageSize}`
);
}
async switchLanguage(sessionId, language) {
return await this.makeRequest(`/api/v1/chat/sessions/${sessionId}/language`, {
method: 'PUT',
body: JSON.stringify({ language })
});
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const client = new ChatAPIClient('http://localhost:5000', 'user-123');
try {
const session = await client.createSession('python');
console.log('Session created:', session.session_id);
const history = await client.getChatHistory(session.session_id);
console.log('Chat history:', history.messages);
await client.switchLanguage(session.session_id, 'javascript');
console.log('Language switched to JavaScript');
} catch (error) {
console.error('API operation failed:', error.message);
}
Batch Operations
import asyncio
import aiohttp
import json
class AsyncChatClient:
def __init__(self, base_url, user_id):
self.base_url = base_url
self.user_id = user_id
self.headers = {
'X-User-ID': user_id,
'Content-Type': 'application/json'
}
async def create_multiple_sessions(self, languages):
"""Create multiple sessions concurrently."""
async with aiohttp.ClientSession() as session:
tasks = []
for language in languages:
task = self._create_session(session, language)
tasks.append(task)
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
async def _create_session(self, session, language):
url = f"{self.base_url}/api/v1/chat/sessions"
data = {"language": language}
async with session.post(url, headers=self.headers, json=data) as response:
if response.status == 201:
return await response.json()
else:
error = await response.json()
raise Exception(f"Failed to create {language} session: {error['message']}")
# Usage
async def main():
client = AsyncChatClient('http://localhost:5000', 'batch-user')
languages = ['python', 'javascript', 'java', 'cpp']
sessions = await client.create_multiple_sessions(languages)
for i, session in enumerate(sessions):
if isinstance(session, Exception):
print(f"Failed to create {languages[i]} session: {session}")
else:
print(f"Created {languages[i]} session: {session['session_id']}")
# Run the async function
asyncio.run(main())
Implementation Notes
- The API uses SQLite for testing and PostgreSQL for production
- Redis is used for caching and session management
- Rate limiting uses in-memory storage by default (configure Redis for production)
- All timestamps are in ISO 8601 format (UTC)
- UUIDs are used for all resource identifiers
- The API supports both development (header-based) and production (token-based) authentication
- WebSocket connections are managed using Flask-SocketIO
- Streaming responses use Server-Sent Events (SSE) over WebSocket
- All WebSocket events include session_id for proper message routing
- Error handling includes automatic retry logic for transient failures
- The system supports concurrent operations across multiple sessions