--- title: Celery Space emoji: 🐳 colorFrom: blue colorTo: gray sdk: docker app_port: 7860 startup_duration_timeout: 3h pinned: false --- # Celery Docker Space This Space is configured as a Docker-based Hugging Face Space. The container installs FastAPI, Uvicorn, and `websocket-client`. `app.py` is a small entrypoint; the worker code lives in `space_worker/`. During ASGI import, it starts a Supabase Realtime worker thread and then intentionally blocks so the Space stays in the Starting state instead of binding to port `7860`. The Space also expects the Hugging Face bucket `admincybers2/protexa-model-space` to be mounted at `/models`. The current instruction model path is `/models/protexa_instruction`, populated from `admincybers2/protexa_instruction`. ## Layout ```text app.py space_worker/ config.py http.py logging_setup.py messages.py model_store.py runtime.py supabase.py worker.py ``` ## Flow 1. Space A connects to Supabase Realtime. 2. Space A subscribes to `SUPABASE_SPACE_INBOX_TOPIC`, default `space-a`. 3. User `ABC` sends a broadcast to channel `space-a`. 4. Space A receives the message, builds `Hello ABC`, and broadcasts it to `user-ABC`. 5. User `ABC` receives the response from their own channel. ## Model Bucket The uploader in this package can mount: ```text hf://buckets/admincybers2/protexa-model-space:/models ``` Runtime variables: ```text MODEL_BUCKET_ID=admincybers2/protexa-model-space MODEL_BUCKET_MOUNT_PATH=/models PROTEXA_INSTRUCTION_REPO_ID=admincybers2/protexa_instruction PROTEXA_INSTRUCTION_MODEL_DIR=/models/protexa_instruction ``` When the Space starts, `space_worker.model_store.ModelStore` checks the mount and logs whether these expected files exist under `/models/protexa_instruction`: ```text .gitattributes README.md checkpoint_best.pt instruction_audit.json metrics_history.jsonl tokenizer_map.json train.txt ``` ## User Request The user sends this to channel `space-a`. By default the worker accepts any broadcast event name with `SUPABASE_REQUEST_EVENTS=*`, including the Inspector default `Test message`. ```json { "user_id": "ABC", "message": "hello", "correlation_id": "request_uuid" } ``` ## Space Response Space A sends this to channel `user-ABC`, event `message`: ```json { "type": "space.response", "ok": true, "user_id": "ABC", "session_id": null, "correlation_id": "request_uuid", "request": { "message": "hello" }, "message": "Hello ABC", "created_at": "2026-06-26T00:00:00+00:00" } ``` ## JavaScript Client Sketch ```js const userId = 'ABC' const inbox = supabase.channel('space-a', { config: { private: true, broadcast: { ack: true } }, }) const replies = supabase.channel(`user-${userId}`, { config: { private: true }, }) replies.on('broadcast', { event: 'message' }, ({ payload }) => { console.log(payload.message) }) await replies.subscribe() await inbox.subscribe() await inbox.send({ type: 'broadcast', event: 'message', payload: { user_id: userId, message: 'hello', correlation_id: crypto.randomUUID(), }, }) ``` Private channels require Supabase Realtime authorization policies. For a quick Realtime Inspector test, you can temporarily set both private flags to `false`, then switch them back to `true` for real users.