CASCADE β Hugging Face Spaces: Deployment Guide
Overview
The HF Space replaces Django with Flask but keeps the exact same Redis job-queue
pattern and frontend JS. The app is mounted at /cascade_v1/ so the live URL is:
https://patonlab-cascade.hf.space/cascade_v1/predict/
The Space is named cascade on HF β the _v1 is a subpath in Flask, not the repo name.
This means you can add cascade_v2 later under the same Space without creating a new repo.
hf_space/
βββ Dockerfile # Python 3.7, Redis, TF1.15, Keras 2.2.5
βββ requirements.txt
βββ start.sh # Redis β worker β gunicorn
βββ app.py # Flask Blueprint mounted at /cascade_v1
βββ worker.py # Redis consumer, runs GNN inference
βββ setup_assets.sh # One-time script: copies binaries from nova app
βββ README.md # HF Space card (YAML front-matter required)
βββ .gitattributes # Git LFS tracking for .hdf5 and .p files
βββ .gitignore
βββ NMR_Prediction/
β βββ __init__.py
β βββ apply.py # β copied + path-fixed by setup_assets.sh
β βββ genConf.py # β copied by setup_assets.sh
β βββ valid.py # new (simple RDKit SMILES check)
β βββ preprocessor.p # β copied by setup_assets.sh
β βββ schnet_edgeupdate/
β βββ best_model.hdf5 # β copied by setup_assets.sh (31 MB)
βββ nfp/ # β copied by setup_assets.sh
βββ static/ # β copied by setup_assets.sh
β βββ main.css
β βββ sketch.css
β βββ JSmol.min.js
β βββ images/
β βββ j2s/
β βββ jquery/
β βββ js/
β βββ jsme/
βββ templates/
βββ cascade/
βββ base.html
βββ home.html
βββ predict.html
βββ results.html
βββ about.html
Step 1 β Copy assets from the nova app
Run the setup script (copies model weights, inference code, static files, and applies the preprocessor path fix automatically):
cd ~/Documents/huggingface/cascade/hf_space
bash setup_assets.sh
You should see a β for each of the 5 asset groups. Afterwards confirm:
ls NMR_Prediction/ # apply.py genConf.py preprocessor.p schnet_edgeupdate/ valid.py __init__.py
ls nfp/ # __init__.py layers/ models/ preprocessing/
ls static/ # main.css JSmol.min.js j2s/ jsme/ jquery/ js/ images/
Step 2 β Test locally with Docker
cd ~/Documents/huggingface/cascade/hf_space
# Build (takes ~5 min first time β TF1.15 + RDKit are large)
docker build -t cascade-local .
# Run
docker run -p 7860:7860 cascade-local
# Open in browser
open http://localhost:7860/cascade_v1/predict/
What to check:
- Page loads, JSME editor opens
- Submitting
CC(=O)O(acetic acid) returns a task_id (check browser Network tab) check_taskeventually returns the results HTML with 2D SVG and shift table- Worker logs appear in the Docker terminal:
Processing task ...
Common first-run issues:
| Symptom | Fix |
|---|---|
ModuleNotFoundError: nfp |
Check nfp/ is in the root of hf_space, not nested inside another folder |
OSError: preprocessor.p not found |
Re-run setup_assets.sh β the path fix may not have applied |
keras load_model custom layer error |
Check custom_objects in worker.py match the nfp layer class names exactly |
| Redis connection refused | Redis takes ~1 s to start; the worker retries automatically β wait a moment |
500 on /cascade_v1/predict/ |
Check templates/cascade/predict.html exists |
| JSME editor blank | Check static/jsme/jsme.nocache.js was copied across |
Step 3 β Create the Hugging Face Space
# Install HF CLI if needed
pip install huggingface_hub
# Login (needs a write token from hf.co/settings/tokens)
huggingface-cli login
# Create the Space β named 'cascade', Docker SDK, public, under patonlab org
huggingface-cli repo create cascade \
--type space \
--space-sdk docker \
--organization patonlab
# This creates: https://huggingface.co/spaces/patonlab/cascade
# Live URL will be: https://patonlab-cascade.hf.space/cascade_v1/predict/
Step 4 β Push to Hugging Face
cd ~/Documents/huggingface/cascade/hf_space
git init
git lfs install # Required β .hdf5 and .p are tracked via Git LFS
# .gitattributes is already written; just add it
git add .gitattributes
git remote add origin https://huggingface.co/spaces/patonlab/cascade
git add .
git commit -m "Initial CASCADE HF Space deployment"
git push origin main
The Space builds automatically. Build logs at:
https://huggingface.co/spaces/patonlab/cascade β Logs tab
Build time is typically 8β12 minutes (TF1.15 + RDKit are large).
Step 5 β Verify the live Space
Once the build is green:
https://patonlab-cascade.hf.space/cascade_v1/predict/β page loads- Submit
CC(=O)O(acetic acid) β result in ~10β15 s - Submit
CC1=CC(=CC(=C1)O)Cβ result in ~30β45 s - Test the JSME drawing tool β OK β predicted shifts labelled on 2D structure
Step 6 β Update the GitHub README
Update patonlab/CASCADE on GitHub to point to the new URL:
The production web server can be found here:
https://patonlab-cascade.hf.space/cascade_v1/predict/
Ongoing maintenance
Pushing updates:
cd ~/Documents/huggingface/cascade/hf_space
git add . && git commit -m "your message" && git push origin main
HF rebuilds automatically on each push.
Checking logs: HF Space β Logs tab (worker output streams there in real time)
Cold starts: The free HF tier sleeps after inactivity. First request after sleep takes ~30 s. Upgrade to HF Pro ($9/mo) for persistent Spaces if needed.
Redis: Results have a 1-hour TTL and do not persist across container restarts. This is fine for interactive use.
What changed from the original Django app
| Original (nova) | New HF Space |
|---|---|
| Django 2.1 | Flask 2.0 with Blueprint at /cascade_v1 |
uwsgi |
gunicorn |
django.template tags |
Plain Jinja2 (/static/... paths) |
ALLOWED_HOSTS = ['129.82.62.62'] |
Flask HOST=0.0.0.0 |
Hard-coded SECRET_KEY |
Not needed (no sessions/auth) |
db.sqlite3 |
Removed (unused) |
cascade/preprocessor.p path |
NMR_Prediction/preprocessor.p |
| Model loaded in Django views at startup | Loaded once in worker.py at startup |
| Manual file copies + sed fix | Automated via setup_assets.sh |