Skip to main content

Keywords AI Instrumentation for Langfuse

OTEL-compliant automatic instrumentation for Langfuse that sends all traces to Keywords AI.

✅ Why This Implementation is OTEL-Compliant

This package follows OpenTelemetry best practices:

  • ✅ Uses BaseInstrumentor - Standard OTEL instrumentation interface
  • ✅ Uses wrapt for safe patching - Reliable, reversible monkey-patching of httpx.Client
  • ✅ Single responsibility - Only does instrumentation (HTTP interception), not span processing
  • ✅ No import substitution - Use from langfuse import Langfuse normally!
  • ✅ Minimal interception - Only redirects Langfuse's HTTP requests to Keywords AI
  • ✅ Supports uninstrumentation - Can be cleanly enabled/disabled
  • ✅ Compatible with auto-instrumentation - Works with opentelemetry-instrument

Installation

pip install keywordsai-instrumentation-langfuse

Usage

# IMPORTANT: Instrument BEFORE importing Langfuse
from keywordsai_instrumentation_langfuse import LangfuseInstrumentor

LangfuseInstrumentor().instrument(api_key="your-keywordsai-api-key")

# Now import and use Langfuse normally - NO code changes needed!
from langfuse import Langfuse, observe

langfuse = Langfuse(
    public_key="your-langfuse-public-key",
    secret_key="your-langfuse-secret-key",
)

@observe()
def my_llm_function(query: str):
    # Your LLM code here
    return f"Response to: {query}"

# All traces automatically go to Keywords AI!
result = my_llm_function("Hello!")
langfuse.flush()

Option 2: Using Environment Variables

export KEYWORDSAI_API_KEY="your-api-key"
# Optionally set custom endpoint:
# export KEYWORDSAI_ENDPOINT="https://custom.endpoint.com/api/v1/traces/ingest"

# Langfuse credentials (Langfuse SDK's own env vars):
export LANGFUSE_PUBLIC_KEY="your-langfuse-public-key"
export LANGFUSE_SECRET_KEY="your-langfuse-secret-key"
# Instrument before importing Langfuse
from keywordsai_instrumentation_langfuse import LangfuseInstrumentor
LangfuseInstrumentor().instrument()

# Use Langfuse normally
from langfuse import Langfuse, observe

Option 3: Zero-Code Auto-Instrumentation

If you have opentelemetry-instrument configured:

export KEYWORDSAI_API_KEY="your-api-key"
# Langfuse credentials can be set via Langfuse's own env vars:
export LANGFUSE_PUBLIC_KEY="your-langfuse-public-key"
export LANGFUSE_SECRET_KEY="your-langfuse-secret-key"

opentelemetry-instrument python your_app.py

Note: LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY are Langfuse SDK's own environment variables, not specific to this instrumentation package.

How It Works

The instrumentor patches Langfuse's HTTP client to redirect trace data from Langfuse backend to Keywords AI:

  1. You call LangfuseInstrumentor().instrument() before importing Langfuse
  2. This patches httpx.Client.send() using wrapt (safe, reversible)
  3. You use Langfuse normally with @observe() decorators
  4. When Langfuse sends data to its backend, the patch intercepts the HTTP request
  5. Data is transformed from Langfuse format to Keywords AI format
  6. Request is redirected to Keywords AI API instead

Why patch before import? The HTTP client must be patched before Langfuse creates its client instances. This is standard OTEL instrumentation behavior.

Configuration

Environment Variables

  • KEYWORDSAI_API_KEY - Your Keywords AI API key (required)
  • KEYWORDSAI_ENDPOINT - Custom endpoint URL (optional, defaults to https://api.keywordsai.co/api/v1/traces/ingest)

Programmatic Configuration

from keywordsai_instrumentation_langfuse import instrument

instrument(
    api_key="your-api-key",
    endpoint="https://custom-endpoint.com/api/v1/traces/ingest",
)

Advanced Usage

Custom Endpoint

from keywordsai_instrumentation_langfuse import LangfuseInstrumentor

LangfuseInstrumentor().instrument(
    api_key="your-api-key",
    endpoint="https://your-instance.com/api/v1/traces/ingest"
)

from langfuse import Langfuse, observe

Disabling Instrumentation

from keywordsai_instrumentation_langfuse import LangfuseInstrumentor

instrumentor = LangfuseInstrumentor()
instrumentor.instrument(api_key="your-key")

# ... use Langfuse ...

# Disable when done
instrumentor.uninstrument()

Troubleshooting

Spans Not Appearing in Keywords AI

  1. Check your API key is set correctly
  2. Ensure langfuse.flush() is called before program exit
  3. Check logs for any error messages
  4. Verify network connectivity to Keywords AI API

Import Errors

Make sure all dependencies are installed:

pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation wrapt langfuse requests

Compatibility Issues

  • Requires Python 3.8+
  • Requires Langfuse SDK v2.0.0+
  • Requires OpenTelemetry SDK v1.20.0+

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black src/

# Lint
ruff check src/

What Makes This OTEL-Compliant?

  1. Uses BaseInstrumentor - Standard OTEL pattern with .instrument() and .uninstrument()
  2. Uses wrapt for Patching - Safe, reversible monkey-patching of httpx client
  3. Single Responsibility - Only intercepts HTTP requests, doesn't create custom span processors
  4. No Import Substitution - Use from langfuse import Langfuse normally
  5. Entry Points - Supports opentelemetry-instrument auto-instrumentation

License

Apache 2.0

Support

Metadata

Release files for respan-instrumentation-langfuse 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for respan-instrumentation-langfuse 1.0.1
File Size Uploaded Provenance
respan_instrumentation_langfuse-1.0.1.tar.gz 5.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for respan-instrumentation-langfuse 1.0.1
File Interpreter ABI Platform
respan_instrumentation_langfuse-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 12.7 kB

Release files / respan_instrumentation_langfuse-1.0.1.tar.gz

Download URL respan_instrumentation_langfuse-1.0.1.tar.gz
Size 5.7 kB
Tags Source
SHA-256 checksum
How to use checksums
dd6589e0a4df0363ee1089be7ebba57a028bae8cc19acd8f4befd74150278d03
BLAKE2b-256 checksum
How to use checksums
985edb73a6fc36841638792366a7b3e7518153d9e630e8441283517e99bf71bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.7.1 CPython/3.12.8 Darwin/25.2.0

Release files / respan_instrumentation_langfuse-1.0.1-py3-none-any.whl

Download URL respan_instrumentation_langfuse-1.0.1-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
504d934ad74536195420c9a10262e91cbd79874e3b763e501226d16602cf8ecf
BLAKE2b-256 checksum
How to use checksums
8c0975f382aa98d3ba4604f66c44c0c59026558d686ad4a967a4557f244311df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.7.1 CPython/3.12.8 Darwin/25.2.0

Security for respan-instrumentation-langfuse 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page