revenium-python-sdk 0.2.0__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.
Files changed (133) hide show
  1. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/PKG-INFO +45 -45
  2. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/README.md +44 -44
  3. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/pyproject.toml +1 -1
  4. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/__init__.py +11 -0
  5. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/bedrock_adapter.py +36 -14
  6. revenium_python_sdk-0.3.0/revenium_middleware/anthropic/bedrock_transport.py +482 -0
  7. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/middleware.py +14 -2
  8. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/utils.py +7 -5
  9. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/middleware.py +1 -1
  10. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/middleware.py +1 -1
  11. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/middleware.py +14 -5
  12. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/PKG-INFO +45 -45
  13. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/SOURCES.txt +1 -0
  14. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/LICENSE +0 -0
  15. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/__init__.py +0 -0
  16. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/__init__.py +0 -0
  17. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/config.py +0 -0
  18. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/context.py +0 -0
  19. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/decorators.py +0 -0
  20. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/enforcement.py +0 -0
  21. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/exceptions.py +0 -0
  22. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/fields.py +0 -0
  23. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/log_sanitize.py +0 -0
  24. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/metering.py +0 -0
  25. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/metering_buffer.py +0 -0
  26. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/metering_submission.py +0 -0
  27. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/patch_registry.py +0 -0
  28. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/prompt_extraction.py +0 -0
  29. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/subscriber.py +0 -0
  30. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_core/trace_fields.py +0 -0
  31. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/LICENSE +0 -0
  32. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/__init__.py +0 -0
  33. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_base_client.py +0 -0
  34. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_client.py +0 -0
  35. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_compat.py +0 -0
  36. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_constants.py +0 -0
  37. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_exceptions.py +0 -0
  38. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_files.py +0 -0
  39. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_models.py +0 -0
  40. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_qs.py +0 -0
  41. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_resource.py +0 -0
  42. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_response.py +0 -0
  43. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_streaming.py +0 -0
  44. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_types.py +0 -0
  45. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/__init__.py +0 -0
  46. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_logs.py +0 -0
  47. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_proxy.py +0 -0
  48. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_reflection.py +0 -0
  49. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_resources_proxy.py +0 -0
  50. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_streams.py +0 -0
  51. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_sync.py +0 -0
  52. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_transform.py +0 -0
  53. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_typing.py +0 -0
  54. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_utils/_utils.py +0 -0
  55. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/_version.py +0 -0
  56. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/context.py +0 -0
  57. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/decorator.py +0 -0
  58. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/py.typed +0 -0
  59. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/__init__.py +0 -0
  60. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/ai.py +0 -0
  61. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/apis.py +0 -0
  62. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/resources/events.py +0 -0
  63. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/__init__.py +0 -0
  64. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_audio_params.py +0 -0
  65. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_completion_params.py +0 -0
  66. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_image_params.py +0 -0
  67. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/ai_create_video_params.py +0 -0
  68. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/api_meter_request_params.py +0 -0
  69. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/api_meter_response_params.py +0 -0
  70. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/event_create_params.py +0 -0
  71. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/_metering/types/metering_response_resource.py +0 -0
  72. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/agentic_outcomes.py +0 -0
  73. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/config.py +0 -0
  74. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/prompt_extractor.py +0 -0
  75. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/provider.py +0 -0
  76. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/stream_create.py +0 -0
  77. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/anthropic/trace_fields.py +0 -0
  78. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/__init__.py +0 -0
  79. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/_metering.py +0 -0
  80. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/config.py +0 -0
  81. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/middleware.py +0 -0
  82. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/fal/trace_fields.py +0 -0
  83. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/__init__.py +0 -0
  84. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/__init__.py +0 -0
  85. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/exceptions.py +0 -0
  86. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/protocols.py +0 -0
  87. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/trace_fields.py +0 -0
  88. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/common/types.py +0 -0
  89. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/config.py +0 -0
  90. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/__init__.py +0 -0
  91. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/google_ai/provider.py +0 -0
  92. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/prompt_extractor.py +0 -0
  93. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/__init__.py +0 -0
  94. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/google/vertex_ai/provider.py +0 -0
  95. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/__init__.py +0 -0
  96. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/__init__.py +0 -0
  97. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/config.py +0 -0
  98. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/context.py +0 -0
  99. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/decorators.py +0 -0
  100. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/hooks.py +0 -0
  101. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/integrations/__init__.py +0 -0
  102. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/integrations/crewai.py +0 -0
  103. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/trace_fields.py +0 -0
  104. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/client/validation.py +0 -0
  105. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/proxy/__init__.py +0 -0
  106. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/litellm/proxy/middleware.py +0 -0
  107. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/__init__.py +0 -0
  108. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/middleware.py +0 -0
  109. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/ollama/trace_fields.py +0 -0
  110. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/__init__.py +0 -0
  111. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/azure_config.py +0 -0
  112. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/azure_model_resolver.py +0 -0
  113. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/config.py +0 -0
  114. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/exceptions.py +0 -0
  115. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/__init__.py +0 -0
  116. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/_utils.py +0 -0
  117. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/langchain/unified_handler.py +0 -0
  118. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/middleware.py +0 -0
  119. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/prompt_extractor.py +0 -0
  120. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/provider.py +0 -0
  121. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/openai/trace_fields.py +0 -0
  122. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/__init__.py +0 -0
  123. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/middleware.py +0 -0
  124. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/perplexity_sdk.py +0 -0
  125. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/provider.py +0 -0
  126. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/perplexity/trace_fields.py +0 -0
  127. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/webhooks/__init__.py +0 -0
  128. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_middleware/webhooks/_verify.py +0 -0
  129. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/dependency_links.txt +0 -0
  130. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/requires.txt +0 -0
  131. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/revenium_python_sdk.egg-info/top_level.txt +0 -0
  132. {revenium_python_sdk-0.2.0 → revenium_python_sdk-0.3.0}/setup.cfg +0 -0
  133. {revenium_python_sdk-0.2.0 → 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.2.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 revenium_middleware_openai # Auto-initializes on 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 revenium_middleware_openai # Auto-initializes
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 revenium_middleware_openai
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 revenium_middleware_anthropic # Auto-initializes
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 revenium_middleware_anthropic
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 revenium_middleware_google
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 revenium_middleware_google
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 revenium_middleware_ollama # Auto-initializes
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 revenium_middleware_openai
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 revenium_middleware_litellm_client.middleware # Auto-initializes
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: ["revenium_middleware_litellm_proxy.middleware.proxy_handler_instance"]
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-middleware-litellm[crewai]"
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 revenium_middleware_perplexity # Auto-patches OpenAI
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 revenium_middleware_perplexity # Auto-patches Perplexity
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 revenium_middleware_fal # Auto-activates
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 revenium_middleware_langchain import ReveniumCallbackHandler
804
+ from revenium_middleware.openai.langchain import wrap
799
805
 
800
- handler = ReveniumCallbackHandler(
801
- trace_id="session-123",
802
- agent_name="support_agent"
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 | output_parser
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
- from revenium_middleware_langchain import AsyncReveniumCallbackHandler
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
- **Programmatic configuration:**
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 revenium_middleware_langchain import ReveniumCallbackHandler, ReveniumConfig, SubscriberConfig
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
- handler = ReveniumCallbackHandler(config=config, trace_id="session-123")
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 revenium_middleware_openai
1182
+ import revenium_middleware.openai
1183
1183
  from openai import OpenAI
1184
1184
 
1185
1185
  client = OpenAI()
@@ -1416,7 +1416,7 @@ print(get_buffer_stats())
1416
1416
 
1417
1417
  **Force direct Anthropic API:** Set `REVENIUM_BEDROCK_DISABLE=1` to disable Bedrock auto-detection.
1418
1418
 
1419
- **Check initialization status:** Use `revenium_middleware_<provider>.is_initialized()` to verify setup.
1419
+ **Check initialization status (Anthropic):** Use `revenium_middleware.anthropic.is_initialized()` to verify setup.
1420
1420
 
1421
1421
  ---
1422
1422
 
@@ -102,7 +102,7 @@ from dotenv import load_dotenv
102
102
  load_dotenv()
103
103
 
104
104
  import openai
105
- import revenium_middleware_openai # Auto-initializes on 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 revenium_middleware_openai # Auto-initializes
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 revenium_middleware_openai
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 revenium_middleware_anthropic # Auto-initializes
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 revenium_middleware_anthropic
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 revenium_middleware_google
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 revenium_middleware_google
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 revenium_middleware_ollama # Auto-initializes
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 revenium_middleware_openai
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 revenium_middleware_litellm_client.middleware # Auto-initializes
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: ["revenium_middleware_litellm_proxy.middleware.proxy_handler_instance"]
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-middleware-litellm[crewai]"
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 revenium_middleware_perplexity # Auto-patches OpenAI
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 revenium_middleware_perplexity # Auto-patches Perplexity
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 revenium_middleware_fal # Auto-activates
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 revenium_middleware_langchain import ReveniumCallbackHandler
711
+ from revenium_middleware.openai.langchain import wrap
706
712
 
707
- handler = ReveniumCallbackHandler(
708
- trace_id="session-123",
709
- agent_name="support_agent"
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 | output_parser
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
- from revenium_middleware_langchain import AsyncReveniumCallbackHandler
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
- **Programmatic configuration:**
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 revenium_middleware_langchain import ReveniumCallbackHandler, ReveniumConfig, SubscriberConfig
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
- handler = ReveniumCallbackHandler(config=config, trace_id="session-123")
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 revenium_middleware_openai
1089
+ import revenium_middleware.openai
1090
1090
  from openai import OpenAI
1091
1091
 
1092
1092
  client = OpenAI()
@@ -1323,7 +1323,7 @@ print(get_buffer_stats())
1323
1323
 
1324
1324
  **Force direct Anthropic API:** Set `REVENIUM_BEDROCK_DISABLE=1` to disable Bedrock auto-detection.
1325
1325
 
1326
- **Check initialization status:** Use `revenium_middleware_<provider>.is_initialized()` to verify setup.
1326
+ **Check initialization status (Anthropic):** Use `revenium_middleware.anthropic.is_initialized()` to verify setup.
1327
1327
 
1328
1328
  ---
1329
1329
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "revenium-python-sdk"
7
- version = "0.2.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"
@@ -21,6 +21,13 @@ logger = logging.getLogger("revenium_middleware.anthropic.init")
21
21
  # Import provider detection (no SDK dependency)
22
22
  from .provider import Provider, detect_provider, get_provider_metadata, is_bedrock_provider
23
23
 
24
+ # Bedrock transport metering (no anthropic-SDK dependency; botocore is lazy).
25
+ # Opt-in canary: patches botocore only when REVENIUM_BEDROCK_TRANSPORT=1.
26
+ from . import bedrock_transport
27
+ from .bedrock_transport import activate_bedrock_transport, suppress_transport_metering
28
+
29
+ bedrock_transport.activate_if_enabled()
30
+
24
31
  # Conditionally import middleware (requires anthropic SDK)
25
32
  try:
26
33
  import anthropic # noqa: F401
@@ -101,6 +108,10 @@ __all__ = [
101
108
  "get_provider_metadata",
102
109
  "is_bedrock_provider",
103
110
 
111
+ # Bedrock transport metering (opt-in canary)
112
+ "activate_bedrock_transport",
113
+ "suppress_transport_metering",
114
+
104
115
  # Initialization control
105
116
  "initialize",
106
117
  "is_initialized",
@@ -19,6 +19,8 @@ import threading
19
19
 
20
20
  from typing import Dict, Any, Optional, Tuple, Generator, Iterator, Union, List
21
21
 
22
+ from revenium_middleware.anthropic.bedrock_transport import suppress_transport_metering
23
+
22
24
  logger = logging.getLogger("revenium_middleware.extension")
23
25
 
24
26
 
@@ -175,8 +177,24 @@ def get_bedrock_client(region: str):
175
177
 
176
178
 
177
179
  def _model_id(model_name: str) -> str:
178
- """Map Anthropic model name to Bedrock model ID."""
179
- return _MODEL_MAP.get(model_name, f"anthropic.{model_name}")
180
+ """Map Anthropic model name to Bedrock model ID.
181
+
182
+ Resolution order: known aliases win, already-qualified Bedrock IDs and
183
+ ARNs pass through byte-for-byte, and only bare names receive the
184
+ ``anthropic.`` fallback. Unmapped IDs without a provider segment must be
185
+ fully qualified by the caller -- the adapter does not infer a provider
186
+ for an arbitrary ``<region>.<name>``.
187
+ """
188
+ mapped = _MODEL_MAP.get(model_name)
189
+ if mapped is not None:
190
+ return mapped
191
+ if (
192
+ model_name.startswith("arn:")
193
+ or "anthropic." in model_name
194
+ or "amazon." in model_name
195
+ ):
196
+ return model_name
197
+ return f"anthropic.{model_name}"
180
198
 
181
199
 
182
200
  def _as_dict(value: Any) -> dict:
@@ -279,12 +297,14 @@ def bedrock_invoke(model: str, payload: dict, region: Optional[str] = None) -> T
279
297
 
280
298
  logger.debug(f"Invoking Bedrock model {model_id} in region {region}")
281
299
 
282
- # Make the API call
283
- resp = client.invoke_model(
284
- modelId=model_id,
285
- body=json.dumps(payload),
286
- accept="application/json"
287
- )
300
+ # Make the API call. Marked internal so the transport-layer patch
301
+ # does not emit a second completion for this invocation.
302
+ with suppress_transport_metering():
303
+ resp = client.invoke_model(
304
+ modelId=model_id,
305
+ body=json.dumps(payload),
306
+ accept="application/json"
307
+ )
288
308
 
289
309
  # Parse response
290
310
  try:
@@ -363,12 +383,14 @@ class BedrockStreamIterator:
363
383
 
364
384
  logger.debug(f"Starting Bedrock streaming for model {model_id} in region {self.region}")
365
385
 
366
- # Make the streaming API call
367
- resp = client.invoke_model_with_response_stream(
368
- modelId=model_id,
369
- body=json.dumps(self.payload),
370
- accept="application/json"
371
- )
386
+ # Make the streaming API call. Marked internal so the
387
+ # transport-layer patch does not emit a second completion.
388
+ with suppress_transport_metering():
389
+ resp = client.invoke_model_with_response_stream(
390
+ modelId=model_id,
391
+ body=json.dumps(self.payload),
392
+ accept="application/json"
393
+ )
372
394
 
373
395
  # Process the streaming response
374
396
  stream = resp.get("body")