relay_post(
base_url: str, path: str, payload: dict[str, Any]
) -> dict[str, Any]
POST JSON to {base}{path} without a Diapason API key.
Guarded by the local-only contract: unlike opening a URL in the user's
own browser, this ships the user's OWN DATA (tasks, notes, habits) to a
remote host. local_only may never be overridden by a per-feature
switch, so syncing to a non-loopback relay requires turning it off — a
deliberate, informed decision, surfaced here in plain French rather than
failing with an opaque network error.
Source code in src/diapason/succes/relay.py
| def relay_post(base_url: str, path: str, payload: dict[str, Any]) -> dict[str, Any]:
"""POST JSON to ``{base}{path}`` without a Diapason API key.
Guarded by the local-only contract: unlike opening a URL in the user's
own browser, this ships the user's OWN DATA (tasks, notes, habits) to a
remote host. ``local_only`` may never be overridden by a per-feature
switch, so syncing to a non-loopback relay requires turning it off — a
deliberate, informed decision, surfaced here in plain French rather than
failing with an opaque network error.
"""
url = f"{normalize_relay_url(base_url)}{path}"
from diapason.core.local_mode import LocalOnlyError, assert_may_leave
try:
assert_may_leave("les données Succès", destination=url)
except LocalOnlyError as exc:
raise SuccesError(
"Le mode local-only est actif : rien ne quitte ce Mac, donc la "
"synchronisation multi-appareils est refusée. Pour l'activer, "
"mettez local_only = false dans la section [privacy] de "
"~/.diapason/config.toml."
) from exc
try:
response = httpx.post(url, json=payload, timeout=30.0)
except httpx.TimeoutException as exc:
raise SuccesError(
"Le relais ne répond pas à temps. Vérifiez l'URL et la connectivité."
) from exc
except httpx.HTTPError as exc:
raise SuccesError(
f"Impossible de joindre le relais : {exc.__class__.__name__}."
) from exc
if response.status_code >= 400:
detail = ""
try:
body = response.json()
if isinstance(body, dict):
detail = str(body.get("detail") or body.get("message") or "")
except Exception:
detail = (response.text or "")[:200]
raise SuccesError(
detail or f"Le relais a renvoyé une erreur HTTP {response.status_code}."
)
data = response.json()
if not isinstance(data, dict):
raise SuccesError("La réponse du relais est illisible.")
return data
|