payi 0.1.0a42__tar.gz → 0.1.0a44__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 (169) hide show
  1. payi-0.1.0a44/.release-please-manifest.json +3 -0
  2. {payi-0.1.0a42 → payi-0.1.0a44}/CHANGELOG.md +16 -0
  3. {payi-0.1.0a42 → payi-0.1.0a44}/PKG-INFO +2 -1
  4. {payi-0.1.0a42 → payi-0.1.0a44}/pyproject.toml +2 -1
  5. {payi-0.1.0a42 → payi-0.1.0a44}/requirements-dev.lock +2 -0
  6. {payi-0.1.0a42 → payi-0.1.0a44}/requirements.lock +3 -0
  7. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_base_client.py +9 -2
  8. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_version.py +1 -1
  9. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/OpenAIInstrumentor.py +6 -0
  10. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/instrument.py +115 -39
  11. payi-0.1.0a42/.release-please-manifest.json +0 -3
  12. {payi-0.1.0a42 → payi-0.1.0a44}/.gitignore +0 -0
  13. {payi-0.1.0a42 → payi-0.1.0a44}/CONTRIBUTING.md +0 -0
  14. {payi-0.1.0a42 → payi-0.1.0a44}/LICENSE +0 -0
  15. {payi-0.1.0a42 → payi-0.1.0a44}/README.md +0 -0
  16. {payi-0.1.0a42 → payi-0.1.0a44}/SECURITY.md +0 -0
  17. {payi-0.1.0a42 → payi-0.1.0a44}/api.md +0 -0
  18. {payi-0.1.0a42 → payi-0.1.0a44}/bin/check-release-environment +0 -0
  19. {payi-0.1.0a42 → payi-0.1.0a44}/bin/publish-pypi +0 -0
  20. {payi-0.1.0a42 → payi-0.1.0a44}/examples/.keep +0 -0
  21. {payi-0.1.0a42 → payi-0.1.0a44}/mypy.ini +0 -0
  22. {payi-0.1.0a42 → payi-0.1.0a44}/noxfile.py +0 -0
  23. {payi-0.1.0a42 → payi-0.1.0a44}/release-please-config.json +0 -0
  24. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/__init__.py +0 -0
  25. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_client.py +0 -0
  26. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_compat.py +0 -0
  27. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_constants.py +0 -0
  28. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_exceptions.py +0 -0
  29. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_files.py +0 -0
  30. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_models.py +0 -0
  31. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_qs.py +0 -0
  32. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_resource.py +0 -0
  33. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_response.py +0 -0
  34. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_streaming.py +0 -0
  35. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_types.py +0 -0
  36. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/__init__.py +0 -0
  37. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_logs.py +0 -0
  38. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_proxy.py +0 -0
  39. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_reflection.py +0 -0
  40. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_streams.py +0 -0
  41. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_sync.py +0 -0
  42. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_transform.py +0 -0
  43. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_typing.py +0 -0
  44. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/_utils/_utils.py +0 -0
  45. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/.keep +0 -0
  46. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/AnthropicInstrumentor.py +0 -0
  47. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/BedrockInstrumentor.py +0 -0
  48. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/Instruments.py +0 -0
  49. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/Stopwatch.py +0 -0
  50. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/lib/helpers.py +0 -0
  51. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/py.typed +0 -0
  52. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/__init__.py +0 -0
  53. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/billing_models.py +0 -0
  54. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/categories/__init__.py +0 -0
  55. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/categories/categories.py +0 -0
  56. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/categories/resources.py +0 -0
  57. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/__init__.py +0 -0
  58. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/experiences.py +0 -0
  59. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/properties.py +0 -0
  60. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/types/__init__.py +0 -0
  61. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/types/limit_config.py +0 -0
  62. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/experiences/types/types.py +0 -0
  63. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/ingest.py +0 -0
  64. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/limits/__init__.py +0 -0
  65. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/limits/limits.py +0 -0
  66. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/limits/tags.py +0 -0
  67. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/price_modifiers.py +0 -0
  68. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/requests/__init__.py +0 -0
  69. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/requests/properties.py +0 -0
  70. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/requests/requests.py +0 -0
  71. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/resources/requests/result.py +0 -0
  72. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/__init__.py +0 -0
  73. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/billing_model.py +0 -0
  74. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/billing_model_create_params.py +0 -0
  75. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/billing_model_list_response.py +0 -0
  76. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/billing_model_update_params.py +0 -0
  77. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/bulk_ingest_response.py +0 -0
  78. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/categories/__init__.py +0 -0
  79. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/categories/resource_create_params.py +0 -0
  80. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/categories/resource_list_response.py +0 -0
  81. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_delete_resource_response.py +0 -0
  82. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_delete_response.py +0 -0
  83. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_list_resources_response.py +0 -0
  84. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_list_response.py +0 -0
  85. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_resource_response.py +0 -0
  86. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/category_response.py +0 -0
  87. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/cost_data.py +0 -0
  88. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/cost_details.py +0 -0
  89. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/default_response.py +0 -0
  90. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experience_instance_response.py +0 -0
  91. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/__init__.py +0 -0
  92. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/experience_type.py +0 -0
  93. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/properties_response.py +0 -0
  94. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/property_create_params.py +0 -0
  95. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/type_create_params.py +0 -0
  96. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/type_list_params.py +0 -0
  97. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/type_list_response.py +0 -0
  98. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/type_update_params.py +0 -0
  99. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/types/__init__.py +0 -0
  100. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
  101. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/ingest_bulk_params.py +0 -0
  102. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/ingest_event_param.py +0 -0
  103. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/ingest_response.py +0 -0
  104. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/ingest_units_params.py +0 -0
  105. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_create_params.py +0 -0
  106. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_history_response.py +0 -0
  107. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_list_params.py +0 -0
  108. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_reset_params.py +0 -0
  109. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_response.py +0 -0
  110. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limit_update_params.py +0 -0
  111. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/__init__.py +0 -0
  112. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/limit_tags.py +0 -0
  113. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_create_params.py +0 -0
  114. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_create_response.py +0 -0
  115. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_delete_response.py +0 -0
  116. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_list_response.py +0 -0
  117. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_remove_params.py +0 -0
  118. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_remove_response.py +0 -0
  119. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_update_params.py +0 -0
  120. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/limits/tag_update_response.py +0 -0
  121. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/paged_limit_list.py +0 -0
  122. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
  123. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/price_modifier.py +0 -0
  124. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/price_modifier_create_params.py +0 -0
  125. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/price_modifier_retrieve_response.py +0 -0
  126. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/price_modifier_update_params.py +0 -0
  127. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/requests/__init__.py +0 -0
  128. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/requests/property_create_params.py +0 -0
  129. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/requests/request_result.py +0 -0
  130. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/requests_data.py +0 -0
  131. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/shared/__init__.py +0 -0
  132. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/shared/evaluation_response.py +0 -0
  133. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
  134. {payi-0.1.0a42 → payi-0.1.0a44}/src/payi/types/total_cost_data.py +0 -0
  135. {payi-0.1.0a42 → payi-0.1.0a44}/tests/__init__.py +0 -0
  136. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/__init__.py +0 -0
  137. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/categories/__init__.py +0 -0
  138. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/categories/test_resources.py +0 -0
  139. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/experiences/__init__.py +0 -0
  140. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/experiences/test_properties.py +0 -0
  141. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/experiences/test_types.py +0 -0
  142. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/experiences/types/__init__.py +0 -0
  143. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
  144. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/limits/__init__.py +0 -0
  145. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/limits/test_tags.py +0 -0
  146. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/requests/__init__.py +0 -0
  147. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/requests/test_properties.py +0 -0
  148. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/requests/test_result.py +0 -0
  149. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_billing_models.py +0 -0
  150. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_categories.py +0 -0
  151. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_experiences.py +0 -0
  152. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_ingest.py +0 -0
  153. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_limits.py +0 -0
  154. {payi-0.1.0a42 → payi-0.1.0a44}/tests/api_resources/test_price_modifiers.py +0 -0
  155. {payi-0.1.0a42 → payi-0.1.0a44}/tests/conftest.py +0 -0
  156. {payi-0.1.0a42 → payi-0.1.0a44}/tests/sample_file.txt +0 -0
  157. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_client.py +0 -0
  158. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_deepcopy.py +0 -0
  159. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_extract_files.py +0 -0
  160. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_files.py +0 -0
  161. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_models.py +0 -0
  162. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_qs.py +0 -0
  163. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_required_args.py +0 -0
  164. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_response.py +0 -0
  165. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_streaming.py +0 -0
  166. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_transform.py +0 -0
  167. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_utils/test_proxy.py +0 -0
  168. {payi-0.1.0a42 → payi-0.1.0a44}/tests/test_utils/test_typing.py +0 -0
  169. {payi-0.1.0a42 → payi-0.1.0a44}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.44"
