fix: split MEALIE_API_URL (internal) from MEALIE_PUBLIC_URL (UI link)
Cauldron's container often can't resolve the public Mealie hostname from inside the Docker network. Symptom: 500 on /connect-mealie POST when validating the pasted token. Fix: take an internal HTTP path straight to Mealie over the container network (MEALIE_API_URL), bypassing the public reverse proxy / TLS termination. The public URL (MEALIE_PUBLIC_URL) stays in the UI so the connect-mealie deep-link to mint a token still goes through the user's browser, which resolves it fine. Also tightened Mealie._get/_put/_post to wrap requests.RequestException into MealieError so connection failures don't 500 callers.
This commit is contained in:
parent
b7926534f6
commit
011362ac0b
3 changed files with 24 additions and 9 deletions
|
|
@ -9,7 +9,8 @@ class Config:
|
||||||
bind_host: str
|
bind_host: str
|
||||||
bind_port: int
|
bind_port: int
|
||||||
|
|
||||||
mealie_base_url: str
|
mealie_api_url: str # internal URL cauldron uses for HTTP calls (LAN-internal)
|
||||||
|
mealie_public_url: str # external URL shown to users for token-mint UI
|
||||||
mealie_api_token: str # system token (Alice's "Cauldron" token, used for admin batch ops)
|
mealie_api_token: str # system token (Alice's "Cauldron" token, used for admin batch ops)
|
||||||
|
|
||||||
clawdforge_url: str
|
clawdforge_url: str
|
||||||
|
|
@ -41,7 +42,12 @@ def load() -> Config:
|
||||||
secret_key=os.environ["SECRET_KEY"],
|
secret_key=os.environ["SECRET_KEY"],
|
||||||
bind_host=os.environ.get("BIND_HOST", "0.0.0.0"),
|
bind_host=os.environ.get("BIND_HOST", "0.0.0.0"),
|
||||||
bind_port=int(os.environ.get("BIND_PORT", "7790")),
|
bind_port=int(os.environ.get("BIND_PORT", "7790")),
|
||||||
mealie_base_url=os.environ["MEALIE_BASE_URL"].rstrip("/"),
|
mealie_api_url=os.environ.get(
|
||||||
|
"MEALIE_API_URL", os.environ["MEALIE_BASE_URL"]
|
||||||
|
).rstrip("/"),
|
||||||
|
mealie_public_url=os.environ.get(
|
||||||
|
"MEALIE_PUBLIC_URL", os.environ["MEALIE_BASE_URL"]
|
||||||
|
).rstrip("/"),
|
||||||
mealie_api_token=os.environ["MEALIE_API_TOKEN"],
|
mealie_api_token=os.environ["MEALIE_API_TOKEN"],
|
||||||
clawdforge_url=os.environ["CLAWDFORGE_URL"].rstrip("/"),
|
clawdforge_url=os.environ["CLAWDFORGE_URL"].rstrip("/"),
|
||||||
clawdforge_token=os.environ["CLAWDFORGE_TOKEN"],
|
clawdforge_token=os.environ["CLAWDFORGE_TOKEN"],
|
||||||
|
|
|
||||||
|
|
@ -35,19 +35,28 @@ class Mealie:
|
||||||
# --- low-level ----------------------------------------------------------
|
# --- low-level ----------------------------------------------------------
|
||||||
|
|
||||||
def _get(self, path: str, **params) -> dict:
|
def _get(self, path: str, **params) -> dict:
|
||||||
r = self.session.get(f"{self.base_url}{path}", params=params, timeout=30)
|
try:
|
||||||
|
r = self.session.get(f"{self.base_url}{path}", params=params, timeout=30)
|
||||||
|
except requests.RequestException as e:
|
||||||
|
raise MealieError(f"GET {path} transport: {e}") from e
|
||||||
if r.status_code >= 400:
|
if r.status_code >= 400:
|
||||||
raise MealieError(f"GET {path} -> {r.status_code}: {r.text[:300]}")
|
raise MealieError(f"GET {path} -> {r.status_code}: {r.text[:300]}")
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def _put(self, path: str, body: dict) -> dict:
|
def _put(self, path: str, body: dict) -> dict:
|
||||||
r = self.session.put(f"{self.base_url}{path}", json=body, timeout=30)
|
try:
|
||||||
|
r = self.session.put(f"{self.base_url}{path}", json=body, timeout=30)
|
||||||
|
except requests.RequestException as e:
|
||||||
|
raise MealieError(f"PUT {path} transport: {e}") from e
|
||||||
if r.status_code >= 400:
|
if r.status_code >= 400:
|
||||||
raise MealieError(f"PUT {path} -> {r.status_code}: {r.text[:300]}")
|
raise MealieError(f"PUT {path} -> {r.status_code}: {r.text[:300]}")
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
||||||
def _post(self, path: str, body: dict) -> dict:
|
def _post(self, path: str, body: dict) -> dict:
|
||||||
r = self.session.post(f"{self.base_url}{path}", json=body, timeout=30)
|
try:
|
||||||
|
r = self.session.post(f"{self.base_url}{path}", json=body, timeout=30)
|
||||||
|
except requests.RequestException as e:
|
||||||
|
raise MealieError(f"POST {path} transport: {e}") from e
|
||||||
if r.status_code >= 400:
|
if r.status_code >= 400:
|
||||||
raise MealieError(f"POST {path} -> {r.status_code}: {r.text[:300]}")
|
raise MealieError(f"POST {path} -> {r.status_code}: {r.text[:300]}")
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ forge = Forge(
|
||||||
default_timeout=cfg.default_timeout_secs,
|
default_timeout=cfg.default_timeout_secs,
|
||||||
)
|
)
|
||||||
# System-tier Mealie client (Alice's "Cauldron" token; admin batch ops only)
|
# System-tier Mealie client (Alice's "Cauldron" token; admin batch ops only)
|
||||||
system_mealie = Mealie(base_url=cfg.mealie_base_url, api_token=cfg.mealie_api_token)
|
system_mealie = Mealie(base_url=cfg.mealie_api_url, api_token=cfg.mealie_api_token)
|
||||||
system_sterilizer = Sterilizer(mealie=system_mealie, forge=forge, model=cfg.default_model)
|
system_sterilizer = Sterilizer(mealie=system_mealie, forge=forge, model=cfg.default_model)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ def create_app() -> Flask:
|
||||||
tok = crypto.decrypt(blob)
|
tok = crypto.decrypt(blob)
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
return Mealie(base_url=cfg.mealie_base_url, api_token=tok)
|
return Mealie(base_url=cfg.mealie_api_url, api_token=tok)
|
||||||
|
|
||||||
# ---------- public ---------------------------------------------------
|
# ---------- public ---------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -188,7 +188,7 @@ def create_app() -> Flask:
|
||||||
return render_template_string(
|
return render_template_string(
|
||||||
CONNECT_TEMPLATE,
|
CONNECT_TEMPLATE,
|
||||||
user=u,
|
user=u,
|
||||||
mealie_url=cfg.mealie_base_url,
|
mealie_url=cfg.mealie_public_url,
|
||||||
css=_PALETTE_CSS,
|
css=_PALETTE_CSS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -201,7 +201,7 @@ def create_app() -> Flask:
|
||||||
return ("empty token", 400)
|
return ("empty token", 400)
|
||||||
|
|
||||||
# Validate against Mealie before storing — don't persist a bad token
|
# Validate against Mealie before storing — don't persist a bad token
|
||||||
test = Mealie(base_url=cfg.mealie_base_url, api_token=token)
|
test = Mealie(base_url=cfg.mealie_api_url, api_token=token)
|
||||||
try:
|
try:
|
||||||
test.who_am_i()
|
test.who_am_i()
|
||||||
except MealieError as e:
|
except MealieError as e:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue