documentverification/verifier/engine/registry.py
2026-10-15 19:42:15 +05:30

69 lines
2.4 KiB
Python

import logging
from typing import Dict, List, Optional
from .base import BaseVendor
logger = logging.getLogger(__name__)
class VendorRegistry:
"""
Central registry for verification vendors.
Manages active vendor adapters and resolves waterfall order.
"""
def __init__(self):
self._vendors: Dict[str, BaseVendor] = {}
def register(self, vendor: BaseVendor, overwrite: bool = True) -> None:
"""Register a vendor instance."""
vendor_key = vendor.name.lower()
if vendor_key in self._vendors and not overwrite:
logger.warning("Vendor '%s' is already registered. Skipping.", vendor_key)
return
self._vendors[vendor_key] = vendor
logger.info("Registered vendor '%s' (priority=%d, active=%s)", vendor.name, vendor.priority, vendor.is_active)
def unregister(self, vendor_name: str) -> Optional[BaseVendor]:
"""Unregister a vendor instance."""
return self._vendors.pop(vendor_name.lower(), None)
def get_vendor(self, vendor_name: str) -> Optional[BaseVendor]:
"""Retrieve vendor by name."""
return self._vendors.get(vendor_name.lower())
def get_all_vendors(self) -> List[BaseVendor]:
"""Return all registered vendors sorted by priority (lowest number = highest priority)."""
return sorted(self._vendors.values(), key=lambda v: v.priority)
def get_vendors_for_document(
self,
document_type: str,
preferred_vendor: Optional[str] = None,
) -> List[BaseVendor]:
"""
Get all active vendors that support `document_type`, sorted by priority.
If `preferred_vendor` is specified, it is placed at the front of the chain.
"""
doc_key = document_type.lower()
active_candidates = [
v for v in self._vendors.values()
if v.is_active and v.supports(doc_key)
]
# Sort by priority
active_candidates.sort(key=lambda v: v.priority)
# If preferred vendor is requested and available, move it to index 0
if preferred_vendor:
pref_key = preferred_vendor.lower()
matching = [v for v in active_candidates if v.name.lower() == pref_key]
if matching:
remaining = [v for v in active_candidates if v.name.lower() != pref_key]
return matching + remaining
return active_candidates
# Global default registry instance
registry = VendorRegistry()