3
+ }
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.44 (2025-02-06)
4
+
5
+ Full Changelog: [v0.1.0-alpha.43...v0.1.0-alpha.44](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.43...v0.1.0-alpha.44)
6
+
7
+ ### Features
8
+
9
+ * feat(api): azure openai ([#215](https://github.com/Pay-i/pay-i-python/issues/215)) ([55781bc](https://github.com/Pay-i/pay-i-python/commit/55781bc055535677c2b694a20172abfde595c596))
10
+
11
+ ## 0.1.0-alpha.43 (2025-02-06)
12
+
13
+ Full Changelog: [v0.1.0-alpha.42...v0.1.0-alpha.43](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.42...v0.1.0-alpha.43)
14
+
15
+ ### Features
16
+
17
+ * **client:** send `X-Stainless-Read-Timeout` header ([#210](https://github.com/Pay-i/pay-i-python/issues/210)) ([fd485f6](https://github.com/Pay-i/pay-i-python/commit/fd485f692182c38d869cfadddc57d1d7c623df8e))
18
+
3
19
  ## 0.1.0-alpha.42 (2025-02-05)
4
20
 
5
21
  Full Changelog: [v0.1.0-alpha.41...v0.1.0-alpha.42](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.41...v0.1.0-alpha.42)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: payi
3
- Version: 0.1.0a42
3
+ Version: 0.1.0a44
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
@@ -25,6 +25,7 @@ Requires-Python: >=3.8
25
25
  Requires-Dist: anyio<5,>=3.5.0
26
26
  Requires-Dist: distro<2,>=1.7.0
27
27
  Requires-Dist: httpx<1,>=0.23.0
28
+ Requires-Dist: nest-asyncio>=1.6.0
28
29
  Requires-Dist: pydantic<3,>=1.9.0
29
30
  Requires-Dist: sniffio
30
31
  Requires-Dist: tiktoken>=0.8.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "payi"
3
- version = "0.1.0-alpha.42"
3
+ version = "0.1.0-alpha.44"
4
4
  description = "The official Python library for the payi API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -16,6 +16,7 @@ dependencies = [
16
16
  "sniffio",
17
17
  "wrapt>=1.17.2",
18
18
  "tiktoken>=0.8.0",
19
+ "nest-asyncio>=1.6.0",
19
20
  ]
20
21
  requires-python = ">= 3.8"
21
22
  classifiers = [
@@ -7,6 +7,7 @@
7
7
  # all-features: true
8
8
  # with-sources: false
9
9
  # generate-hashes: false
10
+ # universal: false
10
11
 
11
12
  -e file:.
12
13
  annotated-types==0.6.0
@@ -56,6 +57,7 @@ mypy==1.14.1
56
57
  mypy-extensions==1.0.0
57
58
  # via mypy
58
59
  nest-asyncio==1.6.0
60
+ # via payi
59
61
  nodeenv==1.8.0
60
62
  # via pyright
61
63
  nox==2023.4.22
@@ -7,6 +7,7 @@
7
7
  # all-features: true
8
8
  # with-sources: false
9
9
  # generate-hashes: false
10
+ # universal: false
10
11
 
11
12
  -e file:.
12
13
  annotated-types==0.6.0
@@ -34,6 +35,8 @@ idna==3.4
34
35
  # via anyio
35
36
  # via httpx
36
37
  # via requests
38
+ nest-asyncio==1.6.0
39
+ # via payi
37
40
  pydantic==2.10.3
38
41
  # via payi
39
42
  pydantic-core==2.27.1
@@ -418,10 +418,17 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
418
418
  if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
419
419
  headers[idempotency_header] = options.idempotency_key or self._idempotency_key()
420
420
 
421
- # Don't set the retry count header if it was already set or removed by the caller. We check
421
+ # Don't set these headers if they were already set or removed by the caller. We check
422
422
  # `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
423
- if "x-stainless-retry-count" not in (header.lower() for header in custom_headers):
423
+ lower_custom_headers = [header.lower() for header in custom_headers]
424
+ if "x-stainless-retry-count" not in lower_custom_headers:
424
425
  headers["x-stainless-retry-count"] = str(retries_taken)
426
+ if "x-stainless-read-timeout" not in lower_custom_headers:
427
+ timeout = self.timeout if isinstance(options.timeout, NotGiven) else options.timeout
428
+ if isinstance(timeout, Timeout):
429
+ timeout = timeout.read
430
+ if timeout is not None:
431
+ headers["x-stainless-read-timeout"] = str(timeout)
425
432
 
426
433
  return headers
427
434
 
@@ -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.42" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.44" # x-release-please-version
@@ -13,6 +13,12 @@ from .instrument import IsStreaming, PayiInstrumentor
13
13
 
14
14
 
15
15
  class OpenAiInstrumentor:
16
+ @staticmethod
17
+ def is_azure(instance: Any) -> bool:
18
+ from openai import AzureOpenAI, AsyncAzureOpenAI # type: ignore # noqa: I001
19
+
20
+ return isinstance(instance._client, (AsyncAzureOpenAI, AzureOpenAI))
21
+
16
22
  @staticmethod
17
23
  def instrument(instrumentor: PayiInstrumentor) -> None:
18
24
  try:
@@ -1,11 +1,13 @@
1
1
  import json
2
2
  import uuid
3
+ import asyncio
3
4
  import inspect
4
5
  import logging
5
6
  import traceback
6
7
  from enum import Enum
7
8
  from typing import Any, Set, Union, Callable, Optional
8
9
 
10
+ import nest_asyncio # type: ignore
9
11
  from wrapt import ObjectProxy # type: ignore
10
12
 
11
13
  from payi import Payi, AsyncPayi
@@ -28,14 +30,16 @@ class PayiInstrumentor:
28
30
 
29
31
  def __init__(
30
32
  self,
31
- payi: Union[Payi, AsyncPayi, None] = None,
33
+ payi: Optional[Payi],
34
+ apayi: Optional[AsyncPayi],
32
35
  instruments: Union[Set[Instruments], None] = None,
33
36
  log_prompt_and_response: bool = True,
34
37
  prompt_and_response_logger: Optional[
35
38
  Callable[[str, "dict[str, str]"], None]
36
39
  ] = None, # (request id, dict of data to store) -> None
37
40
  ):
38
- self._payi: Union[Payi, AsyncPayi, None] = payi
41
+ self._payi: Optional[Payi] = payi
42
+ self._apayi: Optional[AsyncPayi] = apayi
39
43
  self._context_stack: list[dict[str, Any]] = [] # Stack of context dictionaries
40
44
  self._log_prompt_and_response: bool = log_prompt_and_response
41
45
  self._prompt_and_response_logger: Optional[Callable[[str, dict[str, str]], None]] = prompt_and_response_logger
@@ -129,47 +133,82 @@ class PayiInstrumentor:
129
133
  if removeBlockedId:
130
134
  self._blocked_limits.discard(limit_id)
131
135
 
132
- async def _aingest_units(self, ingest_units: IngestUnitsParams) -> None:
136
+ async def _aingest_units(self, ingest_units: IngestUnitsParams) -> Optional[IngestResponse]:
137
+ ingest_response: Optional[IngestResponse] = None
138
+
133
139
  # return early if there are no units to ingest and on a successul ingest request
134
140
  log_data: 'dict[str,str]' = {}
135
141
  if not self._process_ingest_units(ingest_units, log_data):
136
- return
142
+ return None
137
143
 
138
144
  try:
139
- if isinstance(self._payi, AsyncPayi):
140
- ingest_response= await self._payi.ingest.units(**ingest_units)
145
+ if self._apayi:
146
+ ingest_response= await self._apayi.ingest.units(**ingest_units)
147
+ elif self._payi:
148
+ ingest_response = self._payi.ingest.units(**ingest_units)
149
+ else:
150
+ logging.error("No payi instance to ingest units")
151
+ return None
141
152
 
153
+ if ingest_response:
142
154
  self._process_ingest_units_response(ingest_response)
143
155
 
144
- if self._log_prompt_and_response and self._prompt_and_response_logger:
156
+ if ingest_response and self._log_prompt_and_response and self._prompt_and_response_logger:
145
157
  request_id = ingest_response.xproxy_result.request_id
146
158
  self._prompt_and_response_logger(request_id, log_data) # type: ignore
147
- else:
148
- logging.error("No payi instance to ingest units")
149
- return
159
+
160
+ return ingest_response
150
161
  except Exception as e:
151
162
  logging.error(f"Error Pay-i ingesting result: {e}")
152
-
153
- def _ingest_units(self, ingest_units: IngestUnitsParams) -> None:
163
+
164
+ return None
165
+
166
+ def _call_aingest_sync(self, ingest_units: IngestUnitsParams) -> Optional[IngestResponse]:
167
+ try:
168
+ loop = asyncio.get_running_loop()
169
+ except RuntimeError:
170
+ loop = None
171
+
172
+ try:
173
+ if loop and loop.is_running():
174
+ nest_asyncio.apply(loop) # type: ignore
175
+ return asyncio.run(self._aingest_units(ingest_units))
176
+ else:
177
+ # When there's no running loop, create a new one
178
+ return asyncio.run(self._aingest_units(ingest_units))
179
+ except Exception as e:
180
+ logging.error(f"Error calling aingest_units synchronously: {e}")
181
+ return None
182
+
183
+ def _ingest_units(self, ingest_units: IngestUnitsParams) -> Optional[IngestResponse]:
184
+ ingest_response: Optional[IngestResponse] = None
185
+
154
186
  # return early if there are no units to ingest and on a successul ingest request
155
187
  log_data: 'dict[str,str]' = {}
156
188
  if not self._process_ingest_units(ingest_units, log_data):
157
- return
189
+ return None
158
190
 
159
191
  try:
160
- if isinstance(self._payi, Payi):
192
+ if self._payi:
161
193
  ingest_response = self._payi.ingest.units(**ingest_units)
162
-
163
194
  self._process_ingest_units_response(ingest_response)
164
195
 
165
196
  if self._log_prompt_and_response and self._prompt_and_response_logger:
166
197
  request_id = ingest_response.xproxy_result.request_id
167
198
  self._prompt_and_response_logger(request_id, log_data) # type: ignore
199
+
200
+ return ingest_response
201
+ elif self._apayi:
202
+ # task runs async. aingest_units will invoke the callback and post process
203
+ ingest_response = self._call_aingest_sync(ingest_units)
204
+ return ingest_response
168
205
  else:
169
206
  logging.error("No payi instance to ingest units")
170
- return
207
+
171
208
  except Exception as e:
172
209
  logging.error(f"Error Pay-i ingesting result: {e}")
210
+
211
+ return None
173
212
 
174
213
  def _setup_call_func(
175
214
  self
@@ -352,13 +391,9 @@ class PayiInstrumentor:
352
391
  ) -> Any:
353
392
  context = self.get_context()
354
393
 
355
- is_bedrock:bool = category == "system.aws.bedrock"
394
+ # Bedrock client does not have an async method
356
395
 
357
- if not context:
358
- if is_bedrock:
359
- # boto3 doesn't allow extra_headers
360
- kwargs.pop("extra_headers", None)
361
-
396
+ if not context:
362
397
  # wrapped function invoked outside of decorator scope
363
398
  return await wrapped(*args, **kwargs)
364
399
 
@@ -373,12 +408,20 @@ class PayiInstrumentor:
373
408
  return await wrapped(*args, **kwargs)
374
409
 
375
410
  ingest: IngestUnitsParams = {"category": category, "units": {}} # type: ignore
376
- if is_bedrock:
377
- # boto3 doesn't allow extra_headers
378
- kwargs.pop("extra_headers", None)
379
- ingest["resource"] = kwargs.get("modelId", "")
380
- else:
381
- ingest["resource"] = kwargs.get("model", "")
411
+ ingest["resource"] = kwargs.get("model", "")
412
+
413
+ if category == "system.openai" and instance and hasattr(instance, "_client"):
414
+ from .OpenAIInstrumentor import OpenAiInstrumentor # noqa: I001
415
+
416
+ if OpenAiInstrumentor.is_azure(instance):
417
+ resource = extra_headers.pop("xProxy-RouteAs-Resource", None)
418
+ if not resource:
419
+ logging.error("Azure OpenAI route as resource not found, not ingesting")
420
+ return await wrapped(*args, **kwargs)
421
+
422
+ category = "system.azureopenai"
423
+ ingest["category"] = category
424
+ ingest["resource"] = resource
382
425
 
383
426
  current_frame = inspect.currentframe()
384
427
  # f_back excludes the current frame, strip() cleans up whitespace and newlines
@@ -421,16 +464,9 @@ class PayiInstrumentor:
421
464
  ingest=ingest,
422
465
  stopwatch=sw,
423
466
  process_chunk=process_chunk,
424
- is_bedrock=is_bedrock,
467
+ is_bedrock=False,
425
468
  )
426
469
 
427
- if is_bedrock:
428
- if "body" in response:
429
- response["body"] = stream_result
430
- else:
431
- response["stream"] = stream_result
432
- return response
433
-
434
470
  return stream_result
435
471
 
436
472
  sw.stop()
@@ -493,6 +529,18 @@ class PayiInstrumentor:
493
529
  else:
494
530
  ingest["resource"] = kwargs.get("model", "")
495
531
 
532
+ if category == "system.openai" and instance and hasattr(instance, "_client"):
533
+ from .OpenAIInstrumentor import OpenAiInstrumentor
534
+ if OpenAiInstrumentor.is_azure(instance):
535
+ resource = extra_headers.pop("xProxy-RouteAs-Resource", None)
536
+ if not resource:
537
+ logging.error("Azure OpenAI route as resource not found, not ingesting")
538
+ return wrapped(*args, **kwargs)
539
+
540
+ category = "system.azureopenai"
541
+ ingest["category"] = category
542
+ ingest["resource"] = resource
543
+
496
544
  current_frame = inspect.currentframe()
497
545
  # f_back excludes the current frame, strip() cleans up whitespace and newlines
498
546
  stack = [frame.strip() for frame in traceback.format_stack(current_frame.f_back)] # type: ignore
@@ -790,17 +838,37 @@ class ChatStreamWrapper(ObjectProxy): # type: ignore
790
838
  return json.dumps(chunk)
791
839
 
792
840
  global _instrumentor
793
- _instrumentor: PayiInstrumentor
841
+ _instrumentor: Optional[PayiInstrumentor] = None
794
842
 
795
843
  def payi_instrument(
796
- payi: Optional[Union[Payi, AsyncPayi]] = None,
844
+ payi: Optional[Union[Payi, AsyncPayi, 'list[Union[Payi, AsyncPayi]]']] = None,
797
845
  instruments: Optional[Set[Instruments]] = None,
798
846
  log_prompt_and_response: bool = True,
799
847
  prompt_and_response_logger: Optional[Callable[[str, "dict[str, str]"], None]] = None,
800
848
  ) -> None:
801
849
  global _instrumentor
850
+ if _instrumentor:
851
+ return
852
+
853
+ payi_param: Optional[Payi] = None
854
+ apayi_param: Optional[AsyncPayi] = None
855
+
856
+ if isinstance(payi, Payi):
857
+ payi_param = payi
858
+ elif isinstance(payi, AsyncPayi):
859
+ apayi_param = payi
860
+ elif isinstance(payi, list):
861
+ for p in payi:
862
+ if isinstance(p, Payi):
863
+ payi_param = p
864
+ elif isinstance(p, AsyncPayi): # type: ignore
865
+ apayi_param = p
866
+
867
+ # allow for both payi and apayi to be None for the @proxy case
868
+
802
869
  _instrumentor = PayiInstrumentor(
803
- payi=payi,
870
+ payi=payi_param,
871
+ apayi=apayi_param,
804
872
  instruments=instruments,
805
873
  log_prompt_and_response=log_prompt_and_response,
806
874
  prompt_and_response_logger=prompt_and_response_logger,
@@ -817,6 +885,8 @@ def ingest(
817
885
  import asyncio
818
886
  if asyncio.iscoroutinefunction(func):
819
887
  async def awrapper(*args: Any, **kwargs: Any) -> Any:
888
+ if not _instrumentor:
889
+ return await func(*args, **kwargs)
820
890
  # Call the instrumentor's _call_func for async functions
821
891
  return await _instrumentor._acall_func(
822
892
  func,
@@ -832,6 +902,8 @@ def ingest(
832
902
  return awrapper
833
903
  else:
834
904
  def wrapper(*args: Any, **kwargs: Any) -> Any:
905
+ if not _instrumentor:
906
+ return func(*args, **kwargs)
835
907
  return _instrumentor._call_func(
836
908
  func,
837
909
  False,
@@ -857,6 +929,8 @@ def proxy(
857
929
  import asyncio
858
930
  if asyncio.iscoroutinefunction(func):
859
931
  async def _proxy_awrapper(*args: Any, **kwargs: Any) -> Any:
932
+ if not _instrumentor:
933
+ return await func(*args, **kwargs)
860
934
  return await _instrumentor._call_func(
861
935
  func,
862
936
  True,
@@ -872,6 +946,8 @@ def proxy(
872
946
  return _proxy_awrapper
873
947
  else:
874
948
  def _proxy_wrapper(*args: Any, **kwargs: Any) -> Any:
949
+ if not _instrumentor:
950
+ return func(*args, **kwargs)
875
951
  return _instrumentor._call_func(
876
952
  func,
877
953
  True,
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.1.0-alpha.42"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes