"""Entrypoint for the Distinct server on HuggingFace Spaces. This version is optimized for Spaces execution, where the Gradio app must be available at module level. """ from __future__ import annotations import os import sys try: # ZeroGPU hardware: the `spaces` package must be imported before gradio, # and startup fails unless at least one @spaces.GPU function exists. import spaces # type: ignore[import-not-found] except ImportError: # not on ZeroGPU (local dev, CPU Space) spaces = None # type: ignore[assignment] from distinct_protocol.netpolicy import announce_bind, launch_kwargs from distinct_server.auth_routes import attach as attach_auth from distinct_server.identity import NotConfigured, refuse_mocked_oauth from distinct_server.presentation import CSS, HEAD from distinct_server.ui import build_app, distinct_theme # Build the app at module level for Spaces demo = build_app() # Apply presentation settings demo.css = CSS demo.theme = distinct_theme() demo.head = HEAD if spaces is not None: @spaces.GPU def _zerogpu_presence() -> str: """Satisfy ZeroGPU's startup check. Distinct's GPU work happens on distributed worker machines, not in this Space, but ZeroGPU hardware refuses to start an app that declares no @spaces.GPU function. """ return "ok" # HuggingFace Spaces runs this file as a script, so __main__ executes there too. if __name__ == "__main__": try: refuse_mocked_oauth() except NotConfigured as reason: print(f"distinct: {reason}", file=sys.stderr) raise SystemExit(2) from None served = demo.queue(default_concurrency_limit=16, max_size=256) presentation = { "show_error": os.environ.get("DISTINCT_SHOW_ERRORS") == "1", "theme": distinct_theme(), "css": CSS, "head": HEAD, } on_spaces = os.environ.get("SYSTEM") == "spaces" and bool(os.environ.get("SPACE_ID")) if on_spaces: # On Spaces the platform dictates the bind: gradio reads # GRADIO_SERVER_NAME (0.0.0.0) and GRADIO_SERVER_PORT (7860) from the # environment. Never apply the local-dev network policy here — binding # 127.0.0.1 makes the Space unreachable and it hangs at "Preparing". served.launch(**presentation) raise SystemExit(0) # Local development path network = launch_kwargs() announce_bind(str(network["server_name"]), int(network["server_port"])) import fastapi import gradio as gr import uvicorn api = fastapi.FastAPI(docs_url=None, redoc_url=None, openapi_url=None) if attach_auth(api): print( "distinct: sign-in at /auth/login, callback at /auth/callback.", file=sys.stderr, flush=True, ) mounted = gr.mount_gradio_app(api, served, path="/", **presentation) uvicorn.run( mounted, host=str(network["server_name"]), port=int(network["server_port"]), ) else: served.launch(**presentation, **network)