payi 0.1.0a35__tar.gz → 0.1.0a37__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.0a37/.release-please-manifest.json +3 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/CHANGELOG.md +30 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/PKG-INFO +9 -8
- {payi-0.1.0a35 → payi-0.1.0a37}/README.md +7 -7
- {payi-0.1.0a35 → payi-0.1.0a37}/api.md +7 -1
- {payi-0.1.0a35 → payi-0.1.0a37}/mypy.ini +1 -1
- {payi-0.1.0a35 → payi-0.1.0a37}/pyproject.toml +4 -1
- {payi-0.1.0a35 → payi-0.1.0a37}/requirements-dev.lock +5 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/requirements.lock +3 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_models.py +4 -4
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_response.py +9 -3
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_version.py +1 -1
- payi-0.1.0a37/src/payi/lib/AnthropicInstrumentor.py +97 -0
- payi-0.1.0a37/src/payi/lib/Instruments.py +7 -0
- payi-0.1.0a37/src/payi/lib/OpenAIInstrumentor.py +89 -0
- payi-0.1.0a37/src/payi/lib/Stopwatch.py +27 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/lib/helpers.py +12 -10
- payi-0.1.0a37/src/payi/lib/instrument.py +522 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/billing_models.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/categories/categories.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/categories/resources.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/experiences/experiences.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/experiences/properties.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/experiences/types.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/ingest.py +36 -37
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/limits/limits.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/limits/tags.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/price_modifiers.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/requests/properties.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/requests/requests.py +2 -2
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/__init__.py +3 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/ingest_bulk_params.py +1 -1
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/ingest_event_param.py +4 -15
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/ingest_units_params.py +5 -15
- payi-0.1.0a37/src/payi/types/pay_i_common_models_api_router_header_info_param.py +14 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/shared/evaluation_response.py +0 -1
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_client.py +28 -17
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_models.py +10 -0
- payi-0.1.0a35/.release-please-manifest.json +0 -3
- {payi-0.1.0a35 → payi-0.1.0a37}/.gitignore +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/LICENSE +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/SECURITY.md +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/bin/check-release-environment +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/bin/publish-pypi +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/examples/.keep +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/noxfile.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/release-please-config.json +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_client.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_compat.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_constants.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_files.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_qs.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_resource.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_types.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_proxy.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_transform.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/py.typed +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/categories/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/billing_model.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/billing_model_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/billing_model_list_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/billing_model_update_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/bulk_ingest_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/categories/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/categories/resource_list_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_list_resources_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_list_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/properties_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/type_list_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_history_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/paged_limit_list.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/price_modifier.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/price_modifier_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/price_modifier_retrieve_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/price_modifier_update_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_billing_models.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_ingest.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_limits.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/api_resources/test_price_modifiers.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/conftest.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/sample_file.txt +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_files.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_qs.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_required_args.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_response.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_streaming.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_transform.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_utils/test_proxy.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a35 → payi-0.1.0a37}/tests/utils.py +0 -0
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.37 (2025-01-30)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.36...v0.1.0-alpha.37](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.36...v0.1.0-alpha.37)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **api:** manual updates ([#187](https://github.com/Pay-i/pay-i-python/issues/187)) ([028e7c8](https://github.com/Pay-i/pay-i-python/commit/028e7c86f30727a2883d9823cdedb450f8397d1c))
|
|
10
|
+
|
|
11
|
+
## 0.1.0-alpha.36 (2025-01-28)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.1.0-alpha.35...v0.1.0-alpha.36](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.35...v0.1.0-alpha.36)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **tests:** make test_get_platform less flaky ([#181](https://github.com/Pay-i/pay-i-python/issues/181)) ([86d5b4a](https://github.com/Pay-i/pay-i-python/commit/86d5b4aa623c276776f0bdba5fa936d5408c6ab3))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Chores
|
|
21
|
+
|
|
22
|
+
* **internal:** avoid pytest-asyncio deprecation warning ([#182](https://github.com/Pay-i/pay-i-python/issues/182)) ([38bb22c](https://github.com/Pay-i/pay-i-python/commit/38bb22ca2fa0f6dd88942b4744f9b0ffee030d5c))
|
|
23
|
+
* **internal:** codegen related update ([#178](https://github.com/Pay-i/pay-i-python/issues/178)) ([315a2c5](https://github.com/Pay-i/pay-i-python/commit/315a2c576e14d51239590f3bfc53872a288559c7))
|
|
24
|
+
* **internal:** codegen related update ([#183](https://github.com/Pay-i/pay-i-python/issues/183)) ([00fdbe7](https://github.com/Pay-i/pay-i-python/commit/00fdbe791e16fa12e73e1203dd0ab02270127e27))
|
|
25
|
+
* **internal:** codegen related update ([#184](https://github.com/Pay-i/pay-i-python/issues/184)) ([bf04c0e](https://github.com/Pay-i/pay-i-python/commit/bf04c0e4707fc2218da6fa6e676fd6c2e85bff07))
|
|
26
|
+
* **internal:** codegen related update ([#185](https://github.com/Pay-i/pay-i-python/issues/185)) ([e0d7ab1](https://github.com/Pay-i/pay-i-python/commit/e0d7ab154ce6d0a60095d8740b9ba5949a37aa00))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
* **raw responses:** fix duplicate `the` ([#180](https://github.com/Pay-i/pay-i-python/issues/180)) ([ef72f36](https://github.com/Pay-i/pay-i-python/commit/ef72f367b02d8a71b6ef108a8e3544be77d5bd60))
|
|
32
|
+
|
|
3
33
|
## 0.1.0-alpha.35 (2025-01-12)
|
|
4
34
|
|
|
5
35
|
Full Changelog: [v0.1.0-alpha.34...v0.1.0-alpha.35](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.34...v0.1.0-alpha.35)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: payi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a37
|
|
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
|
|
@@ -28,6 +28,7 @@ Requires-Dist: httpx<1,>=0.23.0
|
|
|
28
28
|
Requires-Dist: pydantic<3,>=1.9.0
|
|
29
29
|
Requires-Dist: sniffio
|
|
30
30
|
Requires-Dist: typing-extensions<5,>=4.10
|
|
31
|
+
Requires-Dist: wrapt>=1.17.2
|
|
31
32
|
Description-Content-Type: text/markdown
|
|
32
33
|
|
|
33
34
|
# Payi Python API library
|
|
@@ -65,7 +66,7 @@ client = Payi(
|
|
|
65
66
|
|
|
66
67
|
limit_response = client.limits.create(
|
|
67
68
|
limit_name="x",
|
|
68
|
-
max=
|
|
69
|
+
max=1,
|
|
69
70
|
)
|
|
70
71
|
print(limit_response.request_id)
|
|
71
72
|
```
|
|
@@ -92,7 +93,7 @@ client = AsyncPayi(
|
|
|
92
93
|
async def main() -> None:
|
|
93
94
|
limit_response = await client.limits.create(
|
|
94
95
|
limit_name="x",
|
|
95
|
-
max=
|
|
96
|
+
max=1,
|
|
96
97
|
)
|
|
97
98
|
print(limit_response.request_id)
|
|
98
99
|
|
|
@@ -129,7 +130,7 @@ client = Payi()
|
|
|
129
130
|
try:
|
|
130
131
|
client.limits.create(
|
|
131
132
|
limit_name="x",
|
|
132
|
-
max=
|
|
133
|
+
max=1,
|
|
133
134
|
)
|
|
134
135
|
except payi.APIConnectionError as e:
|
|
135
136
|
print("The server could not be reached")
|
|
@@ -175,7 +176,7 @@ client = Payi(
|
|
|
175
176
|
# Or, configure per-request:
|
|
176
177
|
client.with_options(max_retries=5).limits.create(
|
|
177
178
|
limit_name="x",
|
|
178
|
-
max=
|
|
179
|
+
max=1,
|
|
179
180
|
)
|
|
180
181
|
```
|
|
181
182
|
|
|
@@ -201,7 +202,7 @@ client = Payi(
|
|
|
201
202
|
# Override per-request:
|
|
202
203
|
client.with_options(timeout=5.0).limits.create(
|
|
203
204
|
limit_name="x",
|
|
204
|
-
max=
|
|
205
|
+
max=1,
|
|
205
206
|
)
|
|
206
207
|
```
|
|
207
208
|
|
|
@@ -245,7 +246,7 @@ from payi import Payi
|
|
|
245
246
|
client = Payi()
|
|
246
247
|
response = client.limits.with_raw_response.create(
|
|
247
248
|
limit_name="x",
|
|
248
|
-
max=
|
|
249
|
+
max=1,
|
|
249
250
|
)
|
|
250
251
|
print(response.headers.get('X-My-Header'))
|
|
251
252
|
|
|
@@ -266,7 +267,7 @@ To stream the response body, use `.with_streaming_response` instead, which requi
|
|
|
266
267
|
```python
|
|
267
268
|
with client.limits.with_streaming_response.create(
|
|
268
269
|
limit_name="x",
|
|
269
|
-
max=
|
|
270
|
+
max=1,
|
|
270
271
|
) as response:
|
|
271
272
|
print(response.headers.get("X-My-Header"))
|
|
272
273
|
|
|
@@ -33,7 +33,7 @@ client = Payi(
|
|
|
33
33
|
|
|
34
34
|
limit_response = client.limits.create(
|
|
35
35
|
limit_name="x",
|
|
36
|
-
max=
|
|
36
|
+
max=1,
|
|
37
37
|
)
|
|
38
38
|
print(limit_response.request_id)
|
|
39
39
|
```
|
|
@@ -60,7 +60,7 @@ client = AsyncPayi(
|
|
|
60
60
|
async def main() -> None:
|
|
61
61
|
limit_response = await client.limits.create(
|
|
62
62
|
limit_name="x",
|
|
63
|
-
max=
|
|
63
|
+
max=1,
|
|
64
64
|
)
|
|
65
65
|
print(limit_response.request_id)
|
|
66
66
|
|
|
@@ -97,7 +97,7 @@ client = Payi()
|
|
|
97
97
|
try:
|
|
98
98
|
client.limits.create(
|
|
99
99
|
limit_name="x",
|
|
100
|
-
max=
|
|
100
|
+
max=1,
|
|
101
101
|
)
|
|
102
102
|
except payi.APIConnectionError as e:
|
|
103
103
|
print("The server could not be reached")
|
|
@@ -143,7 +143,7 @@ client = Payi(
|
|
|
143
143
|
# Or, configure per-request:
|
|
144
144
|
client.with_options(max_retries=5).limits.create(
|
|
145
145
|
limit_name="x",
|
|
146
|
-
max=
|
|
146
|
+
max=1,
|
|
147
147
|
)
|
|
148
148
|
```
|
|
149
149
|
|
|
@@ -169,7 +169,7 @@ client = Payi(
|
|
|
169
169
|
# Override per-request:
|
|
170
170
|
client.with_options(timeout=5.0).limits.create(
|
|
171
171
|
limit_name="x",
|
|
172
|
-
max=
|
|
172
|
+
max=1,
|
|
173
173
|
)
|
|
174
174
|
```
|
|
175
175
|
|
|
@@ -213,7 +213,7 @@ from payi import Payi
|
|
|
213
213
|
client = Payi()
|
|
214
214
|
response = client.limits.with_raw_response.create(
|
|
215
215
|
limit_name="x",
|
|
216
|
-
max=
|
|
216
|
+
max=1,
|
|
217
217
|
)
|
|
218
218
|
print(response.headers.get('X-My-Header'))
|
|
219
219
|
|
|
@@ -234,7 +234,7 @@ To stream the response body, use `.with_streaming_response` instead, which requi
|
|
|
234
234
|
```python
|
|
235
235
|
with client.limits.with_streaming_response.create(
|
|
236
236
|
limit_name="x",
|
|
237
|
-
max=
|
|
237
|
+
max=1,
|
|
238
238
|
) as response:
|
|
239
239
|
print(response.headers.get("X-My-Header"))
|
|
240
240
|
|
|
@@ -52,7 +52,13 @@ Methods:
|
|
|
52
52
|
Types:
|
|
53
53
|
|
|
54
54
|
```python
|
|
55
|
-
from payi.types import
|
|
55
|
+
from payi.types import (
|
|
56
|
+
BulkIngestResponse,
|
|
57
|
+
IngestEvent,
|
|
58
|
+
IngestResponse,
|
|
59
|
+
IngestUnits,
|
|
60
|
+
PayICommonModelsAPIRouterHeaderInfo,
|
|
61
|
+
)
|
|
56
62
|
```
|
|
57
63
|
|
|
58
64
|
Methods:
|
|
@@ -41,7 +41,7 @@ cache_fine_grained = True
|
|
|
41
41
|
# ```
|
|
42
42
|
# Changing this codegen to make mypy happy would increase complexity
|
|
43
43
|
# and would not be worth it.
|
|
44
|
-
disable_error_code = func-returns-value
|
|
44
|
+
disable_error_code = func-returns-value,overload-cannot-match
|
|
45
45
|
|
|
46
46
|
# https://github.com/python/mypy/issues/12162
|
|
47
47
|
[mypy.overrides]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "payi"
|
|
3
|
-
version = "0.1.0-alpha.
|
|
3
|
+
version = "0.1.0-alpha.37"
|
|
4
4
|
description = "The official Python library for the payi API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -14,6 +14,7 @@ dependencies = [
|
|
|
14
14
|
"anyio>=3.5.0, <5",
|
|
15
15
|
"distro>=1.7.0, <2",
|
|
16
16
|
"sniffio",
|
|
17
|
+
"wrapt>=1.17.2",
|
|
17
18
|
]
|
|
18
19
|
requires-python = ">= 3.8"
|
|
19
20
|
classifiers = [
|
|
@@ -55,6 +56,7 @@ dev-dependencies = [
|
|
|
55
56
|
"importlib-metadata>=6.7.0",
|
|
56
57
|
"rich>=13.7.1",
|
|
57
58
|
"nest_asyncio==1.6.0",
|
|
59
|
+
"wrapt",
|
|
58
60
|
]
|
|
59
61
|
|
|
60
62
|
[tool.rye.scripts]
|
|
@@ -129,6 +131,7 @@ testpaths = ["tests"]
|
|
|
129
131
|
addopts = "--tb=short"
|
|
130
132
|
xfail_strict = true
|
|
131
133
|
asyncio_mode = "auto"
|
|
134
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
132
135
|
filterwarnings = [
|
|
133
136
|
"error"
|
|
134
137
|
]
|
|
@@ -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
|
|
@@ -48,7 +49,7 @@ markdown-it-py==3.0.0
|
|
|
48
49
|
# via rich
|
|
49
50
|
mdurl==0.1.2
|
|
50
51
|
# via markdown-it-py
|
|
51
|
-
mypy==1.
|
|
52
|
+
mypy==1.14.1
|
|
52
53
|
mypy-extensions==1.0.0
|
|
53
54
|
# via mypy
|
|
54
55
|
nest-asyncio==1.6.0
|
|
@@ -68,7 +69,7 @@ pydantic-core==2.27.1
|
|
|
68
69
|
# via pydantic
|
|
69
70
|
pygments==2.18.0
|
|
70
71
|
# via rich
|
|
71
|
-
pyright==1.1.
|
|
72
|
+
pyright==1.1.392.post0
|
|
72
73
|
pytest==8.3.3
|
|
73
74
|
# via pytest-asyncio
|
|
74
75
|
pytest-asyncio==0.24.0
|
|
@@ -99,5 +100,7 @@ typing-extensions==4.12.2
|
|
|
99
100
|
# via pyright
|
|
100
101
|
virtualenv==20.24.5
|
|
101
102
|
# via nox
|
|
103
|
+
wrapt==1.17.2
|
|
104
|
+
# via payi
|
|
102
105
|
zipp==3.17.0
|
|
103
106
|
# via importlib-metadata
|
|
@@ -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
|
|
@@ -42,3 +43,5 @@ typing-extensions==4.12.2
|
|
|
42
43
|
# via payi
|
|
43
44
|
# via pydantic
|
|
44
45
|
# via pydantic-core
|
|
46
|
+
wrapt==1.17.2
|
|
47
|
+
# via payi
|
|
@@ -179,14 +179,14 @@ class BaseModel(pydantic.BaseModel):
|
|
|
179
179
|
@classmethod
|
|
180
180
|
@override
|
|
181
181
|
def construct( # pyright: ignore[reportIncompatibleMethodOverride]
|
|
182
|
-
|
|
182
|
+
__cls: Type[ModelT],
|
|
183
183
|
_fields_set: set[str] | None = None,
|
|
184
184
|
**values: object,
|
|
185
185
|
) -> ModelT:
|
|
186
|
-
m =
|
|
186
|
+
m = __cls.__new__(__cls)
|
|
187
187
|
fields_values: dict[str, object] = {}
|
|
188
188
|
|
|
189
|
-
config = get_model_config(
|
|
189
|
+
config = get_model_config(__cls)
|
|
190
190
|
populate_by_name = (
|
|
191
191
|
config.allow_population_by_field_name
|
|
192
192
|
if isinstance(config, _ConfigProtocol)
|
|
@@ -196,7 +196,7 @@ class BaseModel(pydantic.BaseModel):
|
|
|
196
196
|
if _fields_set is None:
|
|
197
197
|
_fields_set = set()
|
|
198
198
|
|
|
199
|
-
model_fields = get_model_fields(
|
|
199
|
+
model_fields = get_model_fields(__cls)
|
|
200
200
|
for name, field in model_fields.items():
|
|
201
201
|
key = field.alias
|
|
202
202
|
if key is None or (key not in values and populate_by_name):
|
|
@@ -136,6 +136,8 @@ class BaseAPIResponse(Generic[R]):
|
|
|
136
136
|
if cast_to and is_annotated_type(cast_to):
|
|
137
137
|
cast_to = extract_type_arg(cast_to, 0)
|
|
138
138
|
|
|
139
|
+
origin = get_origin(cast_to) or cast_to
|
|
140
|
+
|
|
139
141
|
if self._is_sse_stream:
|
|
140
142
|
if to:
|
|
141
143
|
if not is_stream_class_type(to):
|
|
@@ -195,8 +197,6 @@ class BaseAPIResponse(Generic[R]):
|
|
|
195
197
|
if cast_to == bool:
|
|
196
198
|
return cast(R, response.text.lower() == "true")
|
|
197
199
|
|
|
198
|
-
origin = get_origin(cast_to) or cast_to
|
|
199
|
-
|
|
200
200
|
if origin == APIResponse:
|
|
201
201
|
raise RuntimeError("Unexpected state - cast_to is `APIResponse`")
|
|
202
202
|
|
|
@@ -210,7 +210,13 @@ class BaseAPIResponse(Generic[R]):
|
|
|
210
210
|
raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`")
|
|
211
211
|
return cast(R, response)
|
|
212
212
|
|
|
213
|
-
if
|
|
213
|
+
if (
|
|
214
|
+
inspect.isclass(
|
|
215
|
+
origin # pyright: ignore[reportUnknownArgumentType]
|
|
216
|
+
)
|
|
217
|
+
and not issubclass(origin, BaseModel)
|
|
218
|
+
and issubclass(origin, pydantic.BaseModel)
|
|
219
|
+
):
|
|
214
220
|
raise TypeError("Pydantic models must subclass our base model type, e.g. `from payi import BaseModel`")
|
|
215
221
|
|
|
216
222
|
if (
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from wrapt import wrap_function_wrapper # type: ignore
|
|
5
|
+
|
|
6
|
+
from payi.types import IngestUnitsParams
|
|
7
|
+
from payi.types.ingest_units_params import Units
|
|
8
|
+
|
|
9
|
+
from .instrument import PayiInstrumentor
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AnthropicIntrumentor:
|
|
13
|
+
@staticmethod
|
|
14
|
+
def instrument(instrumentor: PayiInstrumentor) -> None:
|
|
15
|
+
try:
|
|
16
|
+
import anthropic # type: ignore # noqa: F401 I001
|
|
17
|
+
|
|
18
|
+
# wrap_function_wrapper(
|
|
19
|
+
# "anthropic.resources.completions",
|
|
20
|
+
# "Completions.create",
|
|
21
|
+
# chat_wrapper(instrumentor),
|
|
22
|
+
# )
|
|
23
|
+
|
|
24
|
+
wrap_function_wrapper(
|
|
25
|
+
"anthropic.resources.messages",
|
|
26
|
+
"Messages.create",
|
|
27
|
+
chat_wrapper(instrumentor),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
wrap_function_wrapper(
|
|
31
|
+
"anthropic.resources.messages",
|
|
32
|
+
"Messages.stream",
|
|
33
|
+
chat_wrapper(instrumentor),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
except Exception as e:
|
|
37
|
+
logging.debug(f"Error instrumenting anthropic: {e}")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@PayiInstrumentor.payi_wrapper
|
|
42
|
+
def chat_wrapper(
|
|
43
|
+
instrumentor: PayiInstrumentor,
|
|
44
|
+
wrapped: Any,
|
|
45
|
+
instance: Any,
|
|
46
|
+
args: Any,
|
|
47
|
+
kwargs: Any,
|
|
48
|
+
) -> Any:
|
|
49
|
+
return instrumentor.chat_wrapper(
|
|
50
|
+
"system.anthropic",
|
|
51
|
+
process_chunk,
|
|
52
|
+
process_synchronous_response,
|
|
53
|
+
wrapped,
|
|
54
|
+
instance,
|
|
55
|
+
args,
|
|
56
|
+
kwargs,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def process_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
61
|
+
if chunk.type == "message_start":
|
|
62
|
+
usage = chunk.message.usage
|
|
63
|
+
units = ingest["units"]
|
|
64
|
+
|
|
65
|
+
units["text"] = Units(input=usage.input_tokens, output=0)
|
|
66
|
+
|
|
67
|
+
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
68
|
+
text_cache_write = usage.cache_creation_input_tokens
|
|
69
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
70
|
+
|
|
71
|
+
if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
|
|
72
|
+
text_cache_read = usage.cache_read_input_tokens
|
|
73
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
74
|
+
|
|
75
|
+
elif chunk.type == "message_delta":
|
|
76
|
+
usage = chunk.usage
|
|
77
|
+
ingest["units"]["text"]["output"] = usage.output_tokens
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_prompt_and_response: bool) -> None:
|
|
81
|
+
usage = response.usage
|
|
82
|
+
input = usage.input_tokens
|
|
83
|
+
ouptut = usage.output_tokens
|
|
84
|
+
units: dict[str, Units] = ingest["units"]
|
|
85
|
+
|
|
86
|
+
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
87
|
+
text_cache_write = usage.cache_creation_input_tokens
|
|
88
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
89
|
+
|
|
90
|
+
if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
|
|
91
|
+
text_cache_read = usage.cache_read_input_tokens
|
|
92
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
93
|
+
|
|
94
|
+
units["text"] = Units(input=input, output=ouptut)
|
|
95
|
+
|
|
96
|
+
if log_prompt_and_response:
|
|
97
|
+
ingest["provider_response_json"] = response.to_json()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any
|
|
4
|
+
from importlib.metadata import version
|
|
5
|
+
|
|
6
|
+
from wrapt import wrap_function_wrapper # type: ignore
|
|
7
|
+
|
|
8
|
+
from payi.types import IngestUnitsParams
|
|
9
|
+
from payi.types.ingest_units_params import Units
|
|
10
|
+
|
|
11
|
+
from .instrument import PayiInstrumentor
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class OpenAiInstrumentor:
|
|
15
|
+
@staticmethod
|
|
16
|
+
def instrument(instrumentor: PayiInstrumentor) -> None:
|
|
17
|
+
try:
|
|
18
|
+
from openai import OpenAI # type: ignore # noqa: F401 I001
|
|
19
|
+
|
|
20
|
+
wrap_function_wrapper(
|
|
21
|
+
"openai.resources.chat.completions",
|
|
22
|
+
"Completions.create",
|
|
23
|
+
chat_wrapper(instrumentor),
|
|
24
|
+
)
|
|
25
|
+
except Exception as e:
|
|
26
|
+
logging.debug(f"Error instrumenting openai: {e}")
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@PayiInstrumentor.payi_wrapper
|
|
31
|
+
def chat_wrapper(
|
|
32
|
+
instrumentor: PayiInstrumentor,
|
|
33
|
+
wrapped: Any,
|
|
34
|
+
instance: Any,
|
|
35
|
+
args: Any,
|
|
36
|
+
kwargs: Any,
|
|
37
|
+
) -> Any:
|
|
38
|
+
return instrumentor.chat_wrapper(
|
|
39
|
+
"system.openai",
|
|
40
|
+
process_chat_chunk,
|
|
41
|
+
process_chat_synchronous_response,
|
|
42
|
+
wrapped,
|
|
43
|
+
instance,
|
|
44
|
+
args,
|
|
45
|
+
kwargs,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def process_chat_synchronous_response(response: str, ingest: IngestUnitsParams, log_prompt_and_response: bool) -> None:
|
|
50
|
+
response_dict = model_to_dict(response)
|
|
51
|
+
|
|
52
|
+
add_usage_units(response_dict["usage"], ingest["units"])
|
|
53
|
+
|
|
54
|
+
if log_prompt_and_response:
|
|
55
|
+
ingest["provider_response_json"] = [json.dumps(response_dict)]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def process_chat_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
59
|
+
model = model_to_dict(chunk)
|
|
60
|
+
usage = model.get("usage")
|
|
61
|
+
if usage:
|
|
62
|
+
add_usage_units(usage, ingest["units"])
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def model_to_dict(model: Any) -> Any:
|
|
66
|
+
if version("pydantic") < "2.0.0":
|
|
67
|
+
return model.dict()
|
|
68
|
+
if hasattr(model, "model_dump"):
|
|
69
|
+
return model.model_dump()
|
|
70
|
+
elif hasattr(model, "parse"): # Raw API response
|
|
71
|
+
return model_to_dict(model.parse())
|
|
72
|
+
else:
|
|
73
|
+
return model
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def add_usage_units(usage: "dict[str, Any]", units: "dict[str, Units]") -> None:
|
|
77
|
+
input = usage["prompt_tokens"] if "prompt_tokens" in usage else 0
|
|
78
|
+
output = usage["completion_tokens"] if "completion_tokens" in usage else 0
|
|
79
|
+
input_cache = 0
|
|
80
|
+
|
|
81
|
+
prompt_tokens_details = usage.get("prompt_tokens_details")
|
|
82
|
+
if prompt_tokens_details:
|
|
83
|
+
input_cache = prompt_tokens_details.get("cached_tokens", 0)
|
|
84
|
+
if input_cache != 0:
|
|
85
|
+
units["text_cache_read"] = Units(input=input_cache, output=0)
|
|
86
|
+
|
|
87
|
+
input -= input_cache
|
|
88
|
+
|
|
89
|
+
units["text"] = Units(input=input, output=output)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Stopwatch:
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
self.start_time: Optional[float] = None
|
|
8
|
+
self.end_time: Optional[float] = None
|
|
9
|
+
|
|
10
|
+
def start(self) -> None:
|
|
11
|
+
self.start_time = time.perf_counter()
|
|
12
|
+
|
|
13
|
+
def stop(self) -> None:
|
|
14
|
+
self.end_time = time.perf_counter()
|
|
15
|
+
|
|
16
|
+
def elapsed_s(self) -> float:
|
|
17
|
+
if self.start_time is None:
|
|
18
|
+
raise ValueError("Stopwatch has not been started")
|
|
19
|
+
if self.end_time is None:
|
|
20
|
+
return time.perf_counter() - self.start_time
|
|
21
|
+
return self.end_time - self.start_time
|
|
22
|
+
|
|
23
|
+
def elapsed_ms(self) -> float:
|
|
24
|
+
return self.elapsed_s() * 1000
|
|
25
|
+
|
|
26
|
+
def elapsed_ms_int(self) -> int:
|
|
27
|
+
return int(self.elapsed_ms())
|
|
@@ -3,28 +3,30 @@ from typing import Dict, List, Union
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def create_limit_header_from_ids(limit_ids: List[str]) -> Dict[str, str]:
|
|
6
|
-
if not isinstance(limit_ids, list):
|
|
6
|
+
if not isinstance(limit_ids, list): # type: ignore
|
|
7
7
|
raise TypeError("limit_ids must be a list")
|
|
8
8
|
|
|
9
|
-
valid_ids = [id.strip() for id in limit_ids if isinstance(id, str) and id.strip()]
|
|
9
|
+
valid_ids = [id.strip() for id in limit_ids if isinstance(id, str) and id.strip()] # type: ignore
|
|
10
10
|
|
|
11
11
|
return {"xProxy-Limit-IDs": ",".join(valid_ids)} if valid_ids else {}
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
def create_request_header_from_tags(request_tags: List[str]) -> Dict[str, str]:
|
|
14
|
-
if not isinstance(request_tags, list):
|
|
15
|
+
if not isinstance(request_tags, list): # type: ignore
|
|
15
16
|
raise TypeError("request_tags must be a list")
|
|
16
17
|
|
|
17
|
-
valid_tags = [tag.strip() for tag in request_tags if isinstance(tag, str) and tag.strip()]
|
|
18
|
-
|
|
18
|
+
valid_tags = [tag.strip() for tag in request_tags if isinstance(tag, str) and tag.strip()] # type: ignore
|
|
19
|
+
|
|
19
20
|
return {"xProxy-Request-Tags": ",".join(valid_tags)} if valid_tags else {}
|
|
20
21
|
|
|
22
|
+
|
|
21
23
|
def create_headers(
|
|
22
|
-
limit_ids: Union[List[str], None] = None,
|
|
24
|
+
limit_ids: Union[List[str], None] = None,
|
|
23
25
|
request_tags: Union[List[str], None] = None,
|
|
24
26
|
user_id: Union[str, None] = None,
|
|
25
|
-
experience_id: Union[str, None] = None,
|
|
26
|
-
experience_name: Union[str, None] = None,
|
|
27
|
-
|
|
27
|
+
experience_id: Union[str, None] = None,
|
|
28
|
+
experience_name: Union[str, None] = None,
|
|
29
|
+
) -> Dict[str, str]:
|
|
28
30
|
headers: Dict[str, str] = {}
|
|
29
31
|
|
|
30
32
|
if limit_ids:
|
|
@@ -38,4 +40,4 @@ def create_headers(
|
|
|
38
40
|
if experience_name:
|
|
39
41
|
headers.update({"xProxy-Experience-Name": experience_name})
|
|
40
42
|
|
|
41
|
-
return headers
|
|
43
|
+
return headers
|