| """ |
| Session Manager for ChatCal Voice - Handles user sessions in Gradio environment. |
| |
| Since we're on Hugging Face without persistent storage, we'll use in-memory |
| session management with automatic cleanup. |
| """ |
|
|
| import time |
| import uuid |
| from typing import Dict, List, Any, Optional |
| from datetime import datetime, timedelta |
|
|
| from .session import SessionData |
| from .config import config |
|
|
|
|
| class SessionManager: |
| """Manages user sessions for the voice-enabled ChatCal.""" |
| |
| def __init__(self): |
| self.sessions: Dict[str, SessionData] = {} |
| self.last_cleanup = time.time() |
| self.cleanup_interval = 300 |
| |
| async def get_session(self, session_id: Optional[str] = None) -> SessionData: |
| """Get or create a session.""" |
| |
| await self._cleanup_expired_sessions() |
| |
| |
| if not session_id: |
| session_id = self._generate_session_id() |
| |
| |
| if session_id in self.sessions: |
| session = self.sessions[session_id] |
| session.last_activity = datetime.now() |
| return session |
| |
| |
| session = SessionData(session_id=session_id) |
| self.sessions[session_id] = session |
| return session |
| |
| def _generate_session_id(self) -> str: |
| """Generate a unique session ID.""" |
| timestamp = int(time.time()) |
| unique_id = str(uuid.uuid4())[:8] |
| return f"chatcal_{timestamp}_{unique_id}" |
| |
| async def _cleanup_expired_sessions(self): |
| """Clean up expired sessions.""" |
| current_time = time.time() |
| |
| |
| if current_time - self.last_cleanup < self.cleanup_interval: |
| return |
| |
| cutoff_time = datetime.now() - timedelta(minutes=config.session_timeout_minutes) |
| expired_sessions = [ |
| session_id for session_id, session in self.sessions.items() |
| if session.last_activity < cutoff_time |
| ] |
| |
| for session_id in expired_sessions: |
| del self.sessions[session_id] |
| |
| if expired_sessions: |
| print(f"🧹 Cleaned up {len(expired_sessions)} expired sessions") |
| |
| self.last_cleanup = current_time |
| |
| async def delete_session(self, session_id: str): |
| """Delete a specific session.""" |
| if session_id in self.sessions: |
| del self.sessions[session_id] |
| |
| def get_session_count(self) -> int: |
| """Get the number of active sessions.""" |
| return len(self.sessions) |
| |
| def get_session_stats(self) -> Dict[str, Any]: |
| """Get session statistics.""" |
| return { |
| "active_sessions": len(self.sessions), |
| "total_messages": sum(len(s.conversation_history) for s in self.sessions.values()), |
| "sessions_with_user_info": sum( |
| 1 for s in self.sessions.values() |
| if s.user_info.get("name") or s.user_info.get("email") |
| ) |
| } |
|
|
|
|
| |
| session_manager = SessionManager() |