Edit on GitHub

agent_search_gateway.providers.academic.registry

Registration-order-preserving academic provider and OA resolver registries.

 1"""Registration-order-preserving academic provider and OA resolver registries."""
 2
 3from collections.abc import Callable
 4from dataclasses import dataclass
 5from typing import Literal
 6
 7Requirement = Literal["none", "optional", "required"]
 8AcademicProviderFactory = Callable[..., object]
 9OAResolverFactory = Callable[..., object]
10
11
12@dataclass(frozen=True, slots=True)
13class AcademicProviderRegistration:
14    name: str
15    factory: AcademicProviderFactory
16    allowed_config_keys: frozenset[str] = frozenset()
17    authentication: Requirement = "none"
18    contact: Requirement = "none"
19
20
21@dataclass(frozen=True, slots=True)
22class OAResolverRegistration:
23    name: str
24    factory: OAResolverFactory
25    allowed_config_keys: frozenset[str] = frozenset()
26    authentication: Requirement = "none"
27    contact: Requirement = "none"
28
29
30class AcademicProviderRegistry:
31    def __init__(self) -> None:
32        self._registrations: dict[str, AcademicProviderRegistration] = {}
33
34    def register(self, registration: AcademicProviderRegistration) -> None:
35        _validate_registration(registration.name, registration.authentication, registration.contact)
36        if registration.name in self._registrations:
37            raise ValueError(f"academic provider already registered: {registration.name}")
38        self._registrations[registration.name] = registration
39
40    def get(self, name: str) -> AcademicProviderRegistration | None:
41        return self._registrations.get(name)
42
43    def require(self, name: str) -> AcademicProviderRegistration:
44        registration = self.get(name)
45        if registration is None:
46            raise KeyError(name)
47        return registration
48
49    def list_in_registration_order(self) -> tuple[AcademicProviderRegistration, ...]:
50        return tuple(self._registrations.values())
51
52
53class OAResolverRegistry:
54    def __init__(self) -> None:
55        self._registrations: dict[str, OAResolverRegistration] = {}
56
57    def register(self, registration: OAResolverRegistration) -> None:
58        _validate_registration(registration.name, registration.authentication, registration.contact)
59        if registration.name in self._registrations:
60            raise ValueError(f"OA resolver already registered: {registration.name}")
61        self._registrations[registration.name] = registration
62
63    def get(self, name: str) -> OAResolverRegistration | None:
64        return self._registrations.get(name)
65
66    def require(self, name: str) -> OAResolverRegistration:
67        registration = self.get(name)
68        if registration is None:
69            raise KeyError(name)
70        return registration
71
72    def list_in_registration_order(self) -> tuple[OAResolverRegistration, ...]:
73        return tuple(self._registrations.values())
74
75
76def _validate_registration(name: str, authentication: str, contact: str) -> None:
77    if not name.strip():
78        raise ValueError("registration name must be non-empty")
79    valid = {"none", "optional", "required"}
80    if authentication not in valid:
81        raise ValueError(f"invalid authentication requirement: {authentication}")
82    if contact not in valid:
83        raise ValueError(f"invalid contact requirement: {contact}")
Requirement = typing.Literal['none', 'optional', 'required']
AcademicProviderFactory = collections.abc.Callable[..., object]
OAResolverFactory = collections.abc.Callable[..., object]
@dataclass(frozen=True, slots=True)
class AcademicProviderRegistration:
13@dataclass(frozen=True, slots=True)
14class AcademicProviderRegistration:
15    name: str
16    factory: AcademicProviderFactory
17    allowed_config_keys: frozenset[str] = frozenset()
18    authentication: Requirement = "none"
19    contact: Requirement = "none"
AcademicProviderRegistration( name: str, factory: Callable[..., object], allowed_config_keys: frozenset[str] = frozenset(), authentication: Literal['none', 'optional', 'required'] = 'none', contact: Literal['none', 'optional', 'required'] = 'none')
name: str
factory: Callable[..., object]
allowed_config_keys: frozenset[str]
authentication: Literal['none', 'optional', 'required']
contact: Literal['none', 'optional', 'required']
@dataclass(frozen=True, slots=True)
class OAResolverRegistration:
22@dataclass(frozen=True, slots=True)
23class OAResolverRegistration:
24    name: str
25    factory: OAResolverFactory
26    allowed_config_keys: frozenset[str] = frozenset()
27    authentication: Requirement = "none"
28    contact: Requirement = "none"
OAResolverRegistration( name: str, factory: Callable[..., object], allowed_config_keys: frozenset[str] = frozenset(), authentication: Literal['none', 'optional', 'required'] = 'none', contact: Literal['none', 'optional', 'required'] = 'none')
name: str
factory: Callable[..., object]
allowed_config_keys: frozenset[str]
authentication: Literal['none', 'optional', 'required']
contact: Literal['none', 'optional', 'required']
class AcademicProviderRegistry:
31class AcademicProviderRegistry:
32    def __init__(self) -> None:
33        self._registrations: dict[str, AcademicProviderRegistration] = {}
34
35    def register(self, registration: AcademicProviderRegistration) -> None:
36        _validate_registration(registration.name, registration.authentication, registration.contact)
37        if registration.name in self._registrations:
38            raise ValueError(f"academic provider already registered: {registration.name}")
39        self._registrations[registration.name] = registration
40
41    def get(self, name: str) -> AcademicProviderRegistration | None:
42        return self._registrations.get(name)
43
44    def require(self, name: str) -> AcademicProviderRegistration:
45        registration = self.get(name)
46        if registration is None:
47            raise KeyError(name)
48        return registration
49
50    def list_in_registration_order(self) -> tuple[AcademicProviderRegistration, ...]:
51        return tuple(self._registrations.values())
def register( self, registration: AcademicProviderRegistration) -> None:
35    def register(self, registration: AcademicProviderRegistration) -> None:
36        _validate_registration(registration.name, registration.authentication, registration.contact)
37        if registration.name in self._registrations:
38            raise ValueError(f"academic provider already registered: {registration.name}")
39        self._registrations[registration.name] = registration
def get( self, name: str) -> AcademicProviderRegistration | None:
41    def get(self, name: str) -> AcademicProviderRegistration | None:
42        return self._registrations.get(name)
def require( self, name: str) -> AcademicProviderRegistration:
44    def require(self, name: str) -> AcademicProviderRegistration:
45        registration = self.get(name)
46        if registration is None:
47            raise KeyError(name)
48        return registration
def list_in_registration_order( self) -> tuple[AcademicProviderRegistration, ...]:
50    def list_in_registration_order(self) -> tuple[AcademicProviderRegistration, ...]:
51        return tuple(self._registrations.values())
class OAResolverRegistry:
54class OAResolverRegistry:
55    def __init__(self) -> None:
56        self._registrations: dict[str, OAResolverRegistration] = {}
57
58    def register(self, registration: OAResolverRegistration) -> None:
59        _validate_registration(registration.name, registration.authentication, registration.contact)
60        if registration.name in self._registrations:
61            raise ValueError(f"OA resolver already registered: {registration.name}")
62        self._registrations[registration.name] = registration
63
64    def get(self, name: str) -> OAResolverRegistration | None:
65        return self._registrations.get(name)
66
67    def require(self, name: str) -> OAResolverRegistration:
68        registration = self.get(name)
69        if registration is None:
70            raise KeyError(name)
71        return registration
72
73    def list_in_registration_order(self) -> tuple[OAResolverRegistration, ...]:
74        return tuple(self._registrations.values())
def register( self, registration: OAResolverRegistration) -> None:
58    def register(self, registration: OAResolverRegistration) -> None:
59        _validate_registration(registration.name, registration.authentication, registration.contact)
60        if registration.name in self._registrations:
61            raise ValueError(f"OA resolver already registered: {registration.name}")
62        self._registrations[registration.name] = registration
def get( self, name: str) -> OAResolverRegistration | None:
64    def get(self, name: str) -> OAResolverRegistration | None:
65        return self._registrations.get(name)
def require( self, name: str) -> OAResolverRegistration:
67    def require(self, name: str) -> OAResolverRegistration:
68        registration = self.get(name)
69        if registration is None:
70            raise KeyError(name)
71        return registration
def list_in_registration_order( self) -> tuple[OAResolverRegistration, ...]:
73    def list_in_registration_order(self) -> tuple[OAResolverRegistration, ...]:
74        return tuple(self._registrations.values())