2026-01-01 23:17:19 -03:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import secrets
|
|
|
|
|
import string
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
import httpx
|
|
|
|
|
|
|
|
|
|
from . import settings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def random_password(length: int = 32) -> str:
|
2026-04-11 00:02:26 -03:00
|
|
|
"""Generate a URL-safe mixed-case password for one-off account bootstrap."""
|
|
|
|
|
|
2026-01-01 23:17:19 -03:00
|
|
|
alphabet = string.ascii_letters + string.digits
|
|
|
|
|
return "".join(secrets.choice(alphabet) for _ in range(length))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def best_effort_post(url: str) -> None:
|
2026-04-11 00:02:26 -03:00
|
|
|
"""Fire-and-forget a JSON ping without letting transport failures bubble.
|
|
|
|
|
|
|
|
|
|
WHY: background sync helpers should keep moving even if the destination is
|
|
|
|
|
briefly unavailable or the cluster network is in a bad state.
|
|
|
|
|
"""
|
|
|
|
|
|
2026-01-01 23:17:19 -03:00
|
|
|
if not url:
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
with httpx.Client(timeout=settings.HTTP_CHECK_TIMEOUT_SEC) as client:
|
|
|
|
|
client.post(url, json={"ts": int(time.time())})
|
|
|
|
|
except Exception:
|
|
|
|
|
return
|