081bb3d371
- Document unified search with --provider flag (civitai, hf, all) - Add /api/search to server endpoints - Add TypeScript client section (@saiden/tensors) - Add public API info (tensors-api.saiden.dev) - Update search options table with provider column Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
443 lines
11 KiB
Markdown
443 lines
11 KiB
Markdown
<p align="center">
|
|
<img src="icon.svg" alt="tensors" width="96" height="96">
|
|
</p>
|
|
|
|
<h1 align="center">tensors</h1>
|
|
|
|
<p align="center">
|
|
<a href="https://pypi.org/project/tensors"><img src="https://img.shields.io/pypi/v/tensors?color=blue" alt="PyPI"></a>
|
|
<img src="https://img.shields.io/badge/coverage-73%25-brightgreen" alt="Coverage">
|
|
<img src="https://img.shields.io/badge/python-3.12+-blue" alt="Python">
|
|
<a href="https://github.com/saiden-dev/tensors/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
|
|
</p>
|
|
|
|
<p align="center">
|
|
A CLI tool for working with safetensor files, CivitAI models, and stable-diffusion.cpp image generation.
|
|
</p>
|
|
|
|
## Features
|
|
|
|
- **Read safetensor metadata** - Parse headers, count tensors, extract embedded metadata
|
|
- **CivitAI integration** - Search models, fetch info, identify files by hash
|
|
- **Download models** - Resume support, type-based default paths
|
|
- **Hash verification** - SHA256 computation with progress display
|
|
- **Image generation** - txt2img/img2img via stable-diffusion.cpp server
|
|
- **Server wrapper** - FastAPI wrapper for sd-server with hot reload
|
|
- **Models database** - SQLite cache for local files and CivitAI metadata
|
|
- **Image gallery** - Manage generated images with metadata
|
|
- **Remote mode** - Control remote tsr servers via `--remote` flag
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Clone and install
|
|
git clone https://github.com/saiden-dev/tensors.git
|
|
cd tensors
|
|
uv sync
|
|
|
|
# Or install directly
|
|
uv pip install git+https://github.com/saiden-dev/tensors.git
|
|
|
|
# With server wrapper support
|
|
pip install tensors[server]
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Search Models
|
|
|
|
Search across CivitAI and Hugging Face with a unified interface.
|
|
|
|
```bash
|
|
# Search both CivitAI and Hugging Face (default)
|
|
tsr search "flux lora"
|
|
|
|
# Search CivitAI only
|
|
tsr search "illustrious" -P civitai
|
|
|
|
# Search Hugging Face only
|
|
tsr search "flux" -P hf
|
|
|
|
# Filter by type and base model (CivitAI)
|
|
tsr search -t lora -b sdxl
|
|
|
|
# Sort by newest, limit results
|
|
tsr search -t checkpoint -s newest -n 10
|
|
|
|
# Filter by tag and period
|
|
tsr search --tag anime -p week -b illustrious
|
|
|
|
# By creator/author
|
|
tsr search -u "username" # CivitAI
|
|
tsr search -a "stabilityai" -P hf # Hugging Face
|
|
|
|
# SFW only with commercial use filter
|
|
tsr search --sfw --commercial sell
|
|
|
|
# Hugging Face pipeline filter
|
|
tsr search --pipeline text-to-image -P hf
|
|
```
|
|
|
|
### Get Model Info
|
|
|
|
```bash
|
|
# Get model info by ID (shows all versions)
|
|
tsr get 12345
|
|
|
|
# Get specific version info
|
|
tsr get -v 67890
|
|
```
|
|
|
|
### Download Models
|
|
|
|
```bash
|
|
# Download latest version of a model
|
|
tsr dl -m 12345
|
|
|
|
# Download specific version
|
|
tsr dl -v 67890
|
|
|
|
# Download by hash lookup
|
|
tsr dl -H ABC123...
|
|
|
|
# Custom output directory
|
|
tsr dl -m 12345 -o ./models
|
|
```
|
|
|
|
### Hugging Face Integration
|
|
|
|
Get info and download safetensor files from Hugging Face Hub.
|
|
|
|
```bash
|
|
# Get model info and list safetensor files
|
|
tsr hf get black-forest-labs/FLUX.1-schnell
|
|
|
|
# List safetensor files only
|
|
tsr hf files black-forest-labs/FLUX.1-schnell
|
|
|
|
# Download a specific safetensor file
|
|
tsr hf dl black-forest-labs/FLUX.1-schnell -f ae.safetensors
|
|
|
|
# Download all safetensor files from a model
|
|
tsr hf dl author/model --all -o ./models
|
|
```
|
|
|
|
> **Note:** For searching Hugging Face, use `tsr search -P hf "query"` (see [Search Models](#search-models)).
|
|
|
|
### Inspect Local Files
|
|
|
|
```bash
|
|
# Read safetensor file and lookup on CivitAI
|
|
tsr info model.safetensors
|
|
|
|
# Skip CivitAI lookup
|
|
tsr info model.safetensors --skip-civitai
|
|
|
|
# Output as JSON
|
|
tsr info model.safetensors -j
|
|
|
|
# Save metadata files
|
|
tsr info model.safetensors --save-to ./metadata
|
|
```
|
|
|
|
### Generate Images
|
|
|
|
Requires a running [stable-diffusion.cpp](https://github.com/leejet/stable-diffusion.cpp) server.
|
|
|
|
```bash
|
|
# Generate an image
|
|
tsr generate "a cat sitting on a roof"
|
|
|
|
# Custom size, steps, and output
|
|
tsr generate "sunset over mountains" -W 768 -H 512 --steps 30 -o ./output
|
|
|
|
# Multiple images with seed
|
|
tsr generate "cyberpunk city" -b 4 -s 42
|
|
|
|
# With sampler and negative prompt
|
|
tsr generate "portrait" --sampler euler_a -n "blurry, low quality"
|
|
```
|
|
|
|
### Server Wrapper
|
|
|
|
Manage sd-server process via a REST API. Requires `pip install tensors[server]`.
|
|
|
|
```bash
|
|
# Start the wrapper API with a model
|
|
tsr serve --model /path/to/model.safetensors
|
|
|
|
# Custom host and port
|
|
tsr serve --model /path/to/model.safetensors --host 0.0.0.0 --port 51200
|
|
|
|
# Check server status
|
|
tsr status
|
|
|
|
# Hot-reload with a new model
|
|
tsr reload --model /path/to/other_model.safetensors
|
|
```
|
|
|
|
### Models Database
|
|
|
|
Track local safetensor files and cache CivitAI metadata for offline access.
|
|
|
|
```bash
|
|
# Scan a directory for safetensor files
|
|
tsr db scan /path/to/models
|
|
|
|
# Link unscanned files to CivitAI by hash
|
|
tsr db link
|
|
|
|
# Cache full CivitAI model data
|
|
tsr db cache 12345
|
|
|
|
# List local files with CivitAI info
|
|
tsr db list
|
|
|
|
# Search cached models offline
|
|
tsr db search "pony"
|
|
tsr db search -t lora -b sdxl
|
|
|
|
# Get trigger words for a LoRA
|
|
tsr db triggers model.safetensors
|
|
|
|
# Show database statistics
|
|
tsr db stats
|
|
```
|
|
|
|
### Image Gallery
|
|
|
|
Manage generated images on a remote server.
|
|
|
|
```bash
|
|
# List images in gallery
|
|
tsr images list --remote junkpile
|
|
|
|
# Show image metadata
|
|
tsr images show IMAGE_ID --remote junkpile
|
|
|
|
# Download an image
|
|
tsr images download IMAGE_ID --remote junkpile -o ./downloads
|
|
|
|
# Delete an image
|
|
tsr images delete IMAGE_ID --remote junkpile
|
|
```
|
|
|
|
### Model Management
|
|
|
|
List and switch models on a remote server.
|
|
|
|
```bash
|
|
# List available models
|
|
tsr models list --remote junkpile
|
|
|
|
# Show active model
|
|
tsr models active --remote junkpile
|
|
|
|
# Switch to a different model
|
|
tsr models switch /path/to/model.safetensors --remote junkpile
|
|
|
|
# List available LoRAs
|
|
tsr models loras --remote junkpile
|
|
```
|
|
|
|
### Remote Mode
|
|
|
|
Control a remote tsr server instead of local operations.
|
|
|
|
```bash
|
|
# Configure a remote server
|
|
tsr remote add junkpile http://junkpile:51200
|
|
|
|
# Set default remote
|
|
tsr remote default junkpile
|
|
|
|
# List configured remotes
|
|
tsr remote list
|
|
|
|
# Generate on remote server
|
|
tsr generate "a cat" --remote junkpile
|
|
|
|
# Download model to remote server
|
|
tsr dl -m 12345 --remote junkpile
|
|
|
|
# All commands support --remote flag
|
|
tsr status --remote junkpile
|
|
```
|
|
|
|
### Configuration
|
|
|
|
```bash
|
|
# Show current config
|
|
tsr config
|
|
|
|
# Set CivitAI API key
|
|
tsr config --set-key YOUR_API_KEY
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Config file: `~/.config/tensors/config.toml`
|
|
|
|
```toml
|
|
[api]
|
|
civitai_key = "your-api-key"
|
|
|
|
[remotes]
|
|
junkpile = "http://junkpile:51200"
|
|
local = "http://localhost:51200"
|
|
|
|
# Optional: set default remote for all commands
|
|
default_remote = "junkpile"
|
|
```
|
|
|
|
Or set API keys via environment variables:
|
|
```bash
|
|
export CIVITAI_API_KEY="your-api-key" # For CivitAI API access
|
|
export TENSORS_API_KEY="your-server-key" # For server authentication
|
|
```
|
|
|
|
## Default Paths
|
|
|
|
Data is stored in XDG-compliant paths:
|
|
|
|
| Type | Path |
|
|
|------|------|
|
|
| Config | `~/.config/tensors/config.toml` |
|
|
| Database | `~/.local/share/tensors/models.db` |
|
|
| Checkpoints | `~/.local/share/tensors/models/checkpoints/` |
|
|
| LoRAs | `~/.local/share/tensors/models/loras/` |
|
|
| Gallery | `~/.local/share/tensors/gallery/` |
|
|
| Metadata | `~/.local/share/tensors/metadata/` |
|
|
|
|
## Search Options
|
|
|
|
| Option | Values | Provider |
|
|
|--------|--------|----------|
|
|
| `-P, --provider` | civitai, hf, all (default: all) | Both |
|
|
| `-t, --type` | checkpoint, lora, embedding, vae, controlnet, locon | CivitAI |
|
|
| `-b, --base` | sd14, sd15, sd2, sdxl, pony, flux, illustrious, noobai, auraflow | CivitAI |
|
|
| `-s, --sort` | downloads, rating, newest | Both |
|
|
| `-n, --limit` | Number of results (default: 25) | Both |
|
|
| `-p, --period` | all, year, month, week, day | CivitAI |
|
|
| `--tag` | Filter by tag (e.g., "anime") | Both |
|
|
| `-u, --user` | Filter by creator username | CivitAI |
|
|
| `-a, --author` | Filter by author/organization | HuggingFace |
|
|
| `--pipeline` | Pipeline tag (text-to-image, etc.) | HuggingFace |
|
|
| `--nsfw` | none, soft, mature, x | CivitAI |
|
|
| `--sfw` | Exclude NSFW content | CivitAI |
|
|
| `--commercial` | none, image, rent, sell | CivitAI |
|
|
| `--page` | Page number for pagination | CivitAI |
|
|
|
|
## Hugging Face Download Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `-f, --file` | Specific file to download |
|
|
| `--all` | Download all safetensor files |
|
|
| `-o, --output` | Output directory |
|
|
|
|
## Generate Options
|
|
|
|
| Option | Description |
|
|
|--------|-------------|
|
|
| `-W` | Image width (default: 512) |
|
|
| `-H` | Image height (default: 512) |
|
|
| `--steps` | Sampling steps (default: 20) |
|
|
| `--cfg-scale` | CFG scale (default: 7.0) |
|
|
| `-s` | RNG seed, -1 for random (default: -1) |
|
|
| `-b` | Batch size / number of images (default: 1) |
|
|
| `-n` | Negative prompt |
|
|
| `-o` | Output directory (default: .) |
|
|
| `--sampler` | Sampler name |
|
|
| `--scheduler` | Scheduler name |
|
|
| `--host` | sd-server address (default: 127.0.0.1) |
|
|
| `--port` | sd-server port (default: 1234) |
|
|
|
|
## Server API Endpoints
|
|
|
|
When running `tsr serve`, the following endpoints are available:
|
|
|
|
**OpenAPI Documentation:** Visit `/docs` for interactive Scalar API documentation.
|
|
|
|
**Authentication:** If `TENSORS_API_KEY` is set, all endpoints except `/status` and `/docs` require authentication via:
|
|
- Header: `X-API-Key: your-key`
|
|
- Query param: `?api_key=your-key`
|
|
|
|
| Endpoint | Method | Description |
|
|
|----------|--------|-------------|
|
|
| `/status` | GET | Server status (public) |
|
|
| `/docs` | GET | OpenAPI documentation (public) |
|
|
| `/reload` | POST | Hot-reload with new model |
|
|
| `/api/search` | GET | Unified search (CivitAI + HuggingFace) |
|
|
| `/api/images` | GET | List gallery images |
|
|
| `/api/images/{id}` | GET | Get image file |
|
|
| `/api/images/{id}/meta` | GET | Get image metadata |
|
|
| `/api/images/{id}/edit` | POST | Update image metadata |
|
|
| `/api/images/{id}` | DELETE | Delete image |
|
|
| `/api/models` | GET | List available models |
|
|
| `/api/models/active` | GET | Get active model |
|
|
| `/api/models/switch` | POST | Switch model |
|
|
| `/api/models/loras` | GET | List available LoRAs |
|
|
| `/api/generate` | POST | Generate images |
|
|
| `/api/download` | POST | Start CivitAI download |
|
|
| `/api/db/files` | GET | List local files |
|
|
| `/api/db/models` | GET | Search cached models |
|
|
| `/api/db/stats` | GET | Database statistics |
|
|
|
|
All sd-server endpoints (`/sdapi/v1/*`) are proxied through to the underlying process.
|
|
|
|
## Public API
|
|
|
|
A public API is available at `https://tensors-api.saiden.dev`. Authentication required via `X-API-Key` header.
|
|
|
|
## TypeScript Client
|
|
|
|
A TypeScript client is available for the server API:
|
|
|
|
```bash
|
|
npm install @saiden/tensors
|
|
```
|
|
|
|
```typescript
|
|
import { Configuration, SearchApi, CivitAIApi } from '@saiden/tensors'
|
|
|
|
const config = new Configuration({
|
|
apiKey: 'your-api-key',
|
|
// basePath defaults to https://tensors-api.saiden.dev
|
|
})
|
|
|
|
// Unified search
|
|
const search = new SearchApi(config)
|
|
const results = await search.searchModelsApiSearchGet({ query: 'flux' })
|
|
|
|
// CivitAI specific
|
|
const civitai = new CivitAIApi(config)
|
|
const models = await civitai.searchModelsApiCivitaiSearchGet({ types: 'LORA' })
|
|
```
|
|
|
|
Repository: [github.com/saiden-dev/tensors-typescript](https://github.com/saiden-dev/tensors-typescript)
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Install dev dependencies
|
|
uv sync --group dev
|
|
|
|
# Run tests
|
|
uv run pytest
|
|
|
|
# Run tests with coverage
|
|
uv run pytest --cov=tensors
|
|
|
|
# Lint and format
|
|
uv run ruff check .
|
|
uv run ruff format .
|
|
|
|
# Type check
|
|
uv run mypy tensors/
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|