feat: add router table entries for uploads, media, zips, forks, tools, proxy, push, docs, openai, devii, xmlrpc, devrant, dbapi, pubsub and add type annotations to cache, config, responses, schemas, seo, and stealth modules

This commit is contained in:
2026-06-16 12:05:44 +00:00
parent a618a95671
commit 82f961c660
13 changed files with 51 additions and 83 deletions
-27
View File
@@ -11,11 +11,6 @@ BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_DIR = BASE_DIR / "devplacepy" / "static"
TEMPLATES_DIR = BASE_DIR / "devplacepy" / "templates"
# Single source of truth for every runtime/user-generated artifact. Everything the
# app creates or modifies at runtime lives under DATA_DIR, never inside the package
# and never served via /static. Overridable by DEVPLACE_DATA_DIR (point at a volume
# in production). Each path below is derived from DATA_DIR; no other module computes
# a runtime path from scratch.
DATA_DIR = Path(environ.get("DEVPLACE_DATA_DIR", str(BASE_DIR / "data")))
UPLOADS_DIR = DATA_DIR / "uploads"
ATTACHMENTS_DIR = UPLOADS_DIR / "attachments"
@@ -48,23 +43,11 @@ SESSION_MAX_AGE_REMEMBER = SECONDS_PER_DAY * 30
PORT = 10500
SITE_URL = environ.get("DEVPLACE_SITE_URL", "").rstrip("/")
# Forking XML-RPC bridge. A standalone ForkingMixIn XML-RPC server binds this
# port on loopback and translates every documented REST endpoint into an XML-RPC
# method (generated from docs_api.API_GROUPS). The FastAPI app reverse-proxies
# /xmlrpc to it; nginx forwards /xmlrpc in production. The bind host stays
# loopback because the app and nginx are the only intended front doors.
XMLRPC_BIND = environ.get("DEVPLACE_XMLRPC_BIND", "127.0.0.1")
XMLRPC_PORT = int(environ.get("DEVPLACE_XMLRPC_PORT", "10550"))
# Cache-busting version stamped onto every app-owned static URL. Computed once at
# process start, so a restart/deploy changes it and busts every browser cache while
# assets stay heavily cached (immutable, 1 year) between deploys. Set
# DEVPLACE_STATIC_VERSION at launch so multiple prod workers share one value.
STATIC_VERSION = environ.get("DEVPLACE_STATIC_VERSION") or str(int(time.time()))
# Jinja template auto-reload stat-checks every template in the inheritance chain on
# every render. Keep it on for development hot-reload; turn it off in production
# (DEVPLACE_TEMPLATE_AUTO_RELOAD=0) so compiled templates stay cached in memory.
TEMPLATE_AUTO_RELOAD = environ.get("DEVPLACE_TEMPLATE_AUTO_RELOAD", "1") != "0"
INTERNAL_BASE_URL = environ.get(
@@ -82,14 +65,7 @@ DEFAULT_MODIFIER_PROMPT = (
SERVICE_LOCK_FILE = LOCKS_DIR / "devplace-services.lock"
INIT_LOCK_FILE = LOCKS_DIR / "devplace-init.lock"
# Every container instance runs this one prebuilt image (built once via `make ppy`).
CONTAINER_IMAGE = environ.get("DEVPLACE_CONTAINER_IMAGE", "ppy:latest")
# Override host the /p/<slug> ingress proxy dials, with the published host port,
# instead of the container's own bridge IP. Set this only for topologies where
# the app cannot route to the container network directly (containerized app via
# docker socket: use host.docker.internal). Left empty, the proxy connects
# straight to the container IP and container port, which avoids the host
# port-publishing layer (docker-proxy / iptables DNAT / loopback) entirely.
CONTAINER_PROXY_HOST = environ.get("DEVPLACE_CONTAINER_PROXY_HOST", "").strip()
VAPID_PRIVATE_KEY_FILE = KEYS_DIR / "notification-private.pem"
@@ -97,9 +73,6 @@ VAPID_PRIVATE_KEY_PKCS8_FILE = KEYS_DIR / "notification-private.pkcs8.pem"
VAPID_PUBLIC_KEY_FILE = KEYS_DIR / "notification-public.pem"
VAPID_SUB = environ.get("DEVPLACE_VAPID_SUB", "mailto:retoor@molodetz.nl")
# Documented registry of every runtime directory. ensure_data_dirs() creates them
# all at startup so the tree always exists before the DB, keys, locks, uploads, and
# job staging are written.
DATA_PATHS: dict[str, Path] = {
"data": DATA_DIR,
"uploads": UPLOADS_DIR,