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.
iTi-Flask/iti/exchange/registry.py

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)