"""Import/Export format registry — formats are provided by plugins. A **format plugin** (e.g. ``importexport_formats``) registers handlers for its supported file formats (csv, json, xlsx, ...). An **entity module** (e.g. contacts) contributes via its contract which formats it supports and provides the import/export logic for its data. The core orchestrator (routes + background jobs) resolves the intersection: capabilities(entity) = entity.formats ∩ format_registry.registered The security policy layer (sensitive-data filter, tenant scoping, audit) runs in the orchestrator, independently of the module contribution. """ from __future__ import annotations import logging from typing import Any, Protocol, runtime_checkable logger = logging.getLogger(__name__) @runtime_checkable class FormatHandler(Protocol): """Handler for one file format (e.g. csv, json, xlsx). Provided by a format plugin via the registry. """ format_id: str @staticmethod def parse(content: bytes) -> list[dict[str, Any]]: """Parse file content into a list of row dicts.""" ... @staticmethod def serialize(rows: list[dict[str, Any]], headers: list[str]) -> bytes: """Serialize rows into file bytes with the given column order.""" ... class ImportExportFormatRegistry: """Registry for file-format handlers contributed by format plugins.""" def __init__(self) -> None: self._formats: dict[str, FormatHandler] = {} def register(self, handler: FormatHandler) -> None: """Register (or replace) a format handler.""" self._formats[handler.format_id] = handler logger.debug("Registered import/export format '%s'", handler.format_id) def unregister(self, format_id: str) -> None: self._formats.pop(format_id, None) logger.debug("Unregistered import/export format '%s'", format_id) def get(self, format_id: str) -> FormatHandler | None: return self._formats.get(format_id) def list_formats(self) -> list[str]: return sorted(self._formats.keys()) def available_for(self, entity_formats: list[str]) -> list[str]: """Return the intersection of an entity's declared formats and the currently registered (plugin-provided) format handlers.""" return sorted(set(entity_formats) & set(self._formats.keys())) def clear(self) -> None: """Clear all registrations (testing only).""" self._formats.clear() # ─── module-level singleton ───────────────────────────────────────────────── _registry: ImportExportFormatRegistry | None = None def get_format_registry() -> ImportExportFormatRegistry: global _registry if _registry is None: _registry = ImportExportFormatRegistry() return _registry def reset_format_registry_for_testing() -> ImportExportFormatRegistry: global _registry _registry = ImportExportFormatRegistry() return _registry