WebashalarForML's picture
Upload 178 files
330b6e4 verified

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 fields
  • 401 Unauthorized: Missing or invalid authentication
  • 429 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 user
  • 404 Not Found: Session does not exist
  • 410 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 user
  • 404 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 pagination
  • page_size (integer, default: 50, max: 100): Messages per page
  • recent_only (boolean, default: false): Get only recent messages
  • limit (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 query
  • limit (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 successful
  • 201 Created: Resource created successfully
  • 400 Bad Request: Invalid request data
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Access denied
  • 404 Not Found: Resource not found
  • 410 Gone: Resource expired
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Internal Server Error: Server error
  • 503 Service Unavailable: Service temporarily unavailable

Security Considerations

  1. Authentication: All endpoints require valid authentication
  2. Authorization: Users can only access their own sessions
  3. Rate Limiting: Prevents abuse and manages API costs
  4. Input Validation: All inputs are validated and sanitized
  5. 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