from __future__ import annotations from dataclasses import dataclass, field from .base import ExchangeTemplate, ExchangeTemplateSnapshot @dataclass class ExchangeRegistry: templates: dict[str, ExchangeTemplate] = field(default_factory=dict) versions: dict[str, ExchangeTemplateSnapshot] = field(default_factory=dict) sources: dict[str, object] = field(default_factory=dict) def register_template(self, template: ExchangeTemplate) -> ExchangeTemplate: if not template.id: raise ValueError("template id is required") if not template.code: raise ValueError("template code is required") if template.id in self.templates: raise ValueError(f"template already registered: {template.id}") self.templates[template.id] = template return template def register_version( self, snapshot: ExchangeTemplateSnapshot ) -> ExchangeTemplateSnapshot: if not snapshot.id: raise ValueError("snapshot id is required") if not snapshot.template_id: raise ValueError("snapshot template id is required") key = self._version_key(snapshot.template_id, snapshot.version) if key in self.versions: raise ValueError(f"template version already registered: {key}") self.versions[key] = snapshot return snapshot def get_template(self, template_id: str) -> ExchangeTemplate | None: return self.templates.get(template_id) def get_version( self, template_id: str, version: str ) -> ExchangeTemplateSnapshot | None: return self.versions.get(self._version_key(template_id, version)) def latest_version( self, template_id: str ) -> ExchangeTemplateSnapshot | None: template = self.templates.get(template_id) if template is None or not template.current_version: return None return self.get_version(template_id, template.current_version) def list_templates(self) -> list[ExchangeTemplate]: return sorted(self.templates.values(), key=lambda item: (item.entity, item.code)) def list_versions(self, template_id: str | None = None) -> list[ExchangeTemplateSnapshot]: snapshots = list(self.versions.values()) if template_id is not None: snapshots = [item for item in snapshots if item.template_id == template_id] return sorted(snapshots, key=lambda item: (item.template_id, item.version)) def register_source(self, name: str, source: object) -> object: if not name: raise ValueError("source name is required") if name in self.sources: raise ValueError(f"exchange source already registered: {name}") self.sources[name] = source return source def get_source(self, name: str) -> object | None: return self.sources.get(name) @staticmethod def _version_key(template_id: str, version: str) -> str: return f"{template_id}:{version}" def get_exchange_registry(app) -> ExchangeRegistry: registry = getattr(app.state, "iti_exchange", None) if registry is None: registry = ExchangeRegistry() app.state.iti_exchange = registry return registry def register_exchange_source(app, name: str, source: object) -> object: return get_exchange_registry(app).register_source(name, source) def get_exchange_source_by_name(app, name: str) -> object | None: return get_exchange_registry(app).get_source(name)