Fix CORS_ORIGINS env parsing crash (pydantic-settings NoDecode), bump 0.1.1
list[str] settings fed from env were JSON-decoded by pydantic-settings before the field validator ran, so a plain string like CORS_ORIGINS=http://host:5009 raised JSONDecodeError on startup. Annotate list env fields with NoDecode and parse CSV/JSON in the validator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
21f2852259
commit
7775128c07
+16
-6
@@ -3,9 +3,10 @@ from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
from functools import lru_cache
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
from pydantic_settings import BaseSettings, NoDecode, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
@@ -25,18 +26,22 @@ class Settings(BaseSettings):
|
||||
UPDATE_CHECK_INTERVAL_MINUTES: int = 60
|
||||
|
||||
# Notifications (webhook URLs)
|
||||
NOTIFY_WEBHOOKS: list[str] = []
|
||||
NOTIFY_WEBHOOKS: Annotated[list[str], NoDecode] = []
|
||||
|
||||
# Docker
|
||||
DOCKER_SOCKET: str = "/var/run/docker.sock"
|
||||
HOST_PROC_PATH: str = "/host_proc"
|
||||
|
||||
# Host browser sandbox roots
|
||||
ALLOWED_BROWSE_ROOTS: list[str] = ["/", "/mnt", "/media", "/srv", "/opt"]
|
||||
ALLOWED_BROWSE_ROOTS: Annotated[list[str], NoDecode] = [
|
||||
"/", "/mnt", "/media", "/srv", "/opt",
|
||||
]
|
||||
HOST_ROOT_PREFIX: str = "" # e.g. "/host_root" when host / is bind-mounted
|
||||
|
||||
# CORS
|
||||
CORS_ORIGINS: list[str] = ["http://localhost:5009", "http://localhost:5173"]
|
||||
CORS_ORIGINS: Annotated[list[str], NoDecode] = [
|
||||
"http://localhost:5009", "http://localhost:5173",
|
||||
]
|
||||
|
||||
# Server
|
||||
PORT: int = 5008
|
||||
@@ -55,8 +60,13 @@ class Settings(BaseSettings):
|
||||
v = v.strip()
|
||||
if not v:
|
||||
return []
|
||||
if v.startswith("["): # JSON list
|
||||
return v
|
||||
if v.startswith("["): # tolerate a JSON list too
|
||||
import json
|
||||
|
||||
try:
|
||||
return json.loads(v)
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return [item.strip() for item in v.split(",") if item.strip()]
|
||||
return v
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ async def lifespan(app: FastAPI):
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(title="StackPilot", version="0.1.0", lifespan=lifespan)
|
||||
app = FastAPI(title="StackPilot", version="0.1.1", lifespan=lifespan)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
|
||||
Reference in New Issue
Block a user