payi 0.1.0a83__tar.gz → 0.1.0a85__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.

Potentially problematic release.


This version of payi might be problematic. Click here for more details.

Files changed (208) hide show
  1. payi-0.1.0a85/.release-please-manifest.json +3 -0
  2. {payi-0.1.0a83 → payi-0.1.0a85}/CHANGELOG.md +17 -0
  3. {payi-0.1.0a83 → payi-0.1.0a85}/PKG-INFO +1 -1
  4. {payi-0.1.0a83 → payi-0.1.0a85}/api.md +6 -0
  5. {payi-0.1.0a83 → payi-0.1.0a85}/pyproject.toml +1 -1
  6. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_version.py +1 -1
  7. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/AnthropicInstrumentor.py +111 -70
  8. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/BedrockInstrumentor.py +83 -100
  9. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/GoogleGenAiInstrumentor.py +26 -111
  10. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/VertexInstrumentor.py +132 -98
  11. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/instrument.py +52 -15
  12. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/__init__.py +14 -0
  13. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/categories.py +32 -0
  14. payi-0.1.0a85/src/payi/resources/categories/fixed_cost_resources.py +196 -0
  15. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/ingest.py +14 -0
  16. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/limits.py +4 -0
  17. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/__init__.py +1 -0
  18. payi-0.1.0a85/src/payi/types/categories/fixed_cost_resource_create_params.py +21 -0
  19. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_event_param.py +13 -1
  20. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_units_params.py +11 -1
  21. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_create_params.py +2 -0
  22. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_history_response.py +3 -3
  23. payi-0.1.0a85/tests/api_resources/categories/test_fixed_cost_resources.py +151 -0
  24. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_ingest.py +32 -0
  25. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_limits.py +2 -0
  26. payi-0.1.0a83/.release-please-manifest.json +0 -3
  27. {payi-0.1.0a83 → payi-0.1.0a85}/.gitignore +0 -0
  28. {payi-0.1.0a83 → payi-0.1.0a85}/CONTRIBUTING.md +0 -0
  29. {payi-0.1.0a83 → payi-0.1.0a85}/LICENSE +0 -0
  30. {payi-0.1.0a83 → payi-0.1.0a85}/README.md +0 -0
  31. {payi-0.1.0a83 → payi-0.1.0a85}/SECURITY.md +0 -0
  32. {payi-0.1.0a83 → payi-0.1.0a85}/bin/check-release-environment +0 -0
  33. {payi-0.1.0a83 → payi-0.1.0a85}/bin/publish-pypi +0 -0
  34. {payi-0.1.0a83 → payi-0.1.0a85}/examples/.keep +0 -0
  35. {payi-0.1.0a83 → payi-0.1.0a85}/mypy.ini +0 -0
  36. {payi-0.1.0a83 → payi-0.1.0a85}/noxfile.py +0 -0
  37. {payi-0.1.0a83 → payi-0.1.0a85}/release-please-config.json +0 -0
  38. {payi-0.1.0a83 → payi-0.1.0a85}/requirements-dev.lock +0 -0
  39. {payi-0.1.0a83 → payi-0.1.0a85}/requirements.lock +0 -0
  40. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/__init__.py +0 -0
  41. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_base_client.py +0 -0
  42. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_client.py +0 -0
  43. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_compat.py +0 -0
  44. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_constants.py +0 -0
  45. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_exceptions.py +0 -0
  46. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_files.py +0 -0
  47. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_models.py +0 -0
  48. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_qs.py +0 -0
  49. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_resource.py +0 -0
  50. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_response.py +0 -0
  51. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_streaming.py +0 -0
  52. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_types.py +0 -0
  53. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/__init__.py +0 -0
  54. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_logs.py +0 -0
  55. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_proxy.py +0 -0
  56. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_reflection.py +0 -0
  57. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_resources_proxy.py +0 -0
  58. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_streams.py +0 -0
  59. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_sync.py +0 -0
  60. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_transform.py +0 -0
  61. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_typing.py +0 -0
  62. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_utils.py +0 -0
  63. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/.keep +0 -0
  64. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/OpenAIInstrumentor.py +0 -0
  65. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/Stopwatch.py +0 -0
  66. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/helpers.py +0 -0
  67. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/pagination.py +0 -0
  68. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/py.typed +0 -0
  69. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/__init__.py +0 -0
  70. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/resources.py +0 -0
  71. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/__init__.py +0 -0
  72. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/experiences.py +0 -0
  73. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/properties.py +0 -0
  74. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/__init__.py +0 -0
  75. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/limit_config.py +0 -0
  76. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/types.py +0 -0
  77. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/__init__.py +0 -0
  78. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/tags.py +0 -0
  79. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/__init__.py +0 -0
  80. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/properties.py +0 -0
  81. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/requests.py +0 -0
  82. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/result.py +0 -0
  83. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/__init__.py +0 -0
  84. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/__init__.py +0 -0
  85. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/definitions.py +0 -0
  86. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/kpis.py +0 -0
  87. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/limit_config.py +0 -0
  88. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/version.py +0 -0
  89. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/kpis.py +0 -0
  90. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/properties.py +0 -0
  91. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/use_cases.py +0 -0
  92. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/__init__.py +0 -0
  93. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/bulk_ingest_response.py +0 -0
  94. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/resource_create_params.py +0 -0
  95. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/resource_list_params.py +0 -0
  96. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_delete_resource_response.py +0 -0
  97. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_delete_response.py +0 -0
  98. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_list_params.py +0 -0
  99. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_list_resources_params.py +0 -0
  100. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_resource_response.py +0 -0
  101. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_response.py +0 -0
  102. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/cost_data.py +0 -0
  103. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/cost_details.py +0 -0
  104. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/default_response.py +0 -0
  105. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experience_instance_response.py +0 -0
  106. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/__init__.py +0 -0
  107. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/experience_type.py +0 -0
  108. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/property_create_params.py +0 -0
  109. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_create_params.py +0 -0
  110. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_list_params.py +0 -0
  111. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_update_params.py +0 -0
  112. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/types/__init__.py +0 -0
  113. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
  114. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_bulk_params.py +0 -0
  115. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_response.py +0 -0
  116. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_list_params.py +0 -0
  117. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_list_response.py +0 -0
  118. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_reset_params.py +0 -0
  119. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_response.py +0 -0
  120. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_update_params.py +0 -0
  121. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/__init__.py +0 -0
  122. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/limit_tags.py +0 -0
  123. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_create_params.py +0 -0
  124. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_create_response.py +0 -0
  125. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_delete_response.py +0 -0
  126. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_list_response.py +0 -0
  127. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_remove_params.py +0 -0
  128. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_remove_response.py +0 -0
  129. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_update_params.py +0 -0
  130. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_update_response.py +0 -0
  131. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
  132. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/__init__.py +0 -0
  133. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/property_create_params.py +0 -0
  134. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/request_result.py +0 -0
  135. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests_data.py +0 -0
  136. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/__init__.py +0 -0
  137. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/evaluation_response.py +0 -0
  138. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/ingest_units.py +0 -0
  139. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
  140. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/pay_i_common_models_budget_management_create_limit_base.py +0 -0
  141. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/properties_response.py +0 -0
  142. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/xproxy_error.py +0 -0
  143. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/xproxy_result.py +0 -0
  144. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/__init__.py +0 -0
  145. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/ingest_units.py +0 -0
  146. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/pay_i_common_models_budget_management_create_limit_base.py +0 -0
  147. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/total_cost_data.py +0 -0
  148. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_case_instance_response.py +0 -0
  149. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/__init__.py +0 -0
  150. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_create_params.py +0 -0
  151. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_list_params.py +0 -0
  152. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_update_params.py +0 -0
  153. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/__init__.py +0 -0
  154. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_create_params.py +0 -0
  155. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_create_response.py +0 -0
  156. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_delete_response.py +0 -0
  157. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_list_params.py +0 -0
  158. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_list_response.py +0 -0
  159. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_retrieve_response.py +0 -0
  160. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_update_params.py +0 -0
  161. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_update_response.py +0 -0
  162. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/limit_config_create_params.py +0 -0
  163. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_create_params.py +0 -0
  164. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_list_params.py +0 -0
  165. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_list_response.py +0 -0
  166. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_update_params.py +0 -0
  167. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/property_create_params.py +0 -0
  168. {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/use_case_definition.py +0 -0
  169. {payi-0.1.0a83 → payi-0.1.0a85}/tests/__init__.py +0 -0
  170. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/__init__.py +0 -0
  171. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/categories/__init__.py +0 -0
  172. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/categories/test_resources.py +0 -0
  173. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/__init__.py +0 -0
  174. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/test_properties.py +0 -0
  175. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/test_types.py +0 -0
  176. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/types/__init__.py +0 -0
  177. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
  178. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/limits/__init__.py +0 -0
  179. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/limits/test_tags.py +0 -0
  180. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/__init__.py +0 -0
  181. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/test_properties.py +0 -0
  182. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/test_result.py +0 -0
  183. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_categories.py +0 -0
  184. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_experiences.py +0 -0
  185. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_use_cases.py +0 -0
  186. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/__init__.py +0 -0
  187. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/__init__.py +0 -0
  188. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_kpis.py +0 -0
  189. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_limit_config.py +0 -0
  190. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_version.py +0 -0
  191. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_definitions.py +0 -0
  192. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_kpis.py +0 -0
  193. {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_properties.py +0 -0
  194. {payi-0.1.0a83 → payi-0.1.0a85}/tests/conftest.py +0 -0
  195. {payi-0.1.0a83 → payi-0.1.0a85}/tests/sample_file.txt +0 -0
  196. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_client.py +0 -0
  197. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_deepcopy.py +0 -0
  198. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_extract_files.py +0 -0
  199. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_files.py +0 -0
  200. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_models.py +0 -0
  201. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_qs.py +0 -0
  202. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_required_args.py +0 -0
  203. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_response.py +0 -0
  204. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_streaming.py +0 -0
  205. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_transform.py +0 -0
  206. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_utils/test_proxy.py +0 -0
  207. {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_utils/test_typing.py +0 -0
  208. {payi-0.1.0a83 → payi-0.1.0a85}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.85"
3
+ }
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.85 (2025-06-12)
4
+
5
+ Full Changelog: [v0.1.0-alpha.84...v0.1.0-alpha.85](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.84...v0.1.0-alpha.85)
6
+
7
+ ### Features
8
+
9
+ * AnthropicBedrock ([#320](https://github.com/Pay-i/pay-i-python/issues/320)) ([33b42e3](https://github.com/Pay-i/pay-i-python/commit/33b42e38d7ba3245e0633254b4401cf991937933))
10
+
11
+ ## 0.1.0-alpha.84 (2025-06-09)
12
+
13
+ Full Changelog: [v0.1.0-alpha.83...v0.1.0-alpha.84](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.83...v0.1.0-alpha.84)
14
+
15
+ ### Features
16
+
17
+ * **api:** manual updates ([b5edce3](https://github.com/Pay-i/pay-i-python/commit/b5edce3207c9cd01ded791e67b8cc0bbf5ef4ef4))
18
+ * consolidate anthropic vision, google.genai and vertex compute usage ([#318](https://github.com/Pay-i/pay-i-python/issues/318)) ([28700fd](https://github.com/Pay-i/pay-i-python/commit/28700fd25e76b03e06f9cb7c963890dbb1675f2b))
19
+
3
20
  ## 0.1.0-alpha.83 (2025-06-06)
4
21
 
5
22
  Full Changelog: [v0.1.0-alpha.82...v0.1.0-alpha.83](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.82...v0.1.0-alpha.83)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: payi
3
- Version: 0.1.0a83
3
+ Version: 0.1.0a85
4
4
  Summary: The official Python library for the payi API
5
5
  Project-URL: Homepage, https://github.com/Pay-i/pay-i-python
6
6
  Project-URL: Repository, https://github.com/Pay-i/pay-i-python
@@ -108,6 +108,12 @@ Methods:
108
108
  - <code title="get /api/v1/categories/{category}/resources/{resource}">client.categories.resources.<a href="./src/payi/resources/categories/resources.py">list</a>(resource, \*, category, \*\*<a href="src/payi/types/categories/resource_list_params.py">params</a>) -> <a href="./src/payi/types/category_resource_response.py">SyncCursorPage[CategoryResourceResponse]</a></code>
109
109
  - <code title="delete /api/v1/categories/{category}/resources/{resource}/{resource_id}">client.categories.resources.<a href="./src/payi/resources/categories/resources.py">delete</a>(resource_id, \*, category, resource) -> <a href="./src/payi/types/category_resource_response.py">CategoryResourceResponse</a></code>
110
110
 
111
+ ## FixedCostResources
112
+
113
+ Methods:
114
+
115
+ - <code title="post /api/v1/categories/{category}/fixed_cost_resources/{resource}">client.categories.fixed_cost_resources.<a href="./src/payi/resources/categories/fixed_cost_resources.py">create</a>(resource, \*, category, \*\*<a href="src/payi/types/categories/fixed_cost_resource_create_params.py">params</a>) -> <a href="./src/payi/types/category_resource_response.py">CategoryResourceResponse</a></code>
116
+
111
117
  # Experiences
112
118
 
113
119
  Types:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "payi"
3
- version = "0.1.0-alpha.83"
3
+ version = "0.1.0-alpha.85"
4
4
  description = "The official Python library for the payi API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "payi"
4
- __version__ = "0.1.0-alpha.83" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.85" # x-release-please-version
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from typing import Any, Union, Optional, Sequence
2
3
  from typing_extensions import override
3
4
 
@@ -17,6 +18,12 @@ class AnthropicInstrumentor:
17
18
 
18
19
  return isinstance(instance._client, (AsyncAnthropicVertex, AnthropicVertex))
19
20
 
21
+ @staticmethod
22
+ def is_bedrock(instance: Any) -> bool:
23
+ from anthropic import AnthropicBedrock, AsyncAnthropicBedrock # type: ignore # noqa: I001
24
+
25
+ return isinstance(instance._client, (AsyncAnthropicBedrock, AnthropicBedrock))
26
+
20
27
  @staticmethod
21
28
  def instrument(instrumentor: _PayiInstrumentor) -> None:
22
29
  try:
@@ -125,94 +132,46 @@ async def astream_messages_wrapper(
125
132
 
126
133
  class _AnthropicProviderRequest(_ProviderRequest):
127
134
  def __init__(self, instrumentor: _PayiInstrumentor, streaming_type: _StreamingType, instance: Any = None) -> None:
128
- self._vertex: bool = AnthropicInstrumentor.is_vertex(instance)
135
+ self._is_vertex: bool = AnthropicInstrumentor.is_vertex(instance)
136
+ self._is_bedrock: bool = AnthropicInstrumentor.is_bedrock(instance)
137
+
138
+ category: str = ""
139
+ if self._is_vertex:
140
+ category = PayiCategories.google_vertex
141
+ elif self._is_bedrock:
142
+ category = PayiCategories.aws_bedrock
143
+ else:
144
+ category = PayiCategories.anthropic
145
+
146
+ instrumentor._logger.debug(f"Anthropic messages instrumenting category {category}")
147
+
129
148
  super().__init__(
130
149
  instrumentor=instrumentor,
131
- category=PayiCategories.google_vertex if self._vertex else PayiCategories.anthropic,
150
+ category=category,
132
151
  streaming_type=streaming_type,
133
152
  )
134
153
 
135
154
  @override
136
155
  def process_chunk(self, chunk: Any) -> _ChunkResult:
137
- ingest = False
138
- if chunk.type == "message_start":
139
- self._ingest["provider_response_id"] = chunk.message.id
140
-
141
- usage = chunk.message.usage
142
- units = self._ingest["units"]
143
-
144
- input = _PayiInstrumentor.update_for_vision(usage.input_tokens, units, self._estimated_prompt_tokens)
145
-
146
- units["text"] = Units(input=input, output=0)
147
-
148
- if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
149
- text_cache_write = usage.cache_creation_input_tokens
150
- units["text_cache_write"] = Units(input=text_cache_write, output=0)
151
-
152
- if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
153
- text_cache_read = usage.cache_read_input_tokens
154
- units["text_cache_read"] = Units(input=text_cache_read, output=0)
155
-
156
- elif chunk.type == "message_delta":
157
- usage = chunk.usage
158
- ingest = True
159
-
160
- # Web search will return an updated input tokens value at the end of streaming
161
- if usage.input_tokens > 0:
162
- self._ingest["units"]["text"]["input"] = usage.input_tokens
163
-
164
- self._ingest["units"]["text"]["output"] = usage.output_tokens
165
-
166
- return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
156
+ return anthropic_process_chunk(self, chunk.to_dict(), assign_id=True)
167
157
 
168
158
  @override
169
159
  def process_synchronous_response(self, response: Any, log_prompt_and_response: bool, kwargs: Any) -> Any:
170
- usage = response.usage
171
- input = usage.input_tokens
172
- output = usage.output_tokens
173
- units: dict[str, Units] = self._ingest["units"]
174
-
175
- if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
176
- text_cache_write = usage.cache_creation_input_tokens
177
- units["text_cache_write"] = Units(input=text_cache_write, output=0)
178
-
179
- if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
180
- text_cache_read = usage.cache_read_input_tokens
181
- units["text_cache_read"] = Units(input=text_cache_read, output=0)
160
+ anthropic_process_synchronous_response(
161
+ request=self,
162
+ response=response.to_dict(),
163
+ log_prompt_and_response=log_prompt_and_response,
164
+ assign_id=True)
182
165
 
183
- input = _PayiInstrumentor.update_for_vision(input, units, self._estimated_prompt_tokens)
184
-
185
- units["text"] = Units(input=input, output=output)
186
-
187
- if log_prompt_and_response:
188
- self._ingest["provider_response_json"] = response.to_json()
189
-
190
- self._ingest["provider_response_id"] = response.id
191
-
192
166
  return None
193
167
 
194
168
  @override
195
169
  def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
196
- self._ingest["resource"] = ("anthropic." if self._vertex else "") + kwargs.get("model", "")
170
+ self._ingest["resource"] = ("anthropic." if self._is_vertex else "") + kwargs.get("model", "")
197
171
 
198
172
  messages = kwargs.get("messages")
199
173
  if messages:
200
- estimated_token_count = 0
201
- has_image = False
202
-
203
- try:
204
- enc = tiktoken.get_encoding("cl100k_base")
205
- for message in messages:
206
- msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
207
- if msg_has_image:
208
- has_image = True
209
- estimated_token_count += msg_prompt_tokens
210
-
211
- if has_image and estimated_token_count > 0:
212
- self._estimated_prompt_tokens = estimated_token_count
213
-
214
- except Exception:
215
- self._instrumentor._logger.warning("Error getting encoding for cl100k_base")
174
+ anthropic_has_image_and_get_texts(self, messages)
216
175
 
217
176
  return True
218
177
 
@@ -248,6 +207,88 @@ class _AnthropicProviderRequest(_ProviderRequest):
248
207
 
249
208
  return True
250
209
 
210
+ def anthropic_process_synchronous_response(request: _ProviderRequest, response: 'dict[str, Any]', log_prompt_and_response: bool, assign_id: bool) -> Any:
211
+ usage = response['usage']
212
+ input = usage['input_tokens']
213
+ output = usage['output_tokens']
214
+ units: dict[str, Units] = request._ingest["units"]
215
+
216
+ cache_creation_input_tokens = usage.get("cache_creation_input_tokens", 0)
217
+ if cache_creation_input_tokens > 0:
218
+ units["text_cache_write"] = Units(input=cache_creation_input_tokens, output=0)
219
+
220
+ cache_read_input_tokens = usage.get("cache_read_input_tokens", 0)
221
+ if cache_read_input_tokens > 0:
222
+ units["text_cache_read"] = Units(input=cache_read_input_tokens, output=0)
223
+
224
+ input = _PayiInstrumentor.update_for_vision(input, units, request._estimated_prompt_tokens)
225
+
226
+ units["text"] = Units(input=input, output=output)
227
+
228
+ if log_prompt_and_response:
229
+ request._ingest["provider_response_json"] = json.dumps(response)
230
+
231
+ if assign_id:
232
+ request._ingest["provider_response_id"] = response.get('id', None)
233
+
234
+ return None
235
+
236
+ def anthropic_process_chunk(request: _ProviderRequest, chunk: 'dict[str, Any]', assign_id: bool) -> _ChunkResult:
237
+ ingest = False
238
+ type = chunk.get('type', "")
239
+
240
+ if type == "message_start":
241
+ message = chunk['message']
242
+
243
+ if assign_id:
244
+ request._ingest["provider_response_id"] = message.get('id', None)
245
+
246
+ usage = message['usage']
247
+ units = request._ingest["units"]
248
+
249
+ input = _PayiInstrumentor.update_for_vision(usage['input_tokens'], units, request._estimated_prompt_tokens)
250
+
251
+ units["text"] = Units(input=input, output=0)
252
+
253
+ text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
254
+ if text_cache_write > 0:
255
+ units["text_cache_write"] = Units(input=text_cache_write, output=0)
256
+
257
+ text_cache_read: int = usage.get("cache_read_input_tokens", 0)
258
+ if text_cache_read > 0:
259
+ units["text_cache_read"] = Units(input=text_cache_read, output=0)
260
+
261
+ elif type == "message_delta":
262
+ usage = chunk.get('usage', {})
263
+ ingest = True
264
+
265
+ # Web search will return an updated input tokens value at the end of streaming
266
+ input_tokens = usage.get('input_tokens', None)
267
+ if input_tokens is not None:
268
+ request._ingest["units"]["text"]["input"] = input_tokens
269
+
270
+ request._ingest["units"]["text"]["output"] = usage.get('output_tokens', 0)
271
+
272
+ return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
273
+
274
+
275
+ def anthropic_has_image_and_get_texts(request: _ProviderRequest, messages: Any) -> None:
276
+ estimated_token_count = 0
277
+ has_image = False
278
+
279
+ try:
280
+ enc = tiktoken.get_encoding("cl100k_base")
281
+ for message in messages:
282
+ msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
283
+ if msg_has_image:
284
+ has_image = True
285
+ estimated_token_count += msg_prompt_tokens
286
+
287
+ if has_image and estimated_token_count > 0:
288
+ request._estimated_prompt_tokens = estimated_token_count
289
+
290
+ except Exception:
291
+ request._instrumentor._logger.warning("Error getting encoding for cl100k_base")
251
292
 
252
293
  def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
253
294
  if isinstance(content, list): # type: ignore
@@ -7,12 +7,11 @@ from typing_extensions import override
7
7
  from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore
8
8
 
9
9
  from payi.lib.helpers import PayiCategories, PayiHeaderNames, payi_aws_bedrock_url
10
- from payi.types.ingest_units_params import Units, IngestUnitsParams
10
+ from payi.types.ingest_units_params import Units
11
11
  from payi.types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
12
12
 
13
13
  from .instrument import _ChunkResult, _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
14
14
 
15
- _supported_model_prefixes = ["meta.llama3", "anthropic.", "amazon.nova-pro", "amazon.nova-lite", "amazon.nova-micro"]
16
15
 
17
16
  class BedrockInstrumentor:
18
17
  _instrumentor: _PayiInstrumentor
@@ -100,15 +99,13 @@ class InvokeResponseWrapper(ObjectProxy): # type: ignore
100
99
  def __init__(
101
100
  self,
102
101
  response: Any,
103
- instrumentor: _PayiInstrumentor,
104
- ingest: IngestUnitsParams,
102
+ request: '_BedrockInvokeProviderRequest',
105
103
  log_prompt_and_response: bool
106
104
  ) -> None:
107
105
 
108
106
  super().__init__(response) # type: ignore
109
107
  self._response = response
110
- self._instrumentor = instrumentor
111
- self._ingest = ingest
108
+ self._request = request
112
109
  self._log_prompt_and_response = log_prompt_and_response
113
110
 
114
111
  def read(self, amt: Any =None) -> Any: # type: ignore
@@ -116,51 +113,50 @@ class InvokeResponseWrapper(ObjectProxy): # type: ignore
116
113
  data: bytes = self.__wrapped__.read(amt) # type: ignore
117
114
  response = json.loads(data) # type: ignore
118
115
 
119
- resource = self._ingest["resource"]
116
+ ingest = self._request._ingest
117
+
118
+ resource = ingest["resource"]
120
119
  if not resource:
121
120
  return
122
121
 
123
122
  input: int = 0
124
123
  output: int = 0
125
- units: dict[str, Units] = self._ingest["units"]
124
+ units: dict[str, Units] = ingest["units"]
125
+
126
+ if self._request._is_anthropic:
127
+ from .AnthropicInstrumentor import anthropic_process_synchronous_response
126
128
 
127
- if resource.startswith("meta.llama3"):
129
+ anthropic_process_synchronous_response(
130
+ request=self._request,
131
+ response=response,
132
+ log_prompt_and_response=False, # will evaluate logging later
133
+ assign_id=False)
134
+
135
+ elif resource.startswith("meta.llama3"):
128
136
  input = response['prompt_token_count']
129
137
  output = response['generation_token_count']
130
- elif resource.startswith("anthropic."):
131
- usage = response['usage']
132
- input = usage['input_tokens']
133
- output = usage['output_tokens']
134
- units["text"] = Units(input=input, output=output)
138
+ units["text"] = Units(input=input, output=output)
135
139
 
136
140
  if self._log_prompt_and_response:
137
- self._ingest["provider_response_json"] = data.decode('utf-8') # type: ignore
141
+ ingest["provider_response_json"] = data.decode('utf-8') # type: ignore
138
142
 
139
- self._instrumentor._ingest_units(self._ingest)
143
+ self._request._instrumentor._ingest_units(ingest)
140
144
 
141
145
  return data # type: ignore
142
146
 
143
- def _is_supported_model(modelId: str) -> bool:
144
- return any(prefix in modelId for prefix in _supported_model_prefixes)
145
-
146
147
  def wrap_invoke(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
147
148
  @wraps(wrapped)
148
149
  def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
149
150
  modelId:str = kwargs.get("modelId", "") # type: ignore
150
151
 
151
- if _is_supported_model(modelId):
152
- instrumentor._logger.debug(f"bedrock invoke wrapper, modelId: {modelId}")
153
- return instrumentor.invoke_wrapper(
154
- _BedrockInvokeSynchronousProviderRequest(instrumentor=instrumentor),
155
- _IsStreaming.false,
156
- wrapped,
157
- None,
158
- args,
159
- kwargs,
160
- )
161
-
162
- instrumentor._logger.debug(f"bedrock invoke wrapper, unsupported modelId: {modelId}")
163
- return wrapped(*args, **kwargs)
152
+ return instrumentor.invoke_wrapper(
153
+ _BedrockInvokeProviderRequest(instrumentor=instrumentor, model_id=modelId),
154
+ _IsStreaming.false,
155
+ wrapped,
156
+ None,
157
+ args,
158
+ kwargs,
159
+ )
164
160
 
165
161
  return invoke_wrapper
166
162
 
@@ -169,18 +165,15 @@ def wrap_invoke_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
169
165
  def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
170
166
  modelId: str = kwargs.get("modelId", "") # type: ignore
171
167
 
172
- if _is_supported_model(modelId):
173
- instrumentor._logger.debug(f"bedrock invoke stream wrapper, modelId: {modelId}")
174
- return instrumentor.invoke_wrapper(
175
- _BedrockInvokeStreamingProviderRequest(instrumentor=instrumentor, model_id=modelId),
176
- _IsStreaming.true,
177
- wrapped,
178
- None,
179
- args,
180
- kwargs,
181
- )
182
- instrumentor._logger.debug(f"bedrock invoke stream wrapper, unsupported modelId: {modelId}")
183
- return wrapped(*args, **kwargs)
168
+ instrumentor._logger.debug(f"bedrock invoke stream wrapper, modelId: {modelId}")
169
+ return instrumentor.invoke_wrapper(
170
+ _BedrockInvokeProviderRequest(instrumentor=instrumentor, model_id=modelId),
171
+ _IsStreaming.true,
172
+ wrapped,
173
+ None,
174
+ args,
175
+ kwargs,
176
+ )
184
177
 
185
178
  return invoke_wrapper
186
179
 
@@ -189,18 +182,15 @@ def wrap_converse(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
189
182
  def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
190
183
  modelId:str = kwargs.get("modelId", "") # type: ignore
191
184
 
192
- if _is_supported_model(modelId):
193
- instrumentor._logger.debug(f"bedrock converse wrapper, modelId: {modelId}")
194
- return instrumentor.invoke_wrapper(
195
- _BedrockConverseSynchronousProviderRequest(instrumentor=instrumentor),
196
- _IsStreaming.false,
197
- wrapped,
198
- None,
199
- args,
200
- kwargs,
185
+ instrumentor._logger.debug(f"bedrock converse wrapper, modelId: {modelId}")
186
+ return instrumentor.invoke_wrapper(
187
+ _BedrockConverseProviderRequest(instrumentor=instrumentor),
188
+ _IsStreaming.false,
189
+ wrapped,
190
+ None,
191
+ args,
192
+ kwargs,
201
193
  )
202
- instrumentor._logger.debug(f"bedrock converse wrapper, unsupported modelId: {modelId}")
203
- return wrapped(*args, **kwargs)
204
194
 
205
195
  return invoke_wrapper
206
196
 
@@ -209,18 +199,15 @@ def wrap_converse_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
209
199
  def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
210
200
  modelId: str = kwargs.get("modelId", "") # type: ignore
211
201
 
212
- if _is_supported_model(modelId):
213
- instrumentor._logger.debug(f"bedrock converse stream wrapper, modelId: {modelId}")
214
- return instrumentor.invoke_wrapper(
215
- _BedrockConverseStreamingProviderRequest(instrumentor=instrumentor),
216
- _IsStreaming.true,
217
- wrapped,
218
- None,
219
- args,
220
- kwargs,
221
- )
222
- instrumentor._logger.debug(f"bedrock converse stream wrapper, unsupported modelId: {modelId}")
223
- return wrapped(*args, **kwargs)
202
+ instrumentor._logger.debug(f"bedrock converse stream wrapper, modelId: {modelId}")
203
+ return instrumentor.invoke_wrapper(
204
+ _BedrockConverseProviderRequest(instrumentor=instrumentor),
205
+ _IsStreaming.true,
206
+ wrapped,
207
+ None,
208
+ args,
209
+ kwargs,
210
+ )
224
211
 
225
212
  return invoke_wrapper
226
213
 
@@ -230,6 +217,7 @@ class _BedrockProviderRequest(_ProviderRequest):
230
217
  instrumentor=instrumentor,
231
218
  category=PayiCategories.aws_bedrock,
232
219
  streaming_type=_StreamingType.iterator,
220
+ is_aws_client=True,
233
221
  )
234
222
 
235
223
  @override
@@ -239,6 +227,10 @@ class _BedrockProviderRequest(_ProviderRequest):
239
227
  self._ingest["resource"] = kwargs.get("modelId", "")
240
228
  return True
241
229
 
230
+ @override
231
+ def process_initial_stream_response(self, response: Any) -> None:
232
+ self._ingest["provider_response_id"] = response.get("ResponseMetadata", {}).get("RequestId", None)
233
+
242
234
  @override
243
235
  def process_exception(self, exception: Exception, kwargs: Any, ) -> bool:
244
236
  try:
@@ -264,10 +256,27 @@ class _BedrockProviderRequest(_ProviderRequest):
264
256
  self._instrumentor._logger.debug(f"Error processing exception: {e}")
265
257
  return False
266
258
 
267
- class _BedrockInvokeStreamingProviderRequest(_BedrockProviderRequest):
259
+ class _BedrockInvokeProviderRequest(_BedrockProviderRequest):
268
260
  def __init__(self, instrumentor: _PayiInstrumentor, model_id: str):
269
261
  super().__init__(instrumentor=instrumentor)
270
- self._is_anthropic: bool = model_id.startswith("anthropic.")
262
+ self._is_anthropic: bool = 'anthropic' in model_id
263
+
264
+ @override
265
+ def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
266
+ from .AnthropicInstrumentor import anthropic_has_image_and_get_texts
267
+
268
+ super().process_request(instance, extra_headers, args, kwargs)
269
+
270
+ if self._is_anthropic:
271
+ try:
272
+ body = json.loads( kwargs.get("body", ""))
273
+ messages = body.get("messages", {})
274
+ if messages:
275
+ anthropic_has_image_and_get_texts(self, messages)
276
+ except Exception as e:
277
+ self._instrumentor._logger.debug(f"Bedrock invoke error processing request body: {e}")
278
+
279
+ return True
271
280
 
272
281
  @override
273
282
  def process_chunk(self, chunk: Any) -> _ChunkResult:
@@ -277,32 +286,9 @@ class _BedrockInvokeStreamingProviderRequest(_BedrockProviderRequest):
277
286
  return self.process_invoke_streaming_llama_chunk(chunk)
278
287
 
279
288
  def process_invoke_streaming_anthropic_chunk(self, chunk: str) -> _ChunkResult:
280
- ingest = False
281
- chunk_dict = json.loads(chunk)
282
- type = chunk_dict.get("type", "")
283
-
284
- if type == "message_start":
285
- usage = chunk_dict['message']['usage']
286
- units = self._ingest["units"]
287
-
288
- input = _PayiInstrumentor.update_for_vision(usage['input_tokens'], units, self._estimated_prompt_tokens)
289
-
290
- units["text"] = Units(input=input, output=0)
291
-
292
- text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
293
- if text_cache_write > 0:
294
- units["text_cache_write"] = Units(input=text_cache_write, output=0)
295
-
296
- text_cache_read: int = usage.get("cache_read_input_tokens", 0)
297
- if text_cache_read > 0:
298
- units["text_cache_read"] = Units(input=text_cache_read, output=0)
299
-
300
- elif type == "message_delta":
301
- usage = chunk_dict['usage']
302
- self._ingest["units"]["text"]["output"] = usage['output_tokens']
303
- ingest = True
304
-
305
- return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
289
+ from .AnthropicInstrumentor import anthropic_process_chunk
290
+
291
+ return anthropic_process_chunk(self, json.loads(chunk), assign_id=False)
306
292
 
307
293
  def process_invoke_streaming_llama_chunk(self, chunk: str) -> _ChunkResult:
308
294
  ingest = False
@@ -316,7 +302,6 @@ class _BedrockInvokeStreamingProviderRequest(_BedrockProviderRequest):
316
302
 
317
303
  return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
318
304
 
319
- class _BedrockInvokeSynchronousProviderRequest(_BedrockProviderRequest):
320
305
  @override
321
306
  def process_synchronous_response(
322
307
  self,
@@ -336,13 +321,12 @@ class _BedrockInvokeSynchronousProviderRequest(_BedrockProviderRequest):
336
321
 
337
322
  response["body"] = InvokeResponseWrapper(
338
323
  response=response["body"],
339
- instrumentor=self._instrumentor,
340
- ingest=self._ingest,
324
+ request=self,
341
325
  log_prompt_and_response=log_prompt_and_response)
342
326
 
343
327
  return response
344
328
 
345
- class _BedrockConverseSynchronousProviderRequest(_BedrockProviderRequest):
329
+ class _BedrockConverseProviderRequest(_BedrockProviderRequest):
346
330
  @override
347
331
  def process_synchronous_response(
348
332
  self,
@@ -374,7 +358,6 @@ class _BedrockConverseSynchronousProviderRequest(_BedrockProviderRequest):
374
358
 
375
359
  return None
376
360
 
377
- class _BedrockConverseStreamingProviderRequest(_BedrockProviderRequest):
378
361
  @override
379
362
  def process_chunk(self, chunk: 'dict[str, Any]') -> _ChunkResult:
380
363
  ingest = False