You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
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)
|