from typing import Dict, Any, Type import logging import importlib logger = logging.getLogger(__name__) class ServiceManager: _instance = None _initialized = False def __new__(cls): if cls._instance is None: cls._instance = super(ServiceManager, cls).__new__(cls) return cls._instance def __init__(self): if not self._initialized: self.services: Dict[str, Any] = {} self._service_classes = { 'order_management': 'app.services.external_api.tcgplayer.order_management_service.OrderManagementService', 'tcgplayer_inventory': 'app.services.external_api.tcgplayer.tcgplayer_inventory_service.TCGPlayerInventoryService', 'label_printer': 'app.services.label_printer_service.LabelPrinterService', 'regular_printer': 'app.services.regular_printer_service.RegularPrinterService', 'address_label': 'app.services.address_label_service.AddressLabelService', 'pull_sheet': 'app.services.pull_sheet_service.PullSheetService', 'set_label': 'app.services.set_label_service.SetLabelService', 'data_initialization': 'app.services.data_initialization.DataInitializationService', 'scheduler': 'app.services.scheduler.scheduler_service.SchedulerService', 'file': 'app.services.file_service.FileService', 'tcgcsv': 'app.services.external_api.tcgcsv.tcgcsv_service.TCGCSVService', 'mtgjson': 'app.services.external_api.mtgjson.mtgjson_service.MTGJSONService' } self._service_configs = { 'label_printer': {'printer_api_url': "http://192.168.1.110:8000"}, 'regular_printer': {'printer_name': "MFCL2750DW-3"}, 'file': {'base_cache_dir': "app/data/cache"} } self._initialized = True def _import_service(self, module_path: str) -> Type: """Dynamically import a service class""" module_name, class_name = module_path.rsplit('.', 1) module = importlib.import_module(module_name) return getattr(module, class_name) def register_service(self, service: Any) -> None: """Register a service with the service manager""" service_name = service.__class__.__name__ self.services[service_name] = service logger.info(f"Service {service_name} registered") async def initialize_services(self): """Initialize all services""" try: # Initialize services for name, class_path in self._service_classes.items(): service_class = self._import_service(class_path) config = self._service_configs.get(name, {}) self.services[name] = service_class(**config) self.register_service(self.services[name]) logger.info("All services initialized successfully") except Exception as e: logger.error(f"Failed to initialize services: {str(e)}") raise async def cleanup_services(self): """Clean up all services""" try: # Clean up services in reverse order of initialization for name, service in reversed(self.services.items()): if hasattr(service, 'close'): await service.close() elif hasattr(service, 'cleanup'): await service.cleanup() logger.info(f"Service {name} cleaned up") self.services.clear() logger.info("All services cleaned up successfully") except Exception as e: logger.error(f"Failed to clean up services: {str(e)}") raise def get_service(self, name: str) -> Any: """Get a service by name""" if name not in self.services: raise ValueError(f"Service {name} not found") return self.services[name]