scratch_chat / examples /chat_service_client.py
WebashalarForML's picture
Upload 178 files
330b6e4 verified
#!/usr/bin/env python3
"""
Chat Service Client - For integrating with external applications.
This client provides a simple interface for external applications to use
the multi-language chat agent as a service.
"""
import requests
import json
import time
from typing import Dict, List, Optional, Any
from datetime import datetime
class ChatServiceClient:
"""
Client for interacting with the Chat Agent Service.
This client handles session management, message processing, and
maintains conversation context for external applications.
"""
def __init__(self, base_url: str = "http://localhost:5000",
app_name: str = "ExternalApp", timeout: int = 30):
"""
Initialize the chat service client.
Args:
base_url: Base URL of the chat service
app_name: Name of your application (for tracking)
timeout: Request timeout in seconds
"""
self.base_url = base_url.rstrip('/')
self.app_name = app_name
self.timeout = timeout
self.api_base = f"{self.base_url}/api/v1/chat"
# Session cache for the client
self._sessions = {}
def create_session(self, user_id: str, language: str = "python",
metadata: Optional[Dict] = None) -> Dict[str, Any]:
"""
Create a new chat session for a user.
Args:
user_id: Unique identifier for the user in your app
language: Programming language context
metadata: Additional metadata about the session
Returns:
Dict containing session information
Raises:
Exception: If session creation fails
"""
url = f"{self.api_base}/sessions"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
payload = {
"language": language,
"metadata": {
"source": self.app_name,
"created_by": "chat_service_client",
**(metadata or {})
}
}
try:
response = requests.post(url, headers=headers, json=payload, timeout=self.timeout)
response.raise_for_status()
session_data = response.json()
# Cache session locally
self._sessions[session_data['session_id']] = {
'user_id': user_id,
'language': language,
'created_at': session_data['created_at'],
'message_count': session_data['message_count']
}
return session_data
except requests.exceptions.RequestException as e:
raise Exception(f"Failed to create session: {e}")
def send_message(self, session_id: str, message: str,
language: Optional[str] = None) -> Dict[str, Any]:
"""
Send a message to the chat agent.
Args:
session_id: Session identifier
message: User's message
language: Optional language override
Returns:
Dict containing the response and metadata
Raises:
Exception: If message processing fails
"""
# Get session info for user_id
if session_id not in self._sessions:
# Try to get session info from API
session_info = self.get_session(session_id)
if not session_info:
raise Exception(f"Session {session_id} not found")
user_id = self._sessions[session_id]['user_id']
url = f"{self.api_base}/sessions/{session_id}/message"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
payload = {
"content": message,
"timestamp": datetime.utcnow().isoformat()
}
if language:
payload["language"] = language
try:
response = requests.post(url, headers=headers, json=payload, timeout=self.timeout)
response.raise_for_status()
result = response.json()
# Update local session cache
if session_id in self._sessions:
self._sessions[session_id]['message_count'] += 1
return result
except requests.exceptions.RequestException as e:
raise Exception(f"Failed to send message: {e}")
def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
"""
Get session information.
Args:
session_id: Session identifier
Returns:
Dict containing session information or None if not found
"""
if session_id in self._sessions:
user_id = self._sessions[session_id]['user_id']
else:
# We need user_id to make the request, but we don't have it
# This is a limitation - in practice, you'd store user_id with session_id
return None
url = f"{self.api_base}/sessions/{session_id}"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
try:
response = requests.get(url, headers=headers, timeout=self.timeout)
if response.status_code == 404:
return None
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException:
return None
def get_chat_history(self, session_id: str, limit: int = 50) -> List[Dict[str, Any]]:
"""
Get chat history for a session.
Args:
session_id: Session identifier
limit: Maximum number of messages to retrieve
Returns:
List of messages
"""
if session_id not in self._sessions:
raise Exception(f"Session {session_id} not found in cache")
user_id = self._sessions[session_id]['user_id']
url = f"{self.api_base}/sessions/{session_id}/history"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
params = {
"recent_only": "true",
"limit": limit
}
try:
response = requests.get(url, headers=headers, params=params, timeout=self.timeout)
response.raise_for_status()
result = response.json()
return result.get('messages', [])
except requests.exceptions.RequestException as e:
raise Exception(f"Failed to get chat history: {e}")
def switch_language(self, session_id: str, language: str) -> Dict[str, Any]:
"""
Switch the programming language context for a session.
Args:
session_id: Session identifier
language: New programming language
Returns:
Dict containing switch confirmation
"""
if session_id not in self._sessions:
raise Exception(f"Session {session_id} not found in cache")
user_id = self._sessions[session_id]['user_id']
url = f"{self.api_base}/sessions/{session_id}/language"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
payload = {
"language": language
}
try:
response = requests.put(url, headers=headers, json=payload, timeout=self.timeout)
response.raise_for_status()
result = response.json()
# Update local cache
if session_id in self._sessions:
self._sessions[session_id]['language'] = language
return result
except requests.exceptions.RequestException as e:
raise Exception(f"Failed to switch language: {e}")
def delete_session(self, session_id: str) -> bool:
"""
Delete a chat session.
Args:
session_id: Session identifier
Returns:
True if successful, False otherwise
"""
if session_id not in self._sessions:
return False
user_id = self._sessions[session_id]['user_id']
url = f"{self.api_base}/sessions/{session_id}"
headers = {
"X-User-ID": user_id,
"Content-Type": "application/json"
}
try:
response = requests.delete(url, headers=headers, timeout=self.timeout)
response.raise_for_status()
# Remove from local cache
if session_id in self._sessions:
del self._sessions[session_id]
return True
except requests.exceptions.RequestException:
return False
def health_check(self) -> Dict[str, Any]:
"""
Check if the chat service is healthy.
Returns:
Dict containing health status
"""
url = f"{self.api_base}/health"
try:
response = requests.get(url, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {"status": "unhealthy", "error": str(e)}
# Convenience class for managing multiple user sessions
class MultiUserChatManager:
"""
Manager for handling multiple user sessions in an external application.
This class provides a higher-level interface for managing chat sessions
across multiple users in your application.
"""
def __init__(self, chat_service_url: str = "http://localhost:5000",
app_name: str = "ExternalApp"):
"""
Initialize the multi-user chat manager.
Args:
chat_service_url: URL of the chat service
app_name: Name of your application
"""
self.client = ChatServiceClient(chat_service_url, app_name)
self.user_sessions = {} # user_id -> session_id mapping
def start_chat_for_user(self, user_id: str, language: str = "python",
user_metadata: Optional[Dict] = None) -> str:
"""
Start a new chat session for a user.
Args:
user_id: Unique user identifier in your app
language: Programming language context
user_metadata: Additional user metadata
Returns:
Session ID for the created session
"""
# End existing session if any
if user_id in self.user_sessions:
self.end_chat_for_user(user_id)
# Create new session
session_data = self.client.create_session(user_id, language, user_metadata)
session_id = session_data['session_id']
# Store mapping
self.user_sessions[user_id] = session_id
return session_id
def send_user_message(self, user_id: str, message: str,
language: Optional[str] = None) -> Dict[str, Any]:
"""
Send a message for a specific user.
Args:
user_id: User identifier
message: User's message
language: Optional language override
Returns:
Response from the chat agent
"""
if user_id not in self.user_sessions:
raise Exception(f"No active session for user {user_id}")
session_id = self.user_sessions[user_id]
return self.client.send_message(session_id, message, language)
def get_user_history(self, user_id: str, limit: int = 50) -> List[Dict[str, Any]]:
"""
Get chat history for a specific user.
Args:
user_id: User identifier
limit: Maximum number of messages
Returns:
List of messages
"""
if user_id not in self.user_sessions:
return []
session_id = self.user_sessions[user_id]
return self.client.get_chat_history(session_id, limit)
def switch_user_language(self, user_id: str, language: str) -> Dict[str, Any]:
"""
Switch programming language for a user's session.
Args:
user_id: User identifier
language: New programming language
Returns:
Switch confirmation
"""
if user_id not in self.user_sessions:
raise Exception(f"No active session for user {user_id}")
session_id = self.user_sessions[user_id]
return self.client.switch_language(session_id, language)
def end_chat_for_user(self, user_id: str) -> bool:
"""
End chat session for a specific user.
Args:
user_id: User identifier
Returns:
True if successful
"""
if user_id not in self.user_sessions:
return True
session_id = self.user_sessions[user_id]
success = self.client.delete_session(session_id)
if success:
del self.user_sessions[user_id]
return success
def get_active_users(self) -> List[str]:
"""
Get list of users with active chat sessions.
Returns:
List of user IDs
"""
return list(self.user_sessions.keys())
if __name__ == "__main__":
# Example usage
print("🧪 Testing Chat Service Client")
# Initialize client
client = ChatServiceClient("http://localhost:5000", "TestApp")
# Check service health
health = client.health_check()
print(f"Service health: {health}")
if health.get('status') == 'healthy':
# Create session
session = client.create_session("test-user-123", "python")
print(f"Created session: {session['session_id']}")
# Send message
response = client.send_message(session['session_id'], "What is Python?")
print(f"Response: {response['response'][:100]}...")
# Switch language
switch_result = client.switch_language(session['session_id'], "javascript")
print(f"Language switched: {switch_result}")
# Send another message
response2 = client.send_message(session['session_id'], "What is JavaScript?")
print(f"JS Response: {response2['response'][:100]}...")
# Get history
history = client.get_chat_history(session['session_id'])
print(f"History length: {len(history)} messages")
# Clean up
client.delete_session(session['session_id'])
print("Session deleted")
else:
print("❌ Chat service is not healthy")