Add Redis support for session storage

- Added Redis as optional session storage backend
- SessionManager automatically detects and uses Redis if available
- Falls back to SQL database storage if Redis is not configured
- Added redis>=4.0.0 to requirements.txt
- Configurable via REDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD environment variables
- Maintains same session timeout and functionality
parent 90d3ef94
......@@ -6,4 +6,5 @@ psutil>=5.8.0
nvidia-ml-py>=12.535.108
flash-attn>=2.0.0
pyinstaller>=5.0.0
PyMySQL>=1.0.0
\ No newline at end of file
PyMySQL>=1.0.0
redis>=4.0.0
\ No newline at end of file
......@@ -18,37 +18,112 @@
Authentication and session management for Video AI.
"""
import os
import time
import secrets
from typing import Optional, Dict, Any
from .database import authenticate_user, validate_api_token, create_persistent_session, get_persistent_session, destroy_persistent_session
# Redis support
try:
import redis
REDIS_AVAILABLE = True
except ImportError:
REDIS_AVAILABLE = False
redis = None
class SessionManager:
"""Session manager using persistent database storage."""
"""Session manager using Redis (if available) or database storage."""
def __init__(self):
self.session_timeout = 3600 # 1 hour
self.redis_client = None
# Try to connect to Redis
if REDIS_AVAILABLE:
try:
redis_host = os.environ.get('REDIS_HOST', 'localhost')
redis_port = int(os.environ.get('REDIS_PORT', '6379'))
redis_db = int(os.environ.get('REDIS_DB', '0'))
redis_password = os.environ.get('REDIS_PASSWORD')
self.redis_client = redis.Redis(
host=redis_host,
port=redis_port,
db=redis_db,
password=redis_password,
decode_responses=True
)
# Test connection
self.redis_client.ping()
print("Redis session storage enabled")
except (redis.ConnectionError, redis.AuthenticationError):
print("Redis not available, falling back to database storage")
self.redis_client = None
def _use_redis(self) -> bool:
"""Check if Redis is available and should be used."""
return self.redis_client is not None
def create_session(self, user: Dict[str, Any]) -> str:
"""Create a new persistent session for user."""
return create_persistent_session(user['id'])
"""Create a new session for user."""
if self._use_redis():
return self._create_redis_session(user)
else:
return create_persistent_session(user['id'])
def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
"""Get session data from database."""
return get_persistent_session(session_id)
"""Get session data."""
if self._use_redis():
return self._get_redis_session(session_id)
else:
return get_persistent_session(session_id)
def destroy_session(self, session_id: str) -> None:
"""Destroy persistent session."""
destroy_persistent_session(session_id)
"""Destroy session."""
if self._use_redis():
self._destroy_redis_session(session_id)
else:
destroy_persistent_session(session_id)
def get_user_from_session(self, session_id: str) -> Optional[Dict[str, Any]]:
"""Get user from persistent session."""
"""Get user from session."""
session = self.get_session(session_id)
if session:
return session['user']
return None
# Redis-specific methods
def _create_redis_session(self, user: Dict[str, Any]) -> str:
"""Create a session in Redis."""
import json
session_id = secrets.token_hex(32)
session_data = {
'user': user,
'created_at': time.time()
}
self.redis_client.setex(f"session:{session_id}", self.session_timeout, json.dumps(session_data))
return session_id
def _get_redis_session(self, session_id: str) -> Optional[Dict[str, Any]]:
"""Get session from Redis."""
import json
session_data = self.redis_client.get(f"session:{session_id}")
if session_data:
try:
data = json.loads(session_data)
# Check if session is still valid (extend if accessed)
self.redis_client.expire(f"session:{session_id}", self.session_timeout)
return data
except json.JSONDecodeError:
return None
return None
def _destroy_redis_session(self, session_id: str) -> None:
"""Destroy session in Redis."""
self.redis_client.delete(f"session:{session_id}")
# Global session manager instance
session_manager = SessionManager()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment