Fix runtime imports

This commit is contained in:
James Ketr 2025-09-04 16:23:42 -07:00
parent b5d2605d99
commit 66c2d2e524
5 changed files with 110 additions and 26 deletions

View File

@ -13,9 +13,22 @@ import threading
from typing import Dict, Optional, Tuple
# Import shared models
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import NamePasswordRecord
try:
# Try relative import first (when running as part of the package)
from ...shared.models import NamePasswordRecord
except ImportError:
try:
# Try absolute import (when running directly)
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import NamePasswordRecord
except ImportError:
# Fallback: create minimal model for testing
from pydantic import BaseModel
class NamePasswordRecord(BaseModel):
name: str
password: str
from logger import logger
@ -150,10 +163,14 @@ class AuthManager:
def validate_integrity(self) -> list[str]:
"""Validate auth data integrity and return list of issues"""
issues : list[str] = []
issues = []
with self.lock:
for name, record in self.name_passwords.items():
if not isinstance(record, dict):
issues.append(f"Name '{name}' has invalid record type: {type(record)}")
continue
if "salt" not in record or "hash" not in record:
issues.append(f"Name '{name}' missing salt or hash")
continue

View File

@ -12,19 +12,38 @@ import threading
from typing import Dict, List, Optional, TYPE_CHECKING
# Import shared models
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import ChatMessageModel, ParticipantModel
# Import shared models
try:
# Try relative import first (when running as part of the package)
from ...shared.models import ChatMessageModel, ParticipantModel
except ImportError:
try:
# Try absolute import (when running directly)
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import ChatMessageModel, ParticipantModel
except ImportError:
# Fallback: create minimal models for testing
from pydantic import BaseModel
from typing import Optional
class ChatMessageModel(BaseModel):
id: str
author: str
message: str
timestamp: float
class ParticipantModel(BaseModel):
id: str
name: str
from logger import logger
# Use try/except for importing events to handle both relative and absolute imports
try:
from ..models.events import event_bus, ChatMessageSent
from ..models.events import event_bus, ChatMessageSent, SessionDisconnected, SessionLeftLobby
except ImportError:
try:
from models.events import event_bus, ChatMessageSent
from models.events import event_bus, ChatMessageSent, SessionDisconnected, SessionLeftLobby
except ImportError:
# Create dummy event system for standalone testing
class DummyEventBus:
@ -35,6 +54,12 @@ except ImportError:
class ChatMessageSent:
pass
class SessionDisconnected:
pass
class SessionLeftLobby:
pass
if TYPE_CHECKING:
from .session_manager import Session
@ -225,12 +250,10 @@ class LobbyManager:
# Subscribe to session events - handle import errors gracefully
try:
from ..models.events import SessionDisconnected, SessionLeftLobby
event_bus.subscribe(SessionDisconnected, self)
event_bus.subscribe(SessionLeftLobby, self)
except ImportError:
try:
from models.events import SessionDisconnected, SessionLeftLobby
event_bus.subscribe(SessionDisconnected, self)
event_bus.subscribe(SessionLeftLobby, self)
except (ImportError, AttributeError):
@ -239,7 +262,6 @@ class LobbyManager:
async def handle(self, event):
"""Handle events from the event bus"""
from ..models.events import SessionDisconnected, SessionLeftLobby
if isinstance(event, SessionDisconnected):
await self._handle_session_disconnected(event)

View File

@ -2,7 +2,17 @@
Session management for the AI Voice Bot server.
This module handles session lifecycle, persistence, and cleanup operations.
Extracted from main.py to improve maintainability and separation of concerns.
Extracted from m await lobby.add await lobby.removeSession(self)
# Publish event
await event_bus.publish(SessionLeftLobby(
session_id=self.id,
lobby_id=lobby.id,(self)
# Publish event
await event_bus.publish(SessionJoinedLobby(
session_id=self.id,
lobby_id=lobby.id,to improve maintainability and separation of concerns.
"""
from __future__ import annotations
@ -17,24 +27,53 @@ from fastapi import WebSocket
from pydantic import ValidationError
# Import shared models
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import SessionSaved, LobbySaved, SessionsPayload, NamePasswordRecord
try:
# Try relative import first (when running as part of the package)
from ...shared.models import SessionSaved, LobbySaved, SessionsPayload, NamePasswordRecord
except ImportError:
try:
# Try absolute import (when running directly)
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from shared.models import SessionSaved, LobbySaved, SessionsPayload, NamePasswordRecord
except ImportError:
# Fallback: create minimal models for testing
from pydantic import BaseModel
class SessionSaved(BaseModel):
id: str
name: str = ""
protected: bool = False
is_bot: bool = False
has_media: bool = True
bot_run_id: Optional[str] = None
lobbies: List[str] = []
class LobbySaved(BaseModel):
name: str
private: bool = False
class SessionsPayload(BaseModel):
sessions: List[SessionSaved]
class NamePasswordRecord(BaseModel):
name: str
password: str
from logger import logger
# Use try/except for importing events to handle both relative and absolute imports
try:
from ..models.events import event_bus, SessionDisconnected
from ..models.events import event_bus, SessionDisconnected, UserNameChanged, SessionJoinedLobby, SessionLeftLobby
except ImportError:
try:
from models.events import event_bus, SessionDisconnected
from models.events import event_bus, SessionDisconnected, UserNameChanged, SessionJoinedLobby, SessionLeftLobby
except ImportError:
# Create dummy event system for standalone testing
class DummyEventBus:
async def publish(self, event): pass
event_bus = DummyEventBus()
class SessionDisconnected: pass
class UserNameChanged: pass
class SessionJoinedLobby: pass
class SessionLeftLobby: pass
class SessionConfig:
@ -91,7 +130,6 @@ class Session:
lobby_ids = [lobby.id for lobby in self.lobbies]
# Publish name change event (don't await here to avoid blocking)
from ..models.events import UserNameChanged
asyncio.create_task(event_bus.publish(UserNameChanged(
session_id=self.id,
old_name=old_name,
@ -118,7 +156,6 @@ class Session:
await lobby.addSession(self)
# Publish join event
from ..models.events import SessionJoinedLobby
await event_bus.publish(SessionJoinedLobby(
session_id=self.id,
lobby_id=lobby.id,
@ -136,7 +173,6 @@ class Session:
await lobby.removeSession(self)
# Publish leave event
from ..models.events import SessionLeftLobby
await event_bus.publish(SessionLeftLobby(
session_id=self.id,
lobby_id=lobby.id,

View File

@ -11,9 +11,16 @@ from logger import logger
from .message_handlers import MessageRouter
if TYPE_CHECKING:
from ..core.session_manager import Session, SessionManager
from ..core.lobby_manager import Lobby, LobbyManager
from ..core.auth_manager import AuthManager
# Use absolute imports to avoid relative import issues
try:
from core.session_manager import Session, SessionManager
from core.lobby_manager import Lobby, LobbyManager
from core.auth_manager import AuthManager
except ImportError:
# Fallback for when running from different directory structure
from ..core.session_manager import Session, SessionManager
from ..core.lobby_manager import Lobby, LobbyManager
from ..core.auth_manager import AuthManager
class WebSocketConnectionManager:

View File

@ -290,7 +290,9 @@ class MessageRouter:
try:
await self._handlers[message_type].handle(session, lobby, data, websocket, managers)
except Exception as e:
import traceback
logger.error(f"Error handling message type {message_type}: {e}")
logger.error(f"Full traceback: {traceback.format_exc()}")
await websocket.send_json({
"type": "error",
"data": {"error": f"Internal error handling {message_type}"}