hiddenlayer-sdk 3.5.0__tar.gz → 3.6.0__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.
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/.gitignore +1 -0
- hiddenlayer_sdk-3.6.0/.release-please-manifest.json +3 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/CHANGELOG.md +57 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/PKG-INFO +9 -2
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/README.md +7 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/api.md +7 -7
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/pyproject.toml +3 -2
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/__init__.py +10 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_base_client.py +4 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_client.py +19 -3
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_compat.py +9 -2
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_qs.py +4 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/__init__.py +1 -0
- hiddenlayer_sdk-3.6.0/src/hiddenlayer/_utils/_path.py +127 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_utils.py +3 -2
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_version.py +1 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/__init__.py +4 -0
- hiddenlayer_sdk-3.6.0/src/hiddenlayer/lib/_beta.py +45 -0
- hiddenlayer_sdk-3.6.0/src/hiddenlayer/lib/_beta_endpoints.py +11 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/community_scan.py +11 -4
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/model_scan.py +10 -3
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/scan_utils.py +20 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/evaluations/red_team.py +53 -19
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/models/models.py +5 -4
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/jobs.py +3 -5
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/results.py +3 -2
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/upload/file.py +5 -5
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/upload/upload.py +3 -3
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/sensors.py +7 -7
- hiddenlayer_sdk-3.6.0/src/hiddenlayer/types/evaluations/red_team_retrieve_evaluation_results_response.py +48 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_retrieve_status_response.py +0 -6
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/interaction_analyze_params.py +3 -6
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/job_list_response.py +1 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/job_request_params.py +1 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/scan_job.py +1 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/scan_report.py +1 -1
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/conftest.py +21 -1
- hiddenlayer_sdk-3.6.0/tests/test_beta.py +62 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_client.py +48 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_extract_files.py +9 -0
- hiddenlayer_sdk-3.6.0/tests/test_utils/test_path.py +89 -0
- hiddenlayer_sdk-3.5.0/.release-please-manifest.json +0 -3
- hiddenlayer_sdk-3.5.0/src/hiddenlayer/types/evaluations/red_team_retrieve_evaluation_results_response.py +0 -20
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/CODE_OF_CONDUCT.md +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/CONTRIBUTING.md +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/LICENSE +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/SECURITY.md +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/bin/check-release-environment +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/bin/publish-jfrog +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/bin/publish-pypi +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/examples/.keep +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/examples/demo.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/noxfile.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/release-please-config.json +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/requirements-dev.lock +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/requirements.lock +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_constants.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_exceptions.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_files.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_models.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_oauth2.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_resource.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_streaming.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_types.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_compat.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_datetime_parse.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_json.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_logs.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_proxy.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_reflection.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_resources_proxy.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_streams.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_sync.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_transform.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/_utils/_typing.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/.keep +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/evaluation_sessions.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/red_team_exceptions.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/lib/red_team_session.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/pagination.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/py.typed +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/evaluations/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/evaluations/evaluations.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/interactions.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/models/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/models/cards.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/prompt_analyzer.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/scans.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/resources/scans/upload/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_create_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_create_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_retrieve_next_action_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_submit_target_response_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/evaluations/red_team_submit_target_response_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/interaction_analyze_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/model_retrieve_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/models/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/models/card_list_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/models/card_list_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/prompt_analyzer_create_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/prompt_analyzer_create_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/job_list_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/job_retrieve_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/result_sarif_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload/file_add_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload/file_complete_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload_complete_all_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload_start_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/scans/upload_start_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_create_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_create_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_query_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_query_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_retrieve_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_update_params.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/src/hiddenlayer/types/sensor_update_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/evaluations/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/evaluations/test_red_team.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/models/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/models/test_cards.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/test_jobs.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/test_results.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/test_upload.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/upload/__init__.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/scans/upload/test_file.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/test_interactions.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/test_models.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/test_prompt_analyzer.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/api_resources/test_sensors.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/sample_file.txt +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_community_scan.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_deepcopy.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_files.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_model_scan.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_models.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_qs.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_red_team_session.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_required_args.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_response.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_streaming.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_transform.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_utils/test_datetime_parse.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_utils/test_json.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_utils/test_proxy.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/test_utils/test_typing.py +0 -0
- {hiddenlayer_sdk-3.5.0 → hiddenlayer_sdk-3.6.0}/tests/utils.py +0 -0
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.6.0 (2026-04-14)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v3.5.0...v3.6.0](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/compare/v3.5.0...v3.6.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* add beta instability warnings for unstable SDK methods ([#186](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/issues/186)) ([e56488a](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/e56488a532201b4f6cc46c5a0be68a45614b1734))
|
|
10
|
+
* **api:** add runtime security evaluations endpoints ([2433787](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/2433787d248b222da7a077b2ef1efd54f5116f7e))
|
|
11
|
+
* **api:** api update ([6b894b8](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/6b894b89ab4cef087e0fc7df4a62913c4b1b1710))
|
|
12
|
+
* **api:** api update ([dd91242](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/dd912420f1d2e8574454cdfa754f4817b7a2423e))
|
|
13
|
+
* **api:** api update ([825a274](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/825a2742d0b674b392e37c99be54c576ff9be34c))
|
|
14
|
+
* **api:** api update ([c43deaa](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/c43deaa74339cc7f3f70cb4b5e26c027fe975896))
|
|
15
|
+
* **api:** api update ([716c68c](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/716c68cef3e9ae8d15631d417335c3f387bedc72))
|
|
16
|
+
* **api:** api update ([98a52fa](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/98a52fad11b3e42b9b576738601743f59ad8752d))
|
|
17
|
+
* **api:** finalize runtime security endpoints ([e83726c](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/e83726c4a62ede87be9222e1f3acbbd0c27e1f99))
|
|
18
|
+
* **internal:** implement indices array format for query and form serialization ([05135c2](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/05135c262a3688319bfd7508452b1c101d9901c4))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **beta:** harden CI tests against codegen churn ([#191](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/issues/191)) ([8f85aec](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/8f85aec226a6a7278aa388d30f74d7735031b9cb))
|
|
24
|
+
* **client:** preserve hardcoded query params when merging with user params ([90ad63a](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/90ad63ae4aea92158416a5e1101a3d0496a20646))
|
|
25
|
+
* correct async method indentation in beta warning patcher ([2af3e63](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/2af3e6358565aaca1a3b3069868f2af090db7f92))
|
|
26
|
+
* **deps:** bump minimum typing-extensions version ([53b0b0e](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/53b0b0edfaf7a7dea0b097333fac0ecdc9a16bcb))
|
|
27
|
+
* ensure file data are only sent as 1 parameter ([1ea7561](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/1ea756124f32f0f49ba9d73bcdc2c4d63931c649))
|
|
28
|
+
* **pydantic:** do not pass `by_alias` unless set ([86f9db3](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/86f9db32c94ff8358bf294f14a54a460d1d7444b))
|
|
29
|
+
* sanitize endpoint path params ([ea53526](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/ea5352653b0708eaa5f495a598cdf19935d26fac))
|
|
30
|
+
* **tests:** correct setup of OAuth 2 Client Credentials tests ([b3887a1](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/b3887a1e39f05e01d5e16c768ef96ac6ca6e98ed))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Chores
|
|
34
|
+
|
|
35
|
+
* **ci:** skip lint on metadata-only changes ([803a48b](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/803a48bed50ae657bfe8efdbfce86969d57ac96d))
|
|
36
|
+
* **ci:** skip uploading artifacts on stainless-internal branches ([e901a9f](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/e901a9f5a6af3b5650d0002b9dd18b7ba954c38d))
|
|
37
|
+
* **deps:** bump actions/setup-node from 4 to 6 ([5abc090](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/5abc090fa35bc1efd1422cd8455aa369fed72fc4))
|
|
38
|
+
* **deps:** bump github/codeql-action from 4.32.6 to 4.35.1 ([6715471](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/67154712c4497ee3d90fea9aa9632d2ad6fa763d))
|
|
39
|
+
* **deps:** bump step-security/harden-runner from 2.15.1 to 2.16.1 ([58738e5](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/58738e54c1dd7cfe4b710e0cc75a246598c6b9f7))
|
|
40
|
+
* **internal:** codegen related update ([e2b17fd](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/e2b17fd099188441b0d296a1a745a930f9953665))
|
|
41
|
+
* **internal:** tweak CI branches ([535faac](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/535faacf763992576b28266f92e226be1f07fb09))
|
|
42
|
+
* **internal:** update gitignore ([bf2dcbe](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/bf2dcbe99c112ab5869ecff719ae66c93cacfc15))
|
|
43
|
+
* patch beta warnings [skip ci] ([ff2ae92](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/ff2ae92be61ae0838e24d28632e38aa024ad28cb))
|
|
44
|
+
* regenerate beta endpoint registry [skip ci] ([5aded1f](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/5aded1f3c1b0aa3bc4ae76137faf6987a71c0db2))
|
|
45
|
+
* regenerate beta endpoint registry [skip ci] ([126b13e](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/126b13ea66294a7c1a2d31e8edfcd336552b245e))
|
|
46
|
+
* regenerate beta endpoint registry [skip ci] ([24d568e](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/24d568e9fc74b6a0c044ea9a74120e4504fe1b16))
|
|
47
|
+
* remove stale version comments from SHA-pinned actions ([#184](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/issues/184)) ([cf07e32](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/cf07e322e7b4674fe3ef622e491278b0346e5e7e))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Documentation
|
|
51
|
+
|
|
52
|
+
* **readme:** add Beta APIs section ([#185](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/issues/185)) ([b1381e3](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/b1381e389f6e7ee59ba51ff00ce84b4a43f97c35))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Refactors
|
|
56
|
+
|
|
57
|
+
* **client:** move beta warnings to _prepare_options interceptor ([#190](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/issues/190)) ([893ee22](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/893ee22fdda949ebab80d66d70b99accb79aded2))
|
|
58
|
+
* **types:** use `extra_items` from PEP 728 ([e5ee89f](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/commit/e5ee89fccbefe680538b8b3b06871dfba90d1474))
|
|
59
|
+
|
|
3
60
|
## 3.5.0 (2026-03-03)
|
|
4
61
|
|
|
5
62
|
Full Changelog: [v3.4.0...v3.5.0](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/compare/v3.4.0...v3.5.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: hiddenlayer-sdk
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.0
|
|
4
4
|
Summary: The official Python library for the hiddenlayer API
|
|
5
5
|
Project-URL: Homepage, https://github.com/hiddenlayerai/hiddenlayer-sdk-python
|
|
6
6
|
Project-URL: Repository, https://github.com/hiddenlayerai/hiddenlayer-sdk-python
|
|
@@ -30,7 +30,7 @@ Requires-Dist: requests-auth>=8.0.0
|
|
|
30
30
|
Requires-Dist: requests>=2.32.4
|
|
31
31
|
Requires-Dist: sniffio
|
|
32
32
|
Requires-Dist: types-requests>=2.32.0.20241016
|
|
33
|
-
Requires-Dist: typing-extensions<5,>=4.
|
|
33
|
+
Requires-Dist: typing-extensions<5,>=4.14
|
|
34
34
|
Provides-Extra: aiohttp
|
|
35
35
|
Requires-Dist: aiohttp; extra == 'aiohttp'
|
|
36
36
|
Requires-Dist: httpx-aiohttp>=0.1.9; extra == 'aiohttp'
|
|
@@ -51,6 +51,13 @@ It is generated with [Stainless](https://www.stainless.com/).
|
|
|
51
51
|
|
|
52
52
|
The REST API documentation can be found on [dev.hiddenlayer.ai](https://dev.hiddenlayer.ai). The full API of this library can be found in [api.md](https://github.com/hiddenlayerai/hiddenlayer-sdk-python/tree/main/api.md).
|
|
53
53
|
|
|
54
|
+
## Beta APIs
|
|
55
|
+
|
|
56
|
+
Some HiddenLayer APIs are marked as **Beta**, meaning they are not yet generally available (GA) or production ready. Beta APIs can be used in a production environment, but at your own risk and discretion. For full details, see the [Beta API Guidelines](https://dev.hiddenlayer.ai/docs/beta-api-faq) on the developer portal.
|
|
57
|
+
|
|
58
|
+
- HiddenLayer does not provide compatibility guarantees for Beta APIs. Breaking changes may occur at any time.
|
|
59
|
+
- SDK functions and types associated with Beta APIs are excluded when determining semver release versions.
|
|
60
|
+
|
|
54
61
|
## Installation
|
|
55
62
|
|
|
56
63
|
```sh
|
|
@@ -13,6 +13,13 @@ It is generated with [Stainless](https://www.stainless.com/).
|
|
|
13
13
|
|
|
14
14
|
The REST API documentation can be found on [dev.hiddenlayer.ai](https://dev.hiddenlayer.ai). The full API of this library can be found in [api.md](api.md).
|
|
15
15
|
|
|
16
|
+
## Beta APIs
|
|
17
|
+
|
|
18
|
+
Some HiddenLayer APIs are marked as **Beta**, meaning they are not yet generally available (GA) or production ready. Beta APIs can be used in a production environment, but at your own risk and discretion. For full details, see the [Beta API Guidelines](https://dev.hiddenlayer.ai/docs/beta-api-faq) on the developer portal.
|
|
19
|
+
|
|
20
|
+
- HiddenLayer does not provide compatibility guarantees for Beta APIs. Breaking changes may occur at any time.
|
|
21
|
+
- SDK functions and types associated with Beta APIs are excluded when determining semver release versions.
|
|
22
|
+
|
|
16
23
|
## Installation
|
|
17
24
|
|
|
18
25
|
```sh
|
|
@@ -43,19 +43,19 @@ from hiddenlayer.types.evaluations import (
|
|
|
43
43
|
|
|
44
44
|
Methods:
|
|
45
45
|
|
|
46
|
-
- <code title="post /evaluations/v1
|
|
47
|
-
- <code title="get /evaluations/v1
|
|
48
|
-
- <code title="get /evaluations/v1
|
|
49
|
-
- <code title="get /evaluations/v1
|
|
50
|
-
- <code title="post /evaluations/v1
|
|
51
|
-
- <code title="post /evaluations/v1
|
|
46
|
+
- <code title="post /evaluations/v1/red-team">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">create</a>(\*\*<a href="src/hiddenlayer/types/evaluations/red_team_create_params.py">params</a>) -> <a href="./src/hiddenlayer/types/evaluations/red_team_create_response.py">RedTeamCreateResponse</a></code>
|
|
47
|
+
- <code title="get /evaluations/v1/red-team/{workflow_id}">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">retrieve_evaluation_results</a>(workflow_id) -> <a href="./src/hiddenlayer/types/evaluations/red_team_retrieve_evaluation_results_response.py">RedTeamRetrieveEvaluationResultsResponse</a></code>
|
|
48
|
+
- <code title="get /evaluations/v1/red-team/{workflow_id}/next-action">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">retrieve_next_action</a>(workflow_id) -> <a href="./src/hiddenlayer/types/evaluations/red_team_retrieve_next_action_response.py">RedTeamRetrieveNextActionResponse</a></code>
|
|
49
|
+
- <code title="get /evaluations/v1/red-team/{workflow_id}/status">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">retrieve_status</a>(workflow_id) -> <a href="./src/hiddenlayer/types/evaluations/red_team_retrieve_status_response.py">RedTeamRetrieveStatusResponse</a></code>
|
|
50
|
+
- <code title="post /evaluations/v1/red-team/{workflow_id}/target-response">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">submit_target_response</a>(workflow_id, \*\*<a href="src/hiddenlayer/types/evaluations/red_team_submit_target_response_params.py">params</a>) -> <a href="./src/hiddenlayer/types/evaluations/red_team_submit_target_response_response.py">RedTeamSubmitTargetResponseResponse</a></code>
|
|
51
|
+
- <code title="post /evaluations/v1/jobs/{workflow_id}/termination">client.evaluations.red_team.<a href="./src/hiddenlayer/resources/evaluations/red_team.py">terminate</a>(workflow_id) -> None</code>
|
|
52
52
|
|
|
53
53
|
# PromptAnalyzer
|
|
54
54
|
|
|
55
55
|
Types:
|
|
56
56
|
|
|
57
57
|
```python
|
|
58
|
-
from hiddenlayer.types import PromptAnalyzerCreateResponse
|
|
58
|
+
from hiddenlayer.types import PromptAnalyzerCreateResponse
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Methods:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hiddenlayer-sdk"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.6.0"
|
|
4
4
|
description = "The official Python library for the hiddenlayer API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = {text = "Apache-2.0"}
|
|
@@ -11,7 +11,7 @@ authors = [
|
|
|
11
11
|
dependencies = [
|
|
12
12
|
"httpx>=0.23.0, <1",
|
|
13
13
|
"pydantic>=1.9.0, <3",
|
|
14
|
-
"typing-extensions>=4.
|
|
14
|
+
"typing-extensions>=4.14, <5",
|
|
15
15
|
"anyio>=3.5.0, <5",
|
|
16
16
|
"distro>=1.7.0, <2",
|
|
17
17
|
"sniffio",
|
|
@@ -140,6 +140,7 @@ xfail_strict = true
|
|
|
140
140
|
asyncio_mode = "auto"
|
|
141
141
|
asyncio_default_fixture_loop_scope = "session"
|
|
142
142
|
filterwarnings = [
|
|
143
|
+
"default::hiddenlayer.lib._beta.BetaWarning",
|
|
143
144
|
"error"
|
|
144
145
|
]
|
|
145
146
|
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
import typing as _t
|
|
4
4
|
|
|
5
5
|
from . import types
|
|
6
|
-
from .lib import
|
|
6
|
+
from .lib import (
|
|
7
|
+
BetaWarning,
|
|
8
|
+
ModelScanner,
|
|
9
|
+
CommunityScanner,
|
|
10
|
+
AsyncModelScanner,
|
|
11
|
+
AsyncCommunityScanner,
|
|
12
|
+
warn_beta,
|
|
13
|
+
)
|
|
7
14
|
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given
|
|
8
15
|
from ._utils import file_from_path
|
|
9
16
|
from ._client import (
|
|
@@ -46,6 +53,8 @@ __all__ = [
|
|
|
46
53
|
"__version__",
|
|
47
54
|
"__title__",
|
|
48
55
|
"NoneType",
|
|
56
|
+
"BetaWarning",
|
|
57
|
+
"warn_beta",
|
|
49
58
|
"CommunityScanner",
|
|
50
59
|
"AsyncCommunityScanner",
|
|
51
60
|
"ModelScanner",
|
|
@@ -540,6 +540,10 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
540
540
|
files = cast(HttpxRequestFiles, ForceMultipartDict())
|
|
541
541
|
|
|
542
542
|
prepared_url = self._prepare_url(options.url)
|
|
543
|
+
# preserve hard-coded query params from the url
|
|
544
|
+
if params and prepared_url.query:
|
|
545
|
+
params = {**dict(prepared_url.params.items()), **params}
|
|
546
|
+
prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0])
|
|
543
547
|
if "_" in prepared_url.host:
|
|
544
548
|
# work around https://github.com/encode/httpx/discussions/2880
|
|
545
549
|
kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")}
|
|
@@ -21,6 +21,7 @@ from ._types import (
|
|
|
21
21
|
)
|
|
22
22
|
from ._utils import is_given, get_async_library
|
|
23
23
|
from ._compat import cached_property
|
|
24
|
+
from ._models import FinalRequestOptions
|
|
24
25
|
from ._oauth2 import OAuth2ClientCredentials, make_oauth2
|
|
25
26
|
from ._version import __version__
|
|
26
27
|
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
|
|
@@ -33,16 +34,18 @@ from ._base_client import (
|
|
|
33
34
|
|
|
34
35
|
if TYPE_CHECKING:
|
|
35
36
|
from .resources import scans, models, sensors, evaluations, interactions, prompt_analyzer
|
|
36
|
-
from .lib.model_scan import ModelScanner, AsyncModelScanner
|
|
37
37
|
from .resources.sensors import SensorsResource, AsyncSensorsResource
|
|
38
|
-
from .lib.community_scan import CommunityScanner, AsyncCommunityScanner
|
|
39
38
|
from .resources.scans.scans import ScansResource, AsyncScansResource
|
|
40
39
|
from .resources.interactions import InteractionsResource, AsyncInteractionsResource
|
|
41
|
-
from .lib.evaluation_sessions import EvaluationSessionsResource, AsyncEvaluationSessionsResource
|
|
42
40
|
from .resources.models.models import ModelsResource, AsyncModelsResource
|
|
43
41
|
from .resources.prompt_analyzer import PromptAnalyzerResource, AsyncPromptAnalyzerResource
|
|
44
42
|
from .resources.evaluations.evaluations import EvaluationsResource, AsyncEvaluationsResource
|
|
45
43
|
|
|
44
|
+
if TYPE_CHECKING:
|
|
45
|
+
from .lib.model_scan import ModelScanner, AsyncModelScanner
|
|
46
|
+
from .lib.community_scan import CommunityScanner, AsyncCommunityScanner
|
|
47
|
+
from .lib.evaluation_sessions import EvaluationSessionsResource, AsyncEvaluationSessionsResource
|
|
48
|
+
|
|
46
49
|
__all__ = [
|
|
47
50
|
"ENVIRONMENTS",
|
|
48
51
|
"Timeout",
|
|
@@ -256,6 +259,12 @@ class HiddenLayer(SyncAPIClient):
|
|
|
256
259
|
return True
|
|
257
260
|
return super()._should_retry(response)
|
|
258
261
|
|
|
262
|
+
@override
|
|
263
|
+
def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
|
|
264
|
+
from .lib._beta import check_beta_endpoint
|
|
265
|
+
|
|
266
|
+
check_beta_endpoint(options.url)
|
|
267
|
+
return options
|
|
259
268
|
|
|
260
269
|
def copy(
|
|
261
270
|
self,
|
|
@@ -543,6 +552,13 @@ class AsyncHiddenLayer(AsyncAPIClient):
|
|
|
543
552
|
return True
|
|
544
553
|
return super()._should_retry(response)
|
|
545
554
|
|
|
555
|
+
@override
|
|
556
|
+
async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
|
|
557
|
+
from .lib._beta import check_beta_endpoint
|
|
558
|
+
|
|
559
|
+
check_beta_endpoint(options.url)
|
|
560
|
+
return options
|
|
561
|
+
|
|
546
562
|
def copy(
|
|
547
563
|
self,
|
|
548
564
|
*,
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Union, Generic, TypeVar, Callable, cast, overload
|
|
4
4
|
from datetime import date, datetime
|
|
5
|
-
from typing_extensions import Self, Literal
|
|
5
|
+
from typing_extensions import Self, Literal, TypedDict
|
|
6
6
|
|
|
7
7
|
import pydantic
|
|
8
8
|
from pydantic.fields import FieldInfo
|
|
@@ -131,6 +131,10 @@ def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str:
|
|
|
131
131
|
return model.model_dump_json(indent=indent)
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
class _ModelDumpKwargs(TypedDict, total=False):
|
|
135
|
+
by_alias: bool
|
|
136
|
+
|
|
137
|
+
|
|
134
138
|
def model_dump(
|
|
135
139
|
model: pydantic.BaseModel,
|
|
136
140
|
*,
|
|
@@ -142,6 +146,9 @@ def model_dump(
|
|
|
142
146
|
by_alias: bool | None = None,
|
|
143
147
|
) -> dict[str, Any]:
|
|
144
148
|
if (not PYDANTIC_V1) or hasattr(model, "model_dump"):
|
|
149
|
+
kwargs: _ModelDumpKwargs = {}
|
|
150
|
+
if by_alias is not None:
|
|
151
|
+
kwargs["by_alias"] = by_alias
|
|
145
152
|
return model.model_dump(
|
|
146
153
|
mode=mode,
|
|
147
154
|
exclude=exclude,
|
|
@@ -149,7 +156,7 @@ def model_dump(
|
|
|
149
156
|
exclude_defaults=exclude_defaults,
|
|
150
157
|
# warnings are not supported in Pydantic v1
|
|
151
158
|
warnings=True if PYDANTIC_V1 else warnings,
|
|
152
|
-
|
|
159
|
+
**kwargs,
|
|
153
160
|
)
|
|
154
161
|
return cast(
|
|
155
162
|
"dict[str, Any]",
|
|
@@ -101,7 +101,10 @@ class Querystring:
|
|
|
101
101
|
items.extend(self._stringify_item(key, item, opts))
|
|
102
102
|
return items
|
|
103
103
|
elif array_format == "indices":
|
|
104
|
-
|
|
104
|
+
items = []
|
|
105
|
+
for i, item in enumerate(value):
|
|
106
|
+
items.extend(self._stringify_item(f"{key}[{i}]", item, opts))
|
|
107
|
+
return items
|
|
105
108
|
elif array_format == "brackets":
|
|
106
109
|
items = []
|
|
107
110
|
key = key + "[]"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Mapping,
|
|
7
|
+
Callable,
|
|
8
|
+
)
|
|
9
|
+
from urllib.parse import quote
|
|
10
|
+
|
|
11
|
+
# Matches '.' or '..' where each dot is either literal or percent-encoded (%2e / %2E).
|
|
12
|
+
_DOT_SEGMENT_RE = re.compile(r"^(?:\.|%2[eE]){1,2}$")
|
|
13
|
+
|
|
14
|
+
_PLACEHOLDER_RE = re.compile(r"\{(\w+)\}")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _quote_path_segment_part(value: str) -> str:
|
|
18
|
+
"""Percent-encode `value` for use in a URI path segment.
|
|
19
|
+
|
|
20
|
+
Considers characters not in `pchar` set from RFC 3986 §3.3 to be unsafe.
|
|
21
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
|
|
22
|
+
"""
|
|
23
|
+
# quote() already treats unreserved characters (letters, digits, and -._~)
|
|
24
|
+
# as safe, so we only need to add sub-delims, ':', and '@'.
|
|
25
|
+
# Notably, unlike the default `safe` for quote(), / is unsafe and must be quoted.
|
|
26
|
+
return quote(value, safe="!$&'()*+,;=:@")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _quote_query_part(value: str) -> str:
|
|
30
|
+
"""Percent-encode `value` for use in a URI query string.
|
|
31
|
+
|
|
32
|
+
Considers &, = and characters not in `query` set from RFC 3986 §3.4 to be unsafe.
|
|
33
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.4
|
|
34
|
+
"""
|
|
35
|
+
return quote(value, safe="!$'()*+,;:@/?")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _quote_fragment_part(value: str) -> str:
|
|
39
|
+
"""Percent-encode `value` for use in a URI fragment.
|
|
40
|
+
|
|
41
|
+
Considers characters not in `fragment` set from RFC 3986 §3.5 to be unsafe.
|
|
42
|
+
https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
|
|
43
|
+
"""
|
|
44
|
+
return quote(value, safe="!$&'()*+,;=:@/?")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _interpolate(
|
|
48
|
+
template: str,
|
|
49
|
+
values: Mapping[str, Any],
|
|
50
|
+
quoter: Callable[[str], str],
|
|
51
|
+
) -> str:
|
|
52
|
+
"""Replace {name} placeholders in `template`, quoting each value with `quoter`.
|
|
53
|
+
|
|
54
|
+
Placeholder names are looked up in `values`.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
KeyError: If a placeholder is not found in `values`.
|
|
58
|
+
"""
|
|
59
|
+
# re.split with a capturing group returns alternating
|
|
60
|
+
# [text, name, text, name, ..., text] elements.
|
|
61
|
+
parts = _PLACEHOLDER_RE.split(template)
|
|
62
|
+
|
|
63
|
+
for i in range(1, len(parts), 2):
|
|
64
|
+
name = parts[i]
|
|
65
|
+
if name not in values:
|
|
66
|
+
raise KeyError(f"a value for placeholder {{{name}}} was not provided")
|
|
67
|
+
val = values[name]
|
|
68
|
+
if val is None:
|
|
69
|
+
parts[i] = "null"
|
|
70
|
+
elif isinstance(val, bool):
|
|
71
|
+
parts[i] = "true" if val else "false"
|
|
72
|
+
else:
|
|
73
|
+
parts[i] = quoter(str(values[name]))
|
|
74
|
+
|
|
75
|
+
return "".join(parts)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def path_template(template: str, /, **kwargs: Any) -> str:
|
|
79
|
+
"""Interpolate {name} placeholders in `template` from keyword arguments.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
template: The template string containing {name} placeholders.
|
|
83
|
+
**kwargs: Keyword arguments to interpolate into the template.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
The template with placeholders interpolated and percent-encoded.
|
|
87
|
+
|
|
88
|
+
Safe characters for percent-encoding are dependent on the URI component.
|
|
89
|
+
Placeholders in path and fragment portions are percent-encoded where the `segment`
|
|
90
|
+
and `fragment` sets from RFC 3986 respectively are considered safe.
|
|
91
|
+
Placeholders in the query portion are percent-encoded where the `query` set from
|
|
92
|
+
RFC 3986 §3.3 is considered safe except for = and & characters.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
KeyError: If a placeholder is not found in `kwargs`.
|
|
96
|
+
ValueError: If resulting path contains /./ or /../ segments (including percent-encoded dot-segments).
|
|
97
|
+
"""
|
|
98
|
+
# Split the template into path, query, and fragment portions.
|
|
99
|
+
fragment_template: str | None = None
|
|
100
|
+
query_template: str | None = None
|
|
101
|
+
|
|
102
|
+
rest = template
|
|
103
|
+
if "#" in rest:
|
|
104
|
+
rest, fragment_template = rest.split("#", 1)
|
|
105
|
+
if "?" in rest:
|
|
106
|
+
rest, query_template = rest.split("?", 1)
|
|
107
|
+
path_template = rest
|
|
108
|
+
|
|
109
|
+
# Interpolate each portion with the appropriate quoting rules.
|
|
110
|
+
path_result = _interpolate(path_template, kwargs, _quote_path_segment_part)
|
|
111
|
+
|
|
112
|
+
# Reject dot-segments (. and ..) in the final assembled path. The check
|
|
113
|
+
# runs after interpolation so that adjacent placeholders or a mix of static
|
|
114
|
+
# text and placeholders that together form a dot-segment are caught.
|
|
115
|
+
# Also reject percent-encoded dot-segments to protect against incorrectly
|
|
116
|
+
# implemented normalization in servers/proxies.
|
|
117
|
+
for segment in path_result.split("/"):
|
|
118
|
+
if _DOT_SEGMENT_RE.match(segment):
|
|
119
|
+
raise ValueError(f"Constructed path {path_result!r} contains dot-segment {segment!r} which is not allowed")
|
|
120
|
+
|
|
121
|
+
result = path_result
|
|
122
|
+
if query_template is not None:
|
|
123
|
+
result += "?" + _interpolate(query_template, kwargs, _quote_query_part)
|
|
124
|
+
if fragment_template is not None:
|
|
125
|
+
result += "#" + _interpolate(fragment_template, kwargs, _quote_fragment_part)
|
|
126
|
+
|
|
127
|
+
return result
|
|
@@ -86,8 +86,9 @@ def _extract_items(
|
|
|
86
86
|
index += 1
|
|
87
87
|
if is_dict(obj):
|
|
88
88
|
try:
|
|
89
|
-
#
|
|
90
|
-
|
|
89
|
+
# Remove the field if there are no more dict keys in the path,
|
|
90
|
+
# only "<array>" traversal markers or end.
|
|
91
|
+
if all(p == "<array>" for p in path[index:]):
|
|
91
92
|
item = obj.pop(key)
|
|
92
93
|
else:
|
|
93
94
|
item = obj[key]
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# Custom extensions for HiddenLayer SDK
|
|
2
|
+
from ._beta import BetaWarning, warn_beta, check_beta_endpoint
|
|
2
3
|
from .model_scan import ModelScanner, AsyncModelScanner
|
|
3
4
|
from .community_scan import CommunityScanner, CommunityScanSource, AsyncCommunityScanner
|
|
4
5
|
from .evaluation_sessions import EvaluationSessionsResource, AsyncEvaluationSessionsResource
|
|
5
6
|
|
|
6
7
|
__all__ = [
|
|
8
|
+
"BetaWarning",
|
|
9
|
+
"warn_beta",
|
|
10
|
+
"check_beta_endpoint",
|
|
7
11
|
"CommunityScanner",
|
|
8
12
|
"AsyncCommunityScanner",
|
|
9
13
|
"ModelScanner",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Runtime beta warning utility.
|
|
2
|
+
|
|
3
|
+
Emits a warning when a beta endpoint is called, so SDK consumers know
|
|
4
|
+
the method is not yet GA.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BetaWarning(UserWarning):
|
|
13
|
+
"""Warning emitted when a beta API endpoint is called."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def warn_beta(qualified_name: str, *, stacklevel: int = 3) -> None:
|
|
17
|
+
"""Emit a warning that a beta endpoint was called.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
qualified_name: Fully qualified method name, e.g. "InteractionsResource.analyze"
|
|
21
|
+
stacklevel: How many frames to skip when reporting the warning location.
|
|
22
|
+
"""
|
|
23
|
+
warnings.warn(
|
|
24
|
+
f"[BETA] {qualified_name}: This endpoint is not GA or Production ready "
|
|
25
|
+
"and is subject to changes at any time. Breaking changes may occur.",
|
|
26
|
+
BetaWarning,
|
|
27
|
+
stacklevel=stacklevel,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def check_beta_endpoint(url: str) -> None:
|
|
32
|
+
"""Check whether *url* is a beta endpoint and emit a warning if so.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
url: The URL path for the request (e.g. "/detection/v2/request-evaluations").
|
|
36
|
+
"""
|
|
37
|
+
from ._beta_endpoints import BETA_ENDPOINTS
|
|
38
|
+
|
|
39
|
+
qualified_name = BETA_ENDPOINTS.get(url)
|
|
40
|
+
if qualified_name is not None:
|
|
41
|
+
# Called from _prepare_options, which is deeper in the stack than
|
|
42
|
+
# a direct warn_beta call from a resource method. The higher
|
|
43
|
+
# stacklevel won't point at user code, but the message itself
|
|
44
|
+
# identifies the method.
|
|
45
|
+
warn_beta(qualified_name, stacklevel=4)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Auto-generated registry of beta endpoints.
|
|
2
|
+
|
|
3
|
+
DO NOT EDIT -- regenerated by scripts/utils/generate-beta-endpoints.cjs
|
|
4
|
+
|
|
5
|
+
Maps URL paths to qualified method names for runtime warnings.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
BETA_ENDPOINTS: dict[str, str] = {
|
|
10
|
+
"/evaluations/v1/red-team": "RedTeamResource.create",
|
|
11
|
+
}
|
|
@@ -9,7 +9,14 @@ import logging
|
|
|
9
9
|
from typing import Union, Literal, cast
|
|
10
10
|
from typing_extensions import TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
from .scan_utils import
|
|
12
|
+
from .scan_utils import (
|
|
13
|
+
ScanResultMixin,
|
|
14
|
+
AsyncScanResultMixin,
|
|
15
|
+
get_scan_results,
|
|
16
|
+
wait_for_scan_results,
|
|
17
|
+
get_scan_results_async,
|
|
18
|
+
wait_for_scan_results_async,
|
|
19
|
+
)
|
|
13
20
|
|
|
14
21
|
logger = logging.getLogger(__name__)
|
|
15
22
|
|
|
@@ -31,7 +38,7 @@ class CommunityScanSource:
|
|
|
31
38
|
HUGGING_FACE = "HUGGING_FACE"
|
|
32
39
|
|
|
33
40
|
|
|
34
|
-
class CommunityScanner:
|
|
41
|
+
class CommunityScanner(ScanResultMixin):
|
|
35
42
|
"""
|
|
36
43
|
Community scanner that provides the community_scan method with polling functionality.
|
|
37
44
|
|
|
@@ -108,7 +115,7 @@ class CommunityScanner:
|
|
|
108
115
|
return get_scan_results(self._client, scan_id=scan_id)
|
|
109
116
|
|
|
110
117
|
|
|
111
|
-
class AsyncCommunityScanner:
|
|
118
|
+
class AsyncCommunityScanner(AsyncScanResultMixin):
|
|
112
119
|
"""
|
|
113
120
|
Async version of CommunityScanner for use with AsyncHiddenLayer client.
|
|
114
121
|
"""
|
|
@@ -171,4 +178,4 @@ class AsyncCommunityScanner:
|
|
|
171
178
|
return await wait_for_scan_results_async(self._client, scan_id=scan_id)
|
|
172
179
|
else:
|
|
173
180
|
# Return current scan status without waiting
|
|
174
|
-
return await get_scan_results_async(self._client, scan_id=scan_id)
|
|
181
|
+
return await get_scan_results_async(self._client, scan_id=scan_id)
|
|
@@ -12,7 +12,14 @@ from fnmatch import fnmatch
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing_extensions import TYPE_CHECKING
|
|
14
14
|
|
|
15
|
-
from .scan_utils import
|
|
15
|
+
from .scan_utils import (
|
|
16
|
+
ScanResultMixin,
|
|
17
|
+
AsyncScanResultMixin,
|
|
18
|
+
get_scan_results,
|
|
19
|
+
wait_for_scan_results,
|
|
20
|
+
get_scan_results_async,
|
|
21
|
+
wait_for_scan_results_async,
|
|
22
|
+
)
|
|
16
23
|
from .._exceptions import BadRequestError
|
|
17
24
|
|
|
18
25
|
logger = logging.getLogger(__name__)
|
|
@@ -114,7 +121,7 @@ def filter_path_objects(
|
|
|
114
121
|
|
|
115
122
|
yield item
|
|
116
123
|
|
|
117
|
-
class ModelScanner:
|
|
124
|
+
class ModelScanner(ScanResultMixin):
|
|
118
125
|
"""
|
|
119
126
|
Model scanner that provides file and folder scanning functionality.
|
|
120
127
|
|
|
@@ -483,7 +490,7 @@ class ModelScanner:
|
|
|
483
490
|
self._client.scans.upload.file.complete(file_id=upload.upload_id, scan_id=scan_id)
|
|
484
491
|
|
|
485
492
|
|
|
486
|
-
class AsyncModelScanner:
|
|
493
|
+
class AsyncModelScanner(AsyncScanResultMixin):
|
|
487
494
|
"""
|
|
488
495
|
Async version of ModelScanner for use with AsyncHiddenLayer client.
|
|
489
496
|
"""
|