|
@@ -19,6 +19,11 @@ class ServiceAPI:
|
|
|
Pass a custom `clients` dict to substitute stubs for testing.
|
|
Pass a custom `clients` dict to substitute stubs for testing.
|
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
|
|
+ _CLIENT_CLASSES: dict[str, type] = {
|
|
|
|
|
+ 'airbnb': _AirbnbClient,
|
|
|
|
|
+ 'booking': _BookingClient,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
def __init__(self, clients: dict[str, ServiceClient] | None = None) -> None:
|
|
def __init__(self, clients: dict[str, ServiceClient] | None = None) -> None:
|
|
|
if clients is not None:
|
|
if clients is not None:
|
|
|
self._clients: dict[str, ServiceClient] = clients
|
|
self._clients: dict[str, ServiceClient] = clients
|
|
@@ -27,29 +32,21 @@ class ServiceAPI:
|
|
|
self._clients = {}
|
|
self._clients = {}
|
|
|
self._disabled: dict[str, str] = {}
|
|
self._disabled: dict[str, str] = {}
|
|
|
svc_cfg = get_config().services
|
|
svc_cfg = get_config().services
|
|
|
- for key, factory in {
|
|
|
|
|
- 'airbnb': _AirbnbClient.from_env,
|
|
|
|
|
- 'booking': _BookingClient.from_env,
|
|
|
|
|
- }.items():
|
|
|
|
|
|
|
+ for key, cls in self._CLIENT_CLASSES.items():
|
|
|
if (cfg := svc_cfg.get(key)) and cfg.disabled:
|
|
if (cfg := svc_cfg.get(key)) and cfg.disabled:
|
|
|
_log.info('service %s disabled by config', key)
|
|
_log.info('service %s disabled by config', key)
|
|
|
self._disabled[key] = 'disabled in config'
|
|
self._disabled[key] = 'disabled in config'
|
|
|
continue
|
|
continue
|
|
|
try:
|
|
try:
|
|
|
- self._clients[key] = factory()
|
|
|
|
|
|
|
+ self._clients[key] = cls.from_env()
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
_log.warning('service %s disabled: %s', key, e)
|
|
_log.warning('service %s disabled: %s', key, e)
|
|
|
self._disabled[key] = str(e)
|
|
self._disabled[key] = str(e)
|
|
|
|
|
|
|
|
- _REFRESH_HANDLERS: dict[str, type] = {
|
|
|
|
|
- 'airbnb': _AirbnbClient,
|
|
|
|
|
- 'booking': _BookingClient,
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
async def refresh_credentials(self, key: str) -> None:
|
|
async def refresh_credentials(self, key: str) -> None:
|
|
|
"""Trigger credential refresh for the named service. Raises ServiceAuthError on failure."""
|
|
"""Trigger credential refresh for the named service. Raises ServiceAuthError on failure."""
|
|
|
- cls = self._REFRESH_HANDLERS.get(key)
|
|
|
|
|
- if cls is None:
|
|
|
|
|
|
|
+ cls = self._CLIENT_CLASSES.get(key)
|
|
|
|
|
+ if cls is None or not hasattr(cls, 'refresh_credentials'):
|
|
|
from .types import ServiceAuthError
|
|
from .types import ServiceAuthError
|
|
|
raise ServiceAuthError(f'No automatic refresh handler for service: {key}')
|
|
raise ServiceAuthError(f'No automatic refresh handler for service: {key}')
|
|
|
loop = asyncio.get_running_loop()
|
|
loop = asyncio.get_running_loop()
|