Skip to content

aviadshiber/langfuse-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

langfuse-cli (lf)

CI PyPI version Python License: MIT

Observability-first CLI for the Langfuse LLM platform, following gh-ux patterns.

Features: traces, observations, prompts, scores, datasets, experiments, sessions | JSON/table/TSV output | config profiles | system keyring secrets | agent-friendly --json mode

Installation

# With uv (recommended)
uv tool install langfuse-cli

# With pip
pip install langfuse-cli

# With Homebrew
brew install aviadshiber/tap/langfuse-cli

# From source
git clone https://github.com/aviadshiber/langfuse-cli.git && cd langfuse-cli
uv sync && uv run lf --version

Quick Start

# Set credentials (or use config file below)
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_HOST="https://cloud.langfuse.com"  # optional, this is the default

# List recent traces
lf traces list --limit 5 --from 2026-02-01

# List prompts
lf prompts list

# Get JSON output (agent-friendly)
lf --json traces list --limit 5 --from 2026-02-01

Configuration

Resolution Order

Configuration is resolved in this order (first match wins):

  1. CLI flags (--host, --profile)
  2. Environment variables (LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY)
  3. Config file (~/.config/langfuse/config.toml)
  4. System keyring (macOS Keychain / Linux Secret Service)
  5. Defaults (host: https://cloud.langfuse.com)

Config File

# ~/.config/langfuse/config.toml

[default]
host = "https://cloud.langfuse.com"
public_key = "pk-lf-..."
# secret_key stored in keyring, NOT in plaintext

[profiles.staging]
host = "https://staging.langfuse.example.com"
public_key = "pk-lf-staging-..."

[defaults]
limit = 50
output = "table"

Secret Storage

Secret keys are stored in the system keyring (service: langfuse-cli):

  • macOS: Keychain (security add-generic-password -s langfuse-cli -a default/secret_key -w <secret>)
  • Linux: Secret Service API (GNOME Keyring / KDE Wallet)
  • Fallback: Environment variables or config file

Environment Variables

Variable Description
LANGFUSE_HOST Langfuse host URL
LANGFUSE_BASEURL Alias for LANGFUSE_HOST (SDK compatibility)
LANGFUSE_PUBLIC_KEY Public API key
LANGFUSE_SECRET_KEY Secret API key
LANGFUSE_PROFILE Config profile name
LANGFUSE_FORCE_TTY Force TTY mode (set to 1)
NO_COLOR Disable color output

Global Options

Global options go before the subcommand:

lf --json traces list --limit 5       # correct
lf --quiet scores summary             # correct
Flag Description
--version, -v Show version and exit
--host URL Override Langfuse host URL
--profile NAME Use named config profile
--json Output as JSON
--fields FIELDS Filter JSON to specific fields (comma-separated, implies --json)
--jq EXPR Filter JSON with jq expression (implies --json)
--quiet, -q Suppress status messages

Commands

Traces

# List traces (use --from to avoid timeouts on large projects)
lf traces list --limit 10 --from 2026-02-01
lf traces list --user-id user-123 --session-id sess-456
lf traces list --tags production,v2 --name chat-completion

# Get a single trace
lf traces get <trace-id>

# Visualize trace hierarchy as a tree
lf traces tree <trace-id>
Flag Type Description
--limit, -l INT Max results (default: 50)
--user-id, -u TEXT Filter by user ID
--session-id, -s TEXT Filter by session ID
--tags TEXT Filter by tags (comma-separated)
--name, -n TEXT Filter by trace name
--from DATETIME Start time filter (ISO 8601)
--to DATETIME End time filter (ISO 8601)

Prompts

# List all prompts
lf prompts list

# Get a specific prompt
lf prompts get my-prompt
lf prompts get my-prompt --label production
lf prompts get my-prompt --version 3

# Compile a prompt with variables
lf prompts compile my-prompt --var name=Alice --var role=engineer

# Compare two versions
lf prompts diff my-prompt --v1 3 --v2 5

Scores

# List scores
lf scores list --trace-id abc-123
lf scores list --name quality --from 2026-01-01

# Aggregated statistics
lf scores summary
lf scores summary --name quality --from 2026-01-01

Datasets

# List datasets
lf datasets list

# Get dataset with items
lf datasets get my-dataset --limit 10

Experiments

# List runs for a dataset
lf experiments list my-dataset

# Compare two runs
lf experiments compare my-dataset run-baseline run-improved

Sessions

# List sessions
lf sessions list --limit 20 --from 2026-01-01

# Get session details
lf sessions get session-abc-123

Observations

# List observations for a trace
lf observations list --trace-id abc-123

# Filter by type and name
lf observations list --type GENERATION --name llm-call --limit 20

# With time range
lf observations list --trace-id abc-123 --from 2026-01-01 --to 2026-01-31
Flag Type Description
--limit, -l INT Max results (default: 50)
--trace-id, -t TEXT Filter by trace ID
--type TEXT Filter by type (GENERATION, SPAN, EVENT)
--name, -n TEXT Filter by observation name
--from DATETIME Start time filter (ISO 8601)
--to DATETIME End time filter (ISO 8601)

Output Modes

Context Format Status Messages
Terminal (TTY) Rich aligned columns with colors Shown
Piped (non-TTY) Tab-separated values Suppressed
--json flag JSON array Suppressed unless error
--quiet flag Normal tables All suppressed
# Rich table (terminal)
lf prompts list

# Tab-separated (piped)
lf traces list --limit 5 --from 2026-02-01 | head

# JSON (agent-friendly)
lf --json traces list --limit 5 --from 2026-02-01

# Filtered JSON fields
lf --fields id,name,userId traces list --limit 5 --from 2026-02-01

# jq expression
lf --jq '.[].name' traces list --limit 5 --from 2026-02-01

Exit Codes

Code Meaning
0 Success
1 Error (API failure, auth, general)
2 Resource not found
3 Cancelled (Ctrl+C)

Architecture

Hybrid SDK + REST approach:

  • REST (httpx): Traces, observations, scores, sessions — full filter control, 60s timeout
  • SDK (langfuse): Prompts (built-in 300s caching), datasets, experiments — complex operations

Troubleshooting

Timeouts on large projects — Use --from to limit the time range:

lf traces list --from 2026-02-01          # fast: scoped query
lf traces list                             # slow: may timeout on large projects

Datetime format--from/--to accept ISO 8601 without milliseconds or Z suffix:

lf traces list --from 2026-02-16                  # date only
lf traces list --from 2026-02-16T10:30:00         # datetime
lf traces list --from "2026-02-16 10:30:00"       # space separator (quote it)
# NOT supported: 2026-02-16T10:30:00.213Z (ms + Z suffix)

Authentication errors — Verify credentials are set:

echo $LANGFUSE_PUBLIC_KEY   # should show pk-lf-...
echo $LANGFUSE_SECRET_KEY   # should show sk-lf-...
lf --json traces list --limit 1 --from 2026-02-01  # test connectivity

Batch processing — Use --to with the last timestamp to page through results:

# Batch 1
RAW=$(lf --jq '.[-1].timestamp' traces list --limit 50 --from 2026-02-01 2>/dev/null)
CURSOR=$(echo "$RAW" | tr -d '"' | sed 's/\.[0-9]*Z$//')

# Batch 2 (older results)
lf --json traces list --limit 50 --from 2026-02-01 --to "$CURSOR"

Shell Completions

lf supports tab completions for bash, zsh, and fish via Typer's built-in mechanism.

Bash — add to ~/.bashrc:

eval "$(_LF_COMPLETE=bash_source lf)"

Zsh — add to ~/.zshrc:

eval "$(_LF_COMPLETE=zsh_source lf)"

Fish — add to ~/.config/fish/config.fish:

_LF_COMPLETE=fish_source lf | source

After adding, restart your shell or source the config file.

Development

# Setup
git clone https://github.com/aviadshiber/langfuse-cli.git && cd langfuse-cli
uv sync

# Run tests
uv run pytest

# Lint, format & type check
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run mypy src/

# Run locally
uv run lf --version

See CONTRIBUTING.md for detailed development guidelines.

License

MIT

About

Observability-first CLI for the Langfuse LLM platform, following gh-ux patterns

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors