From 17573185236a50f99f070a7c65dc3b6f2b2987dd Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 2 Apr 2026 17:14:05 -0400 Subject: [PATCH] consolidated env vars and .env --- .env.example | 6 ++-- README.md | 58 +++++++++++++++++++++++++++----------- pm/tasks-v2.org | 8 +++--- youdis.py | 20 +++++-------- youdis/adapters/discord.py | 4 ++- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/.env.example b/.env.example index a9e3ba1..b3a4c1f 100644 --- a/.env.example +++ b/.env.example @@ -1,14 +1,12 @@ -YOUDIS_RUN_BACKEND=1 -YOUDIS_RUN_DISCORD=1 -YOUDIS_ENABLED_ADAPTERS=discord +YOUDIS_ENABLE_BACKEND=1 YOUDIS_BACKEND_HOST=127.0.0.1 YOUDIS_BACKEND_PORT=8000 YOUDIS_BACKEND_HEALTH_TIMEOUT=20 YOUDIS_BACKEND_HEALTH_INTERVAL=0.5 -YOUDIS_BACKEND_URL=http://127.0.0.1:8000 YOUDIS_POLL_INTERVAL_SECONDS=2 YOUDIS_YTDLP_EXECUTABLE=yt-dlp YOUDIS_CONFIG_DIR=/home/user/proj/youdis/test/ YOUDIS_DOWNLOAD_DIR=/home/user/proj/youdis/downloads +ENABLE_DISCORD=1 DISCORD_BOT_TOKEN= DISCORD_BOT_SCOPE=2147491904 diff --git a/README.md b/README.md index 63822b5..ae8cd78 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,55 @@ -v2 architecture draft: see `docs/architecture-v2.org` +# Running youdis -default v2 app run: +build and run the docker container ``` -python3 ./youdis.py +-v [host_downloads]:/downloads +-v [host_config]:/config +-e ENABLE_DISCORD=1 +-e DISCORD_BOT_TOKEN= +-e DISCORD_BOT_SCOPE= ``` +config contains data to persist across container updates, i.e., unraid appdata, +such as yt-dlp's archive.txt -`youdis.py` is the app-level runner. It starts the backend first, waits for health, then starts each enabled adapter explicitly. +# Development -direct component runs still work for testing: +v2 architecture draft: `docs/architecture-v2.org` + +The app runs with `youdis.py`. +This starts the backend first, waits for health, then starts each enabled adapter explicitly. + +Test components directly with uvicorn: ``` python3 -m uvicorn youdis.main:app --host 127.0.0.1 --port 8000 python3 -m youdis.adapters.discord ``` -adapter selection is controlled by env, currently: +Key runner/config vars: +``` +YOUDIS_ENABLE_BACKEND=1 #default enabled, dont disable unless testing +YOUDIS_BACKEND_HOST=127.0.0.1 +YOUDIS_BACKEND_PORT=8000 +YOUDIS_BACKEND_HEALTH_TIMEOUT=20 +YOUDIS_BACKEND_HEALTH_INTERVAL=0.5 +YOUDIS_POLL_INTERVAL_SECONDS=2 +YOUDIS_YTDLP_EXECUTABLE=yt-dlp +YOUDIS_CONFIG_DIR=/path/to/config/ +YOUDIS_DOWNLOAD_DIR=/path/to/downloads/ +ENABLE_DISCORD=1 +DISCORD_BOT_TOKEN= +DISCORD_BOT_SCOPE=123456789 +``` + + +## Add Adapter +Configure adapter selection in .env, like so: ``` YOUDIS_RUN_BACKEND=1 -YOUDIS_ENABLED_ADAPTERS=discord +YOUDIS_BACKEND_HOST=127.0.0.1 +YOUDIS_BACKEND_PORT=8000 +ENABLE_DISCORD=1 +DISCORD_BOT_TOKEN= +DISCORD_BOT_SCOPE=123456789 ``` to add a new adapter: @@ -24,13 +57,4 @@ to add a new adapter: 2. make it independently runnable 3. add `start_()` to `youdis.py` 4. register it in the explicit adapter starter map in `youdis.py` -5. add any required env vars to `.env.example` - -build and run the docker container -``` -DISCORD_BOT_TOKEN = [discord bot token] --v [downloads]:/downloads --v [config]:/config -``` -config contains data to persist across container updates, i.e., unraid appdata, -such as yt-dlp's archive.txt +5. add `ENABLE_` and supporting env vars to `.env.example` diff --git a/pm/tasks-v2.org b/pm/tasks-v2.org index 8d4bb08..99c9f42 100644 --- a/pm/tasks-v2.org +++ b/pm/tasks-v2.org @@ -277,7 +277,7 @@ Build a simple Python orchestration layer in youdis.py so the standard app stack 1. `python3 -m py_compile ./youdis.py ./youdis/adapters/discord.py` 2. backend direct run still works: `python3 -m uvicorn youdis.main:app --host 127.0.0.1 --port 8000` 3. discord direct run still works: `python3 -m youdis.adapters.discord` - 4. app runner backend-only smoke test: `YOUDIS_ENABLED_ADAPTERS= timeout 5s python3 ./youdis.py` + 4. app runner backend-only smoke test: `ENABLE_DISCORD=0 timeout 5s python3 ./youdis.py` 5. app runner default path: `python3 ./youdis.py` - date: [2026-04-02 Thu 14:13] @@ -286,9 +286,9 @@ Build a simple Python orchestration layer in youdis.py so the standard app stack - backend starts first and must pass a health check before the Discord adapter is launched - backend and Discord adapter remain directly runnable for debugging and tests - Docker is intended to invoke `python3 /app/youdis.py`; Python owns app orchestration while Docker owns packaging and runtime environment -- adapter startup remains explicit in `youdis.py`, while `YOUDIS_ENABLED_ADAPTERS` selects which known adapters to run -- adding an adapter means creating `youdis/adapters/.py`, adding `start_()` in `youdis.py`, registering it in the explicit adapter map, and documenting any env vars in `.env.example` -- runner flags currently include `YOUDIS_RUN_BACKEND`, `YOUDIS_ENABLED_ADAPTERS`, `YOUDIS_BACKEND_HOST`, and `YOUDIS_BACKEND_PORT` +- adapter startup remains explicit in `youdis.py`, while each adapter gets its own `ENABLE_` flag +- adding an adapter means creating `youdis/adapters/.py`, adding `start_()` in `youdis.py`, wiring its `ENABLE_` flag, and documenting any supporting env vars in `.env.example` +- runner flags currently include `YOUDIS_RUN_BACKEND`, `YOUDIS_BACKEND_HOST`, `YOUDIS_BACKEND_PORT`, and `ENABLE_DISCORD` * ==== BACKLOG ==== diff --git a/youdis.py b/youdis.py index 977dbe8..76504d4 100644 --- a/youdis.py +++ b/youdis.py @@ -20,9 +20,8 @@ load_project_dotenv() REPO_ROOT = Path(__file__).resolve().parent DEFAULT_BACKEND_HOST = os.getenv("YOUDIS_BACKEND_HOST", "127.0.0.1") DEFAULT_BACKEND_PORT = int(os.getenv("YOUDIS_BACKEND_PORT", "8000")) -RUN_BACKEND = os.getenv("YOUDIS_RUN_BACKEND", "1") not in {"0", "false", "False"} -RUN_DISCORD = os.getenv("YOUDIS_RUN_DISCORD", "1") not in {"0", "false", "False"} -ENABLED_ADAPTERS = os.getenv("YOUDIS_ENABLED_ADAPTERS", "discord") +ENABLE_BACKEND = os.getenv("YOUDIS_RUN_BACKEND", "1") not in {"0", "false", "False"} +ENABLE_DISCORD = os.getenv("ENABLE_DISCORD", "1") not in {"0", "false", "False"} BACKEND_HEALTH_TIMEOUT = float(os.getenv("YOUDIS_BACKEND_HEALTH_TIMEOUT", "20")) BACKEND_HEALTH_INTERVAL = float(os.getenv("YOUDIS_BACKEND_HEALTH_INTERVAL", "0.5")) @@ -76,14 +75,9 @@ ADAPTER_STARTERS = { def selected_adapters() -> list[str]: - requested = [name.strip() for name in ENABLED_ADAPTERS.split(",") if name.strip()] - if not RUN_DISCORD: - requested = [name for name in requested if name != "discord"] - - unknown = [name for name in requested if name not in ADAPTER_STARTERS] - if unknown: - raise ValueError(f"unknown adapters requested: {', '.join(sorted(unknown))}") - + requested: list[str] = [] + if ENABLE_DISCORD: + requested.append("discord") return requested @@ -122,12 +116,12 @@ async def run() -> int: env = build_child_env() adapters = selected_adapters() - if not RUN_BACKEND and not adapters: + if not ENABLE_BACKEND and not adapters: print("nothing to start: backend is disabled and no adapters are enabled") return 1 try: - if RUN_BACKEND: + if ENABLE_BACKEND: backend = await start_backend(env) managed.append(backend) print(f"started backend on {backend_url()}") diff --git a/youdis/adapters/discord.py b/youdis/adapters/discord.py index 74a97ee..95b460f 100644 --- a/youdis/adapters/discord.py +++ b/youdis/adapters/discord.py @@ -12,7 +12,9 @@ from ..env import load_project_dotenv load_project_dotenv() -BACKEND_URL = getenv("YOUDIS_BACKEND_URL", "http://127.0.0.1:8000").rstrip("/") +BACKEND_HOST = getenv("YOUDIS_BACKEND_HOST", "127.0.0.1") +BACKEND_PORT = int(getenv("YOUDIS_BACKEND_PORT", "8000")) +BACKEND_URL = f"http://{BACKEND_HOST}:{BACKEND_PORT}".rstrip("/") POLL_INTERVAL_SECONDS = float(getenv("YOUDIS_POLL_INTERVAL_SECONDS", "2")) DEFAULT_SCOPE = int(getenv("DISCORD_BOT_SCOPE", "2147491904"))