From a1aa89132d21ed4aba6ebec172237e0ca5d2b7b3 Mon Sep 17 00:00:00 2001
From: lilly
Date: Thu, 14 May 2026 15:17:06 +0200
Subject: [PATCH] make app configurable via CLI and ENV parameters
---
.dev.env | 4 +++
api/src/dooris_api/__init__.py | 45 +++++++++++++++++++++++++++++++++-
api/src/dooris_api/app.py | 15 +++++++-----
3 files changed, 57 insertions(+), 7 deletions(-)
create mode 100644 .dev.env
diff --git a/.dev.env b/.dev.env
new file mode 100644
index 0000000..a1a7c4d
--- /dev/null
+++ b/.dev.env
@@ -0,0 +1,4 @@
+DOORIS_OPENID_ISSUER=https://id.hamburg.ccc.de/realms/test/
+DOORIS_OPENID_CLIENT_ID=dooris
+DOORIS_OPENID_CLIENT_SECRET=dp9HhnvUhAtKm3pRnxfGA7q8Nwrd1td8
+DOORIS_BASE_URL=http://localhost:8000
diff --git a/api/src/dooris_api/__init__.py b/api/src/dooris_api/__init__.py
index bc8bc17..57ed503 100644
--- a/api/src/dooris_api/__init__.py
+++ b/api/src/dooris_api/__init__.py
@@ -1,8 +1,51 @@
-from dooris_api.app import app
+import os
+from contextvars import ContextVar
+from argparse import ArgumentParser, Namespace
+
+
+app_config: ContextVar[Namespace] = ContextVar("app_config")
def main():
+ argp = ArgumentParser(
+ "dooris-api",
+ description="Server to interact with CCCHH doors via locks over CCUJACK over HomeMatic over WiFi",
+ )
+ argp.add_argument(
+ "--openid-issuer",
+ required="DOORIS_OPENID_ISSUER" not in os.environ,
+ default=os.environ.get("DOORIS_OPENID_ISSUER", None),
+ help="The Keycloak OpenID isser to use for authentication",
+ )
+ argp.add_argument(
+ "--openid-scope",
+ default=os.environ.get("DOORIS_OPENID_SCOPE", "openid profile"),
+ help="The Keycloak OpenID isser to use for authentication",
+ )
+ argp.add_argument(
+ "--openid-client-id",
+ required="DOORIS_OPENID_CLIENT_ID" not in os.environ,
+ default=os.environ.get("DOORIS_OPENID_CLIENT_ID", None),
+ help="The Keycloak OpenID client-id to use for authentication",
+ )
+ argp.add_argument(
+ "--openid-client-secret",
+ required="DOORIS_OPENID_CLIENT_SECRET" not in os.environ,
+ default=os.environ.get("DOORIS_OPENID_CLIENT_SECRET", None),
+ help="The Keycloak OpenID client secret to use for authentication",
+ )
+ argp.add_argument(
+ "--base-url",
+ required="DOORIS_BASE_URL" not in os.environ,
+ default=os.environ.get("DOORIS_BASE_URL", None),
+ help="The Base-URL that this application is reachable under",
+ )
+ args = argp.parse_args()
+
+ app_config.set(args)
import uvicorn
+ from dooris_api.app import app
+
config = uvicorn.Config(app, port=8000, log_level="debug")
server = uvicorn.Server(config)
server.run()
diff --git a/api/src/dooris_api/app.py b/api/src/dooris_api/app.py
index 9f5ced2..21b6472 100644
--- a/api/src/dooris_api/app.py
+++ b/api/src/dooris_api/app.py
@@ -11,7 +11,6 @@ from simple_openid_connect.client import OpenidClient
from simple_openid_connect.data import TokenSuccessResponse
from cachetools import TTLCache
from aiohttp import BasicAuth
-import asyncio
from dooris_api import deps, models, exceptions
from dooris_api.ccujack import CCUJackClient
@@ -22,6 +21,9 @@ logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
+ from dooris_api import app_config
+ app_config = app_config.get()
+
root_logger = logging.getLogger("")
root_logger.setLevel(logging.INFO)
root_logger.addHandler(logging.StreamHandler(sys.stderr))
@@ -29,10 +31,11 @@ async def lifespan(app: FastAPI):
app_logger.setLevel(logging.DEBUG)
app.extra["oidc_client"] = OpenidClient.from_issuer_url(
- url="https://id.hamburg.ccc.de/realms/test/",
- authentication_redirect_uri="http://localhost:8000/auth/login-callback",
- client_id="dooris",
- client_secret="dp9HhnvUhAtKm3pRnxfGA7q8Nwrd1td8",
+ url=app_config.openid_issuer,
+ authentication_redirect_uri=f"{app_config.base_url}/auth/login-callback",
+ client_id=app_config.openid_client_id,
+ client_secret=app_config.openid_client_secret,
+ scope=app_config.openid_scope,
)
app.extra["cache"] = TTLCache(maxsize=64, ttl=30 * 60)
@@ -43,7 +46,7 @@ async def lifespan(app: FastAPI):
app = FastAPI(
- title="Dooris", summary="API for interacting with HomeMatic door locks in CCCHH", docs_url="/api/docs",
+ title="Dooris", summary="Server to interact with CCCHH doors via locks over CCUJACK over HomeMatic over WiFi", docs_url="/api/docs",
lifespan=lifespan,
)
app.add_exception_handler(exceptions.HttpProblemException, exceptions.problem_exception_handler)