From b21aaa757dcbdde91bebb5519ee3acdd99099175 Mon Sep 17 00:00:00 2001 From: Daniel Bluhm Date: Sun, 26 Nov 2023 17:58:48 -0500 Subject: [PATCH] refactor: refine configuration object Signed-off-by: Daniel Bluhm --- oid4vci/oid4vci/__init__.py | 27 +++++----- oid4vci/oid4vci/config.py | 87 +++++++++++++------------------- oid4vci/oid4vci/public_routes.py | 2 +- 3 files changed, 49 insertions(+), 67 deletions(-) diff --git a/oid4vci/oid4vci/__init__.py b/oid4vci/oid4vci/__init__.py index 0a4d6c3b5..a4091cd83 100644 --- a/oid4vci/oid4vci/__init__.py +++ b/oid4vci/oid4vci/__init__.py @@ -1,34 +1,29 @@ """OID4VCI plugin.""" import logging -from os import getenv from aries_cloudagent.config.injection_context import InjectionContext from aries_cloudagent.core.event_bus import Event, EventBus from aries_cloudagent.core.profile import Profile -from aries_cloudagent.core.util import STARTUP_EVENT_PATTERN -from .oid4vci_server import Oid4vciServer +from aries_cloudagent.core.util import SHUTDOWN_EVENT_PATTERN, STARTUP_EVENT_PATTERN + from .config import Config +from .oid4vci_server import Oid4vciServer LOGGER = logging.getLogger(__name__) -OID4VCI_HOST = getenv("OID4VCI_HOST", default="0.0.0.0") -OID4VCI_PORT = int(getenv("OID4VCI_PORT", default="8081")) - async def setup(context: InjectionContext): """Setup the plugin.""" - LOGGER.info("> oid4vci plugin setup...") event_bus = context.inject(EventBus) - event_bus.subscribe(STARTUP_EVENT_PATTERN, started_event_handler) - LOGGER.info("< oid4vci plugin setup.") + event_bus.subscribe(STARTUP_EVENT_PATTERN, startup) + event_bus.subscribe(SHUTDOWN_EVENT_PATTERN, shutdown) -async def started_event_handler(profile: Profile, event: Event): - """Event handler for Basic Messages.""" - LOGGER.info(event.payload) +async def startup(profile: Profile, event: Event): + """Startup event handler; start the OpenID4VCI server.""" try: - config = Config(profile.context) + config = Config.from_context(profile.context) oid4vci = Oid4vciServer( config.host, config.port, @@ -42,3 +37,9 @@ async def started_event_handler(profile: Profile, event: Event): oid4vci = profile.inject(Oid4vciServer) await oid4vci.start() + + +async def shutdown(context: InjectionContext): + """Teardown the plugin.""" + oid4vci = context.inject(Oid4vciServer) + await oid4vci.stop() diff --git a/oid4vci/oid4vci/config.py b/oid4vci/oid4vci/config.py index a9079a243..3872a1d44 100644 --- a/oid4vci/oid4vci/config.py +++ b/oid4vci/oid4vci/config.py @@ -1,59 +1,40 @@ """Retrieve configuration values.""" -from typing import Any, Optional, overload +from dataclasses import dataclass +from os import getenv from aries_cloudagent.core.profile import InjectionContext -MISSING = object() - +@dataclass class Config: - """Configuration for OID4VCI. - - Expected configuration options: - host: The host to listen on. - -o oid4vci.host=... - OID4VCI_HOST=... - port: The port to listen on. - -o oid4vci.port=... - OID4VCI_PORT=... - endpoint: The endpoint to listen on. - -o oid4vci.endpoint=... - OID4VCI_ENDPOINT=... - """ - - def __init__(self, context: InjectionContext): - """Initialize the configuration.""" - self.context = context - self.plugin_settings = context.settings.for_plugin("oid4vci") - - @overload - def get_plugin_setting_or_env(self, setting: str, var: str) -> Optional[Any]: - ... - - @overload - def get_plugin_setting_or_env(self, setting: str, var: str, default: Any) -> Any: - ... - - def get_plugin_setting_or_env(self, setting: str, var: str, default: Any = MISSING): - """Get a plugin setting or environment variable.""" - value = self.plugin_settings.get(setting) or self.context.settings.get( - var, default - ) - if value is MISSING: - return None - return value - - @property - def host(self) -> str: - """Get the host.""" - return self.get_plugin_setting_or_env("host", "OID4VCI_HOST", "0.0.0.0") - - @property - def port(self) -> int: - """Get the port.""" - return int(self.get_plugin_setting_or_env("port", "OID4VCI_PORT", "8081")) - - @property - def endpoint(self) -> str: - """Get the endpoint.""" - return self.get_plugin_setting_or_env("endpoint", "OID4VCI_ENDPOINT", "oid4vci") + """Configuration for OID4VCI Plugin.""" + + host: str + port: int + endpoint: str + + @classmethod + def from_context(cls, context: InjectionContext) -> "Config": + """Retrieve configuration from context.""" + plugin_settings = context.settings.for_plugin("oid4vci") + host = plugin_settings.get("host") or getenv("OID4VCI_HOST") + port = int(plugin_settings.get("port") or getenv("OID4VCI_PORT", "0")) + endpoint = plugin_settings.get("endpoint") or getenv("OID4VCI_ENDPOINT") + + if not host: + raise ValueError( + "No host specified for OID4VCI server; use either oid4vci.host " + "plugin config value or environment variable OID4VCI_HOST" + ) + if not port: + raise ValueError( + "No port specified for OID4VCI server; use either oid4vci.port " + "plugin config value or environment variable OID4VCI_PORT" + ) + if not endpoint: + raise ValueError( + "No endpoint specified for OID4VCI server; use either oid4vci.endpoint " + "plugin config value or environment variable OID4VCI_ENDPOINT" + ) + + return cls(host, port, endpoint) diff --git a/oid4vci/oid4vci/public_routes.py b/oid4vci/oid4vci/public_routes.py index a849fcf95..153f99771 100644 --- a/oid4vci/oid4vci/public_routes.py +++ b/oid4vci/oid4vci/public_routes.py @@ -73,7 +73,7 @@ class GetTokenSchema(OpenAPISchema): async def oid_cred_issuer(request: web.Request): """Credential issuer metadata endpoint.""" profile = request["context"].profile - config = Config(profile.context) + config = Config.from_context(profile.context) public_url = config.endpoint # Wallet query to retrieve credential definitions