wind-of-change/OnceHere_Timeline
OnceHere Timeline Studio — Hugging Face Space
A Docker-based Hugging Face Space for uploading OnceHere historical-place JSON packages, generating AI historical reconstructions for each timeline checkpoint, and exploring them as an interactive visual timeline.
Features
- Upload any compatible OnceHere timeline JSON.
- Dynamically reads the place, timeline checkpoints, prompts, stories, and sources.
- Joins content by
timepoint_id, never by array order. - Generates individual images or the full timeline.
- Uses OpenAI GPT Image through a server-side API key.
- Shows narrative, historical importance, prompt controls, disclosure, and sources.
- Includes a Pier 21 example package.
- Stores generated images under
/data/siteswhen persistent storage is mounted; otherwise uses the Space container filesystem.
Hugging Face Space configuration
This repository is configured as a Docker Space and serves FastAPI on port 7860.
Required secret
In your Space:
Settings → Variables and secrets → New secret
Create:
OPENAI_API_KEY = your OpenAI API keyDo not commit the key to this repository.
Optional variable
If your Space has persistent storage mounted at /data, no extra configuration is required.
You can override the storage directory with:
ONCEHERE_DATA_DIR=/data/sitesWithout persistent storage, imported JSON and generated images can disappear when the Space restarts or rebuilds.
Deploy
- Create a new Hugging Face Space.
- Select Docker as the SDK.
- Upload/push all files from this package to the root of the Space repository.
- Add
OPENAI_API_KEYas a Space secret. - Wait for the Space build to complete.
The Docker container starts:
uvicorn app:app --host 0.0.0.0 --port 7860Local Docker test
Build:
docker build -t oncehere-timeline .Run:
docker run --rm -p 7860:7860 \
-e OPENAI_API_KEY="$OPENAI_API_KEY" \
oncehere-timelineThen open:
http://127.0.0.1:7860Main files
app.py— FastAPI backend and image-generation API.static/index.html— frontend.static/app.js— upload, timeline, and generation behavior.static/styles.css— responsive UI.Dockerfile— Hugging Face Docker Space image.requirements.txt— Python dependencies.examples/pier21_timeline.json— example OnceHere site package.
JSON structure
Expected core fields:
place
timeline.timepoints[]
research.stories[] # optional
prompts.prompts[]
sources[]prompts.prompts[].timepoint_id should match timeline.timepoints[].timepoint_id.
If no explicit story is linked, the application uses the timepoint narrative as the displayed story.
Production note
The current Space is suitable for demonstration and controlled use. For a production OnceHere deployment, use persistent object storage and a database rather than depending on the Space's local filesystem.
v1.2 — Registered-site catalogue
The Space now discovers all persisted sites from the configured storage directory. A registered site is a folder containing package.json; its manifest.json and generated timeline images are loaded alongside it.
New endpoint:
GET /api/sites?query=&country=&city=The web UI supports:
- browsing all registered sites
- searching by site name, city, region, or country
- filtering by country
- filtering by city
- seeing checkpoint and generated-image counts
- opening an existing site's saved timeline without re-uploading JSON
Storage
Set the attached Hugging Face bucket/volume path explicitly when possible:
ONCEHERE_DATA_DIR=/data/sitesIf no explicit path is set, the app tries /data/sites before its local container directory.
Expected persistent structure:
/data/sites/
<place_id>/
package.json
manifest.json
T1.png
T2.png
...