Revenium middleware for LangChain - AI metering and usage tracking
Project description
Revenium Middleware for LangChain
A LangChain callback handler that sends metering data to Revenium's AI metering API. This middleware automatically tracks LLM calls (tokens, timing, model info), chains, tools, and agent actions.
What Gets Metered
The callback handler automatically captures:
- Token counts: Input tokens, output tokens, total tokens
- Timing: Request start time, response time, duration in milliseconds
- Model info: Model name, provider, stop reason
- Trace context: Transaction ID, trace ID, parent transaction ID
- Metadata: Agent name, environment, organization, etc.
- Prompt capture (optional): Input prompts and output responses
Supported LLM Providers
The middleware automatically detects and tags the provider for:
| Provider | LangChain Classes |
|---|---|
| OpenAI | ChatOpenAI, OpenAI |
| Anthropic | ChatAnthropic |
ChatGoogleGenAI, ChatVertexAI |
|
| AWS Bedrock | ChatBedrock, BedrockLLM |
| Azure OpenAI | AzureChatOpenAI |
| Cohere | ChatCohere |
| HuggingFace | ChatHuggingFace |
| Ollama | ChatOllama, Ollama |
Provider is also auto-detected from model names: gpt-* -> openai, claude-* -> anthropic, gemini-* -> google.
Requirements
- Python 3.9+
langchain-core >= 0.2.0revenium_middleware >= 0.3.4- A Revenium API key (starts with
hak_) - At least one LLM provider SDK installed (e.g.,
langchain-openai,langchain-anthropic)
Getting Started
1. Create a project directory
mkdir my-langchain-project
cd my-langchain-project
2. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # On macOS/Linux
# .venv\Scripts\activate # On Windows
3. Install the package
pip install revenium-middleware-langchain
Or install from source:
git clone https://github.com/revenium/revenium-middleware-langchain.git
cd revenium-middleware-langchain
pip install -e .
4. Install your LLM provider
pip install langchain-openai # For OpenAI / Azure OpenAI
pip install langchain-anthropic # For Anthropic
pip install langchain-google-genai # For Google Gemini
pip install langgraph # For agents
5. Configure environment variables
export REVENIUM_METERING_API_KEY=hak_your_api_key_here
export OPENAI_API_KEY=sk-your_openai_key_here # Or your provider's key
Or copy the .env.example file:
cp .env.example .env
# Edit .env with your actual keys
Quick Start
from langchain_openai import ChatOpenAI
from revenium_middleware_langchain import ReveniumCallbackHandler
# Create the callback handler (uses REVENIUM_METERING_API_KEY from environment)
handler = ReveniumCallbackHandler(
trace_id="session-123",
agent_name="support_agent"
)
# Use with any LangChain LLM
llm = ChatOpenAI(model="gpt-4", callbacks=[handler])
response = llm.invoke("Hello!")
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
REVENIUM_METERING_API_KEY |
Yes | - | Your Revenium API key (must start with hak_) |
REVENIUM_METERING_BASE_URL |
No | https://api.revenium.ai |
Revenium API base URL |
REVENIUM_LOG_LEVEL |
No | INFO |
Log level (DEBUG, INFO, WARNING, ERROR) |
REVENIUM_CAPTURE_PROMPTS |
No | false |
Capture prompts and responses (use with caution) |
REVENIUM_ENVIRONMENT |
No | - | Environment name (e.g., production, staging) |
REVENIUM_ORGANIZATION_NAME |
No | - | Organization name for metering |
REVENIUM_SUBSCRIPTION_ID |
No | - | Subscription ID for metering |
REVENIUM_PRODUCT_NAME |
No | - | Product name for metering |
REVENIUM_SUBSCRIBER_ID |
No | - | Subscriber ID |
REVENIUM_SUBSCRIBER_EMAIL |
No | - | Subscriber email |
REVENIUM_SUBSCRIBER_CREDENTIAL |
No | - | Subscriber credential |
See .env.example for a complete reference with all configuration options including trace visualization fields.
Programmatic Configuration
You can also configure the middleware programmatically:
from revenium_middleware_langchain import ReveniumCallbackHandler, ReveniumConfig, SubscriberConfig
config = ReveniumConfig(
api_key="hak_your_api_key",
base_url="https://api.revenium.ai",
environment="production",
organization_name="my_org",
subscription_id="sub_123",
product_name="my_product",
subscriber=SubscriberConfig(
id="user_123",
email="user@example.com",
),
debug=True,
log_prompts=False,
)
handler = ReveniumCallbackHandler(
config=config,
trace_id="session-123",
trace_name="my_workflow",
agent_name="my_agent",
)
Usage Examples
Basic LLM Usage
from langchain_openai import ChatOpenAI
from revenium_middleware_langchain import ReveniumCallbackHandler
handler = ReveniumCallbackHandler(trace_id="session-123")
llm = ChatOpenAI(model="gpt-4", callbacks=[handler])
response = llm.invoke("What is the capital of France?")
print(response.content)
With Chains
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from revenium_middleware_langchain import ReveniumCallbackHandler
handler = ReveniumCallbackHandler(trace_id="chain-example")
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
llm = ChatOpenAI(model="gpt-4", callbacks=[handler])
output_parser = StrOutputParser()
chain = prompt | llm | output_parser
result = chain.invoke({"topic": "programming"})
With Agents
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agent
from revenium_middleware_langchain import ReveniumCallbackHandler
@tool
def get_weather(city: str) -> str:
"""Get the weather for a city."""
return f"Weather in {city}: Sunny, 72F"
handler = ReveniumCallbackHandler(
trace_id="agent-session",
agent_name="weather_agent"
)
llm = ChatOpenAI(model="gpt-4", callbacks=[handler])
agent = create_react_agent(llm, [get_weather])
result = agent.invoke(
{"messages": [HumanMessage(content="What's the weather in New York?")]},
config={"callbacks": [handler]},
)
Async Usage
For async applications, use the AsyncReveniumCallbackHandler:
from langchain_openai import ChatOpenAI
from revenium_middleware_langchain import AsyncReveniumCallbackHandler
handler = AsyncReveniumCallbackHandler(trace_id="async-session")
llm = ChatOpenAI(model="gpt-4", callbacks=[handler])
# Works with async invoke
response = await llm.ainvoke("Hello!")
See the examples/ directory for complete runnable examples.
Prompt Capture
The middleware can optionally capture prompts and responses for analytics and debugging.
Enable via environment variable:
REVENIUM_CAPTURE_PROMPTS=true
Or via configuration:
config = ReveniumConfig(
api_key="hak_your_key",
capture_prompts=True,
)
Security Warning: Prompts may contain sensitive data. Only enable prompt capture in trusted environments. All captured data is encrypted at rest in Revenium.
When enabled, the middleware captures:
- System prompts and user messages sent to the LLM
- The full response content from the LLM
- These are included in the metering payload for analysis in the Revenium dashboard
Logging Configuration
The middleware uses Python's standard logging module. Configure the log level to control output verbosity:
# Set via environment variable
export REVENIUM_LOG_LEVEL=DEBUG # DEBUG, INFO, WARNING, ERROR, CRITICAL
Debug mode provides detailed output of:
- Metering payloads being built and submitted
- Provider and model detection results
- Token count extraction details
- Trace context management operations
- API submission results
# Enable debug logging
export REVENIUM_LOG_LEVEL=DEBUG
You can also enable debug logging programmatically:
config = ReveniumConfig(
api_key="hak_your_key",
log_level="DEBUG",
)
Troubleshooting
Common Issues
| Problem | Solution |
|---|---|
ValueError: API key must start with 'hak_' |
Check that your REVENIUM_METERING_API_KEY is correct and starts with hak_ |
| No metering data in Revenium dashboard | Set REVENIUM_LOG_LEVEL=DEBUG to see what's being sent |
| Provider shows as "unknown" | Ensure you're using a supported LangChain LLM class (see table above) |
| Token counts are 0 or missing | Some providers don't return token counts for all operations; verify with debug logging |
ModuleNotFoundError: langchain_core |
Run pip install langchain-core>=0.2.0 |
ModuleNotFoundError: langchain_openai |
Run pip install langchain-openai (or your provider's package) |
Debug Mode
When troubleshooting, enable debug logging to see the full metering payload:
export REVENIUM_LOG_LEVEL=DEBUG
This will log:
- When each callback event fires (on_llm_start, on_llm_end, etc.)
- The extracted provider, model, and token counts
- The full metering payload being sent to Revenium
- The API response status
Provider Detection
The middleware detects providers in two ways:
- By LLM class name - Maps class names like
ChatOpenAI->openai,ChatAnthropic->anthropic - By model name prefix - Maps prefixes like
gpt-*->openai,claude-*->anthropic,gemini-*->google
If your provider is showing as "unknown", check that:
- You're using a supported LangChain LLM class
- The model name follows standard naming conventions
- You can file a feature request for new provider support
Development
Setup
# Clone the repository
git clone https://github.com/revenium/revenium-middleware-langchain.git
cd revenium-middleware-langchain
# Create virtual environment
python -m venv .venv
source .venv/bin/activate
# Install development dependencies
pip install -e ".[dev]"
Running Tests
pytest tests/ -v
Running Examples
# Set environment variables
export REVENIUM_API_KEY=hak_your_api_key
export OPENAI_API_KEY=your_openai_key
# Run basic example
python examples/basic_llm.py
# Run agent example
python examples/agent_example.py
Code Quality
# Lint
flake8 revenium_middleware_langchain/
# Format
black revenium_middleware_langchain/
# Type check
mypy revenium_middleware_langchain/
License
MIT License - see LICENSE for details.
Contributing
See CONTRIBUTING.md for guidelines.
Code of Conduct
See CODE_OF_CONDUCT.md.
Security
See SECURITY.md for our security policy and reporting vulnerabilities.
Support
- Documentation: https://docs.revenium.io
- Issues: https://github.com/revenium/revenium-middleware-langchain/issues
- Email: support@revenium.io
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 revenium_middleware_langchain-0.1.0.tar.gz.
File metadata
- Download URL: revenium_middleware_langchain-0.1.0.tar.gz
- Upload date:
- Size: 30.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9b9aeb3e948cbf146be1098d2382d00777ad19af3bffbaac5e8c7b133d5ffe6
|
|
| MD5 |
442dddfb3bacf7febde0ad6f03f076a6
|
|
| BLAKE2b-256 |
07955c89824d1c89a10ce1cfc80b2ee5bac1d80bae735777bf7e76ef19e13c89
|
File details
Details for the file revenium_middleware_langchain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: revenium_middleware_langchain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0d4e0ba04b2e1859b5f01c0f44dc23cf13776c09dcca7a370880af9e61e2915
|
|
| MD5 |
e77c3182d49dd3dee2bbcb5dcf0116f5
|
|
| BLAKE2b-256 |
5064dcf3a222dced4e50275fc8aa395410288677429395d7b3237ea1b79ae495
|