Spaces:
Sleeping
Sleeping
File size: 4,724 Bytes
f16f8f7 3149a63 4ae86e9 3149a63 4ae86e9 3149a63 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | ---
title: TrainHub API
emoji: 🚂
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 7860
pinned: false
short_description: Self-hosted AI training platform backend (FastAPI)
---
# 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
```bash
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000
# open http://localhost:8000/docs
```
## Run with Docker
```bash
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 a `CNAME` from
> `api.yourdomain.com` → `Taimwe-trainhub-api.hf.space` (or the Space's `.hf.space`
> hostname). For a root domain (`yourdomain.com`) you need an `ALIAS`/`ANAME` record 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.:
```python
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.py` with a Celery/Redis or Kubernetes job runner
and keep the same REST contract.
- SQLite is the default for simplicity; set `DATABASE_URL` to Postgres for production.
- `CORS` is wide open for local frontends; tighten `allow_origins` in production.
|