Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """Start the Synderesis proxy inside a Hugging Face Docker Space.""" | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import sys | |
| from decimal import InvalidOperation, Decimal | |
| from pathlib import Path | |
| from huggingface_hub import hf_hub_download | |
| DEFAULT_TINKER_MODEL_PATH = ( | |
| "tinker://69e3ecac-e413-51b3-b3ff-2eb20d22c878:train:1/" | |
| "sampler_weights/synderesis-nemotron-super-catholic-v2-style-20260616T170321Z" | |
| ) | |
| DEFAULT_BACKEND = "llm-synod" | |
| DEPLOYMENT_METADATA_PATH = Path("synderesis_deployment.json") | |
| PERSISTENT_STATE_DIR = Path("/data") | |
| FALLBACK_RUNTIME_DIR = Path("/tmp/synderesis") | |
| REQUIRE_PERSISTENT_STATE_ENV = "SYNDERESIS_REQUIRE_PERSISTENT_STATE" | |
| def load_deployment_metadata() -> dict[str, object]: | |
| """Read build metadata generated by the deploy script.""" | |
| if not DEPLOYMENT_METADATA_PATH.exists(): | |
| return {} | |
| try: | |
| payload = json.loads(DEPLOYMENT_METADATA_PATH.read_text(encoding="utf-8")) | |
| except Exception as exc: | |
| print(f"Could not read deployment metadata: {exc}", file=sys.stderr, flush=True) | |
| return {} | |
| return payload if isinstance(payload, dict) else {} | |
| def configure_deployment_env(metadata: dict[str, object]) -> None: | |
| """Expose safe deployment metadata to the API process.""" | |
| source_db = metadata.get("source_db") if isinstance(metadata.get("source_db"), dict) else {} | |
| website_variant = str(metadata.get("website_variant") or "").strip().lower() | |
| env_values = { | |
| "SYNDERESIS_GIT_COMMIT": metadata.get("git_commit", ""), | |
| "SYNDERESIS_GIT_BRANCH": metadata.get("git_branch", ""), | |
| "SYNDERESIS_BUILD_GENERATED_AT": metadata.get("generated_at", ""), | |
| "SYNDERESIS_SOURCE_DB_SHA256": source_db.get("sha256", "") if isinstance(source_db, dict) else "", | |
| "SYNDERESIS_SOURCE_DB_EMBEDDER_SIGNATURE": source_db.get("embedder_signature", "") if isinstance(source_db, dict) else "", | |
| } | |
| for key, value in env_values.items(): | |
| if value: | |
| os.environ.setdefault(key, str(value)) | |
| # The UI and API mode come from the same uploaded bundle, including upload-only deploys. | |
| os.environ["SYNDERESIS_WEBSITE_VARIANT"] = ( | |
| website_variant if website_variant in {"catholic", "research"} else "catholic" | |
| ) | |
| def log_deployment_metadata(metadata: dict[str, object]) -> None: | |
| """Emit structured non-secret deployment metadata once at startup.""" | |
| if not metadata: | |
| print("SYNDERESIS_DEPLOYMENT_INFO {}", file=sys.stderr, flush=True) | |
| return | |
| print(f"SYNDERESIS_DEPLOYMENT_INFO {json.dumps(metadata, sort_keys=True, separators=(',', ':'))}", file=sys.stderr, flush=True) | |
| def persistent_state_required() -> bool: | |
| """Return whether this deployment must use the mounted /data volume.""" | |
| raw_value = os.getenv(REQUIRE_PERSISTENT_STATE_ENV, "").strip().lower() | |
| if not raw_value: | |
| return False | |
| if raw_value in {"1", "true", "yes", "on"}: | |
| return True | |
| if raw_value in {"0", "false", "no", "off"}: | |
| return False | |
| raise RuntimeError( | |
| f"{REQUIRE_PERSISTENT_STATE_ENV} must be a boolean flag" | |
| ) | |
| def writable_runtime_dir() -> Path: | |
| """Return a writable directory for SQLite state.""" | |
| if ( | |
| PERSISTENT_STATE_DIR.is_dir() | |
| and os.access(PERSISTENT_STATE_DIR, os.W_OK) | |
| ): | |
| return PERSISTENT_STATE_DIR | |
| if persistent_state_required(): | |
| raise RuntimeError( | |
| "Persistent API state requires a writable /data volume" | |
| ) | |
| FALLBACK_RUNTIME_DIR.mkdir(parents=True, exist_ok=True) | |
| return FALLBACK_RUNTIME_DIR | |
| def configure_source_db() -> None: | |
| """Download the retrieval database from a Hub dataset when configured.""" | |
| if os.getenv("SYNDERESIS_SOURCE_DB"): | |
| return | |
| repo_id = os.getenv("SYNDERESIS_SOURCE_DB_REPO", "").strip() | |
| if not repo_id: | |
| return | |
| filename = os.getenv("SYNDERESIS_SOURCE_DB_FILENAME", "official_sources.sqlite3").strip() | |
| repo_type = os.getenv("SYNDERESIS_SOURCE_DB_REPO_TYPE", "dataset").strip() | |
| token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACE_HUB_TOKEN") or None | |
| downloaded_path = hf_hub_download(repo_id=repo_id, filename=filename, repo_type=repo_type, token=token) | |
| os.environ["SYNDERESIS_SOURCE_DB"] = downloaded_path | |
| print(f"Using source retrieval DB: {downloaded_path}", file=sys.stderr) | |
| def configure_defaults() -> None: | |
| """Set Space-safe defaults without overriding explicit variables.""" | |
| runtime_dir = writable_runtime_dir() | |
| os.environ.setdefault("SYNDERESIS_API_DB", str(runtime_dir / "synderesis_api.sqlite3")) | |
| if persistent_state_required(): | |
| ledger = Path(os.environ["SYNDERESIS_API_DB"]).resolve() | |
| if not ledger.is_relative_to(PERSISTENT_STATE_DIR.resolve()): | |
| raise RuntimeError( | |
| "Persistent API state requires SQLite under /data" | |
| ) | |
| os.environ.setdefault("SYNDERESIS_SQLITE_JOURNAL_MODE", "DELETE") | |
| os.environ.setdefault("SYNDERESIS_API_HOST", "0.0.0.0") | |
| os.environ.setdefault("SYNDERESIS_API_PORT", os.getenv("PORT", "7860")) | |
| os.environ.setdefault("SYNDERESIS_BACKEND", os.getenv("SYNDERESIS_MODEL_BACKEND", DEFAULT_BACKEND)) | |
| os.environ.setdefault("SYNDERESIS_MODEL_BACKEND", os.getenv("SYNDERESIS_BACKEND", DEFAULT_BACKEND)) | |
| if os.environ["SYNDERESIS_MODEL_BACKEND"] == "tinker": | |
| os.environ.setdefault( | |
| "SYNDERESIS_TINKER_MODEL_PATH", | |
| DEFAULT_TINKER_MODEL_PATH, | |
| ) | |
| os.environ.setdefault("SYNDERESIS_RETRIEVAL_LIMIT", "6") | |
| os.environ.setdefault("SYNDERESIS_CHAT_CONTEXT_MESSAGE_LIMIT", "12") | |
| os.environ.setdefault("SYNDERESIS_CHAT_CONTEXT_CHAR_LIMIT", "12000") | |
| os.environ.setdefault("SYNDERESIS_SOURCE_EMBEDDER", "harrier") | |
| os.environ.setdefault("NOLEGRAPH_AUTOLOAD_EMBEDDER", "1") | |
| stripe_names = ( | |
| "SYNDERESIS_STRIPE_SECRET_KEY", | |
| "SYNDERESIS_STRIPE_WEBHOOK_SECRET", | |
| "SYNDERESIS_STRIPE_FIXED_PRICE_ID", | |
| "SYNDERESIS_STRIPE_METERED_PRICE_ID", | |
| "SYNDERESIS_STRIPE_METER_EVENT_NAME", | |
| "SYNDERESIS_STRIPE_PUBLIC_ORIGIN", | |
| "SYNDERESIS_STRIPE_INCLUDED_RETAIL_MICRO_USD", | |
| "SYNDERESIS_STRIPE_FIXED_MONTHLY_CENTS", | |
| "SYNDERESIS_STRIPE_EXPECTED_LIVEMODE", | |
| "SYNDERESIS_STRIPE_REQUIRE_PERSISTENT_LEDGER", | |
| ) | |
| byok_fee_name = "SYNDERESIS_STRIPE_BYOK_PLATFORM_FEE_RATE" | |
| configured_byok_fee = os.getenv(byok_fee_name, "").strip() | |
| present = {name for name in stripe_names if os.getenv(name, "").strip()} | |
| if not present and configured_byok_fee: | |
| raise RuntimeError( | |
| "BYOK platform fee configuration requires Stripe billing" | |
| ) | |
| if present and present != set(stripe_names): | |
| raise RuntimeError("Stripe billing configuration is incomplete") | |
| if present: | |
| byok_fee = configured_byok_fee or "0.25" | |
| try: | |
| parsed_fee = Decimal(byok_fee) | |
| except (InvalidOperation, ValueError) as exc: | |
| raise RuntimeError( | |
| "Stripe BYOK platform fee rate must be a finite decimal" | |
| ) from exc | |
| if ( | |
| not parsed_fee.is_finite() | |
| or parsed_fee <= 0 | |
| or parsed_fee >= 1 | |
| ): | |
| raise RuntimeError( | |
| "Stripe BYOK platform fee rate must be greater than zero and less than one" | |
| ) | |
| os.environ[byok_fee_name] = byok_fee | |
| if os.environ["SYNDERESIS_STRIPE_REQUIRE_PERSISTENT_LEDGER"].lower() != "true": | |
| raise RuntimeError("Stripe billing requires persistent ledger enforcement") | |
| ledger = Path(os.environ["SYNDERESIS_API_DB"]).resolve() | |
| if not ledger.is_relative_to(Path("/data")): | |
| raise RuntimeError("Stripe billing requires persistent SQLite state under /data") | |
| def main() -> None: | |
| """Configure the container and replace this process with the API server.""" | |
| deployment_metadata = load_deployment_metadata() | |
| configure_deployment_env(deployment_metadata) | |
| log_deployment_metadata(deployment_metadata) | |
| configure_defaults() | |
| configure_source_db() | |
| port = os.environ["SYNDERESIS_API_PORT"] | |
| cmd = [ | |
| sys.executable, | |
| "scripts/serve_huggingface_api.py", | |
| "--host", | |
| os.environ["SYNDERESIS_API_HOST"], | |
| "--port", | |
| port, | |
| ] | |
| os.execvpe(sys.executable, cmd, os.environ) | |
| if __name__ == "__main__": | |
| main() | |