Spaces:
Configuration error
Download README.md from Taimwe/trainhub-api: direct link, hf CLI and curl.
- Browser
- Download file 4.54 kB
-
https://huggingface.co/spaces/Taimwe/trainhub-api/resolve/main/README.md
- Command line
-
hf download hf://spaces/Taimwe/trainhub-api/README.md
-
curl -L -o README.md https://huggingface.co/spaces/Taimwe/trainhub-api/resolve/main/README.md
TrainHub API
A self-hosted AI training platform backend, modelled on the Hugging Face Hub.
Stack: FastAPI · SQLAlchemy (SQLite) · JWT auth · NumPy training worker · file storage · Hugging Face Hub bridge.
| Capability | Status |
|---|---|
| User registration / login (JWT) | ✅ real, persistent |
| Model / Dataset / Space repos (CRUD, likes) | ✅ real, persistent |
| File upload / list / download (disk + DB) | ✅ real |
| Training jobs (queue → run → metrics → complete) | ✅ real (NumPy backprop; swap in TRL for real models) |
| Hugging Face Hub search + model import | ✅ real (proxies hf.co) |
| Interactive API docs | ✅ /docs |
Run locally
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000
# open http://localhost:8000/docs
Run with Docker
docker build -t trainhub-api .
docker run -p 7860:7860 -e SECRET_KEY=secret -v $(pwd)/storage:/app/storage trainhub-api
Deploy to Hugging Face Spaces
This repo is a docker-SDK Space. Push to main and it builds automatically at
https://huggingface.co/spaces/Taimwe/trainhub-api.
Custom domain (you own a domain): in the Space settings open Settings → Custom domain, add e.g.
api.yourdomain.com, then in your DNS create aCNAMEfromapi.yourdomain.com→Taimwe-trainhub-api.hf.space(or the Space's.hf.spacehostname). For a root domain (yourdomain.com) you need anALIAS/ANAMErecord or a proxy; refer to your DNS provider. Custom domains require a paid HF plan + an HF token set on the Space.
Environment variables
| Var | Default | Purpose |
|---|---|---|
SECRET_KEY |
dev-secret-change-me |
JWT signing key — change in prod |
ACCESS_TOKEN_EXPIRE_MINUTES |
1440 |
token lifetime |
DATABASE_URL |
sqlite:///./trainhub.db |
SQLAlchemy URL (Postgres works too) |
STORAGE_DIR |
./storage |
where uploaded files land |
HF_TOKEN |
— | optional, raises Hub rate limits / enables private access |
API quick tour
Base URL: http://localhost:8000 (or your Space/domain).
Auth
POST /auth/register {"username","email","password"} -> {access_token, user}
POST /auth/login {"username","password"} -> {access_token, user}
Send the token as Authorization: Bearer <token>.
Models / Datasets / Spaces
POST /models {"name","description","pipeline_tag","tags","license"}
GET /models?search=&owner=
GET /models/{id}
PATCH /models/{id}
DELETE /models/{id}
POST /models/{id}/like
POST/GET/PATCH/DELETE /datasets (same pattern)
POST/GET/DELETE /spaces
Files
POST /files/model/{id} multipart "file" -> upload
GET /files/model/{id} -> list
GET /files/model/{id}/{filename} -> download (streamed)
dataset works the same way (/files/dataset/{id}).
Training jobs
POST /jobs {"base_model","dataset","config":{"epochs","lr","batch_size","seed"}}
GET /jobs
GET /jobs/{id}
GET /jobs/{id}/metrics -> [{epoch, loss}, ...] (loss genuinely decreases)
POST /jobs/{id}/cancel
Jobs run in a background thread and persist status + loss history to the DB.
Hugging Face Hub bridge
GET /hub/search?q=llama -> real models from hf.co
POST /hub/import {"repo_id"} -> import metadata into your local models
Meta
GET /health GET /stats GET /
Fine-tuning real models
The worker in app/services/training.py trains a small MLP with NumPy so the whole
stack runs anywhere with zero GPU. To fine-tune actual models, replace
_run() with a transformers/TRL call, e.g.:
from transformers import AutoModelForCausalLM, Trainer, TrainingArguments
model = AutoModelForCausalLM.from_pretrained(job.base_model)
trainer = Trainer(model=model, args=TrainingArguments(..., report_to=[]), train_dataset=ds)
for step in trainer.train(): # or a custom training loop
... # write loss to job.metrics each step, db.commit()
Point base_model at your HF model id (Taimwe/... or any public id) and add
torch/trl to requirements.txt.
Notes
- Single-process design (threads) is ideal for a self-hosted box. To scale to many
workers, replace
services/training.pywith a Celery/Redis or Kubernetes job runner and keep the same REST contract. - SQLite is the default for simplicity; set
DATABASE_URLto Postgres for production. CORSis wide open for local frontends; tightenallow_originsin production.