payi 0.1.0a77__tar.gz → 0.1.0a79__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 (205) hide show
  1. payi-0.1.0a79/.release-please-manifest.json +3 -0
  2. {payi-0.1.0a77 → payi-0.1.0a79}/CHANGELOG.md +16 -0
  3. {payi-0.1.0a77 → payi-0.1.0a79}/PKG-INFO +1 -1
  4. {payi-0.1.0a77 → payi-0.1.0a79}/pyproject.toml +1 -1
  5. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_version.py +1 -1
  6. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/AnthropicInstrumentor.py +43 -9
  7. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/BedrockInstrumentor.py +6 -2
  8. payi-0.1.0a79/src/payi/lib/GoogleGenAiInstrumentor.py +375 -0
  9. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/OpenAIInstrumentor.py +6 -2
  10. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/VertexInstrumentor.py +15 -7
  11. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/instrument.py +109 -41
  12. payi-0.1.0a77/.release-please-manifest.json +0 -3
  13. {payi-0.1.0a77 → payi-0.1.0a79}/.gitignore +0 -0
  14. {payi-0.1.0a77 → payi-0.1.0a79}/CONTRIBUTING.md +0 -0
  15. {payi-0.1.0a77 → payi-0.1.0a79}/LICENSE +0 -0
  16. {payi-0.1.0a77 → payi-0.1.0a79}/README.md +0 -0
  17. {payi-0.1.0a77 → payi-0.1.0a79}/SECURITY.md +0 -0
  18. {payi-0.1.0a77 → payi-0.1.0a79}/api.md +0 -0
  19. {payi-0.1.0a77 → payi-0.1.0a79}/bin/check-release-environment +0 -0
  20. {payi-0.1.0a77 → payi-0.1.0a79}/bin/publish-pypi +0 -0
  21. {payi-0.1.0a77 → payi-0.1.0a79}/examples/.keep +0 -0
  22. {payi-0.1.0a77 → payi-0.1.0a79}/mypy.ini +0 -0
  23. {payi-0.1.0a77 → payi-0.1.0a79}/noxfile.py +0 -0
  24. {payi-0.1.0a77 → payi-0.1.0a79}/release-please-config.json +0 -0
  25. {payi-0.1.0a77 → payi-0.1.0a79}/requirements-dev.lock +0 -0
  26. {payi-0.1.0a77 → payi-0.1.0a79}/requirements.lock +0 -0
  27. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/__init__.py +0 -0
  28. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_base_client.py +0 -0
  29. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_client.py +0 -0
  30. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_compat.py +0 -0
  31. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_constants.py +0 -0
  32. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_exceptions.py +0 -0
  33. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_files.py +0 -0
  34. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_models.py +0 -0
  35. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_qs.py +0 -0
  36. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_resource.py +0 -0
  37. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_response.py +0 -0
  38. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_streaming.py +0 -0
  39. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_types.py +0 -0
  40. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/__init__.py +0 -0
  41. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_logs.py +0 -0
  42. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_proxy.py +0 -0
  43. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_reflection.py +0 -0
  44. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_resources_proxy.py +0 -0
  45. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_streams.py +0 -0
  46. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_sync.py +0 -0
  47. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_transform.py +0 -0
  48. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_typing.py +0 -0
  49. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/_utils/_utils.py +0 -0
  50. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/.keep +0 -0
  51. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/Stopwatch.py +0 -0
  52. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/lib/helpers.py +0 -0
  53. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/pagination.py +0 -0
  54. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/py.typed +0 -0
  55. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/__init__.py +0 -0
  56. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/categories/__init__.py +0 -0
  57. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/categories/categories.py +0 -0
  58. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/categories/resources.py +0 -0
  59. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/__init__.py +0 -0
  60. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/experiences.py +0 -0
  61. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/properties.py +0 -0
  62. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/types/__init__.py +0 -0
  63. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/types/limit_config.py +0 -0
  64. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/experiences/types/types.py +0 -0
  65. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/ingest.py +0 -0
  66. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/limits/__init__.py +0 -0
  67. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/limits/limits.py +0 -0
  68. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/limits/tags.py +0 -0
  69. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/requests/__init__.py +0 -0
  70. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/requests/properties.py +0 -0
  71. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/requests/requests.py +0 -0
  72. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/requests/result.py +0 -0
  73. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/__init__.py +0 -0
  74. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/definitions/__init__.py +0 -0
  75. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/definitions/definitions.py +0 -0
  76. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/definitions/kpis.py +0 -0
  77. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/definitions/limit_config.py +0 -0
  78. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/definitions/version.py +0 -0
  79. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/kpis.py +0 -0
  80. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/properties.py +0 -0
  81. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/resources/use_cases/use_cases.py +0 -0
  82. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/__init__.py +0 -0
  83. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/bulk_ingest_response.py +0 -0
  84. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/categories/__init__.py +0 -0
  85. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/categories/resource_create_params.py +0 -0
  86. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/categories/resource_list_params.py +0 -0
  87. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_delete_resource_response.py +0 -0
  88. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_delete_response.py +0 -0
  89. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_list_params.py +0 -0
  90. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_list_resources_params.py +0 -0
  91. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_resource_response.py +0 -0
  92. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/category_response.py +0 -0
  93. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/cost_data.py +0 -0
  94. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/cost_details.py +0 -0
  95. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/default_response.py +0 -0
  96. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experience_instance_response.py +0 -0
  97. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/__init__.py +0 -0
  98. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/experience_type.py +0 -0
  99. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/property_create_params.py +0 -0
  100. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/type_create_params.py +0 -0
  101. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/type_list_params.py +0 -0
  102. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/type_update_params.py +0 -0
  103. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/types/__init__.py +0 -0
  104. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
  105. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/ingest_bulk_params.py +0 -0
  106. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/ingest_event_param.py +0 -0
  107. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/ingest_response.py +0 -0
  108. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/ingest_units_params.py +0 -0
  109. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_create_params.py +0 -0
  110. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_history_response.py +0 -0
  111. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_list_params.py +0 -0
  112. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_list_response.py +0 -0
  113. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_reset_params.py +0 -0
  114. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_response.py +0 -0
  115. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limit_update_params.py +0 -0
  116. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/__init__.py +0 -0
  117. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/limit_tags.py +0 -0
  118. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_create_params.py +0 -0
  119. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_create_response.py +0 -0
  120. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_delete_response.py +0 -0
  121. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_list_response.py +0 -0
  122. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_remove_params.py +0 -0
  123. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_remove_response.py +0 -0
  124. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_update_params.py +0 -0
  125. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/limits/tag_update_response.py +0 -0
  126. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
  127. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/requests/__init__.py +0 -0
  128. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/requests/property_create_params.py +0 -0
  129. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/requests/request_result.py +0 -0
  130. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/requests_data.py +0 -0
  131. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/__init__.py +0 -0
  132. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/evaluation_response.py +0 -0
  133. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/ingest_units.py +0 -0
  134. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
  135. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/pay_i_common_models_budget_management_create_limit_base.py +0 -0
  136. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/properties_response.py +0 -0
  137. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/xproxy_error.py +0 -0
  138. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared/xproxy_result.py +0 -0
  139. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared_params/__init__.py +0 -0
  140. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared_params/ingest_units.py +0 -0
  141. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/shared_params/pay_i_common_models_budget_management_create_limit_base.py +0 -0
  142. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/total_cost_data.py +0 -0
  143. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_case_instance_response.py +0 -0
  144. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/__init__.py +0 -0
  145. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definition_create_params.py +0 -0
  146. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definition_list_params.py +0 -0
  147. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definition_update_params.py +0 -0
  148. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/__init__.py +0 -0
  149. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_create_params.py +0 -0
  150. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_create_response.py +0 -0
  151. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_delete_response.py +0 -0
  152. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_list_params.py +0 -0
  153. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_list_response.py +0 -0
  154. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_retrieve_response.py +0 -0
  155. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_update_params.py +0 -0
  156. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/kpi_update_response.py +0 -0
  157. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/definitions/limit_config_create_params.py +0 -0
  158. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/kpi_create_params.py +0 -0
  159. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/kpi_list_params.py +0 -0
  160. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/kpi_list_response.py +0 -0
  161. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/kpi_update_params.py +0 -0
  162. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/property_create_params.py +0 -0
  163. {payi-0.1.0a77 → payi-0.1.0a79}/src/payi/types/use_cases/use_case_definition.py +0 -0
  164. {payi-0.1.0a77 → payi-0.1.0a79}/tests/__init__.py +0 -0
  165. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/__init__.py +0 -0
  166. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/categories/__init__.py +0 -0
  167. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/categories/test_resources.py +0 -0
  168. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/experiences/__init__.py +0 -0
  169. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/experiences/test_properties.py +0 -0
  170. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/experiences/test_types.py +0 -0
  171. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/experiences/types/__init__.py +0 -0
  172. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
  173. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/limits/__init__.py +0 -0
  174. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/limits/test_tags.py +0 -0
  175. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/requests/__init__.py +0 -0
  176. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/requests/test_properties.py +0 -0
  177. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/requests/test_result.py +0 -0
  178. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/test_categories.py +0 -0
  179. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/test_experiences.py +0 -0
  180. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/test_ingest.py +0 -0
  181. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/test_limits.py +0 -0
  182. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/test_use_cases.py +0 -0
  183. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/__init__.py +0 -0
  184. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/definitions/__init__.py +0 -0
  185. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/definitions/test_kpis.py +0 -0
  186. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/definitions/test_limit_config.py +0 -0
  187. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/definitions/test_version.py +0 -0
  188. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/test_definitions.py +0 -0
  189. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/test_kpis.py +0 -0
  190. {payi-0.1.0a77 → payi-0.1.0a79}/tests/api_resources/use_cases/test_properties.py +0 -0
  191. {payi-0.1.0a77 → payi-0.1.0a79}/tests/conftest.py +0 -0
  192. {payi-0.1.0a77 → payi-0.1.0a79}/tests/sample_file.txt +0 -0
  193. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_client.py +0 -0
  194. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_deepcopy.py +0 -0
  195. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_extract_files.py +0 -0
  196. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_files.py +0 -0
  197. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_models.py +0 -0
  198. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_qs.py +0 -0
  199. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_required_args.py +0 -0
  200. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_response.py +0 -0
  201. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_streaming.py +0 -0
  202. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_transform.py +0 -0
  203. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_utils/test_proxy.py +0 -0
  204. {payi-0.1.0a77 → payi-0.1.0a79}/tests/test_utils/test_typing.py +0 -0
  205. {payi-0.1.0a77 → payi-0.1.0a79}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.79"
3
+ }
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.79 (2025-06-04)
4
+
5
+ Full Changelog: [v0.1.0-alpha.78...v0.1.0-alpha.79](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.78...v0.1.0-alpha.79)
6
+
7
+ ### Features
8
+
9
+ * optional response_id for vertexai, google.genai sync response ([#308](https://github.com/Pay-i/pay-i-python/issues/308)) ([a3d1207](https://github.com/Pay-i/pay-i-python/commit/a3d1207f26db9b40d849bfb8402d4e8142845c3c))
10
+
11
+ ## 0.1.0-alpha.78 (2025-06-03)
12
+
13
+ Full Changelog: [v0.1.0-alpha.77...v0.1.0-alpha.78](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.77...v0.1.0-alpha.78)
14
+
15
+ ### Features
16
+
17
+ * **api:** google genai, anthropic stream() ([#306](https://github.com/Pay-i/pay-i-python/issues/306)) ([341da40](https://github.com/Pay-i/pay-i-python/commit/341da40fb228cb83994bec12e7cda457f5452692))
18
+
3
19
  ## 0.1.0-alpha.77 (2025-06-03)
4
20
 
5
21
  Full Changelog: [v0.1.0-alpha.76...v0.1.0-alpha.77](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.76...v0.1.0-alpha.77)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: payi
3
- Version: 0.1.0a77
3
+ Version: 0.1.0a79
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "payi"
3
- version = "0.1.0-alpha.77"
3
+ version = "0.1.0-alpha.79"
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.77" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.79" # x-release-please-version
@@ -8,7 +8,7 @@ from wrapt import wrap_function_wrapper # type: ignore
8
8
  from payi.lib.helpers import PayiCategories
9
9
  from payi.types.ingest_units_params import Units
10
10
 
11
- from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
11
+ from .instrument import _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
12
12
 
13
13
 
14
14
  class AnthropicInstrumentor:
@@ -32,7 +32,7 @@ class AnthropicInstrumentor:
32
32
  wrap_function_wrapper(
33
33
  "anthropic.resources.messages",
34
34
  "Messages.stream",
35
- messages_wrapper(instrumentor),
35
+ stream_messages_wrapper(instrumentor),
36
36
  )
37
37
 
38
38
  wrap_function_wrapper(
@@ -44,7 +44,7 @@ class AnthropicInstrumentor:
44
44
  wrap_function_wrapper(
45
45
  "anthropic.resources.messages",
46
46
  "AsyncMessages.stream",
47
- amessages_wrapper(instrumentor),
47
+ astream_messages_wrapper(instrumentor),
48
48
  )
49
49
 
50
50
  except Exception as e:
@@ -61,7 +61,7 @@ def messages_wrapper(
61
61
  **kwargs: Any,
62
62
  ) -> Any:
63
63
  return instrumentor.invoke_wrapper(
64
- _AnthropicProviderRequest(instrumentor, instance),
64
+ _AnthropicProviderRequest(instrumentor=instrumentor, streaming_type=_StreamingType.iterator, instance=instance),
65
65
  _IsStreaming.kwargs,
66
66
  wrapped,
67
67
  instance,
@@ -69,6 +69,23 @@ def messages_wrapper(
69
69
  kwargs,
70
70
  )
71
71
 
72
+ @_PayiInstrumentor.payi_wrapper
73
+ def stream_messages_wrapper(
74
+ instrumentor: _PayiInstrumentor,
75
+ wrapped: Any,
76
+ instance: Any,
77
+ *args: Any,
78
+ **kwargs: Any,
79
+ ) -> Any:
80
+ return instrumentor.invoke_wrapper(
81
+ _AnthropicProviderRequest(instrumentor=instrumentor, streaming_type=_StreamingType.stream_manager, instance=instance),
82
+ _IsStreaming.true,
83
+ wrapped,
84
+ instance,
85
+ args,
86
+ kwargs,
87
+ )
88
+
72
89
  @_PayiInstrumentor.payi_awrapper
73
90
  async def amessages_wrapper(
74
91
  instrumentor: _PayiInstrumentor,
@@ -78,7 +95,7 @@ async def amessages_wrapper(
78
95
  **kwargs: Any,
79
96
  ) -> Any:
80
97
  return await instrumentor.async_invoke_wrapper(
81
- _AnthropicProviderRequest(instrumentor, instance),
98
+ _AnthropicProviderRequest(instrumentor=instrumentor, streaming_type=_StreamingType.iterator, instance=instance),
82
99
  _IsStreaming.kwargs,
83
100
  wrapped,
84
101
  instance,
@@ -86,12 +103,30 @@ async def amessages_wrapper(
86
103
  kwargs,
87
104
  )
88
105
 
106
+ @_PayiInstrumentor.payi_awrapper
107
+ async def astream_messages_wrapper(
108
+ instrumentor: _PayiInstrumentor,
109
+ wrapped: Any,
110
+ instance: Any,
111
+ *args: Any,
112
+ **kwargs: Any,
113
+ ) -> Any:
114
+ return await instrumentor.async_invoke_wrapper(
115
+ _AnthropicProviderRequest(instrumentor=instrumentor, streaming_type=_StreamingType.stream_manager, instance=instance),
116
+ _IsStreaming.true,
117
+ wrapped,
118
+ instance,
119
+ args,
120
+ kwargs,
121
+ )
122
+
89
123
  class _AnthropicProviderRequest(_ProviderRequest):
90
- def __init__(self, instrumentor: _PayiInstrumentor, instance: Any = None) -> None:
124
+ def __init__(self, instrumentor: _PayiInstrumentor, streaming_type: _StreamingType, instance: Any = None) -> None:
91
125
  self._vertex: bool = AnthropicInstrumentor.is_vertex(instance)
92
126
  super().__init__(
93
127
  instrumentor=instrumentor,
94
- category=PayiCategories.google_vertex if self._vertex else PayiCategories.anthropic
128
+ category=PayiCategories.google_vertex if self._vertex else PayiCategories.anthropic,
129
+ streaming_type=streaming_type,
95
130
  )
96
131
 
97
132
  @override
@@ -209,5 +244,4 @@ def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'li
209
244
  token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
210
245
  return has_image, token_count
211
246
 
212
- return False, 0
213
-
247
+ return False, 0
@@ -11,7 +11,7 @@ from payi.lib.helpers import PayiCategories, PayiHeaderNames, payi_aws_bedrock_u
11
11
  from payi.types.ingest_units_params import Units, IngestUnitsParams
12
12
  from payi.types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
13
13
 
14
- from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
14
+ from .instrument import _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
15
15
 
16
16
  _supported_model_prefixes = ["meta.llama3", "anthropic.", "amazon.nova-pro", "amazon.nova-lite", "amazon.nova-micro"]
17
17
 
@@ -216,7 +216,11 @@ def wrap_converse_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
216
216
 
217
217
  class _BedrockProviderRequest(_ProviderRequest):
218
218
  def __init__(self, instrumentor: _PayiInstrumentor):
219
- super().__init__(instrumentor=instrumentor, category=PayiCategories.aws_bedrock)
219
+ super().__init__(
220
+ instrumentor=instrumentor,
221
+ category=PayiCategories.aws_bedrock,
222
+ streaming_type=_StreamingType.iterator,
223
+ )
220
224
 
221
225
  @override
222
226
  def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
@@ -0,0 +1,375 @@
1
+ import json
2
+ import math
3
+ import logging
4
+ from typing import Any, List, Union, Optional, Sequence
5
+ from typing_extensions import override
6
+
7
+ from wrapt import wrap_function_wrapper # type: ignore
8
+
9
+ from payi.lib.helpers import PayiCategories
10
+ from payi.types.ingest_units_params import Units
11
+
12
+ from .instrument import _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
13
+
14
+
15
+ class GoogleGenAiInstrumentor:
16
+ @staticmethod
17
+ def instrument(instrumentor: _PayiInstrumentor) -> None:
18
+ try:
19
+ wrap_function_wrapper(
20
+ "google.genai.models",
21
+ "Models.generate_content",
22
+ generate_wrapper(instrumentor),
23
+ )
24
+
25
+ wrap_function_wrapper(
26
+ "google.genai.models",
27
+ "Models.generate_content_stream",
28
+ generate_stream_wrapper(instrumentor),
29
+ )
30
+
31
+ wrap_function_wrapper(
32
+ "google.genai.models",
33
+ "AsyncModels.generate_content",
34
+ agenerate_wrapper(instrumentor),
35
+ )
36
+
37
+ wrap_function_wrapper(
38
+ "google.genai.models",
39
+ "AsyncModels.generate_content_stream",
40
+ agenerate_stream_wrapper(instrumentor),
41
+ )
42
+
43
+ except Exception as e:
44
+ logging.debug(f"Error instrumenting vertex: {e}")
45
+ return
46
+
47
+ @_PayiInstrumentor.payi_wrapper
48
+ def generate_wrapper(
49
+ instrumentor: _PayiInstrumentor,
50
+ wrapped: Any,
51
+ instance: Any,
52
+ *args: Any,
53
+ **kwargs: Any,
54
+ ) -> Any:
55
+ return instrumentor.invoke_wrapper(
56
+ _GoogleGenAiRequest(instrumentor),
57
+ _IsStreaming.false,
58
+ wrapped,
59
+ instance,
60
+ args,
61
+ kwargs,
62
+ )
63
+
64
+ @_PayiInstrumentor.payi_wrapper
65
+ def generate_stream_wrapper(
66
+ instrumentor: _PayiInstrumentor,
67
+ wrapped: Any,
68
+ instance: Any,
69
+ *args: Any,
70
+ **kwargs: Any,
71
+ ) -> Any:
72
+ return instrumentor.invoke_wrapper(
73
+ _GoogleGenAiRequest(instrumentor),
74
+ _IsStreaming.true,
75
+ wrapped,
76
+ instance,
77
+ args,
78
+ kwargs,
79
+ )
80
+
81
+ @_PayiInstrumentor.payi_awrapper
82
+ async def agenerate_wrapper(
83
+ instrumentor: _PayiInstrumentor,
84
+ wrapped: Any,
85
+ instance: Any,
86
+ *args: Any,
87
+ **kwargs: Any,
88
+ ) -> Any:
89
+ return await instrumentor.async_invoke_wrapper(
90
+ _GoogleGenAiRequest(instrumentor),
91
+ _IsStreaming.false,
92
+ wrapped,
93
+ instance,
94
+ args,
95
+ kwargs,
96
+ )
97
+
98
+ @_PayiInstrumentor.payi_wrapper
99
+ async def agenerate_stream_wrapper(
100
+ instrumentor: _PayiInstrumentor,
101
+ wrapped: Any,
102
+ instance: Any,
103
+ *args: Any,
104
+ **kwargs: Any,
105
+ ) -> Any:
106
+ return await instrumentor.async_invoke_wrapper(
107
+ _GoogleGenAiRequest(instrumentor),
108
+ _IsStreaming.true,
109
+ wrapped,
110
+ instance,
111
+ args,
112
+ kwargs,
113
+ )
114
+
115
+ def count_chars_skip_spaces(text: str) -> int:
116
+ return sum(1 for c in text if not c.isspace())
117
+
118
+ class _GoogleGenAiRequest(_ProviderRequest):
119
+ def __init__(self, instrumentor: _PayiInstrumentor):
120
+ super().__init__(
121
+ instrumentor=instrumentor,
122
+ category=PayiCategories.google_vertex,
123
+ streaming_type=_StreamingType.generator,
124
+ )
125
+ self._prompt_character_count = 0
126
+ self._candiates_character_count = 0
127
+
128
+ @override
129
+ def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
130
+ from google.genai.types import Content, PIL_Image, Part # type: ignore # noqa: F401 I001
131
+
132
+ if not kwargs:
133
+ return True
134
+
135
+ model: str = kwargs.get("model", "")
136
+ self._ingest["resource"] = "google." + model
137
+
138
+ value: Union[ # type: ignore
139
+ Content,
140
+ str,
141
+ PIL_Image,
142
+ Part,
143
+ List[Union[str, PIL_Image, Part]],
144
+ ] = kwargs.get("contents", None) # type: ignore
145
+
146
+ items: List[Union[str, Image, Part]] = [] # type: ignore # noqa: F401 I001
147
+
148
+ if not value:
149
+ raise TypeError("value must not be empty")
150
+
151
+ if isinstance(value, Content):
152
+ items = value.parts # type: ignore
153
+ if isinstance(value, (str, PIL_Image, Part)):
154
+ items = [value] # type: ignore
155
+ if isinstance(value, list):
156
+ items = value # type: ignore
157
+
158
+ for item in items: # type: ignore
159
+ text = ""
160
+ if isinstance(item, Part):
161
+ d = item.to_json_dict() # type: ignore
162
+ if "text" in d:
163
+ text = d["text"] # type: ignore
164
+ elif isinstance(item, str):
165
+ text = item
166
+
167
+ if text != "":
168
+ self._prompt_character_count += count_chars_skip_spaces(text) # type: ignore
169
+
170
+ return True
171
+
172
+ @override
173
+ def process_request_prompt(self, prompt: 'dict[str, Any]', args: Sequence[Any], kwargs: 'dict[str, Any]') -> None:
174
+ from google.genai.types import Content, PIL_Image, Part, Tool, GenerateContentConfig, GenerateContentConfigDict, ToolConfig # type: ignore # noqa: F401 I001
175
+
176
+ key = "contents"
177
+
178
+ if not kwargs:
179
+ return
180
+
181
+ value: Union[ # type: ignore
182
+ Content,
183
+ str,
184
+ PIL_Image,
185
+ Part,
186
+ List[Union[str, PIL_Image, Part]],
187
+ ] = kwargs.get("contents", None) # type: ignore
188
+
189
+ items: List[Union[str, Image, Part]] = [] # type: ignore # noqa: F401 I001
190
+
191
+ if not value:
192
+ return
193
+
194
+ if isinstance(value, str):
195
+ prompt[key] = Content(parts=[Part.from_text(text=value)]).to_json_dict() # type: ignore
196
+ elif isinstance(value, (PIL_Image, Part)):
197
+ prompt[key] = Content(parts=[value]).to_json_dict() # type: ignore
198
+ elif isinstance(value, Content):
199
+ prompt[key] = value.to_json_dict() # type: ignore
200
+ elif isinstance(value, list):
201
+ items = value # type: ignore
202
+ parts = []
203
+
204
+ for item in items: # type: ignore
205
+ if isinstance(item, str):
206
+ parts.append(Part.from_text(text=item)) # type: ignore
207
+ elif isinstance(item, Part):
208
+ parts.append(item) # type: ignore
209
+ # elif isinstance(item, PIL_Image): TODO
210
+ # parts.append(Part.from_image(item)) # type: ignore
211
+
212
+ prompt[key] = Content(parts=parts).to_json_dict() # type: ignore
213
+
214
+ # tools: Optional[list[Tool]] = kwargs.get("tools", None) # type: ignore
215
+ # if tools:
216
+ # t: list[dict[Any, Any]] = []
217
+ # for tool in tools: # type: ignore
218
+ # if isinstance(tool, Tool):
219
+ # t.append(tool.text=()) # type: ignore
220
+ # if t:
221
+ # prompt["tools"] = t
222
+ config_kwarg = kwargs.get("config", None) # type: ignore
223
+ if config_kwarg is None:
224
+ return
225
+
226
+ config: GenerateContentConfigDict = {}
227
+ if isinstance(config_kwarg, GenerateContentConfig):
228
+ config = config_kwarg.to_json_dict() # type: ignore
229
+ else:
230
+ config = config_kwarg
231
+
232
+ tools = config.get("tools", None) # type: ignore
233
+ if isinstance(tools, list):
234
+ t: list[dict[str, object]] = []
235
+ for tool in tools: # type: ignore
236
+ if isinstance(tool, Tool):
237
+ t.append(tool.to_json_dict()) # type: ignore
238
+ if t:
239
+ prompt["tools"] = t
240
+
241
+ tool_config = config.get("tool_config", None) # type: ignore
242
+ if isinstance(tool_config, ToolConfig):
243
+ prompt["tool_config"] = tool_config.to_json_dict() # type: ignore
244
+ elif isinstance(tool_config, dict):
245
+ prompt["tool_config"] = tool_config
246
+
247
+ @override
248
+ def process_chunk(self, chunk: Any) -> bool:
249
+ response_dict: dict[str, Any] = chunk.to_json_dict()
250
+ if "provider_response_id" not in self._ingest:
251
+ id = response_dict.get("response_id", None)
252
+ if id:
253
+ self._ingest["provider_response_id"] = id
254
+
255
+ model: str = response_dict.get("model_version", "")
256
+
257
+ self._ingest["resource"] = "google." + model
258
+
259
+ for candidate in response_dict.get("candidates", []):
260
+ parts = candidate.get("content", {}).get("parts", [])
261
+ for part in parts:
262
+ self._candiates_character_count += count_chars_skip_spaces(part.get("text", ""))
263
+
264
+ usage = response_dict.get("usage_metadata", {})
265
+ if usage and "prompt_token_count" in usage and "candidates_token_count" in usage:
266
+ self._compute_usage(response_dict, streaming_candidates_characters=self._candiates_character_count)
267
+
268
+ return True
269
+
270
+ @staticmethod
271
+ def _is_character_billing_model(model: str) -> bool:
272
+ return model.startswith("gemini-1.")
273
+
274
+ @override
275
+ def process_synchronous_response(
276
+ self,
277
+ response: Any,
278
+ log_prompt_and_response: bool,
279
+ kwargs: Any) -> Any:
280
+ response_dict = response.to_json_dict()
281
+
282
+ id: Optional[str] = response_dict.get("response_id", None)
283
+ if id:
284
+ self._ingest["provider_response_id"] = id
285
+
286
+ model: Optional[str] = response_dict.get("model_version", None)
287
+ if model:
288
+ self._ingest["resource"] = "google." + model
289
+
290
+ self._compute_usage(response_dict)
291
+
292
+ if log_prompt_and_response:
293
+ self._ingest["provider_response_json"] = [json.dumps(response_dict)]
294
+
295
+ return None
296
+
297
+ def add_units(self, key: str, input: Optional[int] = None, output: Optional[int] = None) -> None:
298
+ if key not in self._ingest["units"]:
299
+ self._ingest["units"][key] = {}
300
+ if input is not None:
301
+ self._ingest["units"][key]["input"] = input
302
+ if output is not None:
303
+ self._ingest["units"][key]["output"] = output
304
+
305
+ def _compute_usage(self, response_dict: 'dict[str, Any]', streaming_candidates_characters: Optional[int] = None) -> None:
306
+ usage = response_dict.get("usage_metadata", {})
307
+ input = usage.get("prompt_token_count", 0)
308
+
309
+ prompt_tokens_details: list[dict[str, Any]] = usage.get("prompt_tokens_details")
310
+ candidates_tokens_details: list[dict[str, Any]] = usage.get("candidates_tokens_details")
311
+
312
+ model: str = response_dict.get("model_version", "")
313
+
314
+ if self._is_character_billing_model(model):
315
+ # gemini 1.0 and 1.5 units are reported in characters, per second, per image, etc...
316
+ large_context = "" if input < 128000 else "_large_context"
317
+
318
+ for details in prompt_tokens_details:
319
+ modality = details.get("modality", "")
320
+ if not modality:
321
+ continue
322
+
323
+ modality_token_count = details.get("token_count", 0)
324
+ if modality == "TEXT":
325
+ input = self._prompt_character_count
326
+ if input == 0:
327
+ # back up calc if nothing was calculated from the prompt
328
+ input = response_dict["usage_metadata"]["prompt_token_count"] * 4
329
+
330
+ output = 0
331
+ if streaming_candidates_characters is None:
332
+ for candidate in response_dict.get("candidates", []):
333
+ parts = candidate.get("content", {}).get("parts", [])
334
+ for part in parts:
335
+ output += count_chars_skip_spaces(part.get("text", ""))
336
+
337
+ if output == 0:
338
+ # back up calc if no parts
339
+ output = response_dict["usage_metadata"]["candidates_token_count"] * 4
340
+ else:
341
+ output = streaming_candidates_characters
342
+
343
+ self._ingest["units"]["text"+large_context] = Units(input=input, output=output)
344
+
345
+ elif modality == "IMAGE":
346
+ num_images = math.ceil(modality_token_count / 258)
347
+ self.add_units("vision"+large_context, input=num_images)
348
+
349
+ elif modality == "VIDEO":
350
+ video_seconds = math.ceil(modality_token_count / 285)
351
+ self.add_units("video"+large_context, input=video_seconds)
352
+
353
+ elif modality == "AUDIO":
354
+ audio_seconds = math.ceil(modality_token_count / 25)
355
+ self.add_units("audio"+large_context, input=audio_seconds)
356
+
357
+ elif model.startswith("gemini-2.0"):
358
+ for details in prompt_tokens_details:
359
+ modality = details.get("modality", "")
360
+ if not modality:
361
+ continue
362
+
363
+ modality_token_count = details.get("token_count", 0)
364
+ if modality == "IMAGE":
365
+ self.add_units("vision", input=modality_token_count)
366
+ elif modality in ("VIDEO", "AUDIO", "TEXT"):
367
+ self.add_units(modality.lower(), input=modality_token_count)
368
+ for details in candidates_tokens_details:
369
+ modality = details.get("modality", "")
370
+ if not modality:
371
+ continue
372
+
373
+ modality_token_count = details.get("token_count", 0)
374
+ if modality in ("VIDEO", "AUDIO", "TEXT", "IMAGE"):
375
+ self.add_units(modality.lower(), output=modality_token_count)
@@ -10,7 +10,7 @@ from wrapt import wrap_function_wrapper # type: ignore
10
10
  from payi.lib.helpers import PayiCategories, PayiHeaderNames
11
11
  from payi.types.ingest_units_params import Units
12
12
 
13
- from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
13
+ from .instrument import _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
14
14
 
15
15
 
16
16
  class OpenAiInstrumentor:
@@ -178,7 +178,11 @@ class _OpenAiProviderRequest(_ProviderRequest):
178
178
  responses_input_tokens_details_key: str = "input_tokens_details"
179
179
 
180
180
  def __init__(self, instrumentor: _PayiInstrumentor, input_tokens_key: str, output_tokens_key: str, input_tokens_details_key: str) -> None:
181
- super().__init__(instrumentor=instrumentor, category=PayiCategories.openai)
181
+ super().__init__(
182
+ instrumentor=instrumentor,
183
+ category=PayiCategories.openai,
184
+ streaming_type=_StreamingType.iterator,
185
+ )
182
186
  self._input_tokens_key = input_tokens_key
183
187
  self._output_tokens_key = output_tokens_key
184
188
  self._input_tokens_details_key = input_tokens_details_key
@@ -9,7 +9,7 @@ from wrapt import wrap_function_wrapper # type: ignore
9
9
  from payi.lib.helpers import PayiCategories
10
10
  from payi.types.ingest_units_params import Units
11
11
 
12
- from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
12
+ from .instrument import _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
13
13
 
14
14
 
15
15
  class VertexInstrumentor:
@@ -85,7 +85,11 @@ def count_chars_skip_spaces(text: str) -> int:
85
85
 
86
86
  class _GoogleVertexRequest(_ProviderRequest):
87
87
  def __init__(self, instrumentor: _PayiInstrumentor):
88
- super().__init__(instrumentor=instrumentor, category=PayiCategories.google_vertex)
88
+ super().__init__(
89
+ instrumentor=instrumentor,
90
+ category=PayiCategories.google_vertex,
91
+ streaming_type=_StreamingType.generator,
92
+ )
89
93
  self._prompt_character_count = 0
90
94
  self._candiates_character_count = 0
91
95
 
@@ -110,11 +114,10 @@ class _GoogleVertexRequest(_ProviderRequest):
110
114
  raise TypeError("value must not be empty")
111
115
 
112
116
  if isinstance(value, Content):
113
- return value.parts # type: ignore
117
+ items = value.parts # type: ignore
114
118
  if isinstance(value, (str, Image, Part)):
115
119
  items = [value] # type: ignore
116
-
117
- elif isinstance(value, list):
120
+ if isinstance(value, list):
118
121
  items = value # type: ignore
119
122
 
120
123
  for item in items: # type: ignore
@@ -222,8 +225,13 @@ class _GoogleVertexRequest(_ProviderRequest):
222
225
  kwargs: Any) -> Any:
223
226
  response_dict = response.to_dict()
224
227
 
225
- self._ingest["provider_response_id"] = response_dict["response_id"]
226
- self._ingest["resource"] = "google." + response_dict["model_version"]
228
+ id: Optional[str] = response_dict.get("response_id", None)
229
+ if id:
230
+ self._ingest["provider_response_id"] = id
231
+
232
+ model: Optional[str] = response_dict.get("model_version", None)
233
+ if model:
234
+ self._ingest["resource"] = "google." + model
227
235
 
228
236
  self._compute_usage(response_dict)
229
237