Fix runtime imports
This commit is contained in:
parent
b5d2605d99
commit
66c2d2e524
@ -13,9 +13,22 @@ import threading
|
|||||||
from typing import Dict, Optional, Tuple
|
from typing import Dict, Optional, Tuple
|
||||||
|
|
||||||
# Import shared models
|
# Import shared models
|
||||||
import sys
|
try:
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
# Try relative import first (when running as part of the package)
|
||||||
from shared.models import NamePasswordRecord
|
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
|
from logger import logger
|
||||||
|
|
||||||
@ -150,10 +163,14 @@ class AuthManager:
|
|||||||
|
|
||||||
def validate_integrity(self) -> list[str]:
|
def validate_integrity(self) -> list[str]:
|
||||||
"""Validate auth data integrity and return list of issues"""
|
"""Validate auth data integrity and return list of issues"""
|
||||||
issues : list[str] = []
|
issues = []
|
||||||
|
|
||||||
with self.lock:
|
with self.lock:
|
||||||
for name, record in self.name_passwords.items():
|
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:
|
if "salt" not in record or "hash" not in record:
|
||||||
issues.append(f"Name '{name}' missing salt or hash")
|
issues.append(f"Name '{name}' missing salt or hash")
|
||||||
continue
|
continue
|
||||||
|
@ -12,19 +12,38 @@ import threading
|
|||||||
from typing import Dict, List, Optional, TYPE_CHECKING
|
from typing import Dict, List, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
# Import shared models
|
# Import shared models
|
||||||
import sys
|
# Import shared models
|
||||||
import os
|
try:
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
# Try relative import first (when running as part of the package)
|
||||||
from shared.models import ChatMessageModel, ParticipantModel
|
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
|
from logger import logger
|
||||||
|
|
||||||
# Use try/except for importing events to handle both relative and absolute imports
|
# Use try/except for importing events to handle both relative and absolute imports
|
||||||
try:
|
try:
|
||||||
from ..models.events import event_bus, ChatMessageSent
|
from ..models.events import event_bus, ChatMessageSent, SessionDisconnected, SessionLeftLobby
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from models.events import event_bus, ChatMessageSent
|
from models.events import event_bus, ChatMessageSent, SessionDisconnected, SessionLeftLobby
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Create dummy event system for standalone testing
|
# Create dummy event system for standalone testing
|
||||||
class DummyEventBus:
|
class DummyEventBus:
|
||||||
@ -34,6 +53,12 @@ except ImportError:
|
|||||||
|
|
||||||
class ChatMessageSent:
|
class ChatMessageSent:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class SessionDisconnected:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SessionLeftLobby:
|
||||||
|
pass
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .session_manager import Session
|
from .session_manager import Session
|
||||||
@ -225,12 +250,10 @@ class LobbyManager:
|
|||||||
|
|
||||||
# Subscribe to session events - handle import errors gracefully
|
# Subscribe to session events - handle import errors gracefully
|
||||||
try:
|
try:
|
||||||
from ..models.events import SessionDisconnected, SessionLeftLobby
|
|
||||||
event_bus.subscribe(SessionDisconnected, self)
|
event_bus.subscribe(SessionDisconnected, self)
|
||||||
event_bus.subscribe(SessionLeftLobby, self)
|
event_bus.subscribe(SessionLeftLobby, self)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from models.events import SessionDisconnected, SessionLeftLobby
|
|
||||||
event_bus.subscribe(SessionDisconnected, self)
|
event_bus.subscribe(SessionDisconnected, self)
|
||||||
event_bus.subscribe(SessionLeftLobby, self)
|
event_bus.subscribe(SessionLeftLobby, self)
|
||||||
except (ImportError, AttributeError):
|
except (ImportError, AttributeError):
|
||||||
@ -239,7 +262,6 @@ class LobbyManager:
|
|||||||
|
|
||||||
async def handle(self, event):
|
async def handle(self, event):
|
||||||
"""Handle events from the event bus"""
|
"""Handle events from the event bus"""
|
||||||
from ..models.events import SessionDisconnected, SessionLeftLobby
|
|
||||||
|
|
||||||
if isinstance(event, SessionDisconnected):
|
if isinstance(event, SessionDisconnected):
|
||||||
await self._handle_session_disconnected(event)
|
await self._handle_session_disconnected(event)
|
||||||
|
@ -2,7 +2,17 @@
|
|||||||
Session management for the AI Voice Bot server.
|
Session management for the AI Voice Bot server.
|
||||||
|
|
||||||
This module handles session lifecycle, persistence, and cleanup operations.
|
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
|
from __future__ import annotations
|
||||||
@ -17,24 +27,53 @@ from fastapi import WebSocket
|
|||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
|
|
||||||
# Import shared models
|
# Import shared models
|
||||||
import sys
|
try:
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
# Try relative import first (when running as part of the package)
|
||||||
from shared.models import SessionSaved, LobbySaved, SessionsPayload, NamePasswordRecord
|
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
|
from logger import logger
|
||||||
|
|
||||||
# Use try/except for importing events to handle both relative and absolute imports
|
# Use try/except for importing events to handle both relative and absolute imports
|
||||||
try:
|
try:
|
||||||
from ..models.events import event_bus, SessionDisconnected
|
from ..models.events import event_bus, SessionDisconnected, UserNameChanged, SessionJoinedLobby, SessionLeftLobby
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from models.events import event_bus, SessionDisconnected
|
from models.events import event_bus, SessionDisconnected, UserNameChanged, SessionJoinedLobby, SessionLeftLobby
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# Create dummy event system for standalone testing
|
# Create dummy event system for standalone testing
|
||||||
class DummyEventBus:
|
class DummyEventBus:
|
||||||
async def publish(self, event): pass
|
async def publish(self, event): pass
|
||||||
event_bus = DummyEventBus()
|
event_bus = DummyEventBus()
|
||||||
class SessionDisconnected: pass
|
class SessionDisconnected: pass
|
||||||
|
class UserNameChanged: pass
|
||||||
|
class SessionJoinedLobby: pass
|
||||||
|
class SessionLeftLobby: pass
|
||||||
|
|
||||||
|
|
||||||
class SessionConfig:
|
class SessionConfig:
|
||||||
@ -91,7 +130,6 @@ class Session:
|
|||||||
lobby_ids = [lobby.id for lobby in self.lobbies]
|
lobby_ids = [lobby.id for lobby in self.lobbies]
|
||||||
|
|
||||||
# Publish name change event (don't await here to avoid blocking)
|
# Publish name change event (don't await here to avoid blocking)
|
||||||
from ..models.events import UserNameChanged
|
|
||||||
asyncio.create_task(event_bus.publish(UserNameChanged(
|
asyncio.create_task(event_bus.publish(UserNameChanged(
|
||||||
session_id=self.id,
|
session_id=self.id,
|
||||||
old_name=old_name,
|
old_name=old_name,
|
||||||
@ -118,7 +156,6 @@ class Session:
|
|||||||
await lobby.addSession(self)
|
await lobby.addSession(self)
|
||||||
|
|
||||||
# Publish join event
|
# Publish join event
|
||||||
from ..models.events import SessionJoinedLobby
|
|
||||||
await event_bus.publish(SessionJoinedLobby(
|
await event_bus.publish(SessionJoinedLobby(
|
||||||
session_id=self.id,
|
session_id=self.id,
|
||||||
lobby_id=lobby.id,
|
lobby_id=lobby.id,
|
||||||
@ -136,7 +173,6 @@ class Session:
|
|||||||
await lobby.removeSession(self)
|
await lobby.removeSession(self)
|
||||||
|
|
||||||
# Publish leave event
|
# Publish leave event
|
||||||
from ..models.events import SessionLeftLobby
|
|
||||||
await event_bus.publish(SessionLeftLobby(
|
await event_bus.publish(SessionLeftLobby(
|
||||||
session_id=self.id,
|
session_id=self.id,
|
||||||
lobby_id=lobby.id,
|
lobby_id=lobby.id,
|
||||||
|
@ -11,9 +11,16 @@ from logger import logger
|
|||||||
from .message_handlers import MessageRouter
|
from .message_handlers import MessageRouter
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..core.session_manager import Session, SessionManager
|
# Use absolute imports to avoid relative import issues
|
||||||
from ..core.lobby_manager import Lobby, LobbyManager
|
try:
|
||||||
from ..core.auth_manager import AuthManager
|
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:
|
class WebSocketConnectionManager:
|
||||||
|
@ -290,7 +290,9 @@ class MessageRouter:
|
|||||||
try:
|
try:
|
||||||
await self._handlers[message_type].handle(session, lobby, data, websocket, managers)
|
await self._handlers[message_type].handle(session, lobby, data, websocket, managers)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
logger.error(f"Error handling message type {message_type}: {e}")
|
logger.error(f"Error handling message type {message_type}: {e}")
|
||||||
|
logger.error(f"Full traceback: {traceback.format_exc()}")
|
||||||
await websocket.send_json({
|
await websocket.send_json({
|
||||||
"type": "error",
|
"type": "error",
|
||||||
"data": {"error": f"Internal error handling {message_type}"}
|
"data": {"error": f"Internal error handling {message_type}"}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user