payi 0.1.0a38__tar.gz → 0.1.0a40__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.
- payi-0.1.0a40/.release-please-manifest.json +3 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/CHANGELOG.md +16 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/PKG-INFO +2 -1
- {payi-0.1.0a38 → payi-0.1.0a40}/api.md +1 -8
- {payi-0.1.0a38 → payi-0.1.0a40}/pyproject.toml +2 -1
- {payi-0.1.0a38 → payi-0.1.0a40}/requirements-dev.lock +12 -1
- {payi-0.1.0a38 → payi-0.1.0a40}/requirements.lock +12 -1
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_version.py +1 -1
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/AnthropicInstrumentor.py +40 -2
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/OpenAIInstrumentor.py +39 -2
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/instrument.py +21 -4
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/ingest.py +0 -83
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/__init__.py +0 -3
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_ingest.py +1 -99
- payi-0.1.0a38/.release-please-manifest.json +0 -3
- payi-0.1.0a38/src/payi/types/bulk_ingest_response.py +0 -51
- payi-0.1.0a38/src/payi/types/ingest_bulk_params.py +0 -14
- payi-0.1.0a38/src/payi/types/ingest_event_param.py +0 -60
- {payi-0.1.0a38 → payi-0.1.0a40}/.gitignore +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/LICENSE +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/README.md +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/SECURITY.md +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/bin/check-release-environment +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/bin/publish-pypi +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/examples/.keep +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/mypy.ini +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/noxfile.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/release-please-config.json +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_client.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_compat.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_constants.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_files.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_models.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_qs.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_resource.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_types.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_proxy.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_transform.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/Instruments.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/Stopwatch.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/lib/helpers.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/py.typed +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/billing_models.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/categories/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/categories/categories.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/categories/resources.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/experiences.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/properties.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/types/limit_config.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/experiences/types/types.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/limits/limits.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/limits/tags.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/price_modifiers.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/requests/properties.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/requests/requests.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/resources/requests/result.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/billing_model.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/billing_model_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/billing_model_list_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/billing_model_update_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/categories/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/categories/resource_list_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_list_resources_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_list_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/properties_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/type_list_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/types/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/ingest_units_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_history_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/paged_limit_list.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/price_modifier.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/price_modifier_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/price_modifier_retrieve_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/price_modifier_update_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/requests/request_result.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/shared/evaluation_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/requests/test_result.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_billing_models.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_limits.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/api_resources/test_price_modifiers.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/conftest.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/sample_file.txt +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_client.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_files.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_models.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_qs.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_required_args.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_response.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_streaming.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_transform.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_utils/test_proxy.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a38 → payi-0.1.0a40}/tests/utils.py +0 -0
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.40 (2025-01-31)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.39...v0.1.0-alpha.40](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.39...v0.1.0-alpha.40)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* update units calculation ([a8dda4a](https://github.com/Pay-i/pay-i-python/commit/a8dda4a72b4fa6720e7e3b621f503e435630481f))
|
|
10
|
+
|
|
11
|
+
## 0.1.0-alpha.39 (2025-01-31)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.1.0-alpha.38...v0.1.0-alpha.39](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.38...v0.1.0-alpha.39)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **api:** manual updates ([#194](https://github.com/Pay-i/pay-i-python/issues/194)) ([d31bb11](https://github.com/Pay-i/pay-i-python/commit/d31bb11b5138e4f23b5d5a7eadd09843b2c9df76))
|
|
18
|
+
|
|
3
19
|
## 0.1.0-alpha.38 (2025-01-31)
|
|
4
20
|
|
|
5
21
|
Full Changelog: [v0.1.0-alpha.37...v0.1.0-alpha.38](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.37...v0.1.0-alpha.38)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: payi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a40
|
|
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
|
|
@@ -27,6 +27,7 @@ Requires-Dist: distro<2,>=1.7.0
|
|
|
27
27
|
Requires-Dist: httpx<1,>=0.23.0
|
|
28
28
|
Requires-Dist: pydantic<3,>=1.9.0
|
|
29
29
|
Requires-Dist: sniffio
|
|
30
|
+
Requires-Dist: tiktoken>=0.8.0
|
|
30
31
|
Requires-Dist: typing-extensions<5,>=4.10
|
|
31
32
|
Requires-Dist: wrapt>=1.17.2
|
|
32
33
|
Description-Content-Type: text/markdown
|
|
@@ -58,18 +58,11 @@ Methods:
|
|
|
58
58
|
Types:
|
|
59
59
|
|
|
60
60
|
```python
|
|
61
|
-
from payi.types import
|
|
62
|
-
BulkIngestResponse,
|
|
63
|
-
IngestEvent,
|
|
64
|
-
IngestResponse,
|
|
65
|
-
IngestUnits,
|
|
66
|
-
PayICommonModelsAPIRouterHeaderInfo,
|
|
67
|
-
)
|
|
61
|
+
from payi.types import IngestResponse, IngestUnits, PayICommonModelsAPIRouterHeaderInfo
|
|
68
62
|
```
|
|
69
63
|
|
|
70
64
|
Methods:
|
|
71
65
|
|
|
72
|
-
- <code title="post /api/v1/ingest/bulk">client.ingest.<a href="./src/payi/resources/ingest.py">bulk</a>(\*\*<a href="src/payi/types/ingest_bulk_params.py">params</a>) -> <a href="./src/payi/types/bulk_ingest_response.py">BulkIngestResponse</a></code>
|
|
73
66
|
- <code title="post /api/v1/ingest">client.ingest.<a href="./src/payi/resources/ingest.py">units</a>(\*\*<a href="src/payi/types/ingest_units_params.py">params</a>) -> <a href="./src/payi/types/ingest_response.py">IngestResponse</a></code>
|
|
74
67
|
|
|
75
68
|
# Categories
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "payi"
|
|
3
|
-
version = "0.1.0-alpha.
|
|
3
|
+
version = "0.1.0-alpha.40"
|
|
4
4
|
description = "The official Python library for the payi API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -15,6 +15,7 @@ dependencies = [
|
|
|
15
15
|
"distro>=1.7.0, <2",
|
|
16
16
|
"sniffio",
|
|
17
17
|
"wrapt>=1.17.2",
|
|
18
|
+
"tiktoken>=0.8.0",
|
|
18
19
|
]
|
|
19
20
|
requires-python = ">= 3.8"
|
|
20
21
|
classifiers = [
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
# all-features: true
|
|
8
8
|
# with-sources: false
|
|
9
9
|
# generate-hashes: false
|
|
10
|
-
# universal: false
|
|
11
10
|
|
|
12
11
|
-e file:.
|
|
13
12
|
annotated-types==0.6.0
|
|
@@ -20,6 +19,9 @@ argcomplete==3.1.2
|
|
|
20
19
|
certifi==2023.7.22
|
|
21
20
|
# via httpcore
|
|
22
21
|
# via httpx
|
|
22
|
+
# via requests
|
|
23
|
+
charset-normalizer==3.4.1
|
|
24
|
+
# via requests
|
|
23
25
|
colorlog==6.7.0
|
|
24
26
|
# via nox
|
|
25
27
|
dirty-equals==0.6.0
|
|
@@ -42,6 +44,7 @@ httpx==0.28.1
|
|
|
42
44
|
idna==3.4
|
|
43
45
|
# via anyio
|
|
44
46
|
# via httpx
|
|
47
|
+
# via requests
|
|
45
48
|
importlib-metadata==7.0.0
|
|
46
49
|
iniconfig==2.0.0
|
|
47
50
|
# via pytest
|
|
@@ -77,6 +80,10 @@ python-dateutil==2.8.2
|
|
|
77
80
|
# via time-machine
|
|
78
81
|
pytz==2023.3.post1
|
|
79
82
|
# via dirty-equals
|
|
83
|
+
regex==2024.11.6
|
|
84
|
+
# via tiktoken
|
|
85
|
+
requests==2.32.3
|
|
86
|
+
# via tiktoken
|
|
80
87
|
respx==0.22.0
|
|
81
88
|
rich==13.7.1
|
|
82
89
|
ruff==0.6.9
|
|
@@ -87,6 +94,8 @@ six==1.16.0
|
|
|
87
94
|
sniffio==1.3.0
|
|
88
95
|
# via anyio
|
|
89
96
|
# via payi
|
|
97
|
+
tiktoken==0.8.0
|
|
98
|
+
# via payi
|
|
90
99
|
time-machine==2.9.0
|
|
91
100
|
tomli==2.0.2
|
|
92
101
|
# via mypy
|
|
@@ -98,6 +107,8 @@ typing-extensions==4.12.2
|
|
|
98
107
|
# via pydantic
|
|
99
108
|
# via pydantic-core
|
|
100
109
|
# via pyright
|
|
110
|
+
urllib3==2.3.0
|
|
111
|
+
# via requests
|
|
101
112
|
virtualenv==20.24.5
|
|
102
113
|
# via nox
|
|
103
114
|
wrapt==1.17.2
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
# all-features: true
|
|
8
8
|
# with-sources: false
|
|
9
9
|
# generate-hashes: false
|
|
10
|
-
# universal: false
|
|
11
10
|
|
|
12
11
|
-e file:.
|
|
13
12
|
annotated-types==0.6.0
|
|
@@ -18,6 +17,9 @@ anyio==4.4.0
|
|
|
18
17
|
certifi==2023.7.22
|
|
19
18
|
# via httpcore
|
|
20
19
|
# via httpx
|
|
20
|
+
# via requests
|
|
21
|
+
charset-normalizer==3.4.1
|
|
22
|
+
# via requests
|
|
21
23
|
distro==1.8.0
|
|
22
24
|
# via payi
|
|
23
25
|
exceptiongroup==1.2.2
|
|
@@ -31,17 +33,26 @@ httpx==0.28.1
|
|
|
31
33
|
idna==3.4
|
|
32
34
|
# via anyio
|
|
33
35
|
# via httpx
|
|
36
|
+
# via requests
|
|
34
37
|
pydantic==2.10.3
|
|
35
38
|
# via payi
|
|
36
39
|
pydantic-core==2.27.1
|
|
37
40
|
# via pydantic
|
|
41
|
+
regex==2024.11.6
|
|
42
|
+
# via tiktoken
|
|
43
|
+
requests==2.32.3
|
|
44
|
+
# via tiktoken
|
|
38
45
|
sniffio==1.3.0
|
|
39
46
|
# via anyio
|
|
40
47
|
# via payi
|
|
48
|
+
tiktoken==0.8.0
|
|
49
|
+
# via payi
|
|
41
50
|
typing-extensions==4.12.2
|
|
42
51
|
# via anyio
|
|
43
52
|
# via payi
|
|
44
53
|
# via pydantic
|
|
45
54
|
# via pydantic-core
|
|
55
|
+
urllib3==2.3.0
|
|
56
|
+
# via requests
|
|
46
57
|
wrapt==1.17.2
|
|
47
58
|
# via payi
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any, Union
|
|
3
3
|
|
|
4
|
+
import tiktoken
|
|
4
5
|
from wrapt import wrap_function_wrapper # type: ignore
|
|
5
6
|
|
|
6
7
|
from payi.types import IngestUnitsParams
|
|
@@ -49,6 +50,7 @@ def chat_wrapper(
|
|
|
49
50
|
return instrumentor.chat_wrapper(
|
|
50
51
|
"system.anthropic",
|
|
51
52
|
process_chunk,
|
|
53
|
+
process_request,
|
|
52
54
|
process_synchronous_response,
|
|
53
55
|
wrapped,
|
|
54
56
|
instance,
|
|
@@ -62,7 +64,9 @@ def process_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
|
62
64
|
usage = chunk.message.usage
|
|
63
65
|
units = ingest["units"]
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
input = PayiInstrumentor.update_for_vision(usage.input_tokens, units)
|
|
68
|
+
|
|
69
|
+
units["text"] = Units(input=input, output=0)
|
|
66
70
|
|
|
67
71
|
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
68
72
|
text_cache_write = usage.cache_creation_input_tokens
|
|
@@ -91,7 +95,41 @@ def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_p
|
|
|
91
95
|
text_cache_read = usage.cache_read_input_tokens
|
|
92
96
|
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
93
97
|
|
|
98
|
+
input = PayiInstrumentor.update_for_vision(input, units)
|
|
99
|
+
|
|
94
100
|
units["text"] = Units(input=input, output=ouptut)
|
|
95
101
|
|
|
96
102
|
if log_prompt_and_response:
|
|
97
103
|
ingest["provider_response_json"] = response.to_json()
|
|
104
|
+
|
|
105
|
+
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
106
|
+
if isinstance(content, str):
|
|
107
|
+
return False, 0
|
|
108
|
+
elif isinstance(content, list): # type: ignore
|
|
109
|
+
has_image = any(item.get("type") == "image" for item in content)
|
|
110
|
+
if has_image is False:
|
|
111
|
+
return has_image, 0
|
|
112
|
+
|
|
113
|
+
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
|
|
114
|
+
return has_image, token_count
|
|
115
|
+
|
|
116
|
+
def process_request(ingest: IngestUnitsParams, kwargs: Any) -> None:
|
|
117
|
+
messages = kwargs.get("messages")
|
|
118
|
+
if not messages or len(messages) == 0:
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
estimated_token_count = 0
|
|
122
|
+
has_image = False
|
|
123
|
+
|
|
124
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
|
125
|
+
|
|
126
|
+
for message in messages:
|
|
127
|
+
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
128
|
+
if msg_has_image:
|
|
129
|
+
has_image = True
|
|
130
|
+
estimated_token_count += msg_prompt_tokens
|
|
131
|
+
|
|
132
|
+
if not has_image or estimated_token_count == 0:
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
ingest["units"][PayiInstrumentor.estimated_prompt_tokens] = Units(input=estimated_token_count, output=0)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any, Union
|
|
4
4
|
from importlib.metadata import version
|
|
5
5
|
|
|
6
|
+
import tiktoken
|
|
6
7
|
from wrapt import wrap_function_wrapper # type: ignore
|
|
7
8
|
|
|
8
9
|
from payi.types import IngestUnitsParams
|
|
@@ -38,6 +39,7 @@ def chat_wrapper(
|
|
|
38
39
|
return instrumentor.chat_wrapper(
|
|
39
40
|
"system.openai",
|
|
40
41
|
process_chat_chunk,
|
|
42
|
+
process_request,
|
|
41
43
|
process_chat_synchronous_response,
|
|
42
44
|
wrapped,
|
|
43
45
|
instance,
|
|
@@ -84,6 +86,41 @@ def add_usage_units(usage: "dict[str, Any]", units: "dict[str, Units]") -> None:
|
|
|
84
86
|
if input_cache != 0:
|
|
85
87
|
units["text_cache_read"] = Units(input=input_cache, output=0)
|
|
86
88
|
|
|
87
|
-
input
|
|
89
|
+
input = PayiInstrumentor.update_for_vision(input - input_cache, units)
|
|
88
90
|
|
|
89
91
|
units["text"] = Units(input=input, output=output)
|
|
92
|
+
|
|
93
|
+
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
94
|
+
if isinstance(content, str):
|
|
95
|
+
return False, 0
|
|
96
|
+
elif isinstance(content, list): # type: ignore
|
|
97
|
+
has_image = any(item.get("type") == "image_url" for item in content)
|
|
98
|
+
if has_image is False:
|
|
99
|
+
return has_image, 0
|
|
100
|
+
|
|
101
|
+
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
|
|
102
|
+
return has_image, token_count
|
|
103
|
+
|
|
104
|
+
def process_request(ingest: IngestUnitsParams, kwargs: Any) -> None:
|
|
105
|
+
messages = kwargs.get("messages")
|
|
106
|
+
if not messages or len(messages) == 0:
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
estimated_token_count = 0
|
|
110
|
+
has_image = False
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
enc = tiktoken.encoding_for_model(kwargs.get("model"))
|
|
114
|
+
except KeyError:
|
|
115
|
+
enc = tiktoken.get_encoding("o200k_base")
|
|
116
|
+
|
|
117
|
+
for message in messages:
|
|
118
|
+
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
119
|
+
if msg_has_image:
|
|
120
|
+
has_image = True
|
|
121
|
+
estimated_token_count += msg_prompt_tokens
|
|
122
|
+
|
|
123
|
+
if not has_image or estimated_token_count == 0:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
ingest["units"][PayiInstrumentor.estimated_prompt_tokens] = Units(input=estimated_token_count, output=0)
|
|
@@ -10,12 +10,15 @@ from wrapt import ObjectProxy # type: ignore
|
|
|
10
10
|
|
|
11
11
|
from payi import Payi, AsyncPayi
|
|
12
12
|
from payi.types import IngestUnitsParams
|
|
13
|
+
from payi.types.ingest_units_params import Units
|
|
13
14
|
|
|
14
15
|
from .Stopwatch import Stopwatch
|
|
15
16
|
from .Instruments import Instruments
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class PayiInstrumentor:
|
|
20
|
+
estimated_prompt_tokens: str = "estimated_prompt_tokens"
|
|
21
|
+
|
|
19
22
|
def __init__(
|
|
20
23
|
self,
|
|
21
24
|
payi: Union[Payi, AsyncPayi, None] = None,
|
|
@@ -204,11 +207,12 @@ class PayiInstrumentor:
|
|
|
204
207
|
self,
|
|
205
208
|
category: str,
|
|
206
209
|
process_chunk: Callable[[Any, IngestUnitsParams], None],
|
|
210
|
+
process_request: Optional[Callable[[IngestUnitsParams, Any], None]],
|
|
207
211
|
process_synchronous_response: Optional[Callable[[Any, IngestUnitsParams, bool], None]],
|
|
208
212
|
wrapped: Any,
|
|
209
213
|
instance: Any,
|
|
210
214
|
args: Any,
|
|
211
|
-
kwargs: Any,
|
|
215
|
+
kwargs: 'dict[str, Any]',
|
|
212
216
|
) -> Any:
|
|
213
217
|
context = self.get_context()
|
|
214
218
|
|
|
@@ -226,7 +230,7 @@ class PayiInstrumentor:
|
|
|
226
230
|
|
|
227
231
|
return wrapped(*args, **kwargs)
|
|
228
232
|
|
|
229
|
-
ingest: IngestUnitsParams = {"category": category, "resource": kwargs.get("model"), "units": {}}
|
|
233
|
+
ingest: IngestUnitsParams = {"category": category, "resource": kwargs.get("model"), "units": {}} # type: ignore
|
|
230
234
|
|
|
231
235
|
# blocked_limit = next((limit for limit in (context.get('limit_ids') or []) if limit in self._blocked_limits), None)
|
|
232
236
|
# if blocked_limit:
|
|
@@ -235,8 +239,10 @@ class PayiInstrumentor:
|
|
|
235
239
|
# f_back excludes the current frame, strip() cleans up whitespace and newlines
|
|
236
240
|
stack = [frame.strip() for frame in traceback.format_stack(current_frame.f_back)] # type: ignore
|
|
237
241
|
|
|
238
|
-
|
|
239
|
-
|
|
242
|
+
ingest['properties'] = { 'system.stack_trace': json.dumps(stack) }
|
|
243
|
+
|
|
244
|
+
if process_request:
|
|
245
|
+
process_request(ingest, kwargs)
|
|
240
246
|
|
|
241
247
|
sw = Stopwatch()
|
|
242
248
|
stream = kwargs.get("stream", False)
|
|
@@ -354,6 +360,17 @@ class PayiInstrumentor:
|
|
|
354
360
|
if experience_id is not None:
|
|
355
361
|
extra_headers["xProxy-Experience-ID"] = experience_id
|
|
356
362
|
|
|
363
|
+
@staticmethod
|
|
364
|
+
def update_for_vision(input: int, units: 'dict[str, Units]') -> int:
|
|
365
|
+
if PayiInstrumentor.estimated_prompt_tokens in units:
|
|
366
|
+
prompt_token_estimate: int = units.pop(PayiInstrumentor.estimated_prompt_tokens)["input"] # type: ignore
|
|
367
|
+
vision = input - prompt_token_estimate
|
|
368
|
+
if (vision > 0):
|
|
369
|
+
units["vision"] = Units(input=vision, output=0)
|
|
370
|
+
input = prompt_token_estimate
|
|
371
|
+
|
|
372
|
+
return input
|
|
373
|
+
|
|
357
374
|
@staticmethod
|
|
358
375
|
def payi_wrapper(func: Any) -> Any:
|
|
359
376
|
def _payi_wrapper(o: Any) -> Any:
|
|
@@ -24,8 +24,6 @@ from .._response import (
|
|
|
24
24
|
)
|
|
25
25
|
from .._base_client import make_request_options
|
|
26
26
|
from ..types.ingest_response import IngestResponse
|
|
27
|
-
from ..types.ingest_event_param import IngestEventParam
|
|
28
|
-
from ..types.bulk_ingest_response import BulkIngestResponse
|
|
29
27
|
from ..types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
|
|
30
28
|
|
|
31
29
|
__all__ = ["IngestResource", "AsyncIngestResource"]
|
|
@@ -51,41 +49,6 @@ class IngestResource(SyncAPIResource):
|
|
|
51
49
|
"""
|
|
52
50
|
return IngestResourceWithStreamingResponse(self)
|
|
53
51
|
|
|
54
|
-
def bulk(
|
|
55
|
-
self,
|
|
56
|
-
*,
|
|
57
|
-
events: Iterable[IngestEventParam],
|
|
58
|
-
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
59
|
-
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
60
|
-
extra_headers: Headers | None = None,
|
|
61
|
-
extra_query: Query | None = None,
|
|
62
|
-
extra_body: Body | None = None,
|
|
63
|
-
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
64
|
-
) -> BulkIngestResponse:
|
|
65
|
-
"""
|
|
66
|
-
Bulk Ingest
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
|
|
70
|
-
items (Iterable[IngestUnitsParams]): The items to ingest
|
|
71
|
-
|
|
72
|
-
extra_headers: Send extra headers
|
|
73
|
-
|
|
74
|
-
extra_query: Add additional query parameters to the request
|
|
75
|
-
|
|
76
|
-
extra_body: Add additional JSON properties to the request
|
|
77
|
-
|
|
78
|
-
timeout: Override the client-level default timeout for this request, in seconds
|
|
79
|
-
"""
|
|
80
|
-
return self._post(
|
|
81
|
-
"/api/v1/ingest/bulk",
|
|
82
|
-
body=maybe_transform(events, Iterable[IngestEventParam]),
|
|
83
|
-
options=make_request_options(
|
|
84
|
-
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
85
|
-
),
|
|
86
|
-
cast_to=BulkIngestResponse,
|
|
87
|
-
)
|
|
88
|
-
|
|
89
52
|
def units(
|
|
90
53
|
self,
|
|
91
54
|
*,
|
|
@@ -237,40 +200,6 @@ class AsyncIngestResource(AsyncAPIResource):
|
|
|
237
200
|
"""
|
|
238
201
|
return AsyncIngestResourceWithStreamingResponse(self)
|
|
239
202
|
|
|
240
|
-
async def bulk(
|
|
241
|
-
self,
|
|
242
|
-
*,
|
|
243
|
-
events: Iterable[IngestEventParam],
|
|
244
|
-
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
245
|
-
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
246
|
-
extra_headers: Headers | None = None,
|
|
247
|
-
extra_query: Query | None = None,
|
|
248
|
-
extra_body: Body | None = None,
|
|
249
|
-
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
250
|
-
) -> BulkIngestResponse:
|
|
251
|
-
"""
|
|
252
|
-
Bulk Ingest
|
|
253
|
-
|
|
254
|
-
Args:
|
|
255
|
-
items (Iterable[IngestUnitsParams]): The items to ingest
|
|
256
|
-
|
|
257
|
-
extra_headers: Send extra headers
|
|
258
|
-
|
|
259
|
-
extra_query: Add additional query parameters to the request
|
|
260
|
-
|
|
261
|
-
extra_body: Add additional JSON properties to the request
|
|
262
|
-
|
|
263
|
-
timeout: Override the client-level default timeout for this request, in seconds
|
|
264
|
-
"""
|
|
265
|
-
return await self._post(
|
|
266
|
-
"/api/v1/ingest/bulk",
|
|
267
|
-
body=await async_maybe_transform(events, Iterable[IngestEventParam]),
|
|
268
|
-
options=make_request_options(
|
|
269
|
-
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
270
|
-
),
|
|
271
|
-
cast_to=BulkIngestResponse,
|
|
272
|
-
)
|
|
273
|
-
|
|
274
203
|
async def units(
|
|
275
204
|
self,
|
|
276
205
|
*,
|
|
@@ -405,9 +334,6 @@ class IngestResourceWithRawResponse:
|
|
|
405
334
|
def __init__(self, ingest: IngestResource) -> None:
|
|
406
335
|
self._ingest = ingest
|
|
407
336
|
|
|
408
|
-
self.bulk = to_raw_response_wrapper(
|
|
409
|
-
ingest.bulk,
|
|
410
|
-
)
|
|
411
337
|
self.units = to_raw_response_wrapper(
|
|
412
338
|
ingest.units,
|
|
413
339
|
)
|
|
@@ -417,9 +343,6 @@ class AsyncIngestResourceWithRawResponse:
|
|
|
417
343
|
def __init__(self, ingest: AsyncIngestResource) -> None:
|
|
418
344
|
self._ingest = ingest
|
|
419
345
|
|
|
420
|
-
self.bulk = async_to_raw_response_wrapper(
|
|
421
|
-
ingest.bulk,
|
|
422
|
-
)
|
|
423
346
|
self.units = async_to_raw_response_wrapper(
|
|
424
347
|
ingest.units,
|
|
425
348
|
)
|
|
@@ -429,9 +352,6 @@ class IngestResourceWithStreamingResponse:
|
|
|
429
352
|
def __init__(self, ingest: IngestResource) -> None:
|
|
430
353
|
self._ingest = ingest
|
|
431
354
|
|
|
432
|
-
self.bulk = to_streamed_response_wrapper(
|
|
433
|
-
ingest.bulk,
|
|
434
|
-
)
|
|
435
355
|
self.units = to_streamed_response_wrapper(
|
|
436
356
|
ingest.units,
|
|
437
357
|
)
|
|
@@ -441,9 +361,6 @@ class AsyncIngestResourceWithStreamingResponse:
|
|
|
441
361
|
def __init__(self, ingest: AsyncIngestResource) -> None:
|
|
442
362
|
self._ingest = ingest
|
|
443
363
|
|
|
444
|
-
self.bulk = async_to_streamed_response_wrapper(
|
|
445
|
-
ingest.bulk,
|
|
446
|
-
)
|
|
447
364
|
self.units = async_to_streamed_response_wrapper(
|
|
448
365
|
ingest.units,
|
|
449
366
|
)
|
|
@@ -15,13 +15,10 @@ from .default_response import DefaultResponse as DefaultResponse
|
|
|
15
15
|
from .paged_limit_list import PagedLimitList as PagedLimitList
|
|
16
16
|
from .category_response import CategoryResponse as CategoryResponse
|
|
17
17
|
from .limit_list_params import LimitListParams as LimitListParams
|
|
18
|
-
from .ingest_bulk_params import IngestBulkParams as IngestBulkParams
|
|
19
|
-
from .ingest_event_param import IngestEventParam as IngestEventParam
|
|
20
18
|
from .limit_reset_params import LimitResetParams as LimitResetParams
|
|
21
19
|
from .ingest_units_params import IngestUnitsParams as IngestUnitsParams
|
|
22
20
|
from .limit_create_params import LimitCreateParams as LimitCreateParams
|
|
23
21
|
from .limit_update_params import LimitUpdateParams as LimitUpdateParams
|
|
24
|
-
from .bulk_ingest_response import BulkIngestResponse as BulkIngestResponse
|
|
25
22
|
from .category_list_response import CategoryListResponse as CategoryListResponse
|
|
26
23
|
from .limit_history_response import LimitHistoryResponse as LimitHistoryResponse
|
|
27
24
|
from .category_delete_response import CategoryDeleteResponse as CategoryDeleteResponse
|
|
@@ -8,7 +8,7 @@ from typing import Any, cast
|
|
|
8
8
|
import pytest
|
|
9
9
|
|
|
10
10
|
from payi import Payi, AsyncPayi
|
|
11
|
-
from payi.types import IngestResponse
|
|
11
|
+
from payi.types import IngestResponse
|
|
12
12
|
from payi._utils import parse_datetime
|
|
13
13
|
from tests.utils import assert_matches_type
|
|
14
14
|
|
|
@@ -18,55 +18,6 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
|
|
|
18
18
|
class TestIngest:
|
|
19
19
|
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
|
|
20
20
|
|
|
21
|
-
@parametrize
|
|
22
|
-
def test_method_bulk(self, client: Payi) -> None:
|
|
23
|
-
ingest = client.ingest.bulk(
|
|
24
|
-
events=[
|
|
25
|
-
{
|
|
26
|
-
"category": "x",
|
|
27
|
-
"resource": "x",
|
|
28
|
-
"units": {"foo": {}},
|
|
29
|
-
}
|
|
30
|
-
],
|
|
31
|
-
)
|
|
32
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
33
|
-
|
|
34
|
-
@parametrize
|
|
35
|
-
def test_raw_response_bulk(self, client: Payi) -> None:
|
|
36
|
-
response = client.ingest.with_raw_response.bulk(
|
|
37
|
-
events=[
|
|
38
|
-
{
|
|
39
|
-
"category": "x",
|
|
40
|
-
"resource": "x",
|
|
41
|
-
"units": {"foo": {}},
|
|
42
|
-
}
|
|
43
|
-
],
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
assert response.is_closed is True
|
|
47
|
-
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
|
|
48
|
-
ingest = response.parse()
|
|
49
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
50
|
-
|
|
51
|
-
@parametrize
|
|
52
|
-
def test_streaming_response_bulk(self, client: Payi) -> None:
|
|
53
|
-
with client.ingest.with_streaming_response.bulk(
|
|
54
|
-
events=[
|
|
55
|
-
{
|
|
56
|
-
"category": "x",
|
|
57
|
-
"resource": "x",
|
|
58
|
-
"units": {"foo": {}},
|
|
59
|
-
}
|
|
60
|
-
],
|
|
61
|
-
) as response:
|
|
62
|
-
assert not response.is_closed
|
|
63
|
-
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
|
|
64
|
-
|
|
65
|
-
ingest = response.parse()
|
|
66
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
67
|
-
|
|
68
|
-
assert cast(Any, response.is_closed) is True
|
|
69
|
-
|
|
70
21
|
@parametrize
|
|
71
22
|
def test_method_units(self, client: Payi) -> None:
|
|
72
23
|
ingest = client.ingest.units(
|
|
@@ -148,55 +99,6 @@ class TestIngest:
|
|
|
148
99
|
class TestAsyncIngest:
|
|
149
100
|
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
|
|
150
101
|
|
|
151
|
-
@parametrize
|
|
152
|
-
async def test_method_bulk(self, async_client: AsyncPayi) -> None:
|
|
153
|
-
ingest = await async_client.ingest.bulk(
|
|
154
|
-
events=[
|
|
155
|
-
{
|
|
156
|
-
"category": "x",
|
|
157
|
-
"resource": "x",
|
|
158
|
-
"units": {"foo": {}},
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
)
|
|
162
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
163
|
-
|
|
164
|
-
@parametrize
|
|
165
|
-
async def test_raw_response_bulk(self, async_client: AsyncPayi) -> None:
|
|
166
|
-
response = await async_client.ingest.with_raw_response.bulk(
|
|
167
|
-
events=[
|
|
168
|
-
{
|
|
169
|
-
"category": "x",
|
|
170
|
-
"resource": "x",
|
|
171
|
-
"units": {"foo": {}},
|
|
172
|
-
}
|
|
173
|
-
],
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
assert response.is_closed is True
|
|
177
|
-
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
|
|
178
|
-
ingest = await response.parse()
|
|
179
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
180
|
-
|
|
181
|
-
@parametrize
|
|
182
|
-
async def test_streaming_response_bulk(self, async_client: AsyncPayi) -> None:
|
|
183
|
-
async with async_client.ingest.with_streaming_response.bulk(
|
|
184
|
-
events=[
|
|
185
|
-
{
|
|
186
|
-
"category": "x",
|
|
187
|
-
"resource": "x",
|
|
188
|
-
"units": {"foo": {}},
|
|
189
|
-
}
|
|
190
|
-
],
|
|
191
|
-
) as response:
|
|
192
|
-
assert not response.is_closed
|
|
193
|
-
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
|
|
194
|
-
|
|
195
|
-
ingest = await response.parse()
|
|
196
|
-
assert_matches_type(BulkIngestResponse, ingest, path=["response"])
|
|
197
|
-
|
|
198
|
-
assert cast(Any, response.is_closed) is True
|
|
199
|
-
|
|
200
102
|
@parametrize
|
|
201
103
|
async def test_method_units(self, async_client: AsyncPayi) -> None:
|
|
202
104
|
ingest = await async_client.ingest.units(
|