Skip to content

Commit c798304

Browse files
Use settings for FastAPI debug and RBAC
Introduce FASTAPI_DEBUG, UVICORN_WORKER_COUNT, RBAC_CACHE_BACKEND, and RBAC_PERMISSION_CACHE_TTL_SECONDS in config.settings and wire them into the app. Use FASTAPI_DEBUG for the FastAPI debug flag, and replace ad-hoc env lookups in the lifespan/startup logic with the new config constants to validate worker count, cache backend, and permission cache TTL. Improve logging to report the configured settings, and preserve exception chaining when OpenAI client initialization fails.
1 parent 12e81ae commit c798304

3 files changed

Lines changed: 37 additions & 14 deletions

File tree

src/app/factory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from app.lifespan import run_shutdown, run_startup
1212
from app.middleware import RequestLoggingMiddleware
1313
from app.routes import register_all_routes
14+
from config.settings import FASTAPI_DEBUG
1415
from utils.logging_config import get_logger
1516
from utils.version_utils import OPENRAG_VERSION
1617

@@ -21,7 +22,7 @@ async def create_app():
2122
"""Create and configure the FastAPI application"""
2223
services = await initialize_services()
2324

24-
app = FastAPI(title="OpenRAG API", version=OPENRAG_VERSION, debug=True)
25+
app = FastAPI(title="OpenRAG API", version=OPENRAG_VERSION, debug=FASTAPI_DEBUG)
2526
app.state.services = services
2627
app.state.background_tasks = set()
2728

src/app/lifespan.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
"""
99

1010
import asyncio
11-
import os
1211

1312
from fastapi import FastAPI
1413

15-
from config.settings import clients, get_openrag_config
14+
from config.settings import (
15+
RBAC_CACHE_BACKEND,
16+
RBAC_PERMISSION_CACHE_TTL_SECONDS,
17+
UVICORN_WORKER_COUNT,
18+
clients,
19+
get_openrag_config,
20+
)
1621
from services.startup_orchestrator import startup_tasks
1722
from utils.logging_config import get_logger
1823
from utils.telemetry import Category, MessageId, TelemetryClient
@@ -108,26 +113,24 @@ async def run_startup(app: FastAPI):
108113
# permissions for up to OPENRAG_PERM_CACHE_TTL seconds after
109114
# role mutations. Until the cache moves to a shared backend
110115
# (Redis), this constraint is real and must be enforced.
111-
_workers = int(os.getenv("UVICORN_WORKERS", "1") or "1")
112-
if _workers > 1:
116+
if UVICORN_WORKER_COUNT > 1:
113117
logger.error(
114118
"Multi-worker deployment unsupported until cache is "
115119
"shared across processes. Set UVICORN_WORKERS=1.",
116-
requested_workers=_workers,
120+
requested_workers=UVICORN_WORKER_COUNT,
117121
)
118122
raise RuntimeError("UVICORN_WORKERS>1 is not supported")
119-
cache_backend = os.getenv("CACHE_BACKEND", "memory").lower()
120-
if cache_backend not in ("memory",):
123+
if RBAC_CACHE_BACKEND not in ("memory",):
121124
logger.error(
122125
"Unsupported CACHE_BACKEND. Only 'memory' is wired.",
123-
requested=cache_backend,
126+
requested=RBAC_CACHE_BACKEND,
124127
)
125-
raise RuntimeError(f"unsupported CACHE_BACKEND={cache_backend!r}")
128+
raise RuntimeError(f"unsupported CACHE_BACKEND={RBAC_CACHE_BACKEND!r}")
126129
logger.info(
127130
"Permission cache configured",
128-
backend=cache_backend,
129-
workers=_workers,
130-
perm_cache_ttl_s=int(os.getenv("OPENRAG_PERM_CACHE_TTL", "60") or "60"),
131+
backend=RBAC_CACHE_BACKEND,
132+
workers=UVICORN_WORKER_COUNT,
133+
perm_cache_ttl_s=RBAC_PERMISSION_CACHE_TTL_SECONDS,
131134
)
132135

133136
# RBAC kill-switch visibility. OPENRAG_RBAC_ENFORCE=false makes

src/config/settings.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,25 @@
7474
SEGMENT_WRITE_KEY = os.getenv("SEGMENT_WRITE_KEY", "")
7575
ENVIRONMENT = os.getenv("ENVIRONMENT", "")
7676

77+
# Enable FastAPI's `debug` mode (verbose error responses on the FastAPI app
78+
# instance). Named explicitly so it isn't confused with logging-level "debug"
79+
# or other unrelated debug flags. Defaults to False; flip via FASTAPI_DEBUG=true.
80+
FASTAPI_DEBUG = os.getenv("FASTAPI_DEBUG", "false").lower() in ("true", "1", "yes")
81+
82+
# Number of uvicorn worker processes to allow. Multi-worker is currently
83+
# unsupported because the RBAC permission cache and the OAuth-subject→DB-id
84+
# cache are per-process; the lifespan startup hook hard-fails if this is >1
85+
# until the cache moves to a shared backend (Redis).
86+
UVICORN_WORKER_COUNT = get_env_int("UVICORN_WORKERS", 1)
87+
88+
# Backend for the in-process RBAC permission cache. Only "memory" is wired
89+
# today; the lifespan hook rejects anything else.
90+
RBAC_CACHE_BACKEND = os.getenv("CACHE_BACKEND", "memory").lower()
91+
92+
# TTL (seconds) for cached RBAC permission lookups. Stale permissions can
93+
# linger for up to this many seconds after a role mutation.
94+
RBAC_PERMISSION_CACHE_TTL_SECONDS = get_env_int("OPENRAG_PERM_CACHE_TTL", 60)
95+
7796
# Docling service URL configuration
7897
# Priority:
7998
# 1. DOCLING_SERVE_URL environment variable
@@ -600,7 +619,7 @@ def run_probe_in_thread():
600619
logger.info("Successfully initialized OpenAI client")
601620
except Exception as e:
602621
logger.error(f"Failed to initialize OpenAI client: {e.__class__.__name__}: {str(e)}")
603-
raise ValueError(f"Failed to initialize OpenAI client: {str(e)}. Please complete onboarding or set OPENAI_API_KEY environment variable.")
622+
raise ValueError(f"Failed to initialize OpenAI client: {str(e)}. Please complete onboarding or set OPENAI_API_KEY environment variable.") from e
604623

605624
return self._patched_async_client
606625

0 commit comments

Comments
 (0)