Spaces:
Running
Download README.md from mjpsm/activity-generation-api: direct link, hf CLI and curl.
- Browser
- Download file 7.96 kB
-
https://huggingface.co/spaces/mjpsm/activity-generation-api/resolve/main/README.md
- Command line
-
hf download hf://spaces/mjpsm/activity-generation-api/README.md
-
curl -L -o README.md https://huggingface.co/spaces/mjpsm/activity-generation-api/resolve/main/README.md
title: MyVillage Activity Generation API
emoji: 🌱
colorFrom: green
colorTo: blue
sdk: docker
app_port: 7860
pinned: false
MyVillage Activity Generation API
One lightweight FastAPI wrapper around three separately deployed Hugging Face Spaces:
- Progression: what the villager needs to do next.
- Composition: activity title and description from the progression plan.
- Instruction: step-by-step instructions from the progression and composition results.
Only the final title, description and instructions leave this API. No Qwen weights, GGUF files, Transformers, or GPU are needed in this Space.
Endpoint
POST /generate-activity with this JSON body:
{
"version": "v1",
"knowledge_submission": "I reviewed 25 saved chatbot conversations. I noticed the refund responses sometimes contradicted the policy, but I have not systematically documented the errors.",
"wisdom": {
"content": "Testing systems requires comparing observations with expected outcomes.",
"chapterTitle": "Testing With Purpose",
"BookTypeName": "Personal Records",
"BookType": "personal_record"
},
"village_goal": "Build and evaluate a reliable customer support chatbot",
"previous_activity_title": "Test Chatbot Conversations"
}
Response shape (generated text varies):
{
"output": {
"activity_title": "Evaluate Chatbot Response Accuracy",
"activity_description": "Review saved chatbot conversations to identify recurring errors in responses.",
"instructions": [
"Review the 25 saved chatbot conversations.",
"Compare responses with expected answers.",
"List recurring errors by category."
]
}
}
Input wisdom uses the exact existing field names content, chapterTitle, BookTypeName, BookType. The wrapper does not synthesize wisdom from the current knowledge submission. Progression fields are passed through: no success_evidence field is fabricated or required.
Other endpoints: GET /health (liveness), GET /docs (Swagger), GET /openapi.json.
Deploy on Hugging Face Spaces (Docker)
- Create a Docker Space named e.g.
mjpsm/activity-generation-api. - Copy the entire repository content into that Space (including
Dockerfile,app/,requirements.txt, and thisREADME.md). - Under Settings → Variables and secrets, set the three
*_API_URLvariables if needed, and optionally setAPI_KEYas a secret. SetHF_TOKENas a secret only if the upstream Spaces require authentication. - Wait for Space status Running, then open
https://mjpsm-activity-generation-api.hf.space/docs(assuming that is the Space name you selected). - Use Try it out for
POST /generate-activity, or issue the cURL request below.
Important: Live contract verification
The three Space repository identities have been checked, but their live OpenAPI JSON could not be fetched during development. This project does not claim the live POST paths or exact intermediate request bodies were verified. To avoid inventing endpoint paths, each default API URL points to its base; on first use, the wrapper asks that Space for /openapi.json and automatically selects the POST route when unambiguous.
If the upstream Space has multiple POST routes, set its URL to the full POST endpoint from that Space's /docs, such as https://...hf.space/<actual-post-path> (not /docs).
Intermediate request body contract
By default, this wrapper uses:
- Progression request: original input JSON as sent to
/generate-activity. - Composition request:
{"progression": <unwrapped progression object>}. - Instruction request:
{"progression": <unwrapped progression object>, "composition": {"activity_title": "...", "activity_description": "..."}}.
Common response envelopes {"output": ...} and {"progression": ...} are unwrapped before forwarding. Composition requires non-empty activity_title and activity_description. Instruction requires a nonempty array of nonblank strings in instructions.
If a deployed Space's actual request schema nests its inputs differently, use the corresponding Variables (no code edits needed):
| Variable | Value | Request body |
|---|---|---|
COMPOSITION_INPUT_STYLE |
direct (default) |
{"progression": {...}} |
input |
{"input": {"progression": {...}}} |
|
bare |
progression object directly | |
INSTRUCTION_INPUT_STYLE |
direct (default) |
{"progression": {...}, "composition": {"activity_title": "...", "activity_description": "..."}} |
nested_output |
{"progression": {...}, "composition": {"output": {"activity_title": "...", "activity_description": "..."}}} |
|
input |
wraps the direct request in {"input": ...} |
|
input_nested_output |
wraps the nested_output request in {"input": ...} |
A 502 upstream_http_error with HTTP 422 often indicates a request shape mismatch; check the upstream Swagger docs and change the applicable variable. Avoid silently retrying arbitrary alternate bodies or hiding schema mismatches.
Calling your wrapper
curl -X POST 'http://localhost:7860/generate-activity' \
-H 'Content-Type: application/json' \
-d '{
"version": "v1",
"knowledge_submission": "I tested the chatbot in 25 conversations but have not documented its recurring errors.",
"wisdom": {
"content": "Compare actual outputs against expectations when testing.",
"chapterTitle": "Test With Purpose",
"BookTypeName": "Personal Records",
"BookType": "personal_record"
},
"village_goal": "Build a reliable customer service chatbot",
"previous_activity_title": "Test Chatbot Conversations"
}'
If you set the API_KEY secret, also include -H 'X-API-Key: your-secret-key' in client calls. Treat this like a server-side key; don't embed it in public web frontend JavaScript.
Run locally
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
cp .env.example .env # optional reference; configure env vars in shell to apply them
uvicorn app.main:app --reload --port 7860
Note: This template intentionally does not load .env automatically, to avoid another dependency. To use .env locally, export the file's values into your shell or use a runner that reads dotenv files.
Run tests:
pytest -q
The tests mock all upstream model APIs. They validate orchestration, payload shapes, retries/errors, and output validation without inference costs. They are not live end-to-end verification.
Error handling and safety
- Input validation returns 422 before calling any model.
- Upstream errors return 502/503, and exhausted timeouts return 504. The error contains the failing
stageand a short code, but not submitted knowledge or model output. - Each model call is sequential; the wrapper stops on any error (no partial activities).
- Transient 429/502/503/504, timeouts, and network failures are retried once by default; HTTP 422 contract errors are not retried.
- Set
READ_TIMEOUT_SECONDSfor cold Spaces; default 240s.MAX_ATTEMPTSdefaults to 2. - Logs include stage names, timing and a request identifier, not user input.
GET /healthonly checks the wrapper. It does not prove the three upstream Spaces are awake.- Configure
API_KEYand keep upstreamHF_TOKENsecrets private before production use.
Check the live APIs before your first end-to-end test
On a machine with internet access, run:
python scripts/inspect_upstreams.py
This performs read-only GET requests to the three Spaces' OpenAPI documents. It shows their actual POST URLs, top-level request properties, and required properties without making inference calls. Compare its output with the COMPOSITION_INPUT_STYLE and INSTRUCTION_INPUT_STYLE settings above. You can set the three service URLs in the shell if they have changed.