Deploying OpenSOC to Hugging Face Spaces
This is the one-time deployment recipe. The same Space serves both the
OpenEnv API (consumed by judge bots and OpenSOCClient) and a
Gradio "before vs after" UI at /demo for human reviewers.
1. Local sanity check
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python server.py &
sleep 2
curl -s http://localhost:7860/health | jq .
curl -s -X POST 'http://localhost:7860/reset?task=stage1_basic&mode=defender_only' | jq .
curl -s -I http://localhost:7860/demo | head -1 # should be 200 OK
kill %1
2. Build the Docker image locally
docker build -t opensoc:latest .
docker run -p 7860:7860 opensoc:latest
# in another shell:
curl -s http://localhost:7860/tasks | jq .
open http://localhost:7860/demo
3. Push to Hugging Face
The simplest path is via huggingface-cli; the second is a one-shot
script that does the same thing.
One-shot
export HF_USER=<your-username>
huggingface-cli login # browser-based PAT login
bash scripts/deploy_to_hf.sh
Manual (equivalent)
huggingface-cli login
huggingface-cli repo create opensoc-env --type space --space-sdk docker
# Use SPACE_README.md as the Space's README so HF picks up the docker SDK config:
cp SPACE_README.md /tmp/SPACE_README.md # save a copy
git checkout -b space-deploy
cp SPACE_README.md README.md # or prepend SPACE_README front-matter to README
git add README.md && git commit -m "Space metadata header"
git remote add space https://huggingface.co/spaces/$HF_USER/opensoc-env
git push space space-deploy:main
git checkout main && git checkout README.md
4. Verify the deployed Space
export OPENSOC_URL=https://<your-username>-opensoc-env.hf.space
python -c "
from client import OpenSOCClient
c = OpenSOCClient(base_url='$OPENSOC_URL')
print(c.health())
print(c.tasks())
obs = c.reset(task='stage1_basic', mode='defender_only', seed=1)
print('first log id:', obs['log_window'][0]['log_id'])
"
# And visually:
open $OPENSOC_URL/demo
/demo reads data/demo_examples.json. If you deployed before running
the GPU pipeline, the file holds the placeholder before-vs-after pairs
(always-dismiss vs verifier-oracle). Re-run python -m eval.bake_demo
on a GPU host (no --placeholder) and re-push to overwrite with real
trained-model outputs.
5. (Optional) Run the eval harness against the live Space
# Pure-CPU smoke run (no Unsloth required):
python -m eval.eval --smoke-only --holdout data/holdout.jsonl
OpenEnv hackathon checklist
-
openenv.yamlmanifest withendpoints.demo: GET /demo - gym-style API:
reset/step/state(+grade,tasks,health) - non-reserved tool names (
craft_incident,submit_triage) - FastAPI app exposed on port 7860 inside the container
- Gradio UI mounted at
/demofor the storytelling deliverable - Dockerfile suitable for Hugging Face Spaces (
sdk: docker) - Client / server separation (
client/opensoc_client.pyis HTTP-only) - Frozen 200-incident eval set committed (
data/holdout.jsonl) - 600-example SFT dataset committed (
data/sft_train.jsonl) - 50 pre-baked demo pairs committed (
data/demo_examples.json) - GRPO Colab/HF Jupyter notebook (
train_grpo.ipynb) + one-shotscripts/run_full_pipeline.sh - Pytest suite — 93 tests, all green