mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2026-03-18 11:16:30 +01:00
318 lines
7.7 KiB
Python
318 lines
7.7 KiB
Python
"""Service interfaces using Protocol for structural typing.
|
|
|
|
Defines contracts for different types of services without requiring inheritance.
|
|
Use these for type hints and dependency injection.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Protocol, Any, Dict, List, Optional, TypeVar, runtime_checkable
|
|
import pandas as pd
|
|
|
|
|
|
T = TypeVar("T")
|
|
K = TypeVar("K")
|
|
V = TypeVar("V")
|
|
|
|
|
|
@runtime_checkable
|
|
class SessionService(Protocol):
|
|
"""Interface for session management services."""
|
|
|
|
def new_session_id(self) -> str:
|
|
"""Create a new session ID.
|
|
|
|
Returns:
|
|
Unique session identifier
|
|
"""
|
|
...
|
|
|
|
def get_session(self, session_id: Optional[str]) -> Dict[str, Any]:
|
|
"""Get or create session state.
|
|
|
|
Args:
|
|
session_id: Session identifier (creates new if None)
|
|
|
|
Returns:
|
|
Session state dictionary
|
|
"""
|
|
...
|
|
|
|
def set_value(self, session_id: str, key: str, value: Any) -> None:
|
|
"""Set a value in session state.
|
|
|
|
Args:
|
|
session_id: Session identifier
|
|
key: State key
|
|
value: Value to store
|
|
"""
|
|
...
|
|
|
|
def get_value(self, session_id: str, key: str, default: Any = None) -> Any:
|
|
"""Get a value from session state.
|
|
|
|
Args:
|
|
session_id: Session identifier
|
|
key: State key
|
|
default: Default value if key not found
|
|
|
|
Returns:
|
|
Stored value or default
|
|
"""
|
|
...
|
|
|
|
def cleanup_expired(self) -> int:
|
|
"""Clean up expired sessions.
|
|
|
|
Returns:
|
|
Number of sessions cleaned up
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class CardLoaderService(Protocol):
|
|
"""Interface for card data loading services."""
|
|
|
|
def get_cards(self, force_reload: bool = False) -> pd.DataFrame:
|
|
"""Get card data.
|
|
|
|
Args:
|
|
force_reload: Force reload from source
|
|
|
|
Returns:
|
|
DataFrame with card data
|
|
"""
|
|
...
|
|
|
|
def is_loaded(self) -> bool:
|
|
"""Check if card data is loaded.
|
|
|
|
Returns:
|
|
True if data is loaded
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class CatalogService(Protocol):
|
|
"""Interface for catalog services (commanders, themes, etc.)."""
|
|
|
|
def get_catalog(self, force_reload: bool = False) -> pd.DataFrame:
|
|
"""Get catalog data.
|
|
|
|
Args:
|
|
force_reload: Force reload from source
|
|
|
|
Returns:
|
|
DataFrame with catalog data
|
|
"""
|
|
...
|
|
|
|
def search(self, query: str, **filters: Any) -> pd.DataFrame:
|
|
"""Search catalog with filters.
|
|
|
|
Args:
|
|
query: Search query string
|
|
**filters: Additional filters
|
|
|
|
Returns:
|
|
Filtered DataFrame
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class OwnedCardsService(Protocol):
|
|
"""Interface for owned cards management."""
|
|
|
|
def get_owned_names(self) -> List[str]:
|
|
"""Get list of owned card names.
|
|
|
|
Returns:
|
|
List of card names
|
|
"""
|
|
...
|
|
|
|
def add_owned_names(self, names: List[str]) -> None:
|
|
"""Add card names to owned list.
|
|
|
|
Args:
|
|
names: Card names to add
|
|
"""
|
|
...
|
|
|
|
def remove_owned_name(self, name: str) -> bool:
|
|
"""Remove a card name from owned list.
|
|
|
|
Args:
|
|
name: Card name to remove
|
|
|
|
Returns:
|
|
True if removed, False if not found
|
|
"""
|
|
...
|
|
|
|
def clear_owned(self) -> None:
|
|
"""Clear all owned cards."""
|
|
...
|
|
|
|
def import_from_file(self, file_content: str, format_type: str) -> int:
|
|
"""Import owned cards from file content.
|
|
|
|
Args:
|
|
file_content: File content to parse
|
|
format_type: Format type (csv, txt, etc.)
|
|
|
|
Returns:
|
|
Number of cards imported
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class CacheService(Protocol[K, V]):
|
|
"""Interface for caching services."""
|
|
|
|
def get(self, key: K, default: Optional[V] = None) -> Optional[V]:
|
|
"""Get cached value.
|
|
|
|
Args:
|
|
key: Cache key
|
|
default: Default value if not found
|
|
|
|
Returns:
|
|
Cached value or default
|
|
"""
|
|
...
|
|
|
|
def set(self, key: K, value: V, ttl: Optional[int] = None) -> None:
|
|
"""Set cached value.
|
|
|
|
Args:
|
|
key: Cache key
|
|
value: Value to cache
|
|
ttl: Time-to-live in seconds (None = no expiration)
|
|
"""
|
|
...
|
|
|
|
def invalidate(self, key: Optional[K] = None) -> None:
|
|
"""Invalidate cache entry or entire cache.
|
|
|
|
Args:
|
|
key: Cache key (None = invalidate all)
|
|
"""
|
|
...
|
|
|
|
def cleanup_expired(self) -> int:
|
|
"""Remove expired cache entries.
|
|
|
|
Returns:
|
|
Number of entries removed
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class BuildOrchestratorService(Protocol):
|
|
"""Interface for deck build orchestration."""
|
|
|
|
def orchestrate_build(
|
|
self,
|
|
session_id: str,
|
|
commander_name: str,
|
|
theme_tags: List[str],
|
|
**options: Any
|
|
) -> Dict[str, Any]:
|
|
"""Orchestrate a deck build.
|
|
|
|
Args:
|
|
session_id: Session identifier
|
|
commander_name: Commander card name
|
|
theme_tags: List of theme tags
|
|
**options: Additional build options
|
|
|
|
Returns:
|
|
Build result dictionary
|
|
"""
|
|
...
|
|
|
|
def get_build_status(self, session_id: str) -> Dict[str, Any]:
|
|
"""Get build status for a session.
|
|
|
|
Args:
|
|
session_id: Session identifier
|
|
|
|
Returns:
|
|
Build status dictionary
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class ValidationService(Protocol):
|
|
"""Interface for validation services."""
|
|
|
|
def validate_commander(self, name: str) -> tuple[bool, Optional[str]]:
|
|
"""Validate commander name.
|
|
|
|
Args:
|
|
name: Card name
|
|
|
|
Returns:
|
|
(is_valid, error_message) tuple
|
|
"""
|
|
...
|
|
|
|
def validate_themes(self, themes: List[str]) -> tuple[bool, List[str]]:
|
|
"""Validate theme tags.
|
|
|
|
Args:
|
|
themes: List of theme tags
|
|
|
|
Returns:
|
|
(is_valid, invalid_themes) tuple
|
|
"""
|
|
...
|
|
|
|
def normalize_card_name(self, name: str) -> str:
|
|
"""Normalize card name for lookups.
|
|
|
|
Args:
|
|
name: Raw card name
|
|
|
|
Returns:
|
|
Normalized card name
|
|
"""
|
|
...
|
|
|
|
|
|
@runtime_checkable
|
|
class TelemetryService(Protocol):
|
|
"""Interface for telemetry/metrics services."""
|
|
|
|
def record_event(self, event_type: str, properties: Optional[Dict[str, Any]] = None) -> None:
|
|
"""Record a telemetry event.
|
|
|
|
Args:
|
|
event_type: Type of event
|
|
properties: Event properties
|
|
"""
|
|
...
|
|
|
|
def record_timing(self, operation: str, duration_ms: float) -> None:
|
|
"""Record operation timing.
|
|
|
|
Args:
|
|
operation: Operation name
|
|
duration_ms: Duration in milliseconds
|
|
"""
|
|
...
|
|
|
|
def increment_counter(self, counter_name: str, value: int = 1) -> None:
|
|
"""Increment a counter.
|
|
|
|
Args:
|
|
counter_name: Counter name
|
|
value: Increment value
|
|
"""
|
|
...
|