Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions deploy/hf-space/DEPLOY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Hugging Face Docker Space — deploy runbook

Publishes the read-only demo (`Dockerfile` + `README.md` in this directory) as a
Hugging Face Docker Space. The Space builds the image itself from the public
GitHub repo, so only these two files are pushed to the Space repo.

## Local / Mac build verification (do this before deploying)

Docker is Mac-only in this setup (Windows does not run the daemon). The build
context is this directory; the repo is cloned inside the image.

```bash
docker build -t agentflow-hf deploy/hf-space
docker run --rm -p 8000:8000 agentflow-hf &
sleep 25
curl -fsS http://localhost:8000/v1/health
curl -fsS -H "X-API-Key: demo-key" http://localhost:8000/v1/entity/order/ORD-20260404-1001
```

## Deploy (outward — gated)

Creating/pushing a public Space under the `liovina` account is an external
publish. The HF token lives in `D:/VacancyRadar/.env` (`HF_TOKEN`); never print it.

```bash
# 1. Create the Space (one-time)
huggingface-cli repo create agentflow-demo --repo-type space --space_sdk docker

# 2. Push the two files to the Space repo root
# (clone the Space repo, copy Dockerfile + README.md, commit, push)
git clone https://huggingface.co/spaces/liovina/agentflow-demo /tmp/agentflow-space
cp deploy/hf-space/Dockerfile deploy/hf-space/README.md /tmp/agentflow-space/
cd /tmp/agentflow-space && git add Dockerfile README.md \
&& git commit -m "AgentFlow read-only demo (docker sdk)" && git push
```

The Space builds the Dockerfile and serves on `app_port: 8000`. Live URL:
`https://liovina-agentflow-demo.hf.space`.

## Verify live

```bash
curl -fsS https://liovina-agentflow-demo.hf.space/v1/health
curl -fsS -H "X-API-Key: demo-key" \
https://liovina-agentflow-demo.hf.space/v1/entity/order/ORD-20260404-1001
```

## Refresh after a repo change

The Space tracks `main` (`ARG AGENTFLOW_REF=main`). Trigger a rebuild from the
Space UI ("Factory rebuild"), or bump `AGENTFLOW_REF` to a tag for a pinned demo.
72 changes: 72 additions & 0 deletions deploy/hf-space/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# AgentFlow — public read-only demo for Hugging Face Docker Spaces.
#
# Builds the serving API from the public GitHub repo and runs it in demo mode
# (seeded DuckDB, admin routes 404, mutating routes blocked except /v1/query).
# Mirrors Dockerfile.api / deploy/fly — the same single-container demo, repointed
# at Spaces' port + writable-home conventions.
#
# Local / Mac verify (context is this directory; the repo is cloned at build time):
# docker build -t agentflow-hf deploy/hf-space
# docker run --rm -p 8000:8000 agentflow-hf
# curl -fsS http://localhost:8000/v1/health
# curl -fsS -H "X-API-Key: demo-key" http://localhost:8000/v1/entity/order/ORD-20260404-1001

FROM python:3.11-slim@sha256:ae52c5bef62a6bdd42cd1e8dffef86b9cd284bde9427da79839de7a4b983e7ca AS builder

WORKDIR /build
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Track main by default; pin to a tag/sha with --build-arg AGENTFLOW_REF=v1.5.0
ARG AGENTFLOW_REF=main
RUN apt-get update \
&& apt-get install -y --no-install-recommends git \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch "${AGENTFLOW_REF}" \
https://github.com/brownjuly2003-code/agentflow.git /src
WORKDIR /src
RUN pip install --no-cache-dir --upgrade pip build hatchling \
&& python -m build --wheel --outdir /tmp/dist

FROM python:3.11-slim@sha256:ae52c5bef62a6bdd42cd1e8dffef86b9cd284bde9427da79839de7a4b983e7ca

WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV AGENTFLOW_ENTITY_CONTRACTS_DIR=/app/contracts/entities

# Demo mode (mirrors deploy/fly/README.md): injected public key, admin routes
# return 404, mutating routes blocked except POST /v1/query[/explain], DuckDB
# seeded on first boot. Data lives under the demo user's writable home.
ENV AGENTFLOW_DEMO_MODE=true
ENV AGENTFLOW_SEED_ON_BOOT=true
ENV DEMO_API_KEY=demo-key
ENV DUCKDB_PATH=/home/user/data/agentflow-demo.duckdb
ENV AGENTFLOW_USAGE_DB_PATH=/home/user/data/agentflow-demo-api.duckdb

COPY --from=builder /src/requirements.txt /app/requirements.txt
COPY --from=builder /src/config /app/config
COPY --from=builder /src/contracts /app/contracts
COPY --from=builder /tmp/dist /tmp/dist

RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir --upgrade setuptools==82.0.1 wheel==0.47.0 \
&& pip install --no-cache-dir -r requirements.txt \
&& wheel="$(find /tmp/dist -name '*.whl' -print -quit)" \
&& pip install --no-cache-dir "${wheel}[cloud]" \
&& pip install --no-cache-dir bcrypt PyYAML sqlglot \
&& rm -rf /tmp/dist

# Hugging Face Spaces runs the container as UID 1000 with $HOME=/home/user.
RUN useradd -m -u 1000 user \
&& mkdir -p /home/user/data \
&& chown -R user:user /home/user/data
USER user
ENV HOME=/home/user

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/v1/health', timeout=3).read()" || exit 1

CMD ["uvicorn", "src.serving.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
50 changes: 50 additions & 0 deletions deploy/hf-space/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: AgentFlow Demo
colorFrom: gray
colorTo: indigo
sdk: docker
app_port: 8000
pinned: false
---

# AgentFlow — live demo

An event-native metrics layer: business metrics are produced by operational
events and stay live — the serving cache is invalidated when events arrive, so
reads reflect the latest state rather than a batch snapshot.

This Space runs the serving API as a single read-only container, seeded with
demo data on boot. It is built from the public source at
[github.com/brownjuly2003-code/agentflow](https://github.com/brownjuly2003-code/agentflow).

## Demo-mode behaviour

- A public demo key (`demo-key`) is injected; no signup needed.
- Admin routes (`/v1/admin/*`, `/admin/*`) return `404`.
- Mutating routes are blocked, except `POST /v1/query` and `POST /v1/query/explain`.
- DuckDB demo data is seeded on first boot.

## Try it

`{SPACE}` is the Space URL (e.g. `https://liovina-agentflow-demo.hf.space`).

```bash
# Liveness
curl -fsS {SPACE}/v1/health

# Entity point-lookup (seeded order)
curl -fsS -H "X-API-Key: demo-key" \
{SPACE}/v1/entity/order/ORD-20260404-1001

# Natural-language query (rule-based by default)
curl -fsS -X POST -H "X-API-Key: demo-key" -H "Content-Type: application/json" \
-d '{"question": "revenue in the last hour"}' \
{SPACE}/v1/query

# Demo-mode guards
curl -i -H "X-Admin-Key: admin-secret" {SPACE}/v1/admin/usage # 404
curl -i -X POST -H "X-API-Key: demo-key" -H "Content-Type: application/json" \
-d '{"requests":[]}' {SPACE}/v1/batch # 403
```

Interactive API docs are at `{SPACE}/docs`.
Loading