payi 0.1.0a71__tar.gz → 0.1.0a73__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.0a73/.release-please-manifest.json +3 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/CHANGELOG.md +21 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/PKG-INFO +1 -1
- {payi-0.1.0a71 → payi-0.1.0a73}/pyproject.toml +1 -1
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/__init__.py +5 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_proxy.py +4 -1
- payi-0.1.0a73/src/payi/_utils/_resources_proxy.py +24 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_version.py +1 -1
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/AnthropicInstrumentor.py +23 -12
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/OpenAIInstrumentor.py +210 -52
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/helpers.py +15 -5
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/instrument.py +73 -33
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_utils/test_proxy.py +11 -0
- payi-0.1.0a71/.release-please-manifest.json +0 -3
- {payi-0.1.0a71 → payi-0.1.0a73}/.gitignore +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/LICENSE +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/README.md +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/SECURITY.md +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/api.md +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/bin/check-release-environment +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/bin/publish-pypi +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/examples/.keep +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/mypy.ini +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/noxfile.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/release-please-config.json +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/requirements-dev.lock +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/requirements.lock +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_client.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_compat.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_constants.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_files.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_models.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_qs.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_resource.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_types.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_transform.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/BedrockInstrumentor.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/Stopwatch.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/lib/VertexInstrumentor.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/pagination.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/py.typed +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/categories/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/categories/categories.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/categories/resources.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/experiences.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/types/limit_config.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/experiences/types/types.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/ingest.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/limits/limits.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/limits/tags.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/requests/properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/requests/requests.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/requests/result.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/definitions/definitions.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/definitions/kpis.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/definitions/limit_config.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/definitions/version.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/kpis.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/resources/use_cases/use_cases.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/bulk_ingest_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/categories/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/categories/resource_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_list_resources_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/types/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/ingest_bulk_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/ingest_event_param.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/ingest_units_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_history_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_list_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/requests/request_result.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/evaluation_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/ingest_units.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/properties_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/xproxy_error.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared/xproxy_result.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared_params/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared_params/ingest_units.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/shared_params/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_case_instance_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definition_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definition_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definition_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_create_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_delete_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_list_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_retrieve_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/kpi_update_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/definitions/limit_config_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/kpi_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/kpi_list_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/kpi_list_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/kpi_update_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/property_create_params.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/src/payi/types/use_cases/use_case_definition.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/requests/test_result.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/test_ingest.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/test_limits.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/test_use_cases.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/definitions/test_kpis.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/definitions/test_limit_config.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/definitions/test_version.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/test_definitions.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/test_kpis.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/api_resources/use_cases/test_properties.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/conftest.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/sample_file.txt +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_client.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_files.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_models.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_qs.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_required_args.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_response.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_streaming.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_transform.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a71 → payi-0.1.0a73}/tests/utils.py +0 -0
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.73 (2025-05-13)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.72...v0.1.0-alpha.73](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.72...v0.1.0-alpha.73)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Anthropic Vertex, OpenAi Responses ([#297](https://github.com/Pay-i/pay-i-python/issues/297)) ([535163f](https://github.com/Pay-i/pay-i-python/commit/535163f1d29f39838a16dc87a4ef40542b5d93b0))
|
|
10
|
+
|
|
11
|
+
## 0.1.0-alpha.72 (2025-05-10)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.1.0-alpha.71...v0.1.0-alpha.72](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.71...v0.1.0-alpha.72)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **package:** support direct resource imports ([314f86c](https://github.com/Pay-i/pay-i-python/commit/314f86cb0d46aa35628c9d059c1b1ca25d24d911))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Chores
|
|
21
|
+
|
|
22
|
+
* **internal:** avoid errors for isinstance checks on proxies ([b935f82](https://github.com/Pay-i/pay-i-python/commit/b935f82c9de01353ec83b9c12c4ed6749e984c7d))
|
|
23
|
+
|
|
3
24
|
## 0.1.0-alpha.71 (2025-05-03)
|
|
4
25
|
|
|
5
26
|
Full Changelog: [v0.1.0-alpha.70...v0.1.0-alpha.71](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.70...v0.1.0-alpha.71)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
2
|
|
|
3
|
+
import typing as _t
|
|
4
|
+
|
|
3
5
|
from . import types
|
|
4
6
|
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
|
|
5
7
|
from ._utils import file_from_path
|
|
@@ -68,6 +70,9 @@ __all__ = [
|
|
|
68
70
|
"DefaultAsyncHttpxClient",
|
|
69
71
|
]
|
|
70
72
|
|
|
73
|
+
if not _t.TYPE_CHECKING:
|
|
74
|
+
from ._utils._resources_proxy import resources as resources
|
|
75
|
+
|
|
71
76
|
_setup_logging()
|
|
72
77
|
|
|
73
78
|
# Update the __module__ attribute for exported symbols so that
|
|
@@ -46,7 +46,10 @@ class LazyProxy(Generic[T], ABC):
|
|
|
46
46
|
@property # type: ignore
|
|
47
47
|
@override
|
|
48
48
|
def __class__(self) -> type: # pyright: ignore
|
|
49
|
-
|
|
49
|
+
try:
|
|
50
|
+
proxied = self.__get_proxied__()
|
|
51
|
+
except Exception:
|
|
52
|
+
return type(self)
|
|
50
53
|
if issubclass(type(proxied), LazyProxy):
|
|
51
54
|
return type(proxied)
|
|
52
55
|
return proxied.__class__
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from typing_extensions import override
|
|
5
|
+
|
|
6
|
+
from ._proxy import LazyProxy
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ResourcesProxy(LazyProxy[Any]):
|
|
10
|
+
"""A proxy for the `payi.resources` module.
|
|
11
|
+
|
|
12
|
+
This is used so that we can lazily import `payi.resources` only when
|
|
13
|
+
needed *and* so that users can just import `payi` and reference `payi.resources`
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@override
|
|
17
|
+
def __load__(self) -> Any:
|
|
18
|
+
import importlib
|
|
19
|
+
|
|
20
|
+
mod = importlib.import_module("payi.resources")
|
|
21
|
+
return mod
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
resources = ResourcesProxy().__as_proxied__()
|
|
@@ -11,7 +11,13 @@ from payi.types.ingest_units_params import Units
|
|
|
11
11
|
from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class
|
|
14
|
+
class AnthropicInstrumentor:
|
|
15
|
+
@staticmethod
|
|
16
|
+
def is_vertex(instance: Any) -> bool:
|
|
17
|
+
from anthropic import AnthropicVertex, AsyncAnthropicVertex # type: ignore # noqa: I001
|
|
18
|
+
|
|
19
|
+
return isinstance(instance._client, (AsyncAnthropicVertex, AnthropicVertex))
|
|
20
|
+
|
|
15
21
|
@staticmethod
|
|
16
22
|
def instrument(instrumentor: _PayiInstrumentor) -> None:
|
|
17
23
|
try:
|
|
@@ -20,25 +26,25 @@ class AnthropicIntrumentor:
|
|
|
20
26
|
wrap_function_wrapper(
|
|
21
27
|
"anthropic.resources.messages",
|
|
22
28
|
"Messages.create",
|
|
23
|
-
|
|
29
|
+
messages_wrapper(instrumentor),
|
|
24
30
|
)
|
|
25
31
|
|
|
26
32
|
wrap_function_wrapper(
|
|
27
33
|
"anthropic.resources.messages",
|
|
28
34
|
"Messages.stream",
|
|
29
|
-
|
|
35
|
+
messages_wrapper(instrumentor),
|
|
30
36
|
)
|
|
31
37
|
|
|
32
38
|
wrap_function_wrapper(
|
|
33
39
|
"anthropic.resources.messages",
|
|
34
40
|
"AsyncMessages.create",
|
|
35
|
-
|
|
41
|
+
amessages_wrapper(instrumentor),
|
|
36
42
|
)
|
|
37
43
|
|
|
38
44
|
wrap_function_wrapper(
|
|
39
45
|
"anthropic.resources.messages",
|
|
40
46
|
"AsyncMessages.stream",
|
|
41
|
-
|
|
47
|
+
amessages_wrapper(instrumentor),
|
|
42
48
|
)
|
|
43
49
|
|
|
44
50
|
except Exception as e:
|
|
@@ -47,7 +53,7 @@ class AnthropicIntrumentor:
|
|
|
47
53
|
|
|
48
54
|
|
|
49
55
|
@_PayiInstrumentor.payi_wrapper
|
|
50
|
-
def
|
|
56
|
+
def messages_wrapper(
|
|
51
57
|
instrumentor: _PayiInstrumentor,
|
|
52
58
|
wrapped: Any,
|
|
53
59
|
instance: Any,
|
|
@@ -55,7 +61,7 @@ def chat_wrapper(
|
|
|
55
61
|
**kwargs: Any,
|
|
56
62
|
) -> Any:
|
|
57
63
|
return instrumentor.invoke_wrapper(
|
|
58
|
-
_AnthropicProviderRequest(instrumentor),
|
|
64
|
+
_AnthropicProviderRequest(instrumentor, instance),
|
|
59
65
|
_IsStreaming.kwargs,
|
|
60
66
|
wrapped,
|
|
61
67
|
instance,
|
|
@@ -64,7 +70,7 @@ def chat_wrapper(
|
|
|
64
70
|
)
|
|
65
71
|
|
|
66
72
|
@_PayiInstrumentor.payi_awrapper
|
|
67
|
-
async def
|
|
73
|
+
async def amessages_wrapper(
|
|
68
74
|
instrumentor: _PayiInstrumentor,
|
|
69
75
|
wrapped: Any,
|
|
70
76
|
instance: Any,
|
|
@@ -72,7 +78,7 @@ async def achat_wrapper(
|
|
|
72
78
|
**kwargs: Any,
|
|
73
79
|
) -> Any:
|
|
74
80
|
return await instrumentor.async_invoke_wrapper(
|
|
75
|
-
_AnthropicProviderRequest(instrumentor),
|
|
81
|
+
_AnthropicProviderRequest(instrumentor, instance),
|
|
76
82
|
_IsStreaming.kwargs,
|
|
77
83
|
wrapped,
|
|
78
84
|
instance,
|
|
@@ -81,8 +87,12 @@ async def achat_wrapper(
|
|
|
81
87
|
)
|
|
82
88
|
|
|
83
89
|
class _AnthropicProviderRequest(_ProviderRequest):
|
|
84
|
-
def __init__(self, instrumentor: _PayiInstrumentor):
|
|
85
|
-
|
|
90
|
+
def __init__(self, instrumentor: _PayiInstrumentor, instance: Any = None) -> None:
|
|
91
|
+
self._vertex: bool = AnthropicInstrumentor.is_vertex(instance)
|
|
92
|
+
super().__init__(
|
|
93
|
+
instrumentor=instrumentor,
|
|
94
|
+
category=PayiCategories.google_vertex if self._vertex else PayiCategories.anthropic
|
|
95
|
+
)
|
|
86
96
|
|
|
87
97
|
@override
|
|
88
98
|
def process_chunk(self, chunk: Any) -> bool:
|
|
@@ -138,7 +148,8 @@ class _AnthropicProviderRequest(_ProviderRequest):
|
|
|
138
148
|
|
|
139
149
|
@override
|
|
140
150
|
def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
|
|
141
|
-
self._ingest["resource"] = kwargs.get("model", "")
|
|
151
|
+
self._ingest["resource"] = ("anthropic." if self._vertex else "") + kwargs.get("model", "")
|
|
152
|
+
|
|
142
153
|
messages = kwargs.get("messages")
|
|
143
154
|
if messages:
|
|
144
155
|
estimated_token_count = 0
|
|
@@ -7,7 +7,6 @@ from importlib.metadata import version
|
|
|
7
7
|
import tiktoken # type: ignore
|
|
8
8
|
from wrapt import wrap_function_wrapper # type: ignore
|
|
9
9
|
|
|
10
|
-
from payi.types import IngestUnitsParams
|
|
11
10
|
from payi.lib.helpers import PayiCategories, PayiHeaderNames
|
|
12
11
|
from payi.types.ingest_units_params import Units
|
|
13
12
|
|
|
@@ -50,6 +49,18 @@ class OpenAiInstrumentor:
|
|
|
50
49
|
aembeddings_wrapper(instrumentor),
|
|
51
50
|
)
|
|
52
51
|
|
|
52
|
+
wrap_function_wrapper(
|
|
53
|
+
"openai.resources.responses",
|
|
54
|
+
"Responses.create",
|
|
55
|
+
responses_wrapper(instrumentor),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
wrap_function_wrapper(
|
|
59
|
+
"openai.resources.responses",
|
|
60
|
+
"AsyncResponses.create",
|
|
61
|
+
aresponses_wrapper(instrumentor),
|
|
62
|
+
)
|
|
63
|
+
|
|
53
64
|
except Exception as e:
|
|
54
65
|
logging.debug(f"Error instrumenting openai: {e}")
|
|
55
66
|
return
|
|
@@ -122,10 +133,55 @@ async def achat_wrapper(
|
|
|
122
133
|
args,
|
|
123
134
|
kwargs,
|
|
124
135
|
)
|
|
136
|
+
|
|
137
|
+
@_PayiInstrumentor.payi_wrapper
|
|
138
|
+
def responses_wrapper(
|
|
139
|
+
instrumentor: _PayiInstrumentor,
|
|
140
|
+
wrapped: Any,
|
|
141
|
+
instance: Any,
|
|
142
|
+
*args: Any,
|
|
143
|
+
**kwargs: Any,
|
|
144
|
+
) -> Any:
|
|
145
|
+
return instrumentor.invoke_wrapper(
|
|
146
|
+
_OpenAiResponsesProviderRequest(instrumentor),
|
|
147
|
+
_IsStreaming.kwargs,
|
|
148
|
+
wrapped,
|
|
149
|
+
instance,
|
|
150
|
+
args,
|
|
151
|
+
kwargs,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
@_PayiInstrumentor.payi_awrapper
|
|
155
|
+
async def aresponses_wrapper(
|
|
156
|
+
instrumentor: _PayiInstrumentor,
|
|
157
|
+
wrapped: Any,
|
|
158
|
+
instance: Any,
|
|
159
|
+
*args: Any,
|
|
160
|
+
**kwargs: Any,
|
|
161
|
+
) -> Any:
|
|
162
|
+
return await instrumentor.async_invoke_wrapper(
|
|
163
|
+
_OpenAiResponsesProviderRequest(instrumentor),
|
|
164
|
+
_IsStreaming.kwargs,
|
|
165
|
+
wrapped,
|
|
166
|
+
instance,
|
|
167
|
+
args,
|
|
168
|
+
kwargs,
|
|
169
|
+
)
|
|
125
170
|
|
|
126
171
|
class _OpenAiProviderRequest(_ProviderRequest):
|
|
127
|
-
|
|
172
|
+
chat_input_tokens_key: str = "prompt_tokens"
|
|
173
|
+
chat_output_tokens_key: str = "completion_tokens"
|
|
174
|
+
chat_input_tokens_details_key: str = "prompt_tokens_details"
|
|
175
|
+
|
|
176
|
+
responses_input_tokens_key: str = "input_tokens"
|
|
177
|
+
responses_output_tokens_key: str = "output_tokens"
|
|
178
|
+
responses_input_tokens_details_key: str = "input_tokens_details"
|
|
179
|
+
|
|
180
|
+
def __init__(self, instrumentor: _PayiInstrumentor, input_tokens_key: str, output_tokens_key: str, input_tokens_details_key: str) -> None:
|
|
128
181
|
super().__init__(instrumentor=instrumentor, category=PayiCategories.openai)
|
|
182
|
+
self._input_tokens_key = input_tokens_key
|
|
183
|
+
self._output_tokens_key = output_tokens_key
|
|
184
|
+
self._input_tokens_details_key = input_tokens_details_key
|
|
129
185
|
|
|
130
186
|
@override
|
|
131
187
|
def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool: # type: ignore
|
|
@@ -135,16 +191,19 @@ class _OpenAiProviderRequest(_ProviderRequest):
|
|
|
135
191
|
return True
|
|
136
192
|
|
|
137
193
|
context = self._instrumentor.get_context_safe()
|
|
138
|
-
|
|
194
|
+
price_as_category = extra_headers.get(PayiHeaderNames.price_as_category) or context.get("price_as_category")
|
|
195
|
+
price_as_resource = extra_headers.get(PayiHeaderNames.price_as_resource) or context.get("price_as_resource")
|
|
139
196
|
resource_scope = extra_headers.get(PayiHeaderNames.resource_scope) or context.get("resource_scope")
|
|
140
197
|
|
|
141
|
-
if PayiHeaderNames.
|
|
142
|
-
del extra_headers[PayiHeaderNames.
|
|
198
|
+
if PayiHeaderNames.price_as_category in extra_headers:
|
|
199
|
+
del extra_headers[PayiHeaderNames.price_as_category]
|
|
200
|
+
if PayiHeaderNames.price_as_resource in extra_headers:
|
|
201
|
+
del extra_headers[PayiHeaderNames.price_as_resource]
|
|
143
202
|
if PayiHeaderNames.resource_scope in extra_headers:
|
|
144
203
|
del extra_headers[PayiHeaderNames.resource_scope]
|
|
145
204
|
|
|
146
|
-
if not
|
|
147
|
-
logging.error("Azure OpenAI
|
|
205
|
+
if not price_as_resource and not price_as_category:
|
|
206
|
+
logging.error("Azure OpenAI requires price as resource and/or category to be specified, not ingesting")
|
|
148
207
|
return False
|
|
149
208
|
|
|
150
209
|
if resource_scope:
|
|
@@ -157,8 +216,13 @@ class _OpenAiProviderRequest(_ProviderRequest):
|
|
|
157
216
|
self._category = PayiCategories.azure_openai
|
|
158
217
|
|
|
159
218
|
self._ingest["category"] = self._category
|
|
160
|
-
|
|
161
|
-
|
|
219
|
+
|
|
220
|
+
if price_as_category:
|
|
221
|
+
# price as category overrides default
|
|
222
|
+
self._ingest["category"] = price_as_category
|
|
223
|
+
if price_as_resource:
|
|
224
|
+
self._ingest["resource"] = price_as_resource
|
|
225
|
+
|
|
162
226
|
return True
|
|
163
227
|
|
|
164
228
|
@override
|
|
@@ -193,9 +257,59 @@ class _OpenAiProviderRequest(_ProviderRequest):
|
|
|
193
257
|
|
|
194
258
|
return True
|
|
195
259
|
|
|
260
|
+
def process_synchronous_response_worker(
|
|
261
|
+
self,
|
|
262
|
+
response: str,
|
|
263
|
+
log_prompt_and_response: bool,
|
|
264
|
+
) -> Any:
|
|
265
|
+
response_dict = model_to_dict(response)
|
|
266
|
+
|
|
267
|
+
self.add_usage_units(response_dict.get("usage", {}))
|
|
268
|
+
|
|
269
|
+
if log_prompt_and_response:
|
|
270
|
+
self._ingest["provider_response_json"] = [json.dumps(response_dict)]
|
|
271
|
+
|
|
272
|
+
if "id" in response_dict:
|
|
273
|
+
self._ingest["provider_response_id"] = response_dict["id"]
|
|
274
|
+
|
|
275
|
+
return None
|
|
276
|
+
|
|
277
|
+
def add_usage_units(self, usage: "dict[str, Any]",) -> None:
|
|
278
|
+
units = self._ingest["units"]
|
|
279
|
+
|
|
280
|
+
input = usage[self._input_tokens_key] if self._input_tokens_key in usage else 0
|
|
281
|
+
output = usage[self._output_tokens_key] if self._output_tokens_key in usage else 0
|
|
282
|
+
input_cache = 0
|
|
283
|
+
|
|
284
|
+
prompt_tokens_details = usage.get(self._input_tokens_details_key)
|
|
285
|
+
if prompt_tokens_details:
|
|
286
|
+
input_cache = prompt_tokens_details.get("cached_tokens", 0)
|
|
287
|
+
if input_cache != 0:
|
|
288
|
+
units["text_cache_read"] = Units(input=input_cache, output=0)
|
|
289
|
+
|
|
290
|
+
input = _PayiInstrumentor.update_for_vision(input - input_cache, units, self._estimated_prompt_tokens)
|
|
291
|
+
|
|
292
|
+
units["text"] = Units(input=input, output=output)
|
|
293
|
+
|
|
294
|
+
@staticmethod
|
|
295
|
+
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]'], image_type: str = "image_url", text_type:str = "text") -> 'tuple[bool, int]':
|
|
296
|
+
if isinstance(content, str):
|
|
297
|
+
return False, 0
|
|
298
|
+
elif isinstance(content, list): # type: ignore
|
|
299
|
+
has_image = any(item.get("type") == image_type for item in content)
|
|
300
|
+
if has_image is False:
|
|
301
|
+
return has_image, 0
|
|
302
|
+
|
|
303
|
+
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == text_type)
|
|
304
|
+
return has_image, token_count
|
|
305
|
+
|
|
196
306
|
class _OpenAiEmbeddingsProviderRequest(_OpenAiProviderRequest):
|
|
197
307
|
def __init__(self, instrumentor: _PayiInstrumentor):
|
|
198
|
-
super().__init__(
|
|
308
|
+
super().__init__(
|
|
309
|
+
instrumentor=instrumentor,
|
|
310
|
+
input_tokens_key=_OpenAiProviderRequest.chat_input_tokens_key,
|
|
311
|
+
output_tokens_key=_OpenAiProviderRequest.chat_output_tokens_key,
|
|
312
|
+
input_tokens_details_key=_OpenAiProviderRequest.chat_input_tokens_details_key)
|
|
199
313
|
|
|
200
314
|
@override
|
|
201
315
|
def process_synchronous_response(
|
|
@@ -203,11 +317,16 @@ class _OpenAiEmbeddingsProviderRequest(_OpenAiProviderRequest):
|
|
|
203
317
|
response: Any,
|
|
204
318
|
log_prompt_and_response: bool,
|
|
205
319
|
kwargs: Any) -> Any:
|
|
206
|
-
return
|
|
320
|
+
return self.process_synchronous_response_worker(response, log_prompt_and_response)
|
|
207
321
|
|
|
208
322
|
class _OpenAiChatProviderRequest(_OpenAiProviderRequest):
|
|
209
323
|
def __init__(self, instrumentor: _PayiInstrumentor):
|
|
210
|
-
super().__init__(
|
|
324
|
+
super().__init__(
|
|
325
|
+
instrumentor=instrumentor,
|
|
326
|
+
input_tokens_key=_OpenAiProviderRequest.chat_input_tokens_key,
|
|
327
|
+
output_tokens_key=_OpenAiProviderRequest.chat_output_tokens_key,
|
|
328
|
+
input_tokens_details_key=_OpenAiProviderRequest.chat_input_tokens_details_key)
|
|
329
|
+
|
|
211
330
|
self._include_usage_added = False
|
|
212
331
|
|
|
213
332
|
@override
|
|
@@ -223,9 +342,9 @@ class _OpenAiChatProviderRequest(_OpenAiProviderRequest):
|
|
|
223
342
|
|
|
224
343
|
usage = model.get("usage")
|
|
225
344
|
if usage:
|
|
226
|
-
add_usage_units(usage
|
|
345
|
+
self.add_usage_units(usage)
|
|
227
346
|
|
|
228
|
-
# If we
|
|
347
|
+
# If we added "include_usage" in the request on behalf of the client, do not return the extra
|
|
229
348
|
# packet which contains the usage to the client as they are not expecting the data
|
|
230
349
|
if self._include_usage_added:
|
|
231
350
|
send_chunk_to_client = False
|
|
@@ -249,7 +368,7 @@ class _OpenAiChatProviderRequest(_OpenAiProviderRequest):
|
|
|
249
368
|
enc = tiktoken.get_encoding("o200k_base") # type: ignore
|
|
250
369
|
|
|
251
370
|
for message in messages:
|
|
252
|
-
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
371
|
+
msg_has_image, msg_prompt_tokens = self.has_image_and_get_texts(enc, message.get('content', ''))
|
|
253
372
|
if msg_has_image:
|
|
254
373
|
has_image = True
|
|
255
374
|
estimated_token_count += msg_prompt_tokens
|
|
@@ -276,20 +395,86 @@ class _OpenAiChatProviderRequest(_OpenAiProviderRequest):
|
|
|
276
395
|
response: Any,
|
|
277
396
|
log_prompt_and_response: bool,
|
|
278
397
|
kwargs: Any) -> Any:
|
|
279
|
-
|
|
398
|
+
return self.process_synchronous_response_worker(response, log_prompt_and_response)
|
|
399
|
+
|
|
400
|
+
class _OpenAiResponsesProviderRequest(_OpenAiProviderRequest):
|
|
401
|
+
def __init__(self, instrumentor: _PayiInstrumentor):
|
|
402
|
+
super().__init__(
|
|
403
|
+
instrumentor=instrumentor,
|
|
404
|
+
input_tokens_key=_OpenAiProviderRequest.responses_input_tokens_key,
|
|
405
|
+
output_tokens_key=_OpenAiProviderRequest.responses_output_tokens_key,
|
|
406
|
+
input_tokens_details_key=_OpenAiProviderRequest.responses_input_tokens_details_key)
|
|
280
407
|
|
|
281
|
-
|
|
282
|
-
|
|
408
|
+
@override
|
|
409
|
+
def process_chunk(self, chunk: Any) -> bool:
|
|
410
|
+
model = model_to_dict(chunk)
|
|
411
|
+
response: dict[str, Any] = model.get("response", {})
|
|
412
|
+
|
|
413
|
+
if "provider_response_id" not in self._ingest:
|
|
414
|
+
response_id = response.get("id", None)
|
|
415
|
+
if response_id:
|
|
416
|
+
self._ingest["provider_response_id"] = response_id
|
|
417
|
+
|
|
418
|
+
usage = response.get("usage")
|
|
419
|
+
if usage:
|
|
420
|
+
self.add_usage_units(usage)
|
|
421
|
+
|
|
422
|
+
return True
|
|
283
423
|
|
|
284
|
-
|
|
424
|
+
@override
|
|
425
|
+
def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
|
|
426
|
+
result = super().process_request(instance, extra_headers, args, kwargs)
|
|
427
|
+
if result is False:
|
|
428
|
+
return result
|
|
429
|
+
|
|
430
|
+
input: ResponseInputParam = kwargs.get("input", None) # type: ignore
|
|
431
|
+
if not input or isinstance(input, str) or not isinstance(input, list):
|
|
432
|
+
return True
|
|
433
|
+
|
|
434
|
+
estimated_token_count = 0
|
|
435
|
+
has_image = False
|
|
285
436
|
|
|
286
|
-
|
|
287
|
-
|
|
437
|
+
try:
|
|
438
|
+
enc = tiktoken.encoding_for_model(kwargs.get("model")) # type: ignore
|
|
439
|
+
except KeyError:
|
|
440
|
+
enc = tiktoken.get_encoding("o200k_base") # type: ignore
|
|
441
|
+
|
|
442
|
+
# find each content..type="input_text" and count tokens
|
|
443
|
+
# input=[{
|
|
444
|
+
# "role": "user",
|
|
445
|
+
# "content": [
|
|
446
|
+
# {
|
|
447
|
+
# "type": "input_text",
|
|
448
|
+
# "text": "what's in this image?"
|
|
449
|
+
# },
|
|
450
|
+
# {
|
|
451
|
+
# "type": "input_image",
|
|
452
|
+
# "image_url": ...
|
|
453
|
+
# },
|
|
454
|
+
# ],
|
|
455
|
+
# }]
|
|
456
|
+
for item in input: # type: ignore
|
|
457
|
+
if isinstance(item, dict):
|
|
458
|
+
for key, value in item.items(): # type: ignore
|
|
459
|
+
if key == "content":
|
|
460
|
+
if isinstance(value, list):
|
|
461
|
+
msg_has_image, msg_prompt_tokens = self.has_image_and_get_texts(enc, value, image_type="input_image", text_type="input_text") # type: ignore
|
|
462
|
+
if msg_has_image:
|
|
463
|
+
has_image = True
|
|
464
|
+
estimated_token_count += msg_prompt_tokens
|
|
465
|
+
|
|
466
|
+
if has_image and estimated_token_count > 0:
|
|
467
|
+
self._estimated_prompt_tokens = estimated_token_count
|
|
288
468
|
|
|
289
|
-
|
|
290
|
-
ingest["provider_response_id"] = response_dict["id"]
|
|
469
|
+
return True
|
|
291
470
|
|
|
292
|
-
|
|
471
|
+
@override
|
|
472
|
+
def process_synchronous_response(
|
|
473
|
+
self,
|
|
474
|
+
response: Any,
|
|
475
|
+
log_prompt_and_response: bool,
|
|
476
|
+
kwargs: Any) -> Any:
|
|
477
|
+
return self.process_synchronous_response_worker(response, log_prompt_and_response)
|
|
293
478
|
|
|
294
479
|
def model_to_dict(model: Any) -> Any:
|
|
295
480
|
if version("pydantic") < "2.0.0":
|
|
@@ -299,31 +484,4 @@ def model_to_dict(model: Any) -> Any:
|
|
|
299
484
|
elif hasattr(model, "parse"): # Raw API response
|
|
300
485
|
return model_to_dict(model.parse())
|
|
301
486
|
else:
|
|
302
|
-
return model
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
def add_usage_units(usage: "dict[str, Any]", units: "dict[str, Units]", estimated_prompt_tokens: Optional[int]) -> None:
|
|
306
|
-
input = usage["prompt_tokens"] if "prompt_tokens" in usage else 0
|
|
307
|
-
output = usage["completion_tokens"] if "completion_tokens" in usage else 0
|
|
308
|
-
input_cache = 0
|
|
309
|
-
|
|
310
|
-
prompt_tokens_details = usage.get("prompt_tokens_details")
|
|
311
|
-
if prompt_tokens_details:
|
|
312
|
-
input_cache = prompt_tokens_details.get("cached_tokens", 0)
|
|
313
|
-
if input_cache != 0:
|
|
314
|
-
units["text_cache_read"] = Units(input=input_cache, output=0)
|
|
315
|
-
|
|
316
|
-
input = _PayiInstrumentor.update_for_vision(input - input_cache, units, estimated_prompt_tokens)
|
|
317
|
-
|
|
318
|
-
units["text"] = Units(input=input, output=output)
|
|
319
|
-
|
|
320
|
-
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
321
|
-
if isinstance(content, str):
|
|
322
|
-
return False, 0
|
|
323
|
-
elif isinstance(content, list): # type: ignore
|
|
324
|
-
has_image = any(item.get("type") == "image_url" for item in content)
|
|
325
|
-
if has_image is False:
|
|
326
|
-
return has_image, 0
|
|
327
|
-
|
|
328
|
-
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
|
|
329
|
-
return has_image, token_count
|
|
487
|
+
return model
|
|
@@ -11,8 +11,10 @@ class PayiHeaderNames:
|
|
|
11
11
|
use_case_id:str = "xProxy-UseCase-ID"
|
|
12
12
|
use_case_name:str = "xProxy-UseCase-Name"
|
|
13
13
|
use_case_version:str = "xProxy-UseCase-Version"
|
|
14
|
+
use_case_step:str = "xProxy-UseCase-Step"
|
|
14
15
|
user_id:str = "xProxy-User-ID"
|
|
15
|
-
|
|
16
|
+
price_as_category:str = "xProxy-PriceAs-Category"
|
|
17
|
+
price_as_resource:str = "xProxy-PriceAs-Resource"
|
|
16
18
|
provider_base_uri = "xProxy-Provider-BaseUri"
|
|
17
19
|
resource_scope:str = "xProxy-Resource-Scope"
|
|
18
20
|
api_key:str = "xProxy-Api-Key"
|
|
@@ -32,7 +34,6 @@ def create_limit_header_from_ids(limit_ids: List[str]) -> Dict[str, str]:
|
|
|
32
34
|
|
|
33
35
|
return { PayiHeaderNames.limit_ids: ",".join(valid_ids) } if valid_ids else {}
|
|
34
36
|
|
|
35
|
-
|
|
36
37
|
def create_request_header_from_tags(request_tags: List[str]) -> Dict[str, str]:
|
|
37
38
|
if not isinstance(request_tags, list): # type: ignore
|
|
38
39
|
raise TypeError("request_tags must be a list")
|
|
@@ -50,7 +51,9 @@ def create_headers(
|
|
|
50
51
|
use_case_id: Union[str, None] = None,
|
|
51
52
|
use_case_name: Union[str, None] = None,
|
|
52
53
|
use_case_version: Union[int, None] = None,
|
|
53
|
-
|
|
54
|
+
use_case_step: Union[str, None] = None,
|
|
55
|
+
price_as_category: Union[str, None] = None,
|
|
56
|
+
price_as_resource: Union[str, None] = None,
|
|
54
57
|
resource_scope: Union[str, None] = None,
|
|
55
58
|
) -> Dict[str, str]:
|
|
56
59
|
headers: Dict[str, str] = {}
|
|
@@ -71,8 +74,12 @@ def create_headers(
|
|
|
71
74
|
headers.update({ PayiHeaderNames.use_case_name: use_case_name})
|
|
72
75
|
if use_case_version:
|
|
73
76
|
headers.update({ PayiHeaderNames.use_case_version: str(use_case_version)})
|
|
74
|
-
if
|
|
75
|
-
headers.update({ PayiHeaderNames.
|
|
77
|
+
if use_case_step:
|
|
78
|
+
headers.update({ PayiHeaderNames.use_case_step: use_case_step})
|
|
79
|
+
if price_as_category:
|
|
80
|
+
headers.update({ PayiHeaderNames.price_as_category: price_as_category})
|
|
81
|
+
if price_as_resource:
|
|
82
|
+
headers.update({ PayiHeaderNames.price_as_resource: price_as_resource})
|
|
76
83
|
if resource_scope:
|
|
77
84
|
headers.update({ PayiHeaderNames.resource_scope: resource_scope })
|
|
78
85
|
return headers
|
|
@@ -99,3 +106,6 @@ def payi_azure_openai_url(payi_base_url: Union[str, None] = None) -> str:
|
|
|
99
106
|
|
|
100
107
|
def payi_aws_bedrock_url(payi_base_url: Union[str, None] = None) -> str:
|
|
101
108
|
return _resolve_payi_base_url(payi_base_url=payi_base_url) + "/api/v1/proxy/aws.bedrock"
|
|
109
|
+
|
|
110
|
+
# def payi_google_vertex_url(payi_base_url: Union[str, None] = None) -> str:
|
|
111
|
+
# return _resolve_payi_base_url(payi_base_url=payi_base_url) + "/api/v1/proxy/google.vertex"
|