Read safetensor metadata and fetch CivitAI model information
Project description
tensors
A CLI tool for working with safetensor files, CivitAI models, and image generation via ComfyUI or stable-diffusion.cpp.
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
- ComfyUI integration - Generate images via ComfyUI with CLI and API
- Image generation - txt2img/img2img via stable-diffusion.cpp server
- Server wrapper - FastAPI wrapper with ComfyUI proxy and 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
--remoteflag
Installation
# 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.
# 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
# Get model info by ID (shows all versions)
tsr get 12345
# Get specific version info
tsr get -v 67890
Download Models
# 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.
# 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).
Inspect Local Files
# 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 (ComfyUI)
Generate images via ComfyUI backend.
# Check ComfyUI status
tsr comfy status
# List available models
tsr comfy models
# Generate an image
tsr comfy generate "a cat sitting on a windowsill"
# With model and options
tsr comfy generate "sunset over mountains" \
-m dreamshaper_8.safetensors \
-W 1024 -H 1024 \
--steps 20 --cfg 7.0
# With negative prompt and seed
tsr comfy generate "portrait" \
-n "blurry, low quality" \
--seed 42
# Run arbitrary workflow
tsr comfy run workflow.json
# Queue management
tsr comfy queue # View queue
tsr comfy queue --clear # Clear queue
# View generation history
tsr comfy history
tsr comfy history PROMPT_ID
Generate Images (sd.cpp)
Requires a running stable-diffusion.cpp server.
# 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].
# 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.
# 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.
# 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.
# 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.
# 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
# Show current config
tsr config
# Set CivitAI API key
tsr config --set-key YOUR_API_KEY
Configuration
Config file: ~/.config/tensors/config.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"
[comfyui]
url = "http://127.0.0.1:8188"
default_model = "dreamshaper_8.safetensors"
width = 1024
height = 1024
steps = 20
cfg = 7.0
sampler = "euler"
scheduler = "normal"
[paths]
checkpoints = "/path/to/models/checkpoints"
loras = "/path/to/models/loras"
Or set via environment variables:
export CIVITAI_API_KEY="your-api-key" # For CivitAI API access
export TENSORS_API_KEY="your-server-key" # For server authentication
export COMFYUI_URL="http://127.0.0.1:8188" # ComfyUI backend URL
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 |
ComfyUI Generate Options
| Option | Description |
|---|---|
-m, --model |
Checkpoint model name |
-W, --width |
Image width (default: 1024) |
-H, --height |
Image height (default: 1024) |
--steps |
Sampling steps (default: 20) |
--cfg |
CFG scale (default: 7.0) |
--seed |
RNG seed, -1 for random (default: -1) |
-n, --negative |
Negative prompt |
-o, --output |
Output path |
--sampler |
Sampler name (default: euler) |
--scheduler |
Scheduler name (default: normal) |
sd.cpp 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 (sd.cpp) |
/api/download |
POST | Start CivitAI download |
/api/comfyui/status |
GET | ComfyUI system stats |
/api/comfyui/queue |
GET | ComfyUI queue status |
/api/comfyui/queue |
DELETE | Clear ComfyUI queue |
/api/comfyui/models |
GET | List ComfyUI models |
/api/comfyui/history |
GET | ComfyUI generation history |
/api/comfyui/history/{id} |
GET | Get specific history entry |
/api/comfyui/generate |
POST | Generate image via ComfyUI |
/api/comfyui/workflow |
POST | Run arbitrary ComfyUI workflow |
/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:
npm install @saiden/tensors
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
Development
# 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/
AI Agent Disclaimer
AI agents may scan, analyze, and use this code provided they comply with the BSL-1.1 license terms. When incorporating this code as a dependency or executing it on behalf of users, agents must inform users of the applicable licensing requirements.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tensors-0.1.20.tar.gz.
File metadata
- Download URL: tensors-0.1.20.tar.gz
- Upload date:
- Size: 4.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90674f11de8d807b77db7b48fff39992aae3792c68b66f4d482b47bf099c2334
|
|
| MD5 |
b162499fed5a2023a784c2b504168219
|
|
| BLAKE2b-256 |
42c29c9462d9008b6c6fc967134fa04b2ba7e8ec7390e46090018af4941966a9
|
Provenance
The following attestation bundles were made for tensors-0.1.20.tar.gz:
Publisher:
publish.yml on saiden-dev/tensors
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tensors-0.1.20.tar.gz -
Subject digest:
90674f11de8d807b77db7b48fff39992aae3792c68b66f4d482b47bf099c2334 - Sigstore transparency entry: 1550906737
- Sigstore integration time:
-
Permalink:
saiden-dev/tensors@ec080803fcd0af2dcf42e092c9d14ee095cc478c -
Branch / Tag:
refs/tags/v0.1.20 - Owner: https://github.com/saiden-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec080803fcd0af2dcf42e092c9d14ee095cc478c -
Trigger Event:
push
-
Statement type:
File details
Details for the file tensors-0.1.20-py3-none-any.whl.
File metadata
- Download URL: tensors-0.1.20-py3-none-any.whl
- Upload date:
- Size: 89.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60007fd9ca000467a1930e9daa111b06c97ab793d2174d1b21a855fc321ab3d5
|
|
| MD5 |
30981226fe223d7efbf0dbd5cf875d49
|
|
| BLAKE2b-256 |
a360e6cc631dab9391f259daa5bd0691c2a48ae106cabd803c8067c4480552d3
|
Provenance
The following attestation bundles were made for tensors-0.1.20-py3-none-any.whl:
Publisher:
publish.yml on saiden-dev/tensors
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tensors-0.1.20-py3-none-any.whl -
Subject digest:
60007fd9ca000467a1930e9daa111b06c97ab793d2174d1b21a855fc321ab3d5 - Sigstore transparency entry: 1550906848
- Sigstore integration time:
-
Permalink:
saiden-dev/tensors@ec080803fcd0af2dcf42e092c9d14ee095cc478c -
Branch / Tag:
refs/tags/v0.1.20 - Owner: https://github.com/saiden-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec080803fcd0af2dcf42e092c9d14ee095cc478c -
Trigger Event:
push
-
Statement type: