From ba1132fbd166abd1d45671c2ec5c73f69320a1a1 Mon Sep 17 00:00:00 2001
From: Stefan Hynek <stefan.hynek@uni-goettingen.de>
Date: Mon, 9 Jan 2023 10:18:39 +0100
Subject: [PATCH] refactor(config): wrap all settings that can be configured
 from the environment in an AppConfig object

---
 src/repdav/config.py | 74 +++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 43 deletions(-)

diff --git a/src/repdav/config.py b/src/repdav/config.py
index 1d5553f..b3329bf 100644
--- a/src/repdav/config.py
+++ b/src/repdav/config.py
@@ -3,63 +3,51 @@
 # SPDX-License-Identifier: CC0-1.0
 
 import os
+from typing import Optional
+from urllib.parse import urlparse
 
-from .errors import EnvNotSetError
 
-# TODO: remove "tg_auth_wsdl", "tg_auth_address", "tg_nav_address"
+def check_url(url):
+    """Check if `url` can be parsed."""
+    if url:
+        result = urlparse(url)
+        if result.scheme and result.netloc:
+            return url
+        raise ValueError(f"{url} is not a valid URL.")
 
 
-def lookup_env_name(internal_name: str) -> str:
-    mapping = {
-        "_auth_wsdl": "tg_auth_wsdl",
-        "_auth_address": "tg_auth_address",
-        "_dsn": "sentry_dsn",
-        "_host": "tg_host",
-        "_nav_address": "tg_nav_address",
-    }
-    return mapping[internal_name]
+def check_port(port):
+    """Check if port is set correctly to a non-privileged value."""
+    if 1000 <= port <= 65535:
+        return port
+    raise ValueError(f"{port} is not a valid Port.")
 
 
-# TODO check for trailing "/", add if missing!
-# TODO check URLs for validity
-
 class AppConfig:
-    # TODO: configure the app according to the set environment (i.e. prod or dev)
-    def __init__(self) -> None:
-        self._dsn = os.getenv(lookup_env_name("_dsn"))
-
-    @property
-    def dsn(self) -> str:
-        return self._dsn
+    """Settings that can be be configured from the environment."""
 
-
-class TextgridConfig:
     def __init__(self) -> None:
-        self._auth_wsdl = os.getenv(lookup_env_name("_auth_wsdl"))
-        self._auth_address = os.getenv(lookup_env_name("_auth_address"))
-        self._nav_address = os.getenv(lookup_env_name("_nav_address"))
-        self._host = os.getenv(lookup_env_name("_host"))
+        self._dsn = check_url(os.getenv("SENTRY_DSN"))
+        self._host = os.getenv("REPDAV_HOST") or "localhost"
+        self._port = check_port(int(os.getenv("REPDAV_PORT") or 8080))
+        self._tg_host = check_url(os.getenv("TEXTGRID_HOST"))
 
     @property
-    def auth_wsdl(self) -> str:
-        if self._auth_wsdl:
-            return self._auth_wsdl
-        raise EnvNotSetError(lookup_env_name("_auth_wsdl"))
+    def dsn(self) -> Optional[str]:
+        """Sentry DSN."""
+        return self._dsn
 
     @property
-    def auth_address(self) -> str:
-        if self._auth_address:
-            return self._auth_address
-        raise EnvNotSetError(lookup_env_name("_auth_address"))
+    def host(self) -> str:
+        """Service hostname."""
+        return self._host
 
     @property
-    def nav_address(self) -> str:
-        if self._nav_address:
-            return self._nav_address
-        raise EnvNotSetError(lookup_env_name("_nav_address"))
+    def port(self) -> int:
+        """Service port."""
+        return self._port
 
     @property
-    def host(self) -> str:
-        if self._host:
-            return self._host
-        raise EnvNotSetError(lookup_env_name("_host"))
+    def tg_host(self) -> Optional[str]:
+        """Textgrid host URL."""
+        return self._tg_host
-- 
GitLab