revenium-python-sdk 0.1.10__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/PKG-INFO +85 -45
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/README.md +84 -44
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/pyproject.toml +1 -1
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/__init__.py +6 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/__init__.py +5 -1
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/enforcement.py +91 -23
- revenium_python_sdk-0.3.0/revenium_middleware/_core/log_sanitize.py +100 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/metering.py +77 -0
- revenium_python_sdk-0.3.0/revenium_middleware/_core/metering_buffer.py +327 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/metering_submission.py +17 -3
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/decorator.py +101 -45
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/__init__.py +11 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/bedrock_adapter.py +50 -18
- revenium_python_sdk-0.3.0/revenium_middleware/anthropic/bedrock_transport.py +482 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/middleware.py +208 -21
- revenium_python_sdk-0.3.0/revenium_middleware/anthropic/stream_create.py +176 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/_metering.py +2 -2
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/utils.py +11 -9
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/middleware.py +16 -4
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/middleware.py +19 -5
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/middleware.py +41 -22
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/proxy/middleware.py +3 -3
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/middleware.py +53 -24
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/middleware.py +128 -78
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/middleware.py +2 -1
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/perplexity_sdk.py +2 -1
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/PKG-INFO +85 -45
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/SOURCES.txt +4 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/LICENSE +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/context.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/decorators.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/exceptions.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/patch_registry.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/prompt_extraction.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/subscriber.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/LICENSE +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_base_client.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_client.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_compat.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_constants.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_exceptions.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_files.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_models.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_qs.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_resource.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_response.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_streaming.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_types.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_logs.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_proxy.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_reflection.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_resources_proxy.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_streams.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_sync.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_transform.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_typing.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_utils.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_version.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/context.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/py.typed +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/ai.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/apis.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/events.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_audio_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_completion_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_image_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_video_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/api_meter_request_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/api_meter_response_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/event_create_params.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/metering_response_resource.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/agentic_outcomes.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/prompt_extractor.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/provider.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/middleware.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/exceptions.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/protocols.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/types.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/provider.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/prompt_extractor.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/provider.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/context.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/decorators.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/hooks.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/integrations/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/integrations/crewai.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/validation.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/proxy/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/azure_config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/azure_model_resolver.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/config.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/exceptions.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/_utils.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/unified_handler.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/prompt_extractor.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/provider.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/provider.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/trace_fields.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/webhooks/__init__.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/webhooks/_verify.py +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/dependency_links.txt +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/requires.txt +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/top_level.txt +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/setup.cfg +0 -0
- {revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/tests/test_metering.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: revenium-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: The official Revenium Python SDK — unified AI metering middleware for OpenAI, Anthropic, Google, Ollama, LiteLLM, Perplexity, and fal.ai.
|
|
5
5
|
Author-email: Revenium <support@revenium.io>
|
|
6
6
|
License: MIT
|
|
@@ -195,7 +195,7 @@ from dotenv import load_dotenv
|
|
|
195
195
|
load_dotenv()
|
|
196
196
|
|
|
197
197
|
import openai
|
|
198
|
-
import
|
|
198
|
+
import revenium_middleware.openai # Auto-initializes on import
|
|
199
199
|
|
|
200
200
|
client = openai.OpenAI()
|
|
201
201
|
response = client.chat.completions.create(
|
|
@@ -335,7 +335,7 @@ from dotenv import load_dotenv
|
|
|
335
335
|
load_dotenv()
|
|
336
336
|
|
|
337
337
|
import openai
|
|
338
|
-
import
|
|
338
|
+
import revenium_middleware.openai # Auto-initializes
|
|
339
339
|
|
|
340
340
|
client = openai.OpenAI()
|
|
341
341
|
|
|
@@ -374,7 +374,7 @@ The middleware automatically detects Azure OpenAI when using `AzureOpenAI()` and
|
|
|
374
374
|
|
|
375
375
|
```python
|
|
376
376
|
from openai import AzureOpenAI
|
|
377
|
-
import
|
|
377
|
+
import revenium_middleware.openai
|
|
378
378
|
|
|
379
379
|
client = AzureOpenAI(
|
|
380
380
|
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
|
|
@@ -407,7 +407,7 @@ from dotenv import load_dotenv
|
|
|
407
407
|
load_dotenv()
|
|
408
408
|
|
|
409
409
|
import anthropic
|
|
410
|
-
import
|
|
410
|
+
import revenium_middleware.anthropic # Auto-initializes
|
|
411
411
|
|
|
412
412
|
client = anthropic.Anthropic()
|
|
413
413
|
|
|
@@ -442,7 +442,7 @@ The middleware provides complete AWS Bedrock integration with automatic detectio
|
|
|
442
442
|
|
|
443
443
|
```python
|
|
444
444
|
import anthropic
|
|
445
|
-
import
|
|
445
|
+
import revenium_middleware.anthropic
|
|
446
446
|
|
|
447
447
|
# Bedrock is automatically detected when AWS credentials are available
|
|
448
448
|
# and base_url contains 'amazonaws.com'
|
|
@@ -511,7 +511,7 @@ pip install "revenium-python-sdk[google-vertex]"
|
|
|
511
511
|
from dotenv import load_dotenv
|
|
512
512
|
load_dotenv()
|
|
513
513
|
|
|
514
|
-
import
|
|
514
|
+
import revenium_middleware.google
|
|
515
515
|
from google import genai
|
|
516
516
|
|
|
517
517
|
client = genai.Client()
|
|
@@ -532,7 +532,7 @@ print(response.text)
|
|
|
532
532
|
from dotenv import load_dotenv
|
|
533
533
|
load_dotenv()
|
|
534
534
|
|
|
535
|
-
import
|
|
535
|
+
import revenium_middleware.google
|
|
536
536
|
import vertexai
|
|
537
537
|
from vertexai.generative_models import GenerativeModel
|
|
538
538
|
|
|
@@ -573,7 +573,7 @@ from dotenv import load_dotenv
|
|
|
573
573
|
load_dotenv()
|
|
574
574
|
|
|
575
575
|
import ollama
|
|
576
|
-
import
|
|
576
|
+
import revenium_middleware.ollama # Auto-initializes
|
|
577
577
|
|
|
578
578
|
# Chat completion
|
|
579
579
|
response = ollama.chat(
|
|
@@ -608,7 +608,7 @@ response = ollama.embed(model='nomic-embed-text', input=['Text 1', 'Text 2', 'Te
|
|
|
608
608
|
|
|
609
609
|
```python
|
|
610
610
|
import openai
|
|
611
|
-
import
|
|
611
|
+
import revenium_middleware.openai
|
|
612
612
|
|
|
613
613
|
openai.api_key = 'ollama'
|
|
614
614
|
openai.base_url = 'http://localhost:11434/v1/'
|
|
@@ -636,7 +636,7 @@ Supports all LLM providers available through LiteLLM with two integration patter
|
|
|
636
636
|
from dotenv import load_dotenv
|
|
637
637
|
load_dotenv()
|
|
638
638
|
|
|
639
|
-
import
|
|
639
|
+
import revenium_middleware.litellm.client.middleware # Auto-initializes
|
|
640
640
|
import litellm
|
|
641
641
|
import os
|
|
642
642
|
|
|
@@ -659,7 +659,7 @@ Add the callback to your LiteLLM `config.yaml` for server-side integration:
|
|
|
659
659
|
|
|
660
660
|
```yaml
|
|
661
661
|
litellm_settings:
|
|
662
|
-
callbacks: ["
|
|
662
|
+
callbacks: ["revenium_middleware.litellm.proxy.middleware.proxy_handler_instance"]
|
|
663
663
|
```
|
|
664
664
|
|
|
665
665
|
When using the LiteLLM proxy, pass metadata via HTTP headers (`x-revenium-*`).
|
|
@@ -684,7 +684,7 @@ All decorators support static values, extraction from function arguments (`name_
|
|
|
684
684
|
#### CrewAI Integration
|
|
685
685
|
|
|
686
686
|
```bash
|
|
687
|
-
pip install "revenium-
|
|
687
|
+
pip install "revenium-python-sdk[litellm]" crewai
|
|
688
688
|
```
|
|
689
689
|
|
|
690
690
|
Pre-built wrapper for tracking CrewAI agent executions. **Note:** CrewAI requires Python 3.12 or earlier.
|
|
@@ -708,7 +708,7 @@ from dotenv import load_dotenv
|
|
|
708
708
|
load_dotenv()
|
|
709
709
|
|
|
710
710
|
from openai import OpenAI
|
|
711
|
-
import
|
|
711
|
+
import revenium_middleware.perplexity # Auto-patches OpenAI
|
|
712
712
|
|
|
713
713
|
client = OpenAI(
|
|
714
714
|
api_key=os.getenv("PERPLEXITY_API_KEY"),
|
|
@@ -726,7 +726,7 @@ response = client.chat.completions.create(
|
|
|
726
726
|
|
|
727
727
|
```python
|
|
728
728
|
from perplexity import Perplexity
|
|
729
|
-
import
|
|
729
|
+
import revenium_middleware.perplexity # Auto-patches Perplexity
|
|
730
730
|
|
|
731
731
|
client = Perplexity(api_key=os.getenv("PERPLEXITY_API_KEY"))
|
|
732
732
|
|
|
@@ -761,7 +761,7 @@ for chunk in stream:
|
|
|
761
761
|
Supports image, video, and audio generation through fal.ai with automatic media type detection.
|
|
762
762
|
|
|
763
763
|
```python
|
|
764
|
-
import
|
|
764
|
+
import revenium_middleware.fal # Auto-activates
|
|
765
765
|
import fal_client
|
|
766
766
|
|
|
767
767
|
result = fal_client.subscribe(
|
|
@@ -793,16 +793,23 @@ for image in result.get("images", []):
|
|
|
793
793
|
|
|
794
794
|
Callback handler that automatically tracks LLM calls, chains, tools, and agent actions.
|
|
795
795
|
|
|
796
|
+
```bash
|
|
797
|
+
pip install "revenium-python-sdk[langchain]"
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
Wrap any LangChain LLM (or embeddings model) with `wrap()` — the Revenium callback handler is attached for you:
|
|
801
|
+
|
|
796
802
|
```python
|
|
797
803
|
from langchain_openai import ChatOpenAI
|
|
798
|
-
from
|
|
804
|
+
from revenium_middleware.openai.langchain import wrap
|
|
799
805
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
806
|
+
llm = wrap(
|
|
807
|
+
ChatOpenAI(model="gpt-4o-mini"),
|
|
808
|
+
usage_metadata={
|
|
809
|
+
"trace_id": "session-123",
|
|
810
|
+
"agent": "support_agent",
|
|
811
|
+
},
|
|
803
812
|
)
|
|
804
|
-
|
|
805
|
-
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[handler])
|
|
806
813
|
response = llm.invoke("Hello!")
|
|
807
814
|
```
|
|
808
815
|
|
|
@@ -813,13 +820,14 @@ from langchain_core.prompts import ChatPromptTemplate
|
|
|
813
820
|
from langchain_core.output_parsers import StrOutputParser
|
|
814
821
|
|
|
815
822
|
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
|
|
816
|
-
chain = prompt | llm |
|
|
823
|
+
chain = prompt | llm | StrOutputParser()
|
|
817
824
|
result = chain.invoke({"topic": "programming"})
|
|
818
825
|
```
|
|
819
826
|
|
|
820
827
|
**With agents:**
|
|
821
828
|
|
|
822
829
|
```python
|
|
830
|
+
from langchain_core.messages import HumanMessage
|
|
823
831
|
from langchain_core.tools import tool
|
|
824
832
|
from langgraph.prebuilt import create_react_agent
|
|
825
833
|
|
|
@@ -829,40 +837,32 @@ def get_weather(city: str) -> str:
|
|
|
829
837
|
return f"Sunny, 72F in {city}"
|
|
830
838
|
|
|
831
839
|
agent = create_react_agent(llm, [get_weather])
|
|
832
|
-
result = agent.invoke(
|
|
833
|
-
{"messages": [HumanMessage(content="Weather in NYC?")]},
|
|
834
|
-
config={"callbacks": [handler]}
|
|
835
|
-
)
|
|
840
|
+
result = agent.invoke({"messages": [HumanMessage(content="Weather in NYC?")]})
|
|
836
841
|
```
|
|
837
842
|
|
|
838
|
-
**Async support:**
|
|
843
|
+
**Async support:** the handler is async-native — wrap once and use `ainvoke`/`astream` directly:
|
|
839
844
|
|
|
840
845
|
```python
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
handler = AsyncReveniumCallbackHandler(trace_id="async-session")
|
|
844
|
-
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[handler])
|
|
846
|
+
llm = wrap(ChatOpenAI(model="gpt-4o-mini"))
|
|
845
847
|
response = await llm.ainvoke("Hello!")
|
|
846
848
|
```
|
|
847
849
|
|
|
848
850
|
**Supported providers:** OpenAI, Anthropic, Google, AWS Bedrock, Azure OpenAI, Cohere, HuggingFace, Ollama. Provider is auto-detected from LangChain class name or model name prefix.
|
|
849
851
|
|
|
850
|
-
**
|
|
852
|
+
**Attaching to an existing LLM:** use `attach_to()` to add tracking in-place, with any of the standard metadata fields (see [Metadata Fields](#metadata-fields)):
|
|
851
853
|
|
|
852
854
|
```python
|
|
853
|
-
from
|
|
854
|
-
|
|
855
|
-
config = ReveniumConfig(
|
|
856
|
-
api_key="hak_your_api_key",
|
|
857
|
-
environment="production",
|
|
858
|
-
organization_name="my_org",
|
|
859
|
-
product_name="my_product",
|
|
860
|
-
subscriber=SubscriberConfig(id="user_123", email="user@example.com"),
|
|
861
|
-
)
|
|
855
|
+
from revenium_middleware.openai.langchain import attach_to
|
|
862
856
|
|
|
863
|
-
|
|
857
|
+
attach_to(llm, usage_metadata={
|
|
858
|
+
"organizationName": "my_org",
|
|
859
|
+
"productName": "my_product",
|
|
860
|
+
"subscriber": {"id": "user_123", "email": "user@example.com"},
|
|
861
|
+
})
|
|
864
862
|
```
|
|
865
863
|
|
|
864
|
+
Credentials come from the standard environment variables (`REVENIUM_METERING_API_KEY`, `REVENIUM_METERING_BASE_URL`) or `revenium_middleware.configure()`.
|
|
865
|
+
|
|
866
866
|
---
|
|
867
867
|
|
|
868
868
|
## Metadata Fields
|
|
@@ -1179,7 +1179,7 @@ Each field has a maximum length of **50,000 characters**. If exceeded, it's trun
|
|
|
1179
1179
|
import os
|
|
1180
1180
|
os.environ["REVENIUM_CAPTURE_PROMPTS"] = "true"
|
|
1181
1181
|
|
|
1182
|
-
import
|
|
1182
|
+
import revenium_middleware.openai
|
|
1183
1183
|
from openai import OpenAI
|
|
1184
1184
|
|
|
1185
1185
|
client = OpenAI()
|
|
@@ -1316,6 +1316,44 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1316
1316
|
|----------|-------------|
|
|
1317
1317
|
| `REVENIUM_METERING_API_KEY` | Your Revenium API key (starts with `hak_` or `rev_`) |
|
|
1318
1318
|
|
|
1319
|
+
### Configuring After Import
|
|
1320
|
+
|
|
1321
|
+
The metering client is normally built from the environment when
|
|
1322
|
+
`revenium_middleware` is first imported. If your credentials only become
|
|
1323
|
+
available later (a secrets-vault bootstrap, framework settings hooks, import
|
|
1324
|
+
ordering), you don't need to restart: as soon as `REVENIUM_METERING_API_KEY`
|
|
1325
|
+
appears in the environment, the next metered call picks it up automatically.
|
|
1326
|
+
You can also configure programmatically at any time:
|
|
1327
|
+
|
|
1328
|
+
```python
|
|
1329
|
+
import revenium_middleware
|
|
1330
|
+
|
|
1331
|
+
revenium_middleware.initialize_metering(
|
|
1332
|
+
api_key="hak_your_key", # defaults to REVENIUM_METERING_API_KEY
|
|
1333
|
+
base_url="https://api.revenium.ai", # defaults to REVENIUM_METERING_BASE_URL
|
|
1334
|
+
)
|
|
1335
|
+
```
|
|
1336
|
+
|
|
1337
|
+
`initialize_metering()` returns `True` when metering is enabled after the
|
|
1338
|
+
call; invoke it with no arguments to re-read the environment.
|
|
1339
|
+
|
|
1340
|
+
### Delivery Resilience (Store-and-Forward)
|
|
1341
|
+
|
|
1342
|
+
Metering events that still fail after the client's own retries (network
|
|
1343
|
+
outages, 5xx, rate limiting) are not lost: they are held in a bounded
|
|
1344
|
+
in-memory buffer and replayed automatically in the background every 30
|
|
1345
|
+
seconds, reusing each event's original `Idempotency-Key` so replays can
|
|
1346
|
+
never double-bill. Permanent failures (401/403/404/422) are never buffered.
|
|
1347
|
+
The buffer holds up to 1000 events (oldest evicted first) for at most 24
|
|
1348
|
+
hours, and is drained on graceful shutdown. Inspect it programmatically:
|
|
1349
|
+
|
|
1350
|
+
```python
|
|
1351
|
+
from revenium_middleware import get_buffer_stats
|
|
1352
|
+
|
|
1353
|
+
print(get_buffer_stats())
|
|
1354
|
+
# {'size': 0, 'max_size': 1000, 'total_buffered': 3, 'total_replayed': 3, ...}
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1319
1357
|
### Optional Environment Variables
|
|
1320
1358
|
|
|
1321
1359
|
| Variable | Default | Description |
|
|
@@ -1334,6 +1372,8 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1334
1372
|
| `REVENIUM_TRANSACTION_NAME` | - | Human-friendly operation name |
|
|
1335
1373
|
| `REVENIUM_RETRY_NUMBER` | - | Retry attempt number |
|
|
1336
1374
|
| `REVENIUM_BEDROCK_DISABLE` | - | Set to `1` to disable Bedrock auto-detection |
|
|
1375
|
+
| `REVENIUM_BUFFER_MAX_SIZE` | `1000` | Store-and-forward buffer capacity (oldest events evicted when full) |
|
|
1376
|
+
| `REVENIUM_BUFFER_FLUSH_INTERVAL` | `30` | Seconds between automatic replay attempts for buffered events |
|
|
1337
1377
|
|
|
1338
1378
|
### Provider-Specific Environment Variables
|
|
1339
1379
|
|
|
@@ -1376,7 +1416,7 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1376
1416
|
|
|
1377
1417
|
**Force direct Anthropic API:** Set `REVENIUM_BEDROCK_DISABLE=1` to disable Bedrock auto-detection.
|
|
1378
1418
|
|
|
1379
|
-
**Check initialization status:** Use `
|
|
1419
|
+
**Check initialization status (Anthropic):** Use `revenium_middleware.anthropic.is_initialized()` to verify setup.
|
|
1380
1420
|
|
|
1381
1421
|
---
|
|
1382
1422
|
|
|
@@ -102,7 +102,7 @@ from dotenv import load_dotenv
|
|
|
102
102
|
load_dotenv()
|
|
103
103
|
|
|
104
104
|
import openai
|
|
105
|
-
import
|
|
105
|
+
import revenium_middleware.openai # Auto-initializes on import
|
|
106
106
|
|
|
107
107
|
client = openai.OpenAI()
|
|
108
108
|
response = client.chat.completions.create(
|
|
@@ -242,7 +242,7 @@ from dotenv import load_dotenv
|
|
|
242
242
|
load_dotenv()
|
|
243
243
|
|
|
244
244
|
import openai
|
|
245
|
-
import
|
|
245
|
+
import revenium_middleware.openai # Auto-initializes
|
|
246
246
|
|
|
247
247
|
client = openai.OpenAI()
|
|
248
248
|
|
|
@@ -281,7 +281,7 @@ The middleware automatically detects Azure OpenAI when using `AzureOpenAI()` and
|
|
|
281
281
|
|
|
282
282
|
```python
|
|
283
283
|
from openai import AzureOpenAI
|
|
284
|
-
import
|
|
284
|
+
import revenium_middleware.openai
|
|
285
285
|
|
|
286
286
|
client = AzureOpenAI(
|
|
287
287
|
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
|
|
@@ -314,7 +314,7 @@ from dotenv import load_dotenv
|
|
|
314
314
|
load_dotenv()
|
|
315
315
|
|
|
316
316
|
import anthropic
|
|
317
|
-
import
|
|
317
|
+
import revenium_middleware.anthropic # Auto-initializes
|
|
318
318
|
|
|
319
319
|
client = anthropic.Anthropic()
|
|
320
320
|
|
|
@@ -349,7 +349,7 @@ The middleware provides complete AWS Bedrock integration with automatic detectio
|
|
|
349
349
|
|
|
350
350
|
```python
|
|
351
351
|
import anthropic
|
|
352
|
-
import
|
|
352
|
+
import revenium_middleware.anthropic
|
|
353
353
|
|
|
354
354
|
# Bedrock is automatically detected when AWS credentials are available
|
|
355
355
|
# and base_url contains 'amazonaws.com'
|
|
@@ -418,7 +418,7 @@ pip install "revenium-python-sdk[google-vertex]"
|
|
|
418
418
|
from dotenv import load_dotenv
|
|
419
419
|
load_dotenv()
|
|
420
420
|
|
|
421
|
-
import
|
|
421
|
+
import revenium_middleware.google
|
|
422
422
|
from google import genai
|
|
423
423
|
|
|
424
424
|
client = genai.Client()
|
|
@@ -439,7 +439,7 @@ print(response.text)
|
|
|
439
439
|
from dotenv import load_dotenv
|
|
440
440
|
load_dotenv()
|
|
441
441
|
|
|
442
|
-
import
|
|
442
|
+
import revenium_middleware.google
|
|
443
443
|
import vertexai
|
|
444
444
|
from vertexai.generative_models import GenerativeModel
|
|
445
445
|
|
|
@@ -480,7 +480,7 @@ from dotenv import load_dotenv
|
|
|
480
480
|
load_dotenv()
|
|
481
481
|
|
|
482
482
|
import ollama
|
|
483
|
-
import
|
|
483
|
+
import revenium_middleware.ollama # Auto-initializes
|
|
484
484
|
|
|
485
485
|
# Chat completion
|
|
486
486
|
response = ollama.chat(
|
|
@@ -515,7 +515,7 @@ response = ollama.embed(model='nomic-embed-text', input=['Text 1', 'Text 2', 'Te
|
|
|
515
515
|
|
|
516
516
|
```python
|
|
517
517
|
import openai
|
|
518
|
-
import
|
|
518
|
+
import revenium_middleware.openai
|
|
519
519
|
|
|
520
520
|
openai.api_key = 'ollama'
|
|
521
521
|
openai.base_url = 'http://localhost:11434/v1/'
|
|
@@ -543,7 +543,7 @@ Supports all LLM providers available through LiteLLM with two integration patter
|
|
|
543
543
|
from dotenv import load_dotenv
|
|
544
544
|
load_dotenv()
|
|
545
545
|
|
|
546
|
-
import
|
|
546
|
+
import revenium_middleware.litellm.client.middleware # Auto-initializes
|
|
547
547
|
import litellm
|
|
548
548
|
import os
|
|
549
549
|
|
|
@@ -566,7 +566,7 @@ Add the callback to your LiteLLM `config.yaml` for server-side integration:
|
|
|
566
566
|
|
|
567
567
|
```yaml
|
|
568
568
|
litellm_settings:
|
|
569
|
-
callbacks: ["
|
|
569
|
+
callbacks: ["revenium_middleware.litellm.proxy.middleware.proxy_handler_instance"]
|
|
570
570
|
```
|
|
571
571
|
|
|
572
572
|
When using the LiteLLM proxy, pass metadata via HTTP headers (`x-revenium-*`).
|
|
@@ -591,7 +591,7 @@ All decorators support static values, extraction from function arguments (`name_
|
|
|
591
591
|
#### CrewAI Integration
|
|
592
592
|
|
|
593
593
|
```bash
|
|
594
|
-
pip install "revenium-
|
|
594
|
+
pip install "revenium-python-sdk[litellm]" crewai
|
|
595
595
|
```
|
|
596
596
|
|
|
597
597
|
Pre-built wrapper for tracking CrewAI agent executions. **Note:** CrewAI requires Python 3.12 or earlier.
|
|
@@ -615,7 +615,7 @@ from dotenv import load_dotenv
|
|
|
615
615
|
load_dotenv()
|
|
616
616
|
|
|
617
617
|
from openai import OpenAI
|
|
618
|
-
import
|
|
618
|
+
import revenium_middleware.perplexity # Auto-patches OpenAI
|
|
619
619
|
|
|
620
620
|
client = OpenAI(
|
|
621
621
|
api_key=os.getenv("PERPLEXITY_API_KEY"),
|
|
@@ -633,7 +633,7 @@ response = client.chat.completions.create(
|
|
|
633
633
|
|
|
634
634
|
```python
|
|
635
635
|
from perplexity import Perplexity
|
|
636
|
-
import
|
|
636
|
+
import revenium_middleware.perplexity # Auto-patches Perplexity
|
|
637
637
|
|
|
638
638
|
client = Perplexity(api_key=os.getenv("PERPLEXITY_API_KEY"))
|
|
639
639
|
|
|
@@ -668,7 +668,7 @@ for chunk in stream:
|
|
|
668
668
|
Supports image, video, and audio generation through fal.ai with automatic media type detection.
|
|
669
669
|
|
|
670
670
|
```python
|
|
671
|
-
import
|
|
671
|
+
import revenium_middleware.fal # Auto-activates
|
|
672
672
|
import fal_client
|
|
673
673
|
|
|
674
674
|
result = fal_client.subscribe(
|
|
@@ -700,16 +700,23 @@ for image in result.get("images", []):
|
|
|
700
700
|
|
|
701
701
|
Callback handler that automatically tracks LLM calls, chains, tools, and agent actions.
|
|
702
702
|
|
|
703
|
+
```bash
|
|
704
|
+
pip install "revenium-python-sdk[langchain]"
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Wrap any LangChain LLM (or embeddings model) with `wrap()` — the Revenium callback handler is attached for you:
|
|
708
|
+
|
|
703
709
|
```python
|
|
704
710
|
from langchain_openai import ChatOpenAI
|
|
705
|
-
from
|
|
711
|
+
from revenium_middleware.openai.langchain import wrap
|
|
706
712
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
713
|
+
llm = wrap(
|
|
714
|
+
ChatOpenAI(model="gpt-4o-mini"),
|
|
715
|
+
usage_metadata={
|
|
716
|
+
"trace_id": "session-123",
|
|
717
|
+
"agent": "support_agent",
|
|
718
|
+
},
|
|
710
719
|
)
|
|
711
|
-
|
|
712
|
-
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[handler])
|
|
713
720
|
response = llm.invoke("Hello!")
|
|
714
721
|
```
|
|
715
722
|
|
|
@@ -720,13 +727,14 @@ from langchain_core.prompts import ChatPromptTemplate
|
|
|
720
727
|
from langchain_core.output_parsers import StrOutputParser
|
|
721
728
|
|
|
722
729
|
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
|
|
723
|
-
chain = prompt | llm |
|
|
730
|
+
chain = prompt | llm | StrOutputParser()
|
|
724
731
|
result = chain.invoke({"topic": "programming"})
|
|
725
732
|
```
|
|
726
733
|
|
|
727
734
|
**With agents:**
|
|
728
735
|
|
|
729
736
|
```python
|
|
737
|
+
from langchain_core.messages import HumanMessage
|
|
730
738
|
from langchain_core.tools import tool
|
|
731
739
|
from langgraph.prebuilt import create_react_agent
|
|
732
740
|
|
|
@@ -736,40 +744,32 @@ def get_weather(city: str) -> str:
|
|
|
736
744
|
return f"Sunny, 72F in {city}"
|
|
737
745
|
|
|
738
746
|
agent = create_react_agent(llm, [get_weather])
|
|
739
|
-
result = agent.invoke(
|
|
740
|
-
{"messages": [HumanMessage(content="Weather in NYC?")]},
|
|
741
|
-
config={"callbacks": [handler]}
|
|
742
|
-
)
|
|
747
|
+
result = agent.invoke({"messages": [HumanMessage(content="Weather in NYC?")]})
|
|
743
748
|
```
|
|
744
749
|
|
|
745
|
-
**Async support:**
|
|
750
|
+
**Async support:** the handler is async-native — wrap once and use `ainvoke`/`astream` directly:
|
|
746
751
|
|
|
747
752
|
```python
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
handler = AsyncReveniumCallbackHandler(trace_id="async-session")
|
|
751
|
-
llm = ChatOpenAI(model="gpt-4o-mini", callbacks=[handler])
|
|
753
|
+
llm = wrap(ChatOpenAI(model="gpt-4o-mini"))
|
|
752
754
|
response = await llm.ainvoke("Hello!")
|
|
753
755
|
```
|
|
754
756
|
|
|
755
757
|
**Supported providers:** OpenAI, Anthropic, Google, AWS Bedrock, Azure OpenAI, Cohere, HuggingFace, Ollama. Provider is auto-detected from LangChain class name or model name prefix.
|
|
756
758
|
|
|
757
|
-
**
|
|
759
|
+
**Attaching to an existing LLM:** use `attach_to()` to add tracking in-place, with any of the standard metadata fields (see [Metadata Fields](#metadata-fields)):
|
|
758
760
|
|
|
759
761
|
```python
|
|
760
|
-
from
|
|
761
|
-
|
|
762
|
-
config = ReveniumConfig(
|
|
763
|
-
api_key="hak_your_api_key",
|
|
764
|
-
environment="production",
|
|
765
|
-
organization_name="my_org",
|
|
766
|
-
product_name="my_product",
|
|
767
|
-
subscriber=SubscriberConfig(id="user_123", email="user@example.com"),
|
|
768
|
-
)
|
|
762
|
+
from revenium_middleware.openai.langchain import attach_to
|
|
769
763
|
|
|
770
|
-
|
|
764
|
+
attach_to(llm, usage_metadata={
|
|
765
|
+
"organizationName": "my_org",
|
|
766
|
+
"productName": "my_product",
|
|
767
|
+
"subscriber": {"id": "user_123", "email": "user@example.com"},
|
|
768
|
+
})
|
|
771
769
|
```
|
|
772
770
|
|
|
771
|
+
Credentials come from the standard environment variables (`REVENIUM_METERING_API_KEY`, `REVENIUM_METERING_BASE_URL`) or `revenium_middleware.configure()`.
|
|
772
|
+
|
|
773
773
|
---
|
|
774
774
|
|
|
775
775
|
## Metadata Fields
|
|
@@ -1086,7 +1086,7 @@ Each field has a maximum length of **50,000 characters**. If exceeded, it's trun
|
|
|
1086
1086
|
import os
|
|
1087
1087
|
os.environ["REVENIUM_CAPTURE_PROMPTS"] = "true"
|
|
1088
1088
|
|
|
1089
|
-
import
|
|
1089
|
+
import revenium_middleware.openai
|
|
1090
1090
|
from openai import OpenAI
|
|
1091
1091
|
|
|
1092
1092
|
client = OpenAI()
|
|
@@ -1223,6 +1223,44 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1223
1223
|
|----------|-------------|
|
|
1224
1224
|
| `REVENIUM_METERING_API_KEY` | Your Revenium API key (starts with `hak_` or `rev_`) |
|
|
1225
1225
|
|
|
1226
|
+
### Configuring After Import
|
|
1227
|
+
|
|
1228
|
+
The metering client is normally built from the environment when
|
|
1229
|
+
`revenium_middleware` is first imported. If your credentials only become
|
|
1230
|
+
available later (a secrets-vault bootstrap, framework settings hooks, import
|
|
1231
|
+
ordering), you don't need to restart: as soon as `REVENIUM_METERING_API_KEY`
|
|
1232
|
+
appears in the environment, the next metered call picks it up automatically.
|
|
1233
|
+
You can also configure programmatically at any time:
|
|
1234
|
+
|
|
1235
|
+
```python
|
|
1236
|
+
import revenium_middleware
|
|
1237
|
+
|
|
1238
|
+
revenium_middleware.initialize_metering(
|
|
1239
|
+
api_key="hak_your_key", # defaults to REVENIUM_METERING_API_KEY
|
|
1240
|
+
base_url="https://api.revenium.ai", # defaults to REVENIUM_METERING_BASE_URL
|
|
1241
|
+
)
|
|
1242
|
+
```
|
|
1243
|
+
|
|
1244
|
+
`initialize_metering()` returns `True` when metering is enabled after the
|
|
1245
|
+
call; invoke it with no arguments to re-read the environment.
|
|
1246
|
+
|
|
1247
|
+
### Delivery Resilience (Store-and-Forward)
|
|
1248
|
+
|
|
1249
|
+
Metering events that still fail after the client's own retries (network
|
|
1250
|
+
outages, 5xx, rate limiting) are not lost: they are held in a bounded
|
|
1251
|
+
in-memory buffer and replayed automatically in the background every 30
|
|
1252
|
+
seconds, reusing each event's original `Idempotency-Key` so replays can
|
|
1253
|
+
never double-bill. Permanent failures (401/403/404/422) are never buffered.
|
|
1254
|
+
The buffer holds up to 1000 events (oldest evicted first) for at most 24
|
|
1255
|
+
hours, and is drained on graceful shutdown. Inspect it programmatically:
|
|
1256
|
+
|
|
1257
|
+
```python
|
|
1258
|
+
from revenium_middleware import get_buffer_stats
|
|
1259
|
+
|
|
1260
|
+
print(get_buffer_stats())
|
|
1261
|
+
# {'size': 0, 'max_size': 1000, 'total_buffered': 3, 'total_replayed': 3, ...}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1226
1264
|
### Optional Environment Variables
|
|
1227
1265
|
|
|
1228
1266
|
| Variable | Default | Description |
|
|
@@ -1241,6 +1279,8 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1241
1279
|
| `REVENIUM_TRANSACTION_NAME` | - | Human-friendly operation name |
|
|
1242
1280
|
| `REVENIUM_RETRY_NUMBER` | - | Retry attempt number |
|
|
1243
1281
|
| `REVENIUM_BEDROCK_DISABLE` | - | Set to `1` to disable Bedrock auto-detection |
|
|
1282
|
+
| `REVENIUM_BUFFER_MAX_SIZE` | `1000` | Store-and-forward buffer capacity (oldest events evicted when full) |
|
|
1283
|
+
| `REVENIUM_BUFFER_FLUSH_INTERVAL` | `30` | Seconds between automatic replay attempts for buffered events |
|
|
1244
1284
|
|
|
1245
1285
|
### Provider-Specific Environment Variables
|
|
1246
1286
|
|
|
@@ -1283,7 +1323,7 @@ See [`examples/openai/openai_blocking_demo.py`](examples/openai/openai_blocking_
|
|
|
1283
1323
|
|
|
1284
1324
|
**Force direct Anthropic API:** Set `REVENIUM_BEDROCK_DISABLE=1` to disable Bedrock auto-detection.
|
|
1285
1325
|
|
|
1286
|
-
**Check initialization status:** Use `
|
|
1326
|
+
**Check initialization status (Anthropic):** Use `revenium_middleware.anthropic.is_initialized()` to verify setup.
|
|
1287
1327
|
|
|
1288
1328
|
---
|
|
1289
1329
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "revenium-python-sdk"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "The official Revenium Python SDK — unified AI metering middleware for OpenAI, Anthropic, Google, Ollama, LiteLLM, Perplexity, and fal.ai."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -138,6 +138,9 @@ logger.propagate = True
|
|
|
138
138
|
# Existing imports like `from revenium_middleware import client` keep working.
|
|
139
139
|
from ._core import ( # noqa: E402
|
|
140
140
|
client,
|
|
141
|
+
get_buffer_stats,
|
|
142
|
+
get_client,
|
|
143
|
+
initialize_metering,
|
|
141
144
|
run_async_in_thread,
|
|
142
145
|
shutdown_event,
|
|
143
146
|
revenium_meter,
|
|
@@ -166,6 +169,9 @@ from .agentic_outcomes import AgenticOutcomeClient, AgenticOutcomeSettings # no
|
|
|
166
169
|
__all__ = [
|
|
167
170
|
# Metering exports
|
|
168
171
|
"client",
|
|
172
|
+
"get_buffer_stats",
|
|
173
|
+
"get_client",
|
|
174
|
+
"initialize_metering",
|
|
169
175
|
"run_async_in_thread",
|
|
170
176
|
"shutdown_event",
|
|
171
177
|
# Decorator exports
|
{revenium_python_sdk-0.1.10 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/__init__.py
RENAMED
|
@@ -5,7 +5,8 @@ This subpackage contains the foundational components shared across all
|
|
|
5
5
|
provider-specific middleware implementations.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from .metering import run_async_in_thread, shutdown_event, client
|
|
8
|
+
from .metering import run_async_in_thread, shutdown_event, client, get_client, initialize_metering
|
|
9
|
+
from .metering_buffer import get_buffer_stats
|
|
9
10
|
from .metering_submission import submit_ai_event
|
|
10
11
|
from .exceptions import BudgetExceededError
|
|
11
12
|
from .enforcement import check_enforcement, is_circuit_breaker_enabled, stop_polling
|
|
@@ -50,6 +51,9 @@ from .trace_fields import (
|
|
|
50
51
|
__all__ = [
|
|
51
52
|
# Metering
|
|
52
53
|
"client",
|
|
54
|
+
"get_client",
|
|
55
|
+
"initialize_metering",
|
|
56
|
+
"get_buffer_stats",
|
|
53
57
|
"run_async_in_thread",
|
|
54
58
|
"shutdown_event",
|
|
55
59
|
"submit_ai_event",
|