mirror of
https://github.com/KohakuBlueleaf/KohakuHub.git
synced 2026-04-28 18:38:17 -05:00
update docs
This commit is contained in:
18
docs/API.md
18
docs/API.md
@@ -22,15 +22,15 @@ graph TB
|
||||
|
||||
subgraph "Storage Backend"
|
||||
LakeFS["LakeFS<br/>- Git-like versioning<br/>- Branch management<br/>- Commit history"]
|
||||
DB["PostgreSQL/SQLite<br/>- User data<br/>- Metadata<br/>- Deduplication"]
|
||||
DB["PostgreSQL/SQLite<br/>- User data<br/>- Metadata<br/>- Deduplication<br/>- Synchronous with db.atomic()"]
|
||||
S3["MinIO/S3<br/>- Object storage<br/>- LFS files<br/>- Presigned URLs"]
|
||||
end
|
||||
|
||||
Client -->|HTTP/Git/LFS| Nginx
|
||||
Nginx -->|Static files| Client
|
||||
Nginx -->|/api, /org, resolve| FastAPI
|
||||
FastAPI -->|REST API| LakeFS
|
||||
FastAPI -->|Queries| DB
|
||||
FastAPI -->|REST API (async)| LakeFS
|
||||
FastAPI -->|Sync queries with db.atomic()| DB
|
||||
FastAPI -->|Async wrappers| S3
|
||||
LakeFS -->|Stores objects| S3
|
||||
|
||||
@@ -771,6 +771,18 @@ Examples:
|
||||
LakeFS repo: "hf-dataset-johndoe-dataset"
|
||||
```
|
||||
|
||||
### Implementation Notes
|
||||
|
||||
**Database Operations:**
|
||||
- **Synchronous:** Uses Peewee ORM with synchronous operations
|
||||
- **Transactions:** `db.atomic()` ensures ACID compliance across concurrent workers
|
||||
- **Multi-Worker Safe:** Designed for horizontal scaling (4-8 workers recommended)
|
||||
- **Future:** Migration to peewee-async planned for improved concurrency
|
||||
|
||||
**LakeFS Operations:**
|
||||
- **Pure Async:** All operations use REST API via httpx (no thread pools!)
|
||||
- **No Deprecated Library:** Uses direct REST API instead of lakefs-client
|
||||
|
||||
### Key Operations
|
||||
|
||||
**All LakeFS operations use pure async REST API via httpx (no thread pools!):**
|
||||
|
||||
42
docs/Git.md
42
docs/Git.md
@@ -911,9 +911,10 @@ def parse_git_credentials(authorization: str | None) -> tuple[str | None, str |
|
||||
### Token Validation
|
||||
|
||||
```python
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from kohakuhub.auth.utils import hash_token
|
||||
from kohakuhub.db import Token, User
|
||||
from kohakuhub.db_async import execute_db_query
|
||||
from kohakuhub.db import Token, User, db
|
||||
|
||||
async def get_user_from_git_auth(authorization: str | None) -> User | None:
|
||||
"""Authenticate user from Git Basic Auth."""
|
||||
@@ -924,31 +925,22 @@ async def get_user_from_git_auth(authorization: str | None) -> User | None:
|
||||
# Hash and lookup token
|
||||
token_hash = hash_token(token_str)
|
||||
|
||||
def _get_token():
|
||||
return Token.get_or_none(Token.token_hash == token_hash)
|
||||
# Database operations are synchronous with transactions
|
||||
with db.atomic():
|
||||
token = Token.get_or_none(Token.token_hash == token_hash)
|
||||
if not token:
|
||||
return None
|
||||
|
||||
token = await execute_db_query(_get_token)
|
||||
if not token:
|
||||
return None
|
||||
# Get user
|
||||
user = User.get_or_none(User.id == token.user_id)
|
||||
if not user or not user.is_active:
|
||||
return None
|
||||
|
||||
# Get user
|
||||
def _get_user():
|
||||
return User.get_or_none(User.id == token.user_id)
|
||||
|
||||
user = await execute_db_query(_get_user)
|
||||
if not user or not user.is_active:
|
||||
return None
|
||||
|
||||
# Update last used
|
||||
from datetime import datetime, timezone
|
||||
|
||||
def _update_token():
|
||||
# Update last used
|
||||
Token.update(last_used=datetime.now(timezone.utc)).where(
|
||||
Token.id == token.id
|
||||
).execute()
|
||||
|
||||
await execute_db_query(_update_token)
|
||||
|
||||
return user
|
||||
```
|
||||
|
||||
@@ -1032,12 +1024,12 @@ async def git_head(
|
||||
Since we don't know if a repo is a model/dataset/space from the URL alone:
|
||||
|
||||
```python
|
||||
from kohakuhub.db import Repository
|
||||
from kohakuhub.db_async import execute_db_query
|
||||
from kohakuhub.db import Repository, db
|
||||
|
||||
async def find_repository(namespace: str, name: str) -> Repository | None:
|
||||
"""Find repository by trying all types."""
|
||||
def _get_repo():
|
||||
# Database operations are synchronous
|
||||
with db.atomic():
|
||||
for repo_type in ["model", "dataset", "space"]:
|
||||
repo = Repository.get_or_none(
|
||||
Repository.namespace == namespace,
|
||||
@@ -1047,8 +1039,6 @@ async def find_repository(namespace: str, name: str) -> Repository | None:
|
||||
if repo:
|
||||
return repo
|
||||
return None
|
||||
|
||||
return await execute_db_query(_get_repo)
|
||||
```
|
||||
|
||||
### Registering the Router
|
||||
|
||||
@@ -181,7 +181,11 @@ npm run dev --prefix ./src/kohaku-hub-ui
|
||||
|
||||
**Backend** (port 48888):
|
||||
```bash
|
||||
# Single worker (development with hot reload)
|
||||
uvicorn kohakuhub.main:app --reload --port 48888
|
||||
|
||||
# Multi-worker (production-like testing)
|
||||
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
|
||||
```
|
||||
|
||||
**Client Access:**
|
||||
@@ -200,6 +204,69 @@ uvicorn kohakuhub.main:app --reload --port 48888
|
||||
- **Everything:** http://localhost:28080 (Web UI + API)
|
||||
- Swagger Docs (dev): http://localhost:48888/docs (if port exposed)
|
||||
|
||||
## Multi-Worker Deployment
|
||||
|
||||
KohakuHub supports horizontal scaling with multiple worker processes.
|
||||
|
||||
### Database Architecture
|
||||
|
||||
**Synchronous Database Operations:**
|
||||
- Uses Peewee ORM with synchronous operations
|
||||
- `db.atomic()` transactions ensure consistency across workers
|
||||
- No async database wrappers needed
|
||||
- Safe for multi-worker deployments
|
||||
|
||||
**Why Synchronous?**
|
||||
- PostgreSQL and SQLite handle concurrent connections internally
|
||||
- Atomic transactions prevent race conditions
|
||||
- Simpler code without async/await complexity
|
||||
- Better compatibility with multi-worker setups
|
||||
|
||||
**Future:** Migration to peewee-async is planned for improved concurrency.
|
||||
|
||||
### Running Multi-Worker
|
||||
|
||||
**Development/Testing:**
|
||||
```bash
|
||||
# 4 workers (recommended for testing)
|
||||
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
|
||||
|
||||
# 8 workers (production-like load)
|
||||
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 8
|
||||
```
|
||||
|
||||
**Docker Deployment:**
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
hub-api:
|
||||
command: uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
|
||||
```
|
||||
|
||||
### Worker Recommendations
|
||||
|
||||
| Deployment | Workers | CPU | Memory | Notes |
|
||||
|------------|---------|-----|--------|-------|
|
||||
| Development | 1 | 2 cores | 2GB | Hot reload enabled |
|
||||
| Small | 2-4 | 4 cores | 4GB | For <100 users |
|
||||
| Medium | 4-8 | 8 cores | 8GB | For <1000 users |
|
||||
| Large | 8-16 | 16+ cores | 16GB+ | For >1000 users |
|
||||
|
||||
**Formula:** Workers = (2 × CPU cores) + 1
|
||||
|
||||
### Benefits of Multi-Worker
|
||||
|
||||
1. **Horizontal Scaling:** Handle more concurrent requests
|
||||
2. **High Availability:** Worker crashes don't affect others
|
||||
3. **Better Resource Utilization:** Leverage multiple CPU cores
|
||||
4. **Load Distribution:** Requests distributed across workers
|
||||
|
||||
### Limitations
|
||||
|
||||
- Cannot use `--reload` with multiple workers
|
||||
- Shared state must use database or external cache
|
||||
- Log aggregation recommended for debugging
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### Production Deployment
|
||||
|
||||
@@ -305,6 +305,68 @@ docker-compose up -d --build
|
||||
|
||||
**Note:** Check CHANGELOG for breaking changes before updating.
|
||||
|
||||
## Multi-Worker Deployment
|
||||
|
||||
For production deployments, running multiple workers improves performance and availability.
|
||||
|
||||
### Database Architecture
|
||||
|
||||
KohakuHub uses **synchronous database operations** with Peewee ORM:
|
||||
- `db.atomic()` transactions ensure data consistency
|
||||
- Safe for concurrent access from multiple workers
|
||||
- PostgreSQL and SQLite handle connection pooling internally
|
||||
- No async database wrappers needed
|
||||
|
||||
**Future:** Migration to peewee-async planned for better concurrency.
|
||||
|
||||
### Running with Multiple Workers
|
||||
|
||||
**Development Testing:**
|
||||
```bash
|
||||
# 4 workers (recommended for testing)
|
||||
uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
|
||||
|
||||
# Test with load
|
||||
ab -n 1000 -c 10 http://localhost:48888/health
|
||||
```
|
||||
|
||||
**Docker Deployment:**
|
||||
|
||||
Edit your `docker-compose.yml`:
|
||||
```yaml
|
||||
services:
|
||||
hub-api:
|
||||
image: kohakuhub-api
|
||||
command: uvicorn kohakuhub.main:app --host 0.0.0.0 --port 48888 --workers 4
|
||||
environment:
|
||||
- KOHAKU_HUB_BASE_URL=http://localhost:28080
|
||||
# ... other env vars
|
||||
```
|
||||
|
||||
### Worker Scaling Guide
|
||||
|
||||
| Deployment Size | Workers | CPU Cores | Memory | Concurrent Users |
|
||||
|----------------|---------|-----------|--------|------------------|
|
||||
| Development | 1 | 2 | 2GB | <10 |
|
||||
| Small | 2-4 | 4 | 4GB | <100 |
|
||||
| Medium | 4-8 | 8 | 8GB | <1000 |
|
||||
| Large | 8-16 | 16+ | 16GB+ | >1000 |
|
||||
|
||||
**Recommended Formula:** Workers = (2 × CPU cores) + 1
|
||||
|
||||
### Benefits
|
||||
|
||||
- **Horizontal Scaling:** Handle more concurrent requests
|
||||
- **High Availability:** One worker crash doesn't affect others
|
||||
- **CPU Utilization:** Leverage multiple cores efficiently
|
||||
- **Load Balancing:** Uvicorn distributes requests automatically
|
||||
|
||||
### Limitations
|
||||
|
||||
- Cannot use `--reload` flag with multiple workers
|
||||
- In-memory caches are per-worker (use Redis for shared cache)
|
||||
- Log output from all workers (use log aggregation)
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user