Spaces:
Sleeping
Sleeping
|
Download README.md from Taimwe/trainhub-api: direct link, hf CLI and curl.
- Browser
- Download file 4.72 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
4.72 kB
| 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. | |