From 2619285a439f62332f5cd742d8978d30f7f1edfd Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:00:34 +0000 Subject: [PATCH 1/9] SDK regeneration --- .fern/metadata.json | 2 +- README.md | 52 +- poetry.lock | 716 +++++++++--------- reference.md | 263 +------ src/truefoundry_sdk/__init__.py | 24 +- .../agent_skill_versions/client.py | 10 - src/truefoundry_sdk/agent_skills/client.py | 8 - src/truefoundry_sdk/agent_versions/client.py | 2 - src/truefoundry_sdk/agents/__init__.py | 6 +- src/truefoundry_sdk/agents/client.py | 28 +- src/truefoundry_sdk/agents/raw_client.py | 18 +- src/truefoundry_sdk/agents/types/__init__.py | 6 +- ...st_type.py => list_agents_request_type.py} | 12 +- src/truefoundry_sdk/alerts/client.py | 20 +- src/truefoundry_sdk/applications/__init__.py | 18 +- src/truefoundry_sdk/applications/client.py | 72 +- .../applications/raw_client.py | 38 +- .../applications/types/__init__.py | 18 +- ...ancel_deployment_applications_response.py} | 2 +- ...pplications_request_device_type_filter.py} | 18 +- ...t_applications_request_lifecycle_stage.py} | 12 +- .../artifact_versions/client.py | 34 +- .../artifact_versions/raw_client.py | 16 +- src/truefoundry_sdk/artifacts/client.py | 10 - src/truefoundry_sdk/clusters/client.py | 20 +- src/truefoundry_sdk/clusters/raw_client.py | 16 +- .../data_directories/client.py | 8 - src/truefoundry_sdk/events/client.py | 26 +- src/truefoundry_sdk/events/raw_client.py | 8 +- src/truefoundry_sdk/internal/__init__.py | 18 +- .../internal/ai_gateway/__init__.py | 6 +- .../internal/ai_gateway/client.py | 18 +- .../internal/ai_gateway/raw_client.py | 10 +- .../internal/ai_gateway/types/__init__.py | 6 +- ...gateway_config_ai_gateway_request_type.py} | 28 +- .../internal/applications/client.py | 4 - .../internal/artifact_versions/client.py | 38 +- .../internal/artifact_versions/raw_client.py | 16 +- .../internal/build_logs/client.py | 6 - .../internal/deployments/client.py | 6 - .../internal/docker_registries/client.py | 10 +- .../internal/metrics/__init__.py | 6 +- .../internal/metrics/client.py | 22 +- .../internal/metrics/raw_client.py | 10 +- .../internal/metrics/types/__init__.py | 6 +- ...t_charts_metrics_request_filter_entity.py} | 16 +- .../internal/workflows/__init__.py | 6 +- .../internal/workflows/client.py | 10 +- .../internal/workflows/raw_client.py | 18 +- .../internal/workflows/types/__init__.py | 6 +- ...=> execute_workflow_workflows_response.py} | 2 +- src/truefoundry_sdk/jobs/client.py | 42 +- src/truefoundry_sdk/jobs/raw_client.py | 24 +- src/truefoundry_sdk/logs/client.py | 50 +- src/truefoundry_sdk/logs/raw_client.py | 8 +- src/truefoundry_sdk/ml_repos/client.py | 12 +- src/truefoundry_sdk/ml_repos/raw_client.py | 8 +- src/truefoundry_sdk/model_versions/client.py | 34 +- .../model_versions/raw_client.py | 16 +- src/truefoundry_sdk/models/client.py | 10 - .../personal_access_tokens/client.py | 2 - src/truefoundry_sdk/prompt_versions/client.py | 12 - src/truefoundry_sdk/prompts/client.py | 8 - src/truefoundry_sdk/secret_groups/client.py | 16 +- .../secret_groups/raw_client.py | 8 +- src/truefoundry_sdk/secrets/client.py | 2 - src/truefoundry_sdk/teams/client.py | 10 +- src/truefoundry_sdk/teams/raw_client.py | 8 +- src/truefoundry_sdk/traces/raw_client.py | 8 +- src/truefoundry_sdk/users/client.py | 4 - .../virtual_accounts/client.py | 12 +- .../virtual_accounts/raw_client.py | 8 +- src/truefoundry_sdk/workspaces/client.py | 18 +- src/truefoundry_sdk/workspaces/raw_client.py | 8 +- 74 files changed, 741 insertions(+), 1338 deletions(-) rename src/truefoundry_sdk/agents/types/{agents_list_request_type.py => list_agents_request_type.py} (74%) rename src/truefoundry_sdk/applications/types/{applications_cancel_deployment_response.py => cancel_deployment_applications_response.py} (89%) rename src/truefoundry_sdk/applications/types/{applications_list_request_device_type_filter.py => list_applications_request_device_type_filter.py} (70%) rename src/truefoundry_sdk/applications/types/{applications_list_request_lifecycle_stage.py => list_applications_request_lifecycle_stage.py} (71%) rename src/truefoundry_sdk/internal/ai_gateway/types/{ai_gateway_get_gateway_config_request_type.py => get_gateway_config_ai_gateway_request_type.py} (74%) rename src/truefoundry_sdk/internal/metrics/types/{metrics_get_charts_request_filter_entity.py => get_charts_metrics_request_filter_entity.py} (69%) rename src/truefoundry_sdk/internal/workflows/types/{workflows_execute_workflow_response.py => execute_workflow_workflows_response.py} (92%) diff --git a/.fern/metadata.json b/.fern/metadata.json index aceba663..97b84166 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "32fe60c676059f66eca28ed6042c72b38db2ff04", + "originGitCommit": "68162af8093fdd989741251da8c28c5201afabec", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/README.md b/README.md index 500f32fe..222a387e 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,7 @@ A full reference for this library is available [here](https://github.com/truefou Instantiate and use the client with the following: ```python -from truefoundry_sdk import TrueFoundry, ApplicationType -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -52,21 +51,6 @@ client = TrueFoundry( client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) ``` @@ -76,7 +60,6 @@ The SDK also exports an `async` client so that you can make non-blocking calls t ```python import asyncio -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage from truefoundry_sdk import AsyncTrueFoundry @@ -90,21 +73,6 @@ async def main() -> None: await client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) @@ -131,8 +99,7 @@ except ApiError as e: Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used as generators for the underlying object. ```python -from truefoundry_sdk import TrueFoundry, ApplicationType -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -142,21 +109,6 @@ client = TrueFoundry( client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) ``` diff --git a/poetry.lock b/poetry.lock index 747617e7..6c2130d5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -15,132 +15,132 @@ files = [ [[package]] name = "aiohttp" -version = "3.14.1" +version = "3.14.3" description = "Async http client/server framework (asyncio)" optional = true python-versions = ">=3.10" groups = ["main"] markers = "extra == \"aiohttp\"" files = [ - {file = "aiohttp-3.14.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8f6bb621e5863cfe8fe5ff5468002d200ec31f30f1280b259dc505b02595099e"}, - {file = "aiohttp-3.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f7215cb3933784f79ed20e5f050e15984f390424339b22375d5a53c933a0491"}, - {file = "aiohttp-3.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9d4e294455b23a68c9b8f042d0e8e377a265bcb15332753695f6e5b6819e0ce"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b238af795833d5731d049d82bc84b768ae6f8f97f0495963b3ed9935c5901cc3"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4e5e0ae56914ecdbf446493addefc0159053dd53962cef37d7839f37f73d505"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:092e4ce3619a7c6dee52a6bdabda973d9b34b66781f840ce93c7e0cec30cf521"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb33777ea21e8b7ecde0e6fc84f598be0a1192eab1a63bc746d75aa75d38e7bd"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23119f8fd4f5d16902ed459b63b100bcd269628075162bddac56cc7b5273b3fb"}, - {file = "aiohttp-3.14.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:57fc6745a4b7d0f5a9eb4f40a69718be6c0bc1b8368cc9fe89e90118719f4f42"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6fd35beba67c4183b09375c5fff9accb47524191a244a99f95fd4472f5402c2b"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:672b9d65f42eb877f5c3f234a4547e4e1a226ca8c2eed879bb34670a0ce51192"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:24ba13339fed9251d9b1a1bec8c7ab84c0d1675d79d33501e11f94f8b9a84e05"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:94da27378da0610e341c4d30de29a191672683cc82b8f9556e8f7c7212a020fe"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:52cdac9432d8b4a719f35094a818d95adcae0f0b4fe9b9b921909e0c87de9e7d"}, - {file = "aiohttp-3.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:672ac254412a24d0d0cf00a9e6c238877e4be5e5fa2d188832c1244f45f31966"}, - {file = "aiohttp-3.14.1-cp310-cp310-win32.whl", hash = "sha256:2fe3607e71acc6ebb0ec8e492a247bf7a291226192dc0084236dfc12478916f6"}, - {file = "aiohttp-3.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:30099eda75a53c32efb0920e9c33c195314d2cc1c680fbfd30894932ac5f27df"}, - {file = "aiohttp-3.14.1-cp310-cp310-win_arm64.whl", hash = "sha256:5a837f49d901f9e368651b676912bff1104ed8c1a83b280bcd7b29adccef5c9c"}, - {file = "aiohttp-3.14.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa00140699487bd435fde4342d85c94cb256b7cd3a5b9c3396c67f19922afda2"}, - {file = "aiohttp-3.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c1af67559445498b502030c35c59db59966f47041ca9de5b4e707f86bd10b5f"}, - {file = "aiohttp-3.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d44ec478e713ee7f29b439f7eb8dc2b9d4079e11ae114d2c2ac3d5daf30516c8"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d3b1a184a9a8f548a6b73f1e26b96b052193e4b3175ed7342aaf1151a1f00a04"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5f2504bc0322437c9a1ff6d3333ca56c7477b727c995f036b976ae17b98372c8"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73f05ea02013e02512c3bf42714f1208c57168c779cc6fe23516e4543089d0a6"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:797457503c2d426bee06eef808d07b31ede30b65e054444e7de64cad0061b7af"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b821a1f7dedf7e37450654e620038ac3b2e81e8fa6ea269337e97101978ec730"}, - {file = "aiohttp-3.14.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4cd96b5ba05d67ed0cf00b5b405c8cd99586d8e3481e8ee0a831057591af7621"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d459b98a932296c6f0e94f87511a0b1b90a8a02c30a50e60a297619cd5a58ee"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:764457a7be60825fb770a644852ff717bcbb5042f189f2bd16df61a81b3f6573"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f7a16ef45b081454ef844502d87a848876c490c4cb5c650c230f6ec79ed2c1e7"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2fbc3ed048b3475b9f0cbcb9978e9d2d3511acd91ead203af26ed9f0056004cf"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bedb0cd073cc2dc035e30aeb99444389d3cd2113afe4ef9fcd23d439f5bade85"}, - {file = "aiohttp-3.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b6feea921016eb3d4e04d65fc4e9ca402d1a3801f562aef94989f54694917af3"}, - {file = "aiohttp-3.14.1-cp311-cp311-win32.whl", hash = "sha256:313701e488100074ce99850404ee36e741abf6330179fec908a1944ecf570126"}, - {file = "aiohttp-3.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:03ab4530fdcb3a543a122ba4b65ac9919da9fe9f78a03d328a6e38ff962f7aa5"}, - {file = "aiohttp-3.14.1-cp311-cp311-win_arm64.whl", hash = "sha256:486f7d16ed54c39c2cbd7ca71fd8ba2b8bb7860df65bd7b6ed640bab96a38a8b"}, - {file = "aiohttp-3.14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d35143e27778b4bb0fb189562d7f275bff79c62ab8e98459717c0ea617ff2480"}, - {file = "aiohttp-3.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bcfb80a2cc36fba2534e5e5b5264dc7ae6fcd9bf15256da3e53d2f499e6fa29d"}, - {file = "aiohttp-3.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27fd7c91e51729b4f7e1577865fa6d34c9adccbc39aabe9000285b48af9f0ec2"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c567bf9eaf664280116a8688f63016e6b32db2505908e2bdaca1b6438142f2"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f5e6ff2bdbb8f4cd3fbe41f99e25bbcd58e3bf9f13d3dd31a11e7917251cc77a"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f73e01dc37122325caf079982621262f96d74823c179038a82fddfc50359264"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb2c0c80d431c0d03f2c7dbf125150fedd4f0de17366a7ca33f7ccb822391842"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e6fc1a85fa7194a1a7d19f44e8609180f4a8eb5fa4c7ed8b4355f080fad235c"}, - {file = "aiohttp-3.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:686b6c0d3911ec387b444ddf5dc62fb7f7c0a7d5186a7861626496a5ab4aff95"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c6fa4dc7ad6f8109c70bb1499e589f76b0b792baf39f9b017eb92c8a81d0a199"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:87a5eea1b2a5e21e1ebdbb33ad4165359189327e63fc4e4894693e7f821ac817"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c1421eb01d4fd608d88cc8290211d177a58532b55ad94076fb349c5bf467f0a"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:34b257ec41345c1e8f2df68fa908a7952f5de932723871eb633ecbbff396c9a4"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de538791a80e5d862addbc183f70f0158ac9b9bb872bb147f1fd2a683691e087"}, - {file = "aiohttp-3.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f71173be42d3241d428f760122febb748de0623f44308a6f120d0dd9ec572e3"}, - {file = "aiohttp-3.14.1-cp312-cp312-win32.whl", hash = "sha256:ec8dc383ee57ea3e883477dcca3f11b65d58199f1080acaf4cd6ad9a99698be4"}, - {file = "aiohttp-3.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2aa92c87868cd13674989f9ee83e5f9f7ea4237589b728048e1f0c8f6caa3271"}, - {file = "aiohttp-3.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:2c840c90759922cb5e6dda94596e079a30fb5a5ba548e7e0dc00574703940847"}, - {file = "aiohttp-3.14.1-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:b3a03285a7f9c7b016324574a6d92a1c895da6b978cb8f1deee3ac72bc6da178"}, - {file = "aiohttp-3.14.1-cp313-cp313-android_21_x86_64.whl", hash = "sha256:2a73f487ab8ef5abbb24b7aa9b73e98eaba9e9e031804ff2416f02eca315ccaf"}, - {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:915fbb7b41b115192259f8c9ae58f3ddc444d2b5579917270211858e606a4afd"}, - {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:7fb4bdf95b0561a79f259f9d28fbc109728c5ee7f27aff6391f0ca703a329abe"}, - {file = "aiohttp-3.14.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1b9748363260121d2927704f5d4fc498150669ca3ae93625986ee89c8f80dcd4"}, - {file = "aiohttp-3.14.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:86a6dab78b0e43e2897a3bbe15745aa60dc5423ca437b7b0b164c069bf91b876"}, - {file = "aiohttp-3.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4dfd6e47d3c44c2279907607f73a4240b88c69eb8b90da7e2441a8045dfd21da"}, - {file = "aiohttp-3.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:317acd9f8602858dc7d59679812c376c7f0b97bcbbf16e0d6237f54141d8a8a6"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd869c427324e5cb15195793de951295710db28be7d818247f3097b4ab5d4b96"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93b032b5ec3255473c143627d21a69ac74ae12f7f33974cb587c564d11b1066f"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f234b4deb12f3ad59127e037bc57c40c21e45b45282df7d3a55a0f409f595296"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9af6779bfb46abf124068327abcdf9ce95c9ef8287a3e8da76ccf2d0f16c28fa"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:faccab372e66bc76d5731525e7f1143c922271725b9d38c9f97edcc66266b451"}, - {file = "aiohttp-3.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f380468b09d2a81633ee863b0ec5648d364bd17bb8ecfb8c2f387f7ac1faf42c"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:97e704dcd26271f5bda3fa07c3ce0fb76d6d3f8659f4baa1a24442cc9ba177ca"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:269b76ac5394092b95bc4a098f4fc6c191c083c3bd12775d1e30e663132f6a09"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0b3e614340c889d575451696374c9d17affd54cd607ca0babed8f8c37b9397"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5663ee9257cfa1add7253a7da3035a02f31b6600ec48261585e1800a81533080"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:603a2c834142172ffddc054067f5ec0ca65d57a0aa98a71bc81952573208e345"}, - {file = "aiohttp-3.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cb21957bb8aca671c1765e32f58164cf0c50e6bf41c0bbbd16da20732ecaf588"}, - {file = "aiohttp-3.14.1-cp313-cp313-win32.whl", hash = "sha256:e509a55f681e6158c20f70f102f9cf61fb20fbc382272bc6d94b7343f2582780"}, - {file = "aiohttp-3.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:1ac8531b638959718e18c2207fbfe297819875da46a740b29dfa29beba64355a"}, - {file = "aiohttp-3.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:250d14af67f6b6a1a4a811049b1afa69d61d617fca6bf33149b3ab1a6dbcf7b8"}, - {file = "aiohttp-3.14.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7c106c26852ca1c2047c6b80384f17100b4e439af276f21ef3d4e2f450ae7e15"}, - {file = "aiohttp-3.14.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:20205f7f5ade7aaec9f4b500549bbc071b046453aed72f9c06dcab87896a83e8"}, - {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:62a759436b29e677181a9e76bab8b8f689a29cb9c535f45f7c48c9c830d3f8c3"}, - {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:2964cbf553df4d7a57348da44d961d871895fc1ee4e8c322b2a95612c7b17fba"}, - {file = "aiohttp-3.14.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:237651caadc3a59badd39319c54642b5299e9cc98a3a194310e55d5bb9f5e397"}, - {file = "aiohttp-3.14.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:896e12dfdbbab9d8f7e16d2b28c6769a60126fa92095d1ebf9473d02593a2448"}, - {file = "aiohttp-3.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d03f281ed22579314ba00821ce20115a7c0ac430660b4cc05704a3f818b3e004"}, - {file = "aiohttp-3.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07eabb979d236335fed927e137a928c9adfb7df3b9ec7aa31726f133a62be983"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4fe1f1087cbadb280b5e1bb054a4f00d1423c74d6626c5e48400d871d34ecefe"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:367a9314fdc79dab0fac96e216cb41dd73c85bdca85306ce8999118ba7e0f333"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a24f677ebe83749039e7bdf862ff0bbb16818ae4193d4ef96505e269375bcce0"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c83afe0ba876be7e943d2e0ba645809ad441575d2840c895c21ee5de93b9377a"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:634e385930fb6d2d479cf3aa66515955863b77a5e3c2b5894ca259a25b308602"}, - {file = "aiohttp-3.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeea07c4397bbc57719c4eed8f9c284874d4f175f9b6d57f7a1546b976d455ca"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:335c0cc3e3545ce98dcb9cfcb836f40c3411f43fa03dab757597d80c89af8a35"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:ae6be797afdef264e8a84864a85b196ca06045586481b3df8a967322fd2fa844"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:8560b4d712474335d08907db7973f71912d3a9a8f1dee992ec06b5d2fe359496"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7edd08e0a5deb1e8564a2fcd8f4561014a3f05252334671bbf55ddd47db0e5"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:b6ff7fcee63287ae57b5df3e4f5957ce032122802509246dec1a5bcc55904c95"}, - {file = "aiohttp-3.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6ffbb2f4ec1ceaff7e07d43922954da26b223d188bf30658e561b98e23089444"}, - {file = "aiohttp-3.14.1-cp314-cp314-win32.whl", hash = "sha256:a9875b46d910cff3ea2f5962f9d266b465459fe634e22556ab9bd6fc1192eea0"}, - {file = "aiohttp-3.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:af8b4b81a960eeaf1234971ac3cd0ba5901f3cd42eae42a46b4d089a8b492719"}, - {file = "aiohttp-3.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:cf4491381b1b57425c315a56a439251b1bdac07b2275f19a8c44bc57744532ec"}, - {file = "aiohttp-3.14.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:819c054312f1af92947e6a55883d1b66feefab11531a7fc45e0fb9b63880b5c2"}, - {file = "aiohttp-3.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10ee9c1753a8f706345b22496c79fbddb5be0599e0823f3738b1534058e25340"}, - {file = "aiohttp-3.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1601cc37baf5750ccacae618ec2daf020769581695550e3b654a911f859c563d"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d6e0ac9da31c9c04c84e1c0182ad8d6df35965a85cae29cd71d089621b3ae94"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e8f2d660c350b3d0e259c7a7e3d9b7fc8b41210cbcc3d4a7076ff0a5e5c2fdc"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4691802dda97be727f79d86818acaad7eb8e9252626a1d6b519fedbb92d5e251"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c389c482a7e9b9dc3ee2701ac46c4125297a3818875b9c305ddb603c04828fd1"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fc0cacab7ba4e56f0f81c82a98c09bed2f39c940107b03a34b168bdf7597edd3"}, - {file = "aiohttp-3.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:979ed4717f59b8bb12e3963378fa285d93d367e15bcd66c721311826d3c44a6c"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:38e1e7daaea81df51c952e18483f323d878499a1e2bfe564790e0f9701d6f203"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:4132e72c608fe9fecb8f409113567605915b83e9bdd3ea56538d2f9cd35002f1"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:eefd9cc9b6d4a2db5f00a26bc3e4f9acf71926a6ec557cd56c9c6f27c290b665"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b165790117eea512d7f3fb22f1f6dad3d55a7189571993eb015591c1401276d1"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:ed09c7eb1c391271c2ed0314a51903e72a3acb653d5ccfc264cdf3ef11f8269d"}, - {file = "aiohttp-3.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:99abd37084b82f5830c635fddd0b4993b9742a66eb746dacf433c8590e8f9e3c"}, - {file = "aiohttp-3.14.1-cp314-cp314t-win32.whl", hash = "sha256:47ddf841cdecc810749921d25606dee45857d12d2ad5ddb7b5bd7eab12e4b365"}, - {file = "aiohttp-3.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5e78b522b7a6e27e0b25d19b247b75039ac4c94f99823e3c9e53ae1603a9f7e9"}, - {file = "aiohttp-3.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:90d53f1609c29ccc2193945ef732428382a28f78d0456ae4d3daf0d48b74f0f6"}, - {file = "aiohttp-3.14.1.tar.gz", hash = "sha256:307f2cff90a764d329e77040603fa032db89c5c24fdad50c4c15334cba744035"}, + {file = "aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b"}, + {file = "aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a"}, + {file = "aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479"}, + {file = "aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f"}, + {file = "aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32"}, + {file = "aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e"}, + {file = "aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c"}, + {file = "aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb"}, + {file = "aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3"}, + {file = "aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a"}, + {file = "aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db"}, + {file = "aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910"}, + {file = "aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7"}, + {file = "aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa"}, + {file = "aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d"}, + {file = "aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39"}, + {file = "aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5"}, + {file = "aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228"}, + {file = "aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42"}, + {file = "aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d"}, + {file = "aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19"}, + {file = "aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559"}, + {file = "aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a"}, + {file = "aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c"}, + {file = "aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86"}, + {file = "aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627"}, + {file = "aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82"}, + {file = "aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c"}, + {file = "aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f"}, + {file = "aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80"}, + {file = "aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0"}, + {file = "aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5"}, + {file = "aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e"}, + {file = "aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71"}, + {file = "aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0"}, + {file = "aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883"}, + {file = "aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2"}, + {file = "aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062"}, + {file = "aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6"}, + {file = "aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919"}, + {file = "aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7"}, + {file = "aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0"}, + {file = "aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924"}, + {file = "aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646"}, + {file = "aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147"}, + {file = "aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41"}, + {file = "aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf"}, + {file = "aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da"}, + {file = "aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100"}, + {file = "aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc"}, + {file = "aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b"}, + {file = "aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0"}, + {file = "aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85"}, + {file = "aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9"}, + {file = "aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb"}, + {file = "aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963"}, + {file = "aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b"}, + {file = "aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7"}, + {file = "aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc"}, ] [package.dependencies] @@ -188,26 +188,26 @@ files = [ [[package]] name = "annotated-types" -version = "0.7.0" +version = "0.8.0" description = "Reusable constraint types to use with typing.Annotated" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, + {file = "annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0"}, + {file = "annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7"}, ] [[package]] name = "anyio" -version = "4.14.1" +version = "4.14.2" description = "High-level concurrency and networking framework on top of asyncio or Trio" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "anyio-4.14.1-py3-none-any.whl", hash = "sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72"}, - {file = "anyio-4.14.1.tar.gz", hash = "sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e"}, + {file = "anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494"}, + {file = "anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f"}, ] [package.dependencies] @@ -220,14 +220,14 @@ trio = ["trio (>=0.32.0)"] [[package]] name = "asttokens" -version = "3.0.1" +version = "3.0.2" description = "Annotate AST trees with source code positions" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a"}, - {file = "asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7"}, + {file = "asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933"}, + {file = "asttokens-3.0.2.tar.gz", hash = "sha256:3ecdbd8f2cc195f53ccada3a613538bb5f9ef6f6869129f13e03c30a677b8fe2"}, ] [package.extras] @@ -290,153 +290,117 @@ files = [ [[package]] name = "certifi" -version = "2026.6.17" +version = "2026.7.22" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main", "dev"] files = [ - {file = "certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db"}, - {file = "certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432"}, + {file = "certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"}, + {file = "certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55"}, ] [[package]] name = "charset-normalizer" -version = "3.4.7" +version = "3.4.9" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_armv7l.whl", hash = "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-win32.whl", hash = "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win32.whl", hash = "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c"}, - {file = "charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d"}, - {file = "charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win32.whl", hash = "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win32.whl", hash = "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win32.whl", hash = "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win32.whl", hash = "sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win_amd64.whl", hash = "sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win_arm64.whl", hash = "sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe"}, + {file = "charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5"}, + {file = "charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b"}, ] [[package]] @@ -1278,18 +1242,18 @@ testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "prompt-toolkit" -version = "3.0.52" +version = "3.0.53" description = "Library for building powerful interactive command lines in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"}, - {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"}, + {file = "prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2"}, + {file = "prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6"}, ] [package.dependencies] -wcwidth = "*" +wcwidth = ">=0.1.4" [[package]] name = "propcache" @@ -2008,14 +1972,14 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.17.0,<1.19)", "pre-commit", "pytest [[package]] name = "types-python-dateutil" -version = "2.9.0.20260518" +version = "2.9.0.20260716" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "types_python_dateutil-2.9.0.20260518-py3-none-any.whl", hash = "sha256:d6a9c5bd0de61460c8fdef8ab2b400f956a1a1075cce08d4e2b4434e478c50b8"}, - {file = "types_python_dateutil-2.9.0.20260518.tar.gz", hash = "sha256:51f02dc03b61c7f6a07df45797d4dfe8a1aa47f0b7db9ad89f6fd3a1a70e1b51"}, + {file = "types_python_dateutil-2.9.0.20260716-py3-none-any.whl", hash = "sha256:1ae41d51a5c5f6bbeeb7f1f34df7086d55ff1605cf88d2ed71a7a276e1a7794e"}, + {file = "types_python_dateutil-2.9.0.20260716.tar.gz", hash = "sha256:1d55d1c3024bdb4861bb6a6622c9ec800c433d87bdc5b16fb84cdd0eed4ef2cb"}, ] [[package]] @@ -2077,117 +2041,117 @@ files = [ [[package]] name = "yarl" -version = "1.24.2" +version = "1.24.5" description = "Yet another URL library" optional = true python-versions = ">=3.10" groups = ["main"] markers = "extra == \"aiohttp\"" files = [ - {file = "yarl-1.24.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5249a113065c2b7a958bc699759e359cd61cfc81e3069662208f48f191b7ed12"}, - {file = "yarl-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4425fa244fbf530b006d0c5f79ce920114cfff5b4f5f6056e669f8e160fdc0"}, - {file = "yarl-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15c0b5e49d3c44e2a0b93e6a49476c5edad0a7686b92c395765a7ea775572a75"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:246d32a53a947c8f0189f5d699cbd4c7036de45d9359e13ba238d1239678c727"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:64480fb3e4d4ed9ed71c48a91a477384fc342a50ca30071d2f8a88d51d9c9413"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:349de4701dc3760b6e876628423a8f147ef4f5599d10aba1e10702075d424ed9"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d162677af8d5d3d6ebab8394b021f4d041ac107a4b705873148a77a49dc9e1b2"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5f5c6ec23a9043f2d139cc072f53dd23168d202a334b9b2fda8de4c3e890d90"}, - {file = "yarl-1.24.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:60de6742447fbbf697f16f070b8a443f1b5fe6ca3826fbef9fe70ecd5328e643"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acf93187c3710e422368eb768aee98db551ec7c85adc250207a95c16548ab7ac"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f4b0352fd41fd34b6651934606268816afd6914d09626f9bcbbf018edb0afb3f"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6b208bb939099b4b297438da4e9b25357f0b1c791888669b963e45b203ea9f36"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4b85b8825e631295ff4bc8943f7471d54c533a9360bbe15ebb38e018b555bb8a"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e26acf20c26cb4fefc631fdb75aca2a6b8fa8b7b5d7f204fb6a8f1e63c706f53"}, - {file = "yarl-1.24.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:819ca24f8eafcfb683c1bd5f44f2f488cea1274eb8944731ffd2e1f10f619342"}, - {file = "yarl-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:5cb0f995a901c36be096ccbf4c673591c2faabbe96279598ffaec8c030f85bf4"}, - {file = "yarl-1.24.2-cp310-cp310-win_arm64.whl", hash = "sha256:f408eace7e22a68b467a0562e0d27d322f91fe3eaaa6f466b962c6cfaea9fa39"}, - {file = "yarl-1.24.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:36348bebb147b83818b9d7e673ea4debc75970afc6ffdc7e3975ad05ce5a58c1"}, - {file = "yarl-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a97e42c8a2233f2f279ecadd9e4a037bcb5d813b78435e8eedd4db5a9e9708c"}, - {file = "yarl-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8d027d56f1035e339d1001ac33eceab5b2ec8e42e449787bb75e289fb9a5cd1d"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a6377060e7927187a42b7eb202090cbe2b34933a4eeaf90e3bd9e33432e5cae"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:17076578bce0049a5ce57d14ad1bded391b68a3b213e9b81b0097b090244999a"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:50713f1d4d6be6375bb178bb43d140ee1acb8abe589cd723320b7925a275be1e"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:34263e2fa8fb5bb63a0d97706cda38edbad62fddb58c7f12d6acbc092812aa50"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49016d82f032b1bd1e10b01078a7d29ae71bf468eeae0ea22df8bab691e60003"}, - {file = "yarl-1.24.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3f6d2c216318f8f32038ca3f72501ba08536f0fd18a36e858836b121b2deed9f"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:08d3a33218e0c64393e7610284e770409a9c31c429b078bcb24096ed0a783b8f"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:5d699376c4ca3cba49bbfae3a05b5b70ded572937171ce1e0b8d87118e2ba294"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a1cab588b4fa14bea2e55ebea27478adfb05372f47573738e1acc4a36c0b05d2"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ec87ccc31bd21db7ad009d8572c127c1000f268517618a4cc09adba3c2a7f21c"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d1dd47a22843b212baa8d74f37796815d43bd046b42a0f41e9da433386c3136b"}, - {file = "yarl-1.24.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7b54b9c67c2b06bd7b9a77253d242124b9c95d2c02def5a1144001ee547dd9d5"}, - {file = "yarl-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:f8fdbcff8b2c7c9284e60c196f693588598ddcee31e11c18e14949ce44519d45"}, - {file = "yarl-1.24.2-cp311-cp311-win_arm64.whl", hash = "sha256:b32c37a7a337e90822c45797bf3d79d60875cfcccd3ecc80e9f453d87026c122"}, - {file = "yarl-1.24.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8"}, - {file = "yarl-1.24.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2"}, - {file = "yarl-1.24.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c"}, - {file = "yarl-1.24.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c"}, - {file = "yarl-1.24.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1"}, - {file = "yarl-1.24.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad"}, - {file = "yarl-1.24.2-cp312-cp312-win_arm64.whl", hash = "sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30"}, - {file = "yarl-1.24.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:491ac9141decf49ee8030199e1ee251cdff0e131f25678817ff6aa5f837a3536"}, - {file = "yarl-1.24.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e89418f65eda18f99030386305bd44d7d504e328a7945db1ead514fbe03a0607"}, - {file = "yarl-1.24.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cdfcce633b4a4bb8281913c57fcafd4b5933fbc19111a5e3930bbd299d6102f1"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:863297ddede92ee49024e9a9b11ecb59f310ca85b60d8537f56bed9bbb5b1986"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:374423f70754a2c96942ede36a29d37dc6b0cb8f92f8d009ddf3ed78d3da5488"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33a29b5d00ccbf3219bb3e351d7875739c19481e030779f48cc46a7a71681a9b"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a9532c57211730c515341af11fef6e9b61d157487272a096d0c04da445642592"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91e72cf093fd833483a97ee648e0c053c7c629f51ff4a0e7edd84f806b0c5617"}, - {file = "yarl-1.24.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b3177bc0a768ef3bacceb4f272632990b7bea352f1b2f1eee9d6d6ff16516f92"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e196952aacaf3b232e265ff02980b64d483dc0972bd49bcb061171ff22ac203a"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:204e7a61ce99919c0de1bf904ab5d7aa188a129ea8f690a8f76cfb6e2844dc44"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b156914620f0b9d78dc1adb3751141daee561cfec796088abb89ed49d220f1a"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8372a2b976cf70654b2be6619ab6068acabb35f724c0fda7b277fbf53d66a5cf"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f9a1e9b622ca284143aab5d885848686dcd85453bb1ca9abcdb7503e64dc0056"}, - {file = "yarl-1.24.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:810e19b685c8c3c5862f6a38160a1f4e4c0916c9390024ec347b6157a45a0992"}, - {file = "yarl-1.24.2-cp313-cp313-win_amd64.whl", hash = "sha256:7d37fb7c38f2b6edab0f845c4f85148d4c44204f52bc127021bd2bc9fdbf1656"}, - {file = "yarl-1.24.2-cp313-cp313-win_arm64.whl", hash = "sha256:1e831894be7c2954240e49791fa4b50c05a0dc881de2552cfe3ffd8631c7f461"}, - {file = "yarl-1.24.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:f9312b3c02d9b3d23840f67952913c9c8721d7f1b7db305289faefa878f364c2"}, - {file = "yarl-1.24.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a4f4d6cd615823bfc7fb7e9b5987c3f41666371d870d51058f77e2680fbe9630"}, - {file = "yarl-1.24.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0c3063e5c0a8e8e62fae6c2596fa01da1561e4cd1da6fec5789f5cf99a8aefd8"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fecd17873a096036c1c87ab3486f1aef7f269ada7f23f7f856f93b1cc7744f14"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a46d1ab4ba4d32e6dc80daf8a28ce0bd83d08df52fbc32f3e288663427734535"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:73e68edf6dfd5f73f9ca127d84e2a6f9213c65bdffb736bda19524c0564fcd14"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a296ca617f2d25fbceafb962b88750d627e5984e75732c712154d058ae8d79a3"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51b2cf5ec89a8b8470177641ed62a3ba22d74e1e898e06ad53aa77972487208"}, - {file = "yarl-1.24.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:310fc687f7b2044ec54e372c8cbe923bb88f5c37bded0d3079e5791c2fc3cf50"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:297a2fe352ecf858b30a98f87948746ec16f001d279f84aebdbd3bd965e2f1bd"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2a263e76b97bc42bdcd7c5f4953dec1f7cd62a1112fa7f869e57255229390d67"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:822519b64cf0b474f1a0aaef1dc621438ea46bb77c94df97a5b4d213a7d8a8b1"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b6067060d9dc594899ba83e6db6c48c68d1e494a6dab158156ed86977ca7bcb1"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0063adad533e57171b79db3943b229d40dfafeeee579767f96541f106bac5f1b"}, - {file = "yarl-1.24.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ee8e3fb34513e8dc082b586ef4910c98335d43a6fab688cd44d4851bacfce3e8"}, - {file = "yarl-1.24.2-cp314-cp314-win_amd64.whl", hash = "sha256:afb00d7fd8e0f285ca29a44cc50df2d622ff2f7a6d933fa641577b5f9d5f3db0"}, - {file = "yarl-1.24.2-cp314-cp314-win_arm64.whl", hash = "sha256:68cf6eacd6028ef1142bc4b48376b81566385ca6f9e7dde3b0fa91be08ffcb57"}, - {file = "yarl-1.24.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:221ce1dd921ac4f603957f17d7c18c5cc0797fbb52f156941f92e04605d1d67b"}, - {file = "yarl-1.24.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5f3224db28173a00d7afacdee07045cc4673dfab2b15492c7ae10deddbece761"}, - {file = "yarl-1.24.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c557165320d6244ebe3a02431b2a201a20080e02f41f0cfa0ccc47a183765da8"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:904065e6e85b1fa54d0d87438bd58c14c0bad97aad654ad1077fd9d87e8478ed"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8cec2a38d70edc10e0e856ceda886af5327a017ccbde8e1de1bd44d300357543"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e7484b9361ed222ee1ca5b4337aa4cbdcc4618ce5aff57d9ef1582fd95893fc0"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:84f9670b89f34db07f81e53aee83e0b938a3412329d51c8f922488be7fcc4024"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:abb2759733d63a28b4956500a5dd57140f26486c92b2caedfb964ab7d9b79dbf"}, - {file = "yarl-1.24.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:081c2bf54efe03774d0311172bc04fedf9ca01e644d4cd8c805688e527209bdc"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:86746bef442aa479107fe28132e1277237f9c24c2f00b0b0cf22b3ee0904f2bb"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:2d07d21d0bc4b17558e8de0b02fbfdf1e347d3bb3699edd00bb92e7c57925420"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4fb1ac3fc5fecd8ae7453ea237e4d22b49befa70266dfe1629924245c21a0c7f"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4da31a5512ed1729ca8d8aacde3f7faeb8843cde3165d6bcf7f88f74f17bb8aa"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:533ded4dceb5f1f3da7906244f4e82cf46cfd40d84c69a1faf5ac506aa65ecbe"}, - {file = "yarl-1.24.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7b3a85525f6e7eeabcfdd372862b21ee1915db1b498a04e8bf0e389b607ff0bd"}, - {file = "yarl-1.24.2-cp314-cp314t-win_amd64.whl", hash = "sha256:a7624b1ca46ca5d7b864ef0d2f8efe3091454085ee1855b4e992314529972215"}, - {file = "yarl-1.24.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e434a45ce2e7a947f951fc5a8944c8cc080b7e59f9c50ae80fd39107cf88126d"}, - {file = "yarl-1.24.2-py3-none-any.whl", hash = "sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9"}, - {file = "yarl-1.24.2.tar.gz", hash = "sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8"}, + {file = "yarl-1.24.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88f50c94e21a0a7f14042c015b0eba1881af78562e7bf007e0033e624da59750"}, + {file = "yarl-1.24.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6efbccc3d7f75d5b03105172a8dc86d82ba4da86817952529dd93185f4a88be2"}, + {file = "yarl-1.24.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0ebfaffe1a16cb72141c8e09f18cc76856dbe58639f393a4f2b26e474b96b871"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ac73abdc7ab75610f95a8fd994c6457e87752b02a63987e188f937a1fc180f0"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4d97a951a81039050e45f04e96689b58b8243fa5e62aa14fe67cb6075300885e"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe7b7bb170daccbba19ad33012d2b15f1e7942296fd4d45fc1b79013da8cc0f2"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:89a1bbb58e0e3f7a283653d854b1e95d65e5cfd4af224dac5f02629ec1a3e621"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fa5e51397466ea7e98de493fa2ff1b8193cfef8a7b0f9b4842f92d342df0dba"}, + {file = "yarl-1.24.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4103b77b8a8225e413107d2349b65eb3c1c52627b5cc5c3c4c1c6a798b218950"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f9f3e9c8a9ecffa57bef8fb4fa19e5fa4d2d8307cf6bac5b1fca5e5860f4ba00"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c0ebc836c47a6477e182169c6a476fc691d12b518894bf7dd2572f0d59f1c7ed"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:96d30286dd02679e32a39aa8f0b7498fc847fcda46cfc09df5513e82ce252440"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:fd8c81f346b58f45818d09ea11db69a8d5fd34a224b79871f6d44f12cd7977b1"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5c55256dee8f4b27bfbf636c8363383c7c8db7890c7cba5217d7bd5f5f21dab6"}, + {file = "yarl-1.24.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f4d8cf085a4c6a40fb97ea0f46938a8df43c85d31f9d45e2a8867ea9293790d"}, + {file = "yarl-1.24.5-cp310-cp310-win_amd64.whl", hash = "sha256:240cbec09667c1fed4c6cd0060b9ec57332427d7441289a2ed8875dc9fb2b224"}, + {file = "yarl-1.24.5-cp310-cp310-win_arm64.whl", hash = "sha256:8a6987eaad834cb32dd57d9d582225f0054a5d1af706ccfbbdba735af4927e13"}, + {file = "yarl-1.24.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c1fe720934a16ea8e7146175cba2126f87f54912c8c5435e7f7c7a51ef808d3"}, + {file = "yarl-1.24.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c687ed078e145f5fd53a14854beff320e1d2ab76df03e2009c98f39a0f68f39a"}, + {file = "yarl-1.24.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:709f1efed56c4a145793c046cd4939f9959bcd818979a787b77d8e09c57a0840"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874019bd513008b009f58657134e5d0c5e030b3559bd0553976837adf52fe966"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4582acf7ef76482f6f511ebaf1946dae7f2e85ec4728b81a678c01df63bd723"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2cabe6546e41dabe439999a23fcb5246e0c3b595b4315b96ef755252be90caeb"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:17f57620f5475b3c69109376cc87e42a7af5db13c9398e4292772a706ff10780"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:570fec8fbd22b032733625f03f10b7ff023bc399213db15e72a7acaef28c2f4e"}, + {file = "yarl-1.24.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fede79c6f73ff2c3ef822864cb1ada23196e62756df53bc6231d351a49516a2"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ccf9aca873b767977c73df497a85dbedee4ee086ae9ae49dc461333b9b79f58"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ad5d8201d310b031e6cd839d9bac2d4e5a01533ce5d3d5b50b7de1ef3af1de61"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:841f0852f48fefea3b12c9dfec00704dfa3aef5215d0e3ce564bb3d7cd8d57c6"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9baafc71b04f8f4bb0703b21d6fc9f0c30b346c636a532ff16ec8491a5ea4b1f"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d897129df1a22b12aeed2c2c98df0785a2e8e6e0bde87b389491d0025c187077"}, + {file = "yarl-1.24.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd625535328fd9882374356269227670189adfcc6a2d90284f323c05862eecbd"}, + {file = "yarl-1.24.5-cp311-cp311-win_amd64.whl", hash = "sha256:f4239bbec5a3577ddb49e4b50aeb32d8e5792098262ae2f63723f916a29b1a25"}, + {file = "yarl-1.24.5-cp311-cp311-win_arm64.whl", hash = "sha256:3ac6aff147deb9c09461b2d4bbdf6256831198f5d8a23f5d37138213090b6d8a"}, + {file = "yarl-1.24.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d693396e5aea78db03decd60aec9ece16c9b40ba00a587f089615ff4e718a81d"}, + {file = "yarl-1.24.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3363fcc96e665878946ad7a106b9a13eac0541766a690ef287c0232ac768b6ec"}, + {file = "yarl-1.24.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d399bdcfb4a0f659b9b3788bbc89babe63d9a6a65aacdf4d4e7065ff2e6316c"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90333fd89b43c0d08ac85f3f1447593fc2c66de18c3d6378d7125ea118dc7a54"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:665b0a2c463cc9423dd647e0bfd9f4ccc9b50f768c55304d5e9f80b177c1de12"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e006d3a974c4ee19512e5f058abedb6eef36a5e553c14812bdeba1758d812e6d"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7d42c531243450ef0d4d9c172e7ed6ef052640f195629065041b5add4e058d1"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f08c7513ecef5aad65687bfdf6bc601ae9fccd04a42904501f8f7141abad9eb9"}, + {file = "yarl-1.24.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95b17fe34ed802f17e205112e6e10db92275c34fee290aa9bdc55a9c724027"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56b149b22de33b23b0c6077ab9518c6dcb538ad462e1830e68d06591ccf6e38b"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8fe66b8f300da93798025a785a5b90b42f3810dc2b72283ff84a41aaaebc293"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:377fe3732edbaf78ee74efdf2c9f49f6e99f20e7f9d2649fda3eb4badd77d76e"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e8ffa78582120024f476a611d7befc123cee59e47e8309d470cf667d806e613b"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:daba5e594f06114e37db186efd2dd916609071e59daca901a0a2e71f02b142ce"}, + {file = "yarl-1.24.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65be18ec59496c13908f02a2472751d9ef840b4f3fb5726f129306bf6a2a7bba"}, + {file = "yarl-1.24.5-cp312-cp312-win_amd64.whl", hash = "sha256:a929d878fec099030c292803b31e5d5540a7b6a31e6a3cc76cb4685fc2a2f51b"}, + {file = "yarl-1.24.5-cp312-cp312-win_arm64.whl", hash = "sha256:7ce27823052e2013b597e0c738b13e7e36b8ccb9400df8959417b052ab0fd92c"}, + {file = "yarl-1.24.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:79af890482fc94648e8cde4c68620378f7fef60932710fa17a66abc039244da2"}, + {file = "yarl-1.24.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46c2f213e23a04b93a392942d782eb9e413e6ef6bf7c8c53884e599a5c174dcb"}, + {file = "yarl-1.24.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92ab3e11448f2ff7bf53c5a26eff0edc086898ec8b21fb154b85839ce1d88075"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebb0ec7f17803063d5aeb982f3b1bd2b2f4e4fae6751226cbd6ba1fcfe9e63ff"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:82632daed195dcc8ea664e8556dc9bdbd671960fb3776bd92806ce05792c2448"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:53e549287ef628fecba270045c9701b0c564563a9b0577d24a4ec75b8ab8040f"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fcd3b77e2f17bbe4ca56ec7bcb07992647d19d0b9c05d84886dcd6f9eb810afd"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d46b86567dd4e248c6c159fcbcdcce01e0a5c8a7cd2334a0fff759d0fa075b16"}, + {file = "yarl-1.24.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f72c74aa99359e27a2ee8d6613fefa28b5f76a983c083074dfc2aaa4ab46213"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f45789ce415a7ec0820dc4f82925f9b5f7732070be1dec1f5f23ec381435a24"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6e73e7fe93f17a7b191f52ec9da9dd8c06a8fe735a1ecbd13b97d1c723bff385"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4a36f9becdd4c5c52a20c3e9484128b070b1dcfc8944c006f3a528295a359a9c"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:7bcbe0fcf850eae67b6b01749815a4f7161c560a844c769ad7b48fcd99f791c4"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:24e861e9630e0daddcb9191fb187f60f034e17a4426f8101279f0c475cd74144"}, + {file = "yarl-1.24.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9335a099ad87287c37fe5d1a982ff392fa5efe5d14b40a730b1ec1d6a41382b4"}, + {file = "yarl-1.24.5-cp313-cp313-win_amd64.whl", hash = "sha256:2dbe06fc16bc91502bca713704022182e5729861ae00277c3a23354b40929740"}, + {file = "yarl-1.24.5-cp313-cp313-win_arm64.whl", hash = "sha256:6b8536851f9f65e7f00c7a1d49ba7f2be0ffe2c11555367fc9f50d9f842410a1"}, + {file = "yarl-1.24.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:2729fcfc4f6a596fb0c50f32090400aa9367774ac296a00387e65098c0befa76"}, + {file = "yarl-1.24.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ff330d3c30db4eb6b01d79e29d2d0b407a7ecad39cfd9ec993ece57396a2ec0d"}, + {file = "yarl-1.24.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e42d75862735da90e7fc5a7b23db0c976f737113a54b3c9777a9b665e9cbff75"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3732e66413163e72508da9eff9ce9d2846fde51fae45d3605393d3e6cd303e9"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b8ee53be440a0cffc991a27be3057e0530122548dbe7c0892df08822fce5ede"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:af3aefa655adb5869491fa907e652290386800ae99cc50095cba71e2c6aefdca"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2120b96872df4a117cde97d270bac96aea7cc52205d305cf4611df694a487027"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66410eb6345d467151934b49bfa70fb32f5b35a6140baa40ad97d6436abea2e9"}, + {file = "yarl-1.24.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4af7b7e1be0a69bee8210735fe6dcfc38879adfac6d62e789d53ba432d1ffa41"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa139875ff98ab97da323cfadfaff08900d1ad42f1b5087b0b812a55c5a06373"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0055afc45e864b92729ac7600e2d102c17bef060647e74bca75fa84d66b9ff36"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f0e466ed7511fe9d459a819edbc6c2585c0b6eabde9fa8a8947552468a7a6ef0"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f141474e85b7e54998ec5180530a7cda99ab29e282fa50e0756d89981a9b43c5"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e2935f8c39e3b03e83519292d78f075189978f3f4adc15a78144c7c8e2a1cba5"}, + {file = "yarl-1.24.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9d1216a7f6f77836617dba35687c5b78a4170afc3c3f18fc788f785ba26565c4"}, + {file = "yarl-1.24.5-cp314-cp314-win_amd64.whl", hash = "sha256:5ba4f78df2bcc19f764a4b26a8a4f5049c110090ad5825993aacb052bf8003ad"}, + {file = "yarl-1.24.5-cp314-cp314-win_arm64.whl", hash = "sha256:9e4e16c73d717c5cf27626c524d0a2e261ad20e46932b2670f64ad5dde23e26f"}, + {file = "yarl-1.24.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e1ae548a9d901adca07899a4147a7c826bbcc06239d3ce9a59f57886a28a4c88"}, + {file = "yarl-1.24.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ff405d91509d88e8d44129cd87b18d70acd1f0c1aeabd7bc3c46792b1fe2acba"}, + {file = "yarl-1.24.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47e98aab9d8d82ff682e7b0b5dded33bf138a32b817fcf7fa3b27b2d7c412928"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0a658a6d3fafee5c6f63c58f3e785c8c43c93fbc02bf9f2b6663f8185e0971f"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4377407001ca3c057773f44d8ddd6358fa5f691407c1ba92210bd3cf8d9e4c95"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7c0494a31a1ac5461a226e7947a9c9b78c44e1dc7185164fa7e9651557a5d9bc"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a7cff474ab7cd149765bb784cf6d78b32e18e20473fb7bda860bce98ab58e9da"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbb833ccacdb5519eff9b8b71ee618cc2801c878e77e288775d77c3a2ced858a"}, + {file = "yarl-1.24.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:82f75e05912e84b7a0fe57075d9c59de3cb352b928330f2eb69b2e1f54c3e1f0"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:16a2f5010280020e90f5330257e6944bc33e73593b136cc5a241e6c1dc292498"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ffcd54362564dc1a30fb74d8b8a6e5a6b11ebd5e27266adc3b7427a21a6c9104"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0465ec8cedc2349b97a6b595ace64084a50c6e839eca40aa0626f38b8350e331"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4db9aecb141cb7a5447171b57aa1ed3a8fee06af40b992ffc31206c0b0121550"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f540c013589084679a6c7fac07096b10159737918174f5dfc5e11bf5bca4dfe6"}, + {file = "yarl-1.24.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a61834fb15d81322d872eaafd333838ae7c9cea84067f232656f75965933d047"}, + {file = "yarl-1.24.5-cp314-cp314t-win_amd64.whl", hash = "sha256:5c88e5815a49d289e599f3513aa7fde0bc2092ff188f99c940f007f90f53d104"}, + {file = "yarl-1.24.5-cp314-cp314t-win_arm64.whl", hash = "sha256:cf139c02f5f23ef6532040a30ff662c00a318c952334f211046b8e60b7f17688"}, + {file = "yarl-1.24.5-py3-none-any.whl", hash = "sha256:a33700d13d9b7d84fd10947b09ff69fb9a792e519c8cb9764a3ca70baa6c23a7"}, + {file = "yarl-1.24.5.tar.gz", hash = "sha256:e81b83143bee16329c23db3c1b2d82b29892fcbcb849186d2f6e98a5abe9a57f"}, ] [package.dependencies] diff --git a/reference.md b/reference.md index b44662b3..de656f91 100644 --- a/reference.md +++ b/reference.md @@ -292,7 +292,6 @@ client.users.list( limit=10, offset=0, query="john@example.com", - show_invalid_users=True, ) ``` @@ -656,7 +655,6 @@ client = TrueFoundry( client.users.delete( id="jqfwg345gi25n5ju2yz5iz6m", - tenant_name="tenantName", ) ``` @@ -1286,10 +1284,6 @@ client = TrueFoundry( client.teams.list( limit=10, offset=0, - role="manager", - attributes=[ - "attributes" - ], ) ``` @@ -1330,7 +1324,7 @@ client.teams.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included.
@@ -2225,7 +2219,6 @@ client = TrueFoundry( client.personal_access_tokens.get( name="name", - team_name="teamName", ) ``` @@ -2309,10 +2302,6 @@ client.virtual_accounts.list( limit=10, offset=0, name_search_query="staging-bot", - owned_by_teams=[ - "ownedByTeams" - ], - is_expired=True, filter="{\"type\":\"AND\",\"children\":[{\"column\":\"name\",\"op\":\"STRING_CONTAINS\",\"value\":\"bot\"}]}", ) @@ -2354,7 +2343,7 @@ client.virtual_accounts.list(
-**owned_by_teams:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated team names. Return virtual accounts owned by these teams. +**owned_by_teams:** `typing.Optional[typing.List[str]]` — Comma-separated team names. Return virtual accounts owned by these teams.
@@ -2968,9 +2957,6 @@ client = TrueFoundry( client.clusters.list( limit=10, offset=0, - attributes=[ - "attributes" - ], ) ``` @@ -3003,7 +2989,7 @@ client.clusters.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -3298,9 +3284,6 @@ client.clusters.get_addons( id="id", limit=10, offset=0, - attributes=[ - "attributes" - ], ) ``` @@ -3341,7 +3324,7 @@ client.clusters.get_addons(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -3461,8 +3444,7 @@ List applications the caller can read.
```python -from truefoundry_sdk import TrueFoundry, ApplicationType -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -3472,21 +3454,6 @@ client = TrueFoundry( client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) ``` @@ -3607,7 +3574,7 @@ client.applications.list(
-**device_type_filter:** `typing.Optional[ApplicationsListRequestDeviceTypeFilter]` — Device type to filter by (comma-separated). +**device_type_filter:** `typing.Optional[ListApplicationsRequestDeviceTypeFilter]` — Device type to filter by (comma-separated).
@@ -3623,7 +3590,7 @@ client.applications.list(
-**lifecycle_stage:** `typing.Optional[ApplicationsListRequestLifecycleStage]` — Application lifecycle stage to filter by +**lifecycle_stage:** `typing.Optional[ListApplicationsRequestLifecycleStage]` — Application lifecycle stage to filter by
@@ -4150,7 +4117,7 @@ client.applications.scale_to_original( -
client.applications.cancel_deployment(...) -> ApplicationsCancelDeploymentResponse +
client.applications.cancel_deployment(...) -> CancelDeploymentApplicationsResponse
@@ -4449,7 +4416,7 @@ List Job Runs for provided Job Id. Filter the data based on parameters passed in
```python -from truefoundry_sdk import TrueFoundry, JobRunsSortBy, SortDirection, JobRunStatus +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -4460,18 +4427,6 @@ client.jobs.list_runs( job_id="jobId", limit=10, offset=0, - search_prefix="searchPrefix", - sort_by=JobRunsSortBy.START_TIME, - order=SortDirection.ASC, - triggered_by=[ - "triggeredBy" - ], - status=[ - JobRunStatus.CREATED - ], - version_numbers=[ - 1.1 - ], ) ``` @@ -4536,7 +4491,7 @@ client.jobs.list_runs(
-**triggered_by:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Array of subject slugs +**triggered_by:** `typing.Optional[typing.List[str]]` — Array of subject slugs
@@ -4552,7 +4507,7 @@ client.jobs.list_runs(
-**version_numbers:** `typing.Optional[typing.Union[float, typing.Sequence[float]]]` — Version number of the deployment +**version_numbers:** `typing.Optional[typing.List[float]]` — Version number of the deployment
@@ -4948,12 +4903,6 @@ client.workspaces.list( limit=10, offset=0, cluster_id="jqfwg345gi25n5ju2yz5iz6m", - name="name", - fqn="fqn", - include_cluster=True, - attributes=[ - "attributes" - ], ) ``` @@ -5018,7 +4967,7 @@ client.workspaces.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -5160,7 +5109,6 @@ client.workspaces.search( limit=10, offset=0, filter="[{\"type\":\"name\",\"operator\":\"STRING_CONTAINS\",\"value\":\"prod\"}]", - include_cluster=True, ) ``` @@ -5888,7 +5836,6 @@ client = TrueFoundry( client.secrets.delete( id="id", - force_delete=True, ) ``` @@ -5971,11 +5918,6 @@ client = TrueFoundry( client.secret_groups.list( limit=10, offset=0, - fqn="fqn", - search="search", - attributes=[ - "attributes" - ], ) ``` @@ -6024,7 +5966,7 @@ client.secret_groups.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -6422,7 +6364,6 @@ client = TrueFoundry( client.secret_groups.delete( id="id", - force_delete=True, ) ``` @@ -6502,16 +6443,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.events.get( - start_ts="startTs", - end_ts="endTs", - application_id="applicationId", - application_fqn="applicationFqn", - pod_names=[ - "podNames" - ], - job_run_name="jobRunName", -) +client.events.get() ```
@@ -6559,7 +6491,7 @@ client.events.get(
-**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName. +**pod_names:** `typing.Optional[typing.List[str]]` — List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName.
@@ -6615,20 +6547,14 @@ Get alerts for a given application or cluster filtered by start and end timestam
```python -from truefoundry_sdk import TrueFoundry, AlertStatus +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", base_url="https://yourhost.com/path/to/api", ) -client.alerts.list( - start_ts="startTs", - end_ts="endTs", - cluster_id="clusterId", - application_id="applicationId", - alert_status=AlertStatus.FIRING, -) +client.alerts.list() ```
@@ -6725,7 +6651,6 @@ List all Agents for a tenant. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.agents import AgentsListRequestType client = TrueFoundry( api_key="", @@ -6735,12 +6660,6 @@ client = TrueFoundry( client.agents.list( limit=10, offset=0, - name="name", - name_prefix="namePrefix", - type=AgentsListRequestType.REMOTE_AGENT, - attributes=[ - "attributes" - ], ) ``` @@ -6789,7 +6708,7 @@ client.agents.list(
-**type:** `typing.Optional[AgentsListRequestType]` — Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future. +**type:** `typing.Optional[ListAgentsRequestType]` — Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future.
@@ -6797,7 +6716,7 @@ client.agents.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -7092,7 +7011,6 @@ client = TrueFoundry( client.agent_versions.list( limit=10, offset=0, - id="id", ) ``` @@ -7327,10 +7245,6 @@ client = TrueFoundry( client.prompts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_prompts=True, ) ``` @@ -7528,12 +7442,6 @@ client = TrueFoundry( client.prompt_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - prompt_id="prompt_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) ``` @@ -8043,11 +7951,6 @@ client = TrueFoundry( client.artifacts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_artifacts=True, ) ``` @@ -8251,19 +8154,6 @@ client = TrueFoundry( client.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=[ - "run_ids" - ], - run_steps=[ - 1.1 - ], - include_internal_metadata=True, ) ``` @@ -8344,7 +8234,7 @@ client.artifact_versions.list(
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Run IDs to filter artifact versions by. +**run_ids:** `typing.Optional[typing.List[str]]` — Run IDs to filter artifact versions by.
@@ -8352,7 +8242,7 @@ client.artifact_versions.list(
-**run_steps:** `typing.Optional[typing.Union[float, typing.Sequence[float]]]` — Run steps to filter artifact versions by. +**run_steps:** `typing.Optional[typing.List[float]]` — Run steps to filter artifact versions by.
@@ -9172,10 +9062,6 @@ client = TrueFoundry( client.ml_repos.list( limit=10, offset=0, - name="name", - attributes=[ - "attributes" - ], ) ``` @@ -9216,7 +9102,7 @@ client.ml_repos.list(
-**attributes:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included.
@@ -9364,9 +9250,6 @@ client = TrueFoundry( client.data_directories.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", ) ``` @@ -9930,7 +9813,6 @@ client = TrueFoundry( client.data_directories.delete( id="id", - delete_contents=True, ) ``` @@ -11286,11 +11168,6 @@ client = TrueFoundry( client.models.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_models=True, ) ``` @@ -11494,19 +11371,6 @@ client = TrueFoundry( client.model_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - model_id="model_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=[ - "run_ids" - ], - run_steps=[ - 1.1 - ], - include_internal_metadata=True, ) ``` @@ -11587,7 +11451,7 @@ client.model_versions.list(
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Filter model versions by associated run identifiers. +**run_ids:** `typing.Optional[typing.List[str]]` — Filter model versions by associated run identifiers.
@@ -11595,7 +11459,7 @@ client.model_versions.list(
-**run_steps:** `typing.Optional[typing.Union[float, typing.Sequence[float]]]` — Filter model versions by associated run steps. +**run_steps:** `typing.Optional[typing.List[float]]` — Filter model versions by associated run steps.
@@ -11886,7 +11750,7 @@ Get runtime logs (stdout/stderr) emitted by the pods of a deployed application.
```python -from truefoundry_sdk import TrueFoundry, LogsSortingDirection, LogsSearchFilterType, LogsSearchOperatorType +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -11896,23 +11760,7 @@ client = TrueFoundry( client.logs.get( start_ts="1779262323000000000", end_ts="1779348723000000000", - limit=1, - direction=LogsSortingDirection.ASC, - num_logs_to_ignore=1, - application_id="applicationId", - application_fqn="applicationFqn", - deployment_id="deploymentId", - job_run_name="jobRunName", - pod_name="podName", - container_name="containerName", - pod_names=[ - "podNames" - ], - pod_names_regex="podNamesRegex", search_filters="[{\"string\":\"error\",\"type\":\"substring\",\"operator\":\"equal\"}]", - search_string="searchString", - search_type=LogsSearchFilterType.REGEX, - search_operator=LogsSearchOperatorType.EQUAL, ) ``` @@ -12017,7 +11865,7 @@ client.logs.get(
-**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex. +**pod_names:** `typing.Optional[typing.List[str]]` — List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex.
@@ -12259,10 +12107,6 @@ client = TrueFoundry( client.agent_skills.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_agent_skills=True, ) ``` @@ -12460,11 +12304,6 @@ client = TrueFoundry( client.agent_skill_versions.list( limit=10, offset=0, - fqn="fqn", - agent_skill_id="agent_skill_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) ``` @@ -12956,7 +12795,7 @@ Get the AI Gateway configuration for the given type. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.internal.ai_gateway import AiGatewayGetGatewayConfigRequestType +from truefoundry_sdk.internal.ai_gateway import GetGatewayConfigAiGatewayRequestType client = TrueFoundry( api_key="", @@ -12964,7 +12803,7 @@ client = TrueFoundry( ) client.internal.ai_gateway.get_gateway_config( - type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, + type=GetGatewayConfigAiGatewayRequestType.GATEWAY_RATE_LIMITING_CONFIG, ) ``` @@ -12981,7 +12820,7 @@ client.internal.ai_gateway.get_gateway_config(
-**type:** `AiGatewayGetGatewayConfigRequestType` — The type of gateway configuration to retrieve or delete. +**type:** `GetGatewayConfigAiGatewayRequestType` — The type of gateway configuration to retrieve or delete.
@@ -13418,9 +13257,6 @@ client.internal.deployments.get_suggested_endpoint( application_type=ApplicationType.ASYNC_SERVICE, application_name="applicationName", workspace_id="workspaceId", - base_domain="baseDomain", - port="port", - prefer_wildcard=True, ) ``` @@ -13534,7 +13370,6 @@ client = TrueFoundry( client.internal.applications.promote_rollout( id="id", - full=True, ) ``` @@ -13615,7 +13450,6 @@ client = TrueFoundry( client.internal.applications.get_pod_template_hash_to_deployment_version( id="id", - pod_template_hashes="podTemplateHashes", ) ``` @@ -13689,7 +13523,7 @@ List metric charts available for an application. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity +from truefoundry_sdk.internal.metrics import GetChartsMetricsRequestFilterEntity client = TrueFoundry( api_key="", @@ -13699,9 +13533,7 @@ client = TrueFoundry( client.internal.metrics.get_charts( workspace_id="workspaceId", application_id="applicationId", - start_ts="startTs", - end_ts="endTs", - filter_entity=MetricsGetChartsRequestFilterEntity.APPLICATION, + filter_entity=GetChartsMetricsRequestFilterEntity.APPLICATION, filter_query="{\"pod\":\"my-app-abc123-xyz\"}", ) @@ -13735,7 +13567,7 @@ client.internal.metrics.get_charts(
-**filter_entity:** `MetricsGetChartsRequestFilterEntity` — Scope of the chart bundle to return. +**filter_entity:** `GetChartsMetricsRequestFilterEntity` — Scope of the chart bundle to return.
@@ -13942,23 +13774,6 @@ client = TrueFoundry( client.internal.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=[ - "run_ids" - ], - run_steps=[ - 1.1 - ], - include_internal_metadata=True, - include_model_versions=True, - artifact_types=[ - "artifact_types" - ], ) ``` @@ -14039,7 +13854,7 @@ client.internal.artifact_versions.list(
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Run IDs to filter artifact versions by. +**run_ids:** `typing.Optional[typing.List[str]]` — Run IDs to filter artifact versions by.
@@ -14047,7 +13862,7 @@ client.internal.artifact_versions.list(
-**run_steps:** `typing.Optional[typing.Union[float, typing.Sequence[float]]]` — Run steps to filter artifact versions by. +**run_steps:** `typing.Optional[typing.List[float]]` — Run steps to filter artifact versions by.
@@ -14216,10 +14031,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.internal.docker_registries.get_credentials( - fqn="fqn", - cluster_id="clusterId", -) +client.internal.docker_registries.get_credentials() ```
@@ -14264,7 +14076,7 @@ client.internal.docker_registries.get_credentials(
## Internal Workflows -
client.internal.workflows.execute_workflow(...) -> WorkflowsExecuteWorkflowResponse +
client.internal.workflows.execute_workflow(...) -> ExecuteWorkflowWorkflowsResponse
@@ -14391,10 +14203,7 @@ client.internal.build_logs.get( pipeline_run_name="pipelineRunName", start_ts="1635467890123456789", end_ts="1635467891123456789", - limit="limit", - direction="direction", filter_query="{\"matchString\":\"error\",\"type\":\"substring\",\"operator\":\"equal\"}", - num_logs_to_ignore=1.1, ) ``` diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index ba79f583..9c86a112 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -1193,11 +1193,11 @@ workspaces, ) from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient - from .agents import AgentsListRequestType + from .agents import ListAgentsRequestType from .applications import ( - ApplicationsCancelDeploymentResponse, - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, + CancelDeploymentApplicationsResponse, + ListApplicationsRequestDeviceTypeFilter, + ListApplicationsRequestLifecycleStage, ) from .artifact_versions import StageArtifactRequestManifest from .client import AsyncTrueFoundry, TrueFoundry @@ -1234,7 +1234,6 @@ "AgentSource": ".types", "AgentVersion": ".types", "AgentVersionMetadata": ".types", - "AgentsListRequestType": ".agents", "Ai21Integrations": ".types", "Ai21KeyAuth": ".types", "Ai21Model": ".types", @@ -1268,9 +1267,6 @@ "ApplicationSetComponentsItem": ".types", "ApplicationSummary": ".types", "ApplicationType": ".types", - "ApplicationsCancelDeploymentResponse": ".applications", - "ApplicationsListRequestDeviceTypeFilter": ".applications", - "ApplicationsListRequestLifecycleStage": ".applications", "Artifact": ".types", "ArtifactManifest": ".types", "ArtifactManifestSource": ".types", @@ -1421,6 +1417,7 @@ "BuildStatus": ".types", "Canary": ".types", "CanaryStep": ".types", + "CancelDeploymentApplicationsResponse": ".applications", "CartesiaApiKeyAuth": ".types", "CartesiaModel": ".types", "CartesiaProviderAccount": ".types", @@ -1800,8 +1797,11 @@ "ListAgentSkillVersionsResponse": ".types", "ListAgentSkillsResponse": ".types", "ListAgentVersionsResponse": ".types", + "ListAgentsRequestType": ".agents", "ListAgentsResponse": ".types", "ListApplicationDeploymentsResponse": ".types", + "ListApplicationsRequestDeviceTypeFilter": ".applications", + "ListApplicationsRequestLifecycleStage": ".applications", "ListApplicationsResponse": ".types", "ListArtifactVersionsResponse": ".types", "ListArtifactsResponse": ".types", @@ -2452,7 +2452,6 @@ def __dir__(): "AgentSource", "AgentVersion", "AgentVersionMetadata", - "AgentsListRequestType", "Ai21Integrations", "Ai21KeyAuth", "Ai21Model", @@ -2486,9 +2485,6 @@ def __dir__(): "ApplicationSetComponentsItem", "ApplicationSummary", "ApplicationType", - "ApplicationsCancelDeploymentResponse", - "ApplicationsListRequestDeviceTypeFilter", - "ApplicationsListRequestLifecycleStage", "Artifact", "ArtifactManifest", "ArtifactManifestSource", @@ -2639,6 +2635,7 @@ def __dir__(): "BuildStatus", "Canary", "CanaryStep", + "CancelDeploymentApplicationsResponse", "CartesiaApiKeyAuth", "CartesiaModel", "CartesiaProviderAccount", @@ -3018,8 +3015,11 @@ def __dir__(): "ListAgentSkillVersionsResponse", "ListAgentSkillsResponse", "ListAgentVersionsResponse", + "ListAgentsRequestType", "ListAgentsResponse", "ListApplicationDeploymentsResponse", + "ListApplicationsRequestDeviceTypeFilter", + "ListApplicationsRequestLifecycleStage", "ListApplicationsResponse", "ListArtifactVersionsResponse", "ListArtifactsResponse", diff --git a/src/truefoundry_sdk/agent_skill_versions/client.py b/src/truefoundry_sdk/agent_skill_versions/client.py index 25679d2b..f2456e12 100644 --- a/src/truefoundry_sdk/agent_skill_versions/client.py +++ b/src/truefoundry_sdk/agent_skill_versions/client.py @@ -84,11 +84,6 @@ def list( response = client.agent_skill_versions.list( limit=10, offset=0, - fqn="fqn", - agent_skill_id="agent_skill_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) for item in response: yield item @@ -253,11 +248,6 @@ async def main() -> None: response = await client.agent_skill_versions.list( limit=10, offset=0, - fqn="fqn", - agent_skill_id="agent_skill_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/agent_skills/client.py b/src/truefoundry_sdk/agent_skills/client.py index 556deafa..c32190b9 100644 --- a/src/truefoundry_sdk/agent_skills/client.py +++ b/src/truefoundry_sdk/agent_skills/client.py @@ -151,10 +151,6 @@ def list( response = client.agent_skills.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_agent_skills=True, ) for item in response: yield item @@ -375,10 +371,6 @@ async def main() -> None: response = await client.agent_skills.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_agent_skills=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/agent_versions/client.py b/src/truefoundry_sdk/agent_versions/client.py index ced22a82..260088c8 100644 --- a/src/truefoundry_sdk/agent_versions/client.py +++ b/src/truefoundry_sdk/agent_versions/client.py @@ -66,7 +66,6 @@ def list( response = client.agent_versions.list( limit=10, offset=0, - id="id", ) for item in response: yield item @@ -138,7 +137,6 @@ async def main() -> None: response = await client.agent_versions.list( limit=10, offset=0, - id="id", ) async for item in response: yield item diff --git a/src/truefoundry_sdk/agents/__init__.py b/src/truefoundry_sdk/agents/__init__.py index 57105290..68effd11 100644 --- a/src/truefoundry_sdk/agents/__init__.py +++ b/src/truefoundry_sdk/agents/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import AgentsListRequestType -_dynamic_imports: typing.Dict[str, str] = {"AgentsListRequestType": ".types"} + from .types import ListAgentsRequestType +_dynamic_imports: typing.Dict[str, str] = {"ListAgentsRequestType": ".types"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["AgentsListRequestType"] +__all__ = ["ListAgentsRequestType"] diff --git a/src/truefoundry_sdk/agents/client.py b/src/truefoundry_sdk/agents/client.py index eb52776d..1998e35c 100644 --- a/src/truefoundry_sdk/agents/client.py +++ b/src/truefoundry_sdk/agents/client.py @@ -11,7 +11,7 @@ from ..types.get_agent_version_response import GetAgentVersionResponse from ..types.list_agents_response import ListAgentsResponse from .raw_client import AsyncRawAgentsClient, RawAgentsClient -from .types.agents_list_request_type import AgentsListRequestType +from .types.list_agents_request_type import ListAgentsRequestType # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -39,8 +39,8 @@ def list( offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, name_prefix: typing.Optional[str] = None, - type: typing.Optional[AgentsListRequestType] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + type: typing.Optional[ListAgentsRequestType] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Agent, ListAgentsResponse]: """ @@ -60,10 +60,10 @@ def list( name_prefix : typing.Optional[str] When set, only agents whose name starts with this string (case-sensitive). Ignored when `name` is also provided. - type : typing.Optional[AgentsListRequestType] + type : typing.Optional[ListAgentsRequestType] Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -77,7 +77,6 @@ def list( Examples -------- from truefoundry_sdk import TrueFoundry - from truefoundry_sdk.agents import AgentsListRequestType client = TrueFoundry( api_key="YOUR_API_KEY", @@ -86,10 +85,6 @@ def list( response = client.agents.list( limit=10, offset=0, - name="name", - name_prefix="namePrefix", - type=AgentsListRequestType.REMOTE_AGENT, - attributes=["attributes"], ) for item in response: yield item @@ -253,8 +248,8 @@ async def list( offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, name_prefix: typing.Optional[str] = None, - type: typing.Optional[AgentsListRequestType] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + type: typing.Optional[ListAgentsRequestType] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Agent, ListAgentsResponse]: """ @@ -274,10 +269,10 @@ async def list( name_prefix : typing.Optional[str] When set, only agents whose name starts with this string (case-sensitive). Ignored when `name` is also provided. - type : typing.Optional[AgentsListRequestType] + type : typing.Optional[ListAgentsRequestType] Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -293,7 +288,6 @@ async def list( import asyncio from truefoundry_sdk import AsyncTrueFoundry - from truefoundry_sdk.agents import AgentsListRequestType client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -305,10 +299,6 @@ async def main() -> None: response = await client.agents.list( limit=10, offset=0, - name="name", - name_prefix="namePrefix", - type=AgentsListRequestType.REMOTE_AGENT, - attributes=["attributes"], ) async for item in response: yield item diff --git a/src/truefoundry_sdk/agents/raw_client.py b/src/truefoundry_sdk/agents/raw_client.py index d9768df6..d7622515 100644 --- a/src/truefoundry_sdk/agents/raw_client.py +++ b/src/truefoundry_sdk/agents/raw_client.py @@ -23,7 +23,7 @@ from ..types.get_agent_version_response import GetAgentVersionResponse from ..types.http_error import HttpError from ..types.list_agents_response import ListAgentsResponse -from .types.agents_list_request_type import AgentsListRequestType +from .types.list_agents_request_type import ListAgentsRequestType from pydantic import ValidationError # this is used as the default value for optional parameters @@ -41,8 +41,8 @@ def list( offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, name_prefix: typing.Optional[str] = None, - type: typing.Optional[AgentsListRequestType] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + type: typing.Optional[ListAgentsRequestType] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Agent, ListAgentsResponse]: """ @@ -62,10 +62,10 @@ def list( name_prefix : typing.Optional[str] When set, only agents whose name starts with this string (case-sensitive). Ignored when `name` is also provided. - type : typing.Optional[AgentsListRequestType] + type : typing.Optional[ListAgentsRequestType] Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -401,8 +401,8 @@ async def list( offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, name_prefix: typing.Optional[str] = None, - type: typing.Optional[AgentsListRequestType] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + type: typing.Optional[ListAgentsRequestType] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Agent, ListAgentsResponse]: """ @@ -422,10 +422,10 @@ async def list( name_prefix : typing.Optional[str] When set, only agents whose name starts with this string (case-sensitive). Ignored when `name` is also provided. - type : typing.Optional[AgentsListRequestType] + type : typing.Optional[ListAgentsRequestType] Filter by latest manifest discriminator (`remote-agent`, `truefoundry-agent`, or `agent`). NOTE: `agent` is a legacy type and will be removed in the future. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/agents/types/__init__.py b/src/truefoundry_sdk/agents/types/__init__.py index 6b7c4072..2a463560 100644 --- a/src/truefoundry_sdk/agents/types/__init__.py +++ b/src/truefoundry_sdk/agents/types/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .agents_list_request_type import AgentsListRequestType -_dynamic_imports: typing.Dict[str, str] = {"AgentsListRequestType": ".agents_list_request_type"} + from .list_agents_request_type import ListAgentsRequestType +_dynamic_imports: typing.Dict[str, str] = {"ListAgentsRequestType": ".list_agents_request_type"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["AgentsListRequestType"] +__all__ = ["ListAgentsRequestType"] diff --git a/src/truefoundry_sdk/agents/types/agents_list_request_type.py b/src/truefoundry_sdk/agents/types/list_agents_request_type.py similarity index 74% rename from src/truefoundry_sdk/agents/types/agents_list_request_type.py rename to src/truefoundry_sdk/agents/types/list_agents_request_type.py index d87c3ba4..9682ff0e 100644 --- a/src/truefoundry_sdk/agents/types/agents_list_request_type.py +++ b/src/truefoundry_sdk/agents/types/list_agents_request_type.py @@ -7,17 +7,17 @@ T_Result = typing.TypeVar("T_Result") -class AgentsListRequestType(enum.StrEnum): +class ListAgentsRequestType(enum.StrEnum): REMOTE_AGENT = "remote-agent" TRUEFOUNDRY_AGENT = "truefoundry-agent" AGENT = "agent" - _UNKNOWN = "__AGENTSLISTREQUESTTYPE_UNKNOWN__" + _UNKNOWN = "__LISTAGENTSREQUESTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "AgentsListRequestType": + def _missing_(cls, value: typing.Any) -> "ListAgentsRequestType": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -29,10 +29,10 @@ def visit( agent: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is AgentsListRequestType.REMOTE_AGENT: + if self is ListAgentsRequestType.REMOTE_AGENT: return remote_agent() - if self is AgentsListRequestType.TRUEFOUNDRY_AGENT: + if self is ListAgentsRequestType.TRUEFOUNDRY_AGENT: return truefoundry_agent() - if self is AgentsListRequestType.AGENT: + if self is ListAgentsRequestType.AGENT: return agent() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/alerts/client.py b/src/truefoundry_sdk/alerts/client.py index afbbe3de..fe78e4cd 100644 --- a/src/truefoundry_sdk/alerts/client.py +++ b/src/truefoundry_sdk/alerts/client.py @@ -64,19 +64,13 @@ def list( Examples -------- - from truefoundry_sdk import AlertStatus, TrueFoundry + from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.alerts.list( - start_ts="startTs", - end_ts="endTs", - cluster_id="clusterId", - application_id="applicationId", - alert_status=AlertStatus.FIRING, - ) + client.alerts.list() """ _response = self._raw_client.list( start_ts=start_ts, @@ -146,7 +140,7 @@ async def list( -------- import asyncio - from truefoundry_sdk import AlertStatus, AsyncTrueFoundry + from truefoundry_sdk import AsyncTrueFoundry client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -155,13 +149,7 @@ async def list( async def main() -> None: - await client.alerts.list( - start_ts="startTs", - end_ts="endTs", - cluster_id="clusterId", - application_id="applicationId", - alert_status=AlertStatus.FIRING, - ) + await client.alerts.list() asyncio.run(main()) diff --git a/src/truefoundry_sdk/applications/__init__.py b/src/truefoundry_sdk/applications/__init__.py index 892fbccd..15ac4877 100644 --- a/src/truefoundry_sdk/applications/__init__.py +++ b/src/truefoundry_sdk/applications/__init__.py @@ -7,14 +7,14 @@ if typing.TYPE_CHECKING: from .types import ( - ApplicationsCancelDeploymentResponse, - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, + CancelDeploymentApplicationsResponse, + ListApplicationsRequestDeviceTypeFilter, + ListApplicationsRequestLifecycleStage, ) _dynamic_imports: typing.Dict[str, str] = { - "ApplicationsCancelDeploymentResponse": ".types", - "ApplicationsListRequestDeviceTypeFilter": ".types", - "ApplicationsListRequestLifecycleStage": ".types", + "CancelDeploymentApplicationsResponse": ".types", + "ListApplicationsRequestDeviceTypeFilter": ".types", + "ListApplicationsRequestLifecycleStage": ".types", } @@ -40,7 +40,7 @@ def __dir__(): __all__ = [ - "ApplicationsCancelDeploymentResponse", - "ApplicationsListRequestDeviceTypeFilter", - "ApplicationsListRequestLifecycleStage", + "CancelDeploymentApplicationsResponse", + "ListApplicationsRequestDeviceTypeFilter", + "ListApplicationsRequestLifecycleStage", ] diff --git a/src/truefoundry_sdk/applications/client.py b/src/truefoundry_sdk/applications/client.py index d56d9ebc..81808c4e 100644 --- a/src/truefoundry_sdk/applications/client.py +++ b/src/truefoundry_sdk/applications/client.py @@ -13,9 +13,9 @@ from ..types.get_application_response import GetApplicationResponse from ..types.list_applications_response import ListApplicationsResponse from .raw_client import AsyncRawApplicationsClient, RawApplicationsClient -from .types.applications_cancel_deployment_response import ApplicationsCancelDeploymentResponse -from .types.applications_list_request_device_type_filter import ApplicationsListRequestDeviceTypeFilter -from .types.applications_list_request_lifecycle_stage import ApplicationsListRequestLifecycleStage +from .types.cancel_deployment_applications_response import CancelDeploymentApplicationsResponse +from .types.list_applications_request_device_type_filter import ListApplicationsRequestDeviceTypeFilter +from .types.list_applications_request_lifecycle_stage import ListApplicationsRequestLifecycleStage # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -52,9 +52,9 @@ def list( cluster_id: typing.Optional[str] = None, application_set_id: typing.Optional[str] = None, paused: typing.Optional[bool] = None, - device_type_filter: typing.Optional[ApplicationsListRequestDeviceTypeFilter] = None, + device_type_filter: typing.Optional[ListApplicationsRequestDeviceTypeFilter] = None, last_deployed_by_subjects: typing.Optional[str] = None, - lifecycle_stage: typing.Optional[ApplicationsListRequestLifecycleStage] = None, + lifecycle_stage: typing.Optional[ListApplicationsRequestLifecycleStage] = None, is_recommendation_present_and_visible: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Application, ListApplicationsResponse]: @@ -102,13 +102,13 @@ def list( paused : typing.Optional[bool] Filter by explicit pause state (true = paused, false = not paused). Does not account for autoshutdown. - device_type_filter : typing.Optional[ApplicationsListRequestDeviceTypeFilter] + device_type_filter : typing.Optional[ListApplicationsRequestDeviceTypeFilter] Device type to filter by (comma-separated). last_deployed_by_subjects : typing.Optional[str] Subject slugs of last deployers to filter by (comma-separated). Email for users (e.g. user@example.com), name for virtual accounts. - lifecycle_stage : typing.Optional[ApplicationsListRequestLifecycleStage] + lifecycle_stage : typing.Optional[ListApplicationsRequestLifecycleStage] Application lifecycle stage to filter by is_recommendation_present_and_visible : typing.Optional[bool] @@ -124,11 +124,7 @@ def list( Examples -------- - from truefoundry_sdk import ApplicationType, TrueFoundry - from truefoundry_sdk.applications import ( - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, - ) + from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -137,21 +133,6 @@ def list( response = client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) for item in response: yield item @@ -422,7 +403,7 @@ def scale_to_original(self, id: str, *, request_options: typing.Optional[Request def cancel_deployment( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> ApplicationsCancelDeploymentResponse: + ) -> CancelDeploymentApplicationsResponse: """ Cancel an in-progress deployment. @@ -439,7 +420,7 @@ def cancel_deployment( Returns ------- - ApplicationsCancelDeploymentResponse + CancelDeploymentApplicationsResponse Deployment cancelled. Examples @@ -490,9 +471,9 @@ async def list( cluster_id: typing.Optional[str] = None, application_set_id: typing.Optional[str] = None, paused: typing.Optional[bool] = None, - device_type_filter: typing.Optional[ApplicationsListRequestDeviceTypeFilter] = None, + device_type_filter: typing.Optional[ListApplicationsRequestDeviceTypeFilter] = None, last_deployed_by_subjects: typing.Optional[str] = None, - lifecycle_stage: typing.Optional[ApplicationsListRequestLifecycleStage] = None, + lifecycle_stage: typing.Optional[ListApplicationsRequestLifecycleStage] = None, is_recommendation_present_and_visible: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Application, ListApplicationsResponse]: @@ -540,13 +521,13 @@ async def list( paused : typing.Optional[bool] Filter by explicit pause state (true = paused, false = not paused). Does not account for autoshutdown. - device_type_filter : typing.Optional[ApplicationsListRequestDeviceTypeFilter] + device_type_filter : typing.Optional[ListApplicationsRequestDeviceTypeFilter] Device type to filter by (comma-separated). last_deployed_by_subjects : typing.Optional[str] Subject slugs of last deployers to filter by (comma-separated). Email for users (e.g. user@example.com), name for virtual accounts. - lifecycle_stage : typing.Optional[ApplicationsListRequestLifecycleStage] + lifecycle_stage : typing.Optional[ListApplicationsRequestLifecycleStage] Application lifecycle stage to filter by is_recommendation_present_and_visible : typing.Optional[bool] @@ -564,11 +545,7 @@ async def list( -------- import asyncio - from truefoundry_sdk import ApplicationType, AsyncTrueFoundry - from truefoundry_sdk.applications import ( - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, - ) + from truefoundry_sdk import AsyncTrueFoundry client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -580,21 +557,6 @@ async def main() -> None: response = await client.applications.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type=ApplicationType.ASYNC_SERVICE, - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, - is_recommendation_present_and_visible=True, ) async for item in response: yield item @@ -921,7 +883,7 @@ async def main() -> None: async def cancel_deployment( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> ApplicationsCancelDeploymentResponse: + ) -> CancelDeploymentApplicationsResponse: """ Cancel an in-progress deployment. @@ -938,7 +900,7 @@ async def cancel_deployment( Returns ------- - ApplicationsCancelDeploymentResponse + CancelDeploymentApplicationsResponse Deployment cancelled. Examples diff --git a/src/truefoundry_sdk/applications/raw_client.py b/src/truefoundry_sdk/applications/raw_client.py index 24ea313e..2096cfc7 100644 --- a/src/truefoundry_sdk/applications/raw_client.py +++ b/src/truefoundry_sdk/applications/raw_client.py @@ -25,9 +25,9 @@ from ..types.get_application_response import GetApplicationResponse from ..types.http_error import HttpError from ..types.list_applications_response import ListApplicationsResponse -from .types.applications_cancel_deployment_response import ApplicationsCancelDeploymentResponse -from .types.applications_list_request_device_type_filter import ApplicationsListRequestDeviceTypeFilter -from .types.applications_list_request_lifecycle_stage import ApplicationsListRequestLifecycleStage +from .types.cancel_deployment_applications_response import CancelDeploymentApplicationsResponse +from .types.list_applications_request_device_type_filter import ListApplicationsRequestDeviceTypeFilter +from .types.list_applications_request_lifecycle_stage import ListApplicationsRequestLifecycleStage from pydantic import ValidationError # this is used as the default value for optional parameters @@ -54,9 +54,9 @@ def list( cluster_id: typing.Optional[str] = None, application_set_id: typing.Optional[str] = None, paused: typing.Optional[bool] = None, - device_type_filter: typing.Optional[ApplicationsListRequestDeviceTypeFilter] = None, + device_type_filter: typing.Optional[ListApplicationsRequestDeviceTypeFilter] = None, last_deployed_by_subjects: typing.Optional[str] = None, - lifecycle_stage: typing.Optional[ApplicationsListRequestLifecycleStage] = None, + lifecycle_stage: typing.Optional[ListApplicationsRequestLifecycleStage] = None, is_recommendation_present_and_visible: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Application, ListApplicationsResponse]: @@ -104,13 +104,13 @@ def list( paused : typing.Optional[bool] Filter by explicit pause state (true = paused, false = not paused). Does not account for autoshutdown. - device_type_filter : typing.Optional[ApplicationsListRequestDeviceTypeFilter] + device_type_filter : typing.Optional[ListApplicationsRequestDeviceTypeFilter] Device type to filter by (comma-separated). last_deployed_by_subjects : typing.Optional[str] Subject slugs of last deployers to filter by (comma-separated). Email for users (e.g. user@example.com), name for virtual accounts. - lifecycle_stage : typing.Optional[ApplicationsListRequestLifecycleStage] + lifecycle_stage : typing.Optional[ListApplicationsRequestLifecycleStage] Application lifecycle stage to filter by is_recommendation_present_and_visible : typing.Optional[bool] @@ -687,7 +687,7 @@ def scale_to_original( def cancel_deployment( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[ApplicationsCancelDeploymentResponse]: + ) -> HttpResponse[CancelDeploymentApplicationsResponse]: """ Cancel an in-progress deployment. @@ -704,7 +704,7 @@ def cancel_deployment( Returns ------- - HttpResponse[ApplicationsCancelDeploymentResponse] + HttpResponse[CancelDeploymentApplicationsResponse] Deployment cancelled. """ _response = self._client_wrapper.httpx_client.request( @@ -715,9 +715,9 @@ def cancel_deployment( try: if 200 <= _response.status_code < 300: _data = typing.cast( - ApplicationsCancelDeploymentResponse, + CancelDeploymentApplicationsResponse, parse_obj_as( - type_=ApplicationsCancelDeploymentResponse, # type: ignore + type_=CancelDeploymentApplicationsResponse, # type: ignore object_=_response.json(), ), ) @@ -785,9 +785,9 @@ async def list( cluster_id: typing.Optional[str] = None, application_set_id: typing.Optional[str] = None, paused: typing.Optional[bool] = None, - device_type_filter: typing.Optional[ApplicationsListRequestDeviceTypeFilter] = None, + device_type_filter: typing.Optional[ListApplicationsRequestDeviceTypeFilter] = None, last_deployed_by_subjects: typing.Optional[str] = None, - lifecycle_stage: typing.Optional[ApplicationsListRequestLifecycleStage] = None, + lifecycle_stage: typing.Optional[ListApplicationsRequestLifecycleStage] = None, is_recommendation_present_and_visible: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Application, ListApplicationsResponse]: @@ -835,13 +835,13 @@ async def list( paused : typing.Optional[bool] Filter by explicit pause state (true = paused, false = not paused). Does not account for autoshutdown. - device_type_filter : typing.Optional[ApplicationsListRequestDeviceTypeFilter] + device_type_filter : typing.Optional[ListApplicationsRequestDeviceTypeFilter] Device type to filter by (comma-separated). last_deployed_by_subjects : typing.Optional[str] Subject slugs of last deployers to filter by (comma-separated). Email for users (e.g. user@example.com), name for virtual accounts. - lifecycle_stage : typing.Optional[ApplicationsListRequestLifecycleStage] + lifecycle_stage : typing.Optional[ListApplicationsRequestLifecycleStage] Application lifecycle stage to filter by is_recommendation_present_and_visible : typing.Optional[bool] @@ -1423,7 +1423,7 @@ async def scale_to_original( async def cancel_deployment( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[ApplicationsCancelDeploymentResponse]: + ) -> AsyncHttpResponse[CancelDeploymentApplicationsResponse]: """ Cancel an in-progress deployment. @@ -1440,7 +1440,7 @@ async def cancel_deployment( Returns ------- - AsyncHttpResponse[ApplicationsCancelDeploymentResponse] + AsyncHttpResponse[CancelDeploymentApplicationsResponse] Deployment cancelled. """ _response = await self._client_wrapper.httpx_client.request( @@ -1451,9 +1451,9 @@ async def cancel_deployment( try: if 200 <= _response.status_code < 300: _data = typing.cast( - ApplicationsCancelDeploymentResponse, + CancelDeploymentApplicationsResponse, parse_obj_as( - type_=ApplicationsCancelDeploymentResponse, # type: ignore + type_=CancelDeploymentApplicationsResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/truefoundry_sdk/applications/types/__init__.py b/src/truefoundry_sdk/applications/types/__init__.py index c170b79b..656ef365 100644 --- a/src/truefoundry_sdk/applications/types/__init__.py +++ b/src/truefoundry_sdk/applications/types/__init__.py @@ -6,13 +6,13 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .applications_cancel_deployment_response import ApplicationsCancelDeploymentResponse - from .applications_list_request_device_type_filter import ApplicationsListRequestDeviceTypeFilter - from .applications_list_request_lifecycle_stage import ApplicationsListRequestLifecycleStage + from .cancel_deployment_applications_response import CancelDeploymentApplicationsResponse + from .list_applications_request_device_type_filter import ListApplicationsRequestDeviceTypeFilter + from .list_applications_request_lifecycle_stage import ListApplicationsRequestLifecycleStage _dynamic_imports: typing.Dict[str, str] = { - "ApplicationsCancelDeploymentResponse": ".applications_cancel_deployment_response", - "ApplicationsListRequestDeviceTypeFilter": ".applications_list_request_device_type_filter", - "ApplicationsListRequestLifecycleStage": ".applications_list_request_lifecycle_stage", + "CancelDeploymentApplicationsResponse": ".cancel_deployment_applications_response", + "ListApplicationsRequestDeviceTypeFilter": ".list_applications_request_device_type_filter", + "ListApplicationsRequestLifecycleStage": ".list_applications_request_lifecycle_stage", } @@ -38,7 +38,7 @@ def __dir__(): __all__ = [ - "ApplicationsCancelDeploymentResponse", - "ApplicationsListRequestDeviceTypeFilter", - "ApplicationsListRequestLifecycleStage", + "CancelDeploymentApplicationsResponse", + "ListApplicationsRequestDeviceTypeFilter", + "ListApplicationsRequestLifecycleStage", ] diff --git a/src/truefoundry_sdk/applications/types/applications_cancel_deployment_response.py b/src/truefoundry_sdk/applications/types/cancel_deployment_applications_response.py similarity index 89% rename from src/truefoundry_sdk/applications/types/applications_cancel_deployment_response.py rename to src/truefoundry_sdk/applications/types/cancel_deployment_applications_response.py index b13640fd..ca3560e4 100644 --- a/src/truefoundry_sdk/applications/types/applications_cancel_deployment_response.py +++ b/src/truefoundry_sdk/applications/types/cancel_deployment_applications_response.py @@ -6,7 +6,7 @@ from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class ApplicationsCancelDeploymentResponse(UniversalBaseModel): +class CancelDeploymentApplicationsResponse(UniversalBaseModel): message: typing.Optional[str] = pydantic.Field(default=None) """ Deployment cancelled diff --git a/src/truefoundry_sdk/applications/types/applications_list_request_device_type_filter.py b/src/truefoundry_sdk/applications/types/list_applications_request_device_type_filter.py similarity index 70% rename from src/truefoundry_sdk/applications/types/applications_list_request_device_type_filter.py rename to src/truefoundry_sdk/applications/types/list_applications_request_device_type_filter.py index 30c137e5..7249acfe 100644 --- a/src/truefoundry_sdk/applications/types/applications_list_request_device_type_filter.py +++ b/src/truefoundry_sdk/applications/types/list_applications_request_device_type_filter.py @@ -7,20 +7,20 @@ T_Result = typing.TypeVar("T_Result") -class ApplicationsListRequestDeviceTypeFilter(enum.StrEnum): +class ListApplicationsRequestDeviceTypeFilter(enum.StrEnum): CPU = "cpu" NVIDIA_GPU = "nvidia_gpu" AWS_INFERENTIA = "aws_inferentia" NVIDIA_MIG_GPU = "nvidia_mig_gpu" NVIDIA_TIMESLICING_GPU = "nvidia_timeslicing_gpu" GCP_TPU = "gcp_tpu" - _UNKNOWN = "__APPLICATIONSLISTREQUESTDEVICETYPEFILTER_UNKNOWN__" + _UNKNOWN = "__LISTAPPLICATIONSREQUESTDEVICETYPEFILTER_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "ApplicationsListRequestDeviceTypeFilter": + def _missing_(cls, value: typing.Any) -> "ListApplicationsRequestDeviceTypeFilter": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -35,16 +35,16 @@ def visit( gcp_tpu: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is ApplicationsListRequestDeviceTypeFilter.CPU: + if self is ListApplicationsRequestDeviceTypeFilter.CPU: return cpu() - if self is ApplicationsListRequestDeviceTypeFilter.NVIDIA_GPU: + if self is ListApplicationsRequestDeviceTypeFilter.NVIDIA_GPU: return nvidia_gpu() - if self is ApplicationsListRequestDeviceTypeFilter.AWS_INFERENTIA: + if self is ListApplicationsRequestDeviceTypeFilter.AWS_INFERENTIA: return aws_inferentia() - if self is ApplicationsListRequestDeviceTypeFilter.NVIDIA_MIG_GPU: + if self is ListApplicationsRequestDeviceTypeFilter.NVIDIA_MIG_GPU: return nvidia_mig_gpu() - if self is ApplicationsListRequestDeviceTypeFilter.NVIDIA_TIMESLICING_GPU: + if self is ListApplicationsRequestDeviceTypeFilter.NVIDIA_TIMESLICING_GPU: return nvidia_timeslicing_gpu() - if self is ApplicationsListRequestDeviceTypeFilter.GCP_TPU: + if self is ListApplicationsRequestDeviceTypeFilter.GCP_TPU: return gcp_tpu() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/applications/types/applications_list_request_lifecycle_stage.py b/src/truefoundry_sdk/applications/types/list_applications_request_lifecycle_stage.py similarity index 71% rename from src/truefoundry_sdk/applications/types/applications_list_request_lifecycle_stage.py rename to src/truefoundry_sdk/applications/types/list_applications_request_lifecycle_stage.py index e3fe18a5..ad1a59db 100644 --- a/src/truefoundry_sdk/applications/types/applications_list_request_lifecycle_stage.py +++ b/src/truefoundry_sdk/applications/types/list_applications_request_lifecycle_stage.py @@ -7,17 +7,17 @@ T_Result = typing.TypeVar("T_Result") -class ApplicationsListRequestLifecycleStage(enum.StrEnum): +class ListApplicationsRequestLifecycleStage(enum.StrEnum): ACTIVE = "active" DELETING = "deleting" DELETION_FAILED = "deletion_failed" - _UNKNOWN = "__APPLICATIONSLISTREQUESTLIFECYCLESTAGE_UNKNOWN__" + _UNKNOWN = "__LISTAPPLICATIONSREQUESTLIFECYCLESTAGE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "ApplicationsListRequestLifecycleStage": + def _missing_(cls, value: typing.Any) -> "ListApplicationsRequestLifecycleStage": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -29,10 +29,10 @@ def visit( deletion_failed: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is ApplicationsListRequestLifecycleStage.ACTIVE: + if self is ListApplicationsRequestLifecycleStage.ACTIVE: return active() - if self is ApplicationsListRequestLifecycleStage.DELETING: + if self is ListApplicationsRequestLifecycleStage.DELETING: return deleting() - if self is ApplicationsListRequestLifecycleStage.DELETION_FAILED: + if self is ListApplicationsRequestLifecycleStage.DELETION_FAILED: return deletion_failed() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/artifact_versions/client.py b/src/truefoundry_sdk/artifact_versions/client.py index 516b3be4..48906611 100644 --- a/src/truefoundry_sdk/artifact_versions/client.py +++ b/src/truefoundry_sdk/artifact_versions/client.py @@ -48,8 +48,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ArtifactVersion, ListArtifactVersionsResponse]: @@ -82,10 +82,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -110,15 +110,6 @@ def list( response = client.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, ) for item in response: yield item @@ -502,8 +493,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse]: @@ -536,10 +527,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -569,15 +560,6 @@ async def main() -> None: response = await client.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/artifact_versions/raw_client.py b/src/truefoundry_sdk/artifact_versions/raw_client.py index 2642f753..aa947a6c 100644 --- a/src/truefoundry_sdk/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/artifact_versions/raw_client.py @@ -45,8 +45,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ArtifactVersion, ListArtifactVersionsResponse]: @@ -79,10 +79,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -642,8 +642,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse]: @@ -676,10 +676,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] diff --git a/src/truefoundry_sdk/artifacts/client.py b/src/truefoundry_sdk/artifacts/client.py index 11364dc1..0f42d8f1 100644 --- a/src/truefoundry_sdk/artifacts/client.py +++ b/src/truefoundry_sdk/artifacts/client.py @@ -153,11 +153,6 @@ def list( response = client.artifacts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_artifacts=True, ) for item in response: yield item @@ -376,11 +371,6 @@ async def main() -> None: response = await client.artifacts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_artifacts=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/clusters/client.py b/src/truefoundry_sdk/clusters/client.py index c019f118..7a106371 100644 --- a/src/truefoundry_sdk/clusters/client.py +++ b/src/truefoundry_sdk/clusters/client.py @@ -38,7 +38,7 @@ def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Cluster, ListClustersResponse]: """ @@ -52,7 +52,7 @@ def list( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -74,7 +74,6 @@ def list( response = client.clusters.list( limit=10, offset=0, - attributes=["attributes"], ) for item in response: yield item @@ -212,7 +211,7 @@ def get_addons( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ListClusterAddonsResponse: """ @@ -229,7 +228,7 @@ def get_addons( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -252,7 +251,6 @@ def get_addons( id="id", limit=10, offset=0, - attributes=["attributes"], ) """ _response = self._raw_client.get_addons( @@ -315,7 +313,7 @@ async def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Cluster, ListClustersResponse]: """ @@ -329,7 +327,7 @@ async def list( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -356,7 +354,6 @@ async def main() -> None: response = await client.clusters.list( limit=10, offset=0, - attributes=["attributes"], ) async for item in response: yield item @@ -526,7 +523,7 @@ async def get_addons( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ListClusterAddonsResponse: """ @@ -543,7 +540,7 @@ async def get_addons( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -571,7 +568,6 @@ async def main() -> None: id="id", limit=10, offset=0, - attributes=["attributes"], ) diff --git a/src/truefoundry_sdk/clusters/raw_client.py b/src/truefoundry_sdk/clusters/raw_client.py index cf2c525a..8d56a040 100644 --- a/src/truefoundry_sdk/clusters/raw_client.py +++ b/src/truefoundry_sdk/clusters/raw_client.py @@ -39,7 +39,7 @@ def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Cluster, ListClustersResponse]: """ @@ -53,7 +53,7 @@ def list( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -343,7 +343,7 @@ def get_addons( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ListClusterAddonsResponse]: """ @@ -360,7 +360,7 @@ def get_addons( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -486,7 +486,7 @@ async def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Cluster, ListClustersResponse]: """ @@ -500,7 +500,7 @@ async def list( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -793,7 +793,7 @@ async def get_addons( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ListClusterAddonsResponse]: """ @@ -810,7 +810,7 @@ async def get_addons( offset : typing.Optional[int] Number of items to skip - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/data_directories/client.py b/src/truefoundry_sdk/data_directories/client.py index 22109971..df08bc30 100644 --- a/src/truefoundry_sdk/data_directories/client.py +++ b/src/truefoundry_sdk/data_directories/client.py @@ -85,9 +85,6 @@ def list( response = client.data_directories.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", ) for item in response: yield item @@ -396,7 +393,6 @@ def delete( ) client.data_directories.delete( id="id", - delete_contents=True, ) """ _response = self._raw_client.delete(id, delete_contents=delete_contents, request_options=request_options) @@ -472,9 +468,6 @@ async def main() -> None: response = await client.data_directories.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", ) async for item in response: yield item @@ -843,7 +836,6 @@ async def delete( async def main() -> None: await client.data_directories.delete( id="id", - delete_contents=True, ) diff --git a/src/truefoundry_sdk/events/client.py b/src/truefoundry_sdk/events/client.py index b9506bbb..e5804cf1 100644 --- a/src/truefoundry_sdk/events/client.py +++ b/src/truefoundry_sdk/events/client.py @@ -30,7 +30,7 @@ def get( end_ts: typing.Optional[str] = None, application_id: typing.Optional[str] = None, application_fqn: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, job_run_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GetEventsResponse: @@ -51,7 +51,7 @@ def get( application_fqn : typing.Optional[str] Fully qualified name of the application. Either applicationId or applicationFqn must be provided. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName. job_run_name : typing.Optional[str] @@ -73,14 +73,7 @@ def get( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.events.get( - start_ts="startTs", - end_ts="endTs", - application_id="applicationId", - application_fqn="applicationFqn", - pod_names=["podNames"], - job_run_name="jobRunName", - ) + client.events.get() """ _response = self._raw_client.get( start_ts=start_ts, @@ -116,7 +109,7 @@ async def get( end_ts: typing.Optional[str] = None, application_id: typing.Optional[str] = None, application_fqn: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, job_run_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> GetEventsResponse: @@ -137,7 +130,7 @@ async def get( application_fqn : typing.Optional[str] Fully qualified name of the application. Either applicationId or applicationFqn must be provided. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName. job_run_name : typing.Optional[str] @@ -164,14 +157,7 @@ async def get( async def main() -> None: - await client.events.get( - start_ts="startTs", - end_ts="endTs", - application_id="applicationId", - application_fqn="applicationFqn", - pod_names=["podNames"], - job_run_name="jobRunName", - ) + await client.events.get() asyncio.run(main()) diff --git a/src/truefoundry_sdk/events/raw_client.py b/src/truefoundry_sdk/events/raw_client.py index b8ada4d7..2c67b3bd 100644 --- a/src/truefoundry_sdk/events/raw_client.py +++ b/src/truefoundry_sdk/events/raw_client.py @@ -28,7 +28,7 @@ def get( end_ts: typing.Optional[str] = None, application_id: typing.Optional[str] = None, application_fqn: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, job_run_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetEventsResponse]: @@ -49,7 +49,7 @@ def get( application_fqn : typing.Optional[str] Fully qualified name of the application. Either applicationId or applicationFqn must be provided. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName. job_run_name : typing.Optional[str] @@ -140,7 +140,7 @@ async def get( end_ts: typing.Optional[str] = None, application_id: typing.Optional[str] = None, application_fqn: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, job_run_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetEventsResponse]: @@ -161,7 +161,7 @@ async def get( application_fqn : typing.Optional[str] Fully qualified name of the application. Either applicationId or applicationFqn must be provided. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of Kubernetes pod names to filter events. Cannot be provided together with jobRunName. job_run_name : typing.Optional[str] diff --git a/src/truefoundry_sdk/internal/__init__.py b/src/truefoundry_sdk/internal/__init__.py index 4dfb0a17..ebbe08bf 100644 --- a/src/truefoundry_sdk/internal/__init__.py +++ b/src/truefoundry_sdk/internal/__init__.py @@ -19,13 +19,13 @@ vcs, workflows, ) - from .ai_gateway import AiGatewayGetGatewayConfigRequestType - from .metrics import MetricsGetChartsRequestFilterEntity - from .workflows import WorkflowsExecuteWorkflowResponse + from .ai_gateway import GetGatewayConfigAiGatewayRequestType + from .metrics import GetChartsMetricsRequestFilterEntity + from .workflows import ExecuteWorkflowWorkflowsResponse _dynamic_imports: typing.Dict[str, str] = { - "AiGatewayGetGatewayConfigRequestType": ".ai_gateway", - "MetricsGetChartsRequestFilterEntity": ".metrics", - "WorkflowsExecuteWorkflowResponse": ".workflows", + "ExecuteWorkflowWorkflowsResponse": ".workflows", + "GetChartsMetricsRequestFilterEntity": ".metrics", + "GetGatewayConfigAiGatewayRequestType": ".ai_gateway", "ai_gateway": ".ai_gateway", "applications": ".applications", "artifact_versions": ".artifact_versions", @@ -62,9 +62,9 @@ def __dir__(): __all__ = [ - "AiGatewayGetGatewayConfigRequestType", - "MetricsGetChartsRequestFilterEntity", - "WorkflowsExecuteWorkflowResponse", + "ExecuteWorkflowWorkflowsResponse", + "GetChartsMetricsRequestFilterEntity", + "GetGatewayConfigAiGatewayRequestType", "ai_gateway", "applications", "artifact_versions", diff --git a/src/truefoundry_sdk/internal/ai_gateway/__init__.py b/src/truefoundry_sdk/internal/ai_gateway/__init__.py index f601c83a..7ca99ac2 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/__init__.py +++ b/src/truefoundry_sdk/internal/ai_gateway/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import AiGatewayGetGatewayConfigRequestType -_dynamic_imports: typing.Dict[str, str] = {"AiGatewayGetGatewayConfigRequestType": ".types"} + from .types import GetGatewayConfigAiGatewayRequestType +_dynamic_imports: typing.Dict[str, str] = {"GetGatewayConfigAiGatewayRequestType": ".types"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["AiGatewayGetGatewayConfigRequestType"] +__all__ = ["GetGatewayConfigAiGatewayRequestType"] diff --git a/src/truefoundry_sdk/internal/ai_gateway/client.py b/src/truefoundry_sdk/internal/ai_gateway/client.py index 1ac40d0a..d32fa8bb 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/client.py +++ b/src/truefoundry_sdk/internal/ai_gateway/client.py @@ -6,7 +6,7 @@ from ...core.request_options import RequestOptions from ...types.gateway_configuration import GatewayConfiguration from .raw_client import AsyncRawAiGatewayClient, RawAiGatewayClient -from .types.ai_gateway_get_gateway_config_request_type import AiGatewayGetGatewayConfigRequestType +from .types.get_gateway_config_ai_gateway_request_type import GetGatewayConfigAiGatewayRequestType class AiGatewayClient: @@ -25,14 +25,14 @@ def with_raw_response(self) -> RawAiGatewayClient: return self._raw_client def get_gateway_config( - self, type: AiGatewayGetGatewayConfigRequestType, *, request_options: typing.Optional[RequestOptions] = None + self, type: GetGatewayConfigAiGatewayRequestType, *, request_options: typing.Optional[RequestOptions] = None ) -> GatewayConfiguration: """ Get the AI Gateway configuration for the given type. Parameters ---------- - type : AiGatewayGetGatewayConfigRequestType + type : GetGatewayConfigAiGatewayRequestType The type of gateway configuration to retrieve or delete. request_options : typing.Optional[RequestOptions] @@ -47,7 +47,7 @@ def get_gateway_config( -------- from truefoundry_sdk import TrueFoundry from truefoundry_sdk.internal.ai_gateway import ( - AiGatewayGetGatewayConfigRequestType, + GetGatewayConfigAiGatewayRequestType, ) client = TrueFoundry( @@ -55,7 +55,7 @@ def get_gateway_config( base_url="https://yourhost.com/path/to/api", ) client.internal.ai_gateway.get_gateway_config( - type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, + type=GetGatewayConfigAiGatewayRequestType.GATEWAY_RATE_LIMITING_CONFIG, ) """ _response = self._raw_client.get_gateway_config(type, request_options=request_options) @@ -104,14 +104,14 @@ def with_raw_response(self) -> AsyncRawAiGatewayClient: return self._raw_client async def get_gateway_config( - self, type: AiGatewayGetGatewayConfigRequestType, *, request_options: typing.Optional[RequestOptions] = None + self, type: GetGatewayConfigAiGatewayRequestType, *, request_options: typing.Optional[RequestOptions] = None ) -> GatewayConfiguration: """ Get the AI Gateway configuration for the given type. Parameters ---------- - type : AiGatewayGetGatewayConfigRequestType + type : GetGatewayConfigAiGatewayRequestType The type of gateway configuration to retrieve or delete. request_options : typing.Optional[RequestOptions] @@ -128,7 +128,7 @@ async def get_gateway_config( from truefoundry_sdk import AsyncTrueFoundry from truefoundry_sdk.internal.ai_gateway import ( - AiGatewayGetGatewayConfigRequestType, + GetGatewayConfigAiGatewayRequestType, ) client = AsyncTrueFoundry( @@ -139,7 +139,7 @@ async def get_gateway_config( async def main() -> None: await client.internal.ai_gateway.get_gateway_config( - type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, + type=GetGatewayConfigAiGatewayRequestType.GATEWAY_RATE_LIMITING_CONFIG, ) diff --git a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py index 90780412..d501839b 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py +++ b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py @@ -12,7 +12,7 @@ from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...types.gateway_configuration import GatewayConfiguration -from .types.ai_gateway_get_gateway_config_request_type import AiGatewayGetGatewayConfigRequestType +from .types.get_gateway_config_ai_gateway_request_type import GetGatewayConfigAiGatewayRequestType from pydantic import ValidationError @@ -21,14 +21,14 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def get_gateway_config( - self, type: AiGatewayGetGatewayConfigRequestType, *, request_options: typing.Optional[RequestOptions] = None + self, type: GetGatewayConfigAiGatewayRequestType, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GatewayConfiguration]: """ Get the AI Gateway configuration for the given type. Parameters ---------- - type : AiGatewayGetGatewayConfigRequestType + type : GetGatewayConfigAiGatewayRequestType The type of gateway configuration to retrieve or delete. request_options : typing.Optional[RequestOptions] @@ -110,14 +110,14 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def get_gateway_config( - self, type: AiGatewayGetGatewayConfigRequestType, *, request_options: typing.Optional[RequestOptions] = None + self, type: GetGatewayConfigAiGatewayRequestType, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GatewayConfiguration]: """ Get the AI Gateway configuration for the given type. Parameters ---------- - type : AiGatewayGetGatewayConfigRequestType + type : GetGatewayConfigAiGatewayRequestType The type of gateway configuration to retrieve or delete. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/internal/ai_gateway/types/__init__.py b/src/truefoundry_sdk/internal/ai_gateway/types/__init__.py index e3b46549..88b9eb8d 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/types/__init__.py +++ b/src/truefoundry_sdk/internal/ai_gateway/types/__init__.py @@ -6,9 +6,9 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .ai_gateway_get_gateway_config_request_type import AiGatewayGetGatewayConfigRequestType + from .get_gateway_config_ai_gateway_request_type import GetGatewayConfigAiGatewayRequestType _dynamic_imports: typing.Dict[str, str] = { - "AiGatewayGetGatewayConfigRequestType": ".ai_gateway_get_gateway_config_request_type" + "GetGatewayConfigAiGatewayRequestType": ".get_gateway_config_ai_gateway_request_type" } @@ -33,4 +33,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["AiGatewayGetGatewayConfigRequestType"] +__all__ = ["GetGatewayConfigAiGatewayRequestType"] diff --git a/src/truefoundry_sdk/internal/ai_gateway/types/ai_gateway_get_gateway_config_request_type.py b/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py similarity index 74% rename from src/truefoundry_sdk/internal/ai_gateway/types/ai_gateway_get_gateway_config_request_type.py rename to src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py index 90318809..66e195d3 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/types/ai_gateway_get_gateway_config_request_type.py +++ b/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py @@ -7,7 +7,7 @@ T_Result = typing.TypeVar("T_Result") -class AiGatewayGetGatewayConfigRequestType(enum.StrEnum): +class GetGatewayConfigAiGatewayRequestType(enum.StrEnum): GATEWAY_RATE_LIMITING_CONFIG = "gateway-rate-limiting-config" GATEWAY_FALLBACK_CONFIG = "gateway-fallback-config" GATEWAY_LOAD_BALANCING_CONFIG = "gateway-load-balancing-config" @@ -19,13 +19,13 @@ class AiGatewayGetGatewayConfigRequestType(enum.StrEnum): GATEWAY_GLOBAL_SETTINGS = "gateway-global-settings" GATEWAY_DATA_ACCESS_CONFIG = "gateway-data-access-config" GATEWAY_DATA_ROUTING_CONFIG = "gateway-data-routing-config" - _UNKNOWN = "__AIGATEWAYGETGATEWAYCONFIGREQUESTTYPE_UNKNOWN__" + _UNKNOWN = "__GETGATEWAYCONFIGAIGATEWAYREQUESTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "AiGatewayGetGatewayConfigRequestType": + def _missing_(cls, value: typing.Any) -> "GetGatewayConfigAiGatewayRequestType": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -45,26 +45,26 @@ def visit( gateway_data_routing_config: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_RATE_LIMITING_CONFIG: return gateway_rate_limiting_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_FALLBACK_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_FALLBACK_CONFIG: return gateway_fallback_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_LOAD_BALANCING_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_LOAD_BALANCING_CONFIG: return gateway_load_balancing_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_GUARDRAILS_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_GUARDRAILS_CONFIG: return gateway_guardrails_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_BUDGET_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_BUDGET_CONFIG: return gateway_budget_config() - if self is AiGatewayGetGatewayConfigRequestType.TENANT_BUDGET_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.TENANT_BUDGET_CONFIG: return tenant_budget_config() - if self is AiGatewayGetGatewayConfigRequestType.TEAM_BUDGET_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.TEAM_BUDGET_CONFIG: return team_budget_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_OTEL_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_OTEL_CONFIG: return gateway_otel_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_GLOBAL_SETTINGS: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_GLOBAL_SETTINGS: return gateway_global_settings() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_DATA_ACCESS_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_DATA_ACCESS_CONFIG: return gateway_data_access_config() - if self is AiGatewayGetGatewayConfigRequestType.GATEWAY_DATA_ROUTING_CONFIG: + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_DATA_ROUTING_CONFIG: return gateway_data_routing_config() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/internal/applications/client.py b/src/truefoundry_sdk/internal/applications/client.py index 53e3c2ea..1f5971a7 100644 --- a/src/truefoundry_sdk/internal/applications/client.py +++ b/src/truefoundry_sdk/internal/applications/client.py @@ -53,7 +53,6 @@ def promote_rollout( ) client.internal.applications.promote_rollout( id="id", - full=True, ) """ _response = self._raw_client.promote_rollout(id, full=full, request_options=request_options) @@ -95,7 +94,6 @@ def get_pod_template_hash_to_deployment_version( ) client.internal.applications.get_pod_template_hash_to_deployment_version( id="id", - pod_template_hashes="podTemplateHashes", ) """ _response = self._raw_client.get_pod_template_hash_to_deployment_version( @@ -155,7 +153,6 @@ async def promote_rollout( async def main() -> None: await client.internal.applications.promote_rollout( id="id", - full=True, ) @@ -205,7 +202,6 @@ async def get_pod_template_hash_to_deployment_version( async def main() -> None: await client.internal.applications.get_pod_template_hash_to_deployment_version( id="id", - pod_template_hashes="podTemplateHashes", ) diff --git a/src/truefoundry_sdk/internal/artifact_versions/client.py b/src/truefoundry_sdk/internal/artifact_versions/client.py index 4caead08..63c7a820 100644 --- a/src/truefoundry_sdk/internal/artifact_versions/client.py +++ b/src/truefoundry_sdk/internal/artifact_versions/client.py @@ -37,8 +37,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, include_model_versions: typing.Optional[bool] = False, artifact_types: typing.Optional[typing.Union[ArtifactType, typing.Sequence[ArtifactType]]] = None, @@ -73,10 +73,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -107,17 +107,6 @@ def list( response = client.internal.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, - include_model_versions=True, - artifact_types=["artifact_types"], ) for item in response: yield item @@ -169,8 +158,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, include_model_versions: typing.Optional[bool] = False, artifact_types: typing.Optional[typing.Union[ArtifactType, typing.Sequence[ArtifactType]]] = None, @@ -205,10 +194,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -244,17 +233,6 @@ async def main() -> None: response = await client.internal.artifact_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - artifact_id="artifact_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, - include_model_versions=True, - artifact_types=["artifact_types"], ) async for item in response: yield item diff --git a/src/truefoundry_sdk/internal/artifact_versions/raw_client.py b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py index f6fe4e80..b1af3c11 100644 --- a/src/truefoundry_sdk/internal/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py @@ -30,8 +30,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, include_model_versions: typing.Optional[bool] = False, artifact_types: typing.Optional[typing.Union[ArtifactType, typing.Sequence[ArtifactType]]] = None, @@ -66,10 +66,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] @@ -164,8 +164,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, include_model_versions: typing.Optional[bool] = False, artifact_types: typing.Optional[typing.Union[ArtifactType, typing.Sequence[ArtifactType]]] = None, @@ -200,10 +200,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Run IDs to filter artifact versions by. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Run steps to filter artifact versions by. include_internal_metadata : typing.Optional[bool] diff --git a/src/truefoundry_sdk/internal/build_logs/client.py b/src/truefoundry_sdk/internal/build_logs/client.py index 0cf4109a..c081c150 100644 --- a/src/truefoundry_sdk/internal/build_logs/client.py +++ b/src/truefoundry_sdk/internal/build_logs/client.py @@ -81,10 +81,7 @@ def get( pipeline_run_name="pipelineRunName", start_ts="1635467890123456789", end_ts="1635467891123456789", - limit="limit", - direction="direction", filter_query='{"matchString":"error","type":"substring","operator":"equal"}', - num_logs_to_ignore=1.1, ) """ _response = self._raw_client.get( @@ -178,10 +175,7 @@ async def main() -> None: pipeline_run_name="pipelineRunName", start_ts="1635467890123456789", end_ts="1635467891123456789", - limit="limit", - direction="direction", filter_query='{"matchString":"error","type":"substring","operator":"equal"}', - num_logs_to_ignore=1.1, ) diff --git a/src/truefoundry_sdk/internal/deployments/client.py b/src/truefoundry_sdk/internal/deployments/client.py index f6014538..94fe62bf 100644 --- a/src/truefoundry_sdk/internal/deployments/client.py +++ b/src/truefoundry_sdk/internal/deployments/client.py @@ -200,9 +200,6 @@ def get_suggested_endpoint( application_type=ApplicationType.ASYNC_SERVICE, application_name="applicationName", workspace_id="workspaceId", - base_domain="baseDomain", - port="port", - prefer_wildcard=True, ) """ _response = self._raw_client.get_suggested_endpoint( @@ -431,9 +428,6 @@ async def main() -> None: application_type=ApplicationType.ASYNC_SERVICE, application_name="applicationName", workspace_id="workspaceId", - base_domain="baseDomain", - port="port", - prefer_wildcard=True, ) diff --git a/src/truefoundry_sdk/internal/docker_registries/client.py b/src/truefoundry_sdk/internal/docker_registries/client.py index 5e7c0924..ed10b135 100644 --- a/src/truefoundry_sdk/internal/docker_registries/client.py +++ b/src/truefoundry_sdk/internal/docker_registries/client.py @@ -110,10 +110,7 @@ def get_credentials( api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.docker_registries.get_credentials( - fqn="fqn", - cluster_id="clusterId", - ) + client.internal.docker_registries.get_credentials() """ _response = self._raw_client.get_credentials(fqn=fqn, cluster_id=cluster_id, request_options=request_options) return _response.data @@ -230,10 +227,7 @@ async def get_credentials( async def main() -> None: - await client.internal.docker_registries.get_credentials( - fqn="fqn", - cluster_id="clusterId", - ) + await client.internal.docker_registries.get_credentials() asyncio.run(main()) diff --git a/src/truefoundry_sdk/internal/metrics/__init__.py b/src/truefoundry_sdk/internal/metrics/__init__.py index 64d20cf4..c3efa3ca 100644 --- a/src/truefoundry_sdk/internal/metrics/__init__.py +++ b/src/truefoundry_sdk/internal/metrics/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import MetricsGetChartsRequestFilterEntity -_dynamic_imports: typing.Dict[str, str] = {"MetricsGetChartsRequestFilterEntity": ".types"} + from .types import GetChartsMetricsRequestFilterEntity +_dynamic_imports: typing.Dict[str, str] = {"GetChartsMetricsRequestFilterEntity": ".types"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["MetricsGetChartsRequestFilterEntity"] +__all__ = ["GetChartsMetricsRequestFilterEntity"] diff --git a/src/truefoundry_sdk/internal/metrics/client.py b/src/truefoundry_sdk/internal/metrics/client.py index 29ea11c3..8e9bf791 100644 --- a/src/truefoundry_sdk/internal/metrics/client.py +++ b/src/truefoundry_sdk/internal/metrics/client.py @@ -6,7 +6,7 @@ from ...core.request_options import RequestOptions from ...types.get_charts_response import GetChartsResponse from .raw_client import AsyncRawMetricsClient, RawMetricsClient -from .types.metrics_get_charts_request_filter_entity import MetricsGetChartsRequestFilterEntity +from .types.get_charts_metrics_request_filter_entity import GetChartsMetricsRequestFilterEntity class MetricsClient: @@ -29,7 +29,7 @@ def get_charts( workspace_id: str, *, application_id: str, - filter_entity: MetricsGetChartsRequestFilterEntity, + filter_entity: GetChartsMetricsRequestFilterEntity, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, filter_query: typing.Optional[str] = None, @@ -45,7 +45,7 @@ def get_charts( application_id : str Unique identifier of the application. - filter_entity : MetricsGetChartsRequestFilterEntity + filter_entity : GetChartsMetricsRequestFilterEntity Scope of the chart bundle to return. start_ts : typing.Optional[str] @@ -68,7 +68,7 @@ def get_charts( Examples -------- from truefoundry_sdk import TrueFoundry - from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity + from truefoundry_sdk.internal.metrics import GetChartsMetricsRequestFilterEntity client = TrueFoundry( api_key="YOUR_API_KEY", @@ -77,9 +77,7 @@ def get_charts( client.internal.metrics.get_charts( workspace_id="workspaceId", application_id="applicationId", - start_ts="startTs", - end_ts="endTs", - filter_entity=MetricsGetChartsRequestFilterEntity.APPLICATION, + filter_entity=GetChartsMetricsRequestFilterEntity.APPLICATION, filter_query='{"pod":"my-app-abc123-xyz"}', ) """ @@ -115,7 +113,7 @@ async def get_charts( workspace_id: str, *, application_id: str, - filter_entity: MetricsGetChartsRequestFilterEntity, + filter_entity: GetChartsMetricsRequestFilterEntity, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, filter_query: typing.Optional[str] = None, @@ -131,7 +129,7 @@ async def get_charts( application_id : str Unique identifier of the application. - filter_entity : MetricsGetChartsRequestFilterEntity + filter_entity : GetChartsMetricsRequestFilterEntity Scope of the chart bundle to return. start_ts : typing.Optional[str] @@ -156,7 +154,7 @@ async def get_charts( import asyncio from truefoundry_sdk import AsyncTrueFoundry - from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity + from truefoundry_sdk.internal.metrics import GetChartsMetricsRequestFilterEntity client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -168,9 +166,7 @@ async def main() -> None: await client.internal.metrics.get_charts( workspace_id="workspaceId", application_id="applicationId", - start_ts="startTs", - end_ts="endTs", - filter_entity=MetricsGetChartsRequestFilterEntity.APPLICATION, + filter_entity=GetChartsMetricsRequestFilterEntity.APPLICATION, filter_query='{"pod":"my-app-abc123-xyz"}', ) diff --git a/src/truefoundry_sdk/internal/metrics/raw_client.py b/src/truefoundry_sdk/internal/metrics/raw_client.py index 19e1e759..dbfdd893 100644 --- a/src/truefoundry_sdk/internal/metrics/raw_client.py +++ b/src/truefoundry_sdk/internal/metrics/raw_client.py @@ -14,7 +14,7 @@ from ...errors.method_not_allowed_error import MethodNotAllowedError from ...errors.not_found_error import NotFoundError from ...types.get_charts_response import GetChartsResponse -from .types.metrics_get_charts_request_filter_entity import MetricsGetChartsRequestFilterEntity +from .types.get_charts_metrics_request_filter_entity import GetChartsMetricsRequestFilterEntity from pydantic import ValidationError @@ -27,7 +27,7 @@ def get_charts( workspace_id: str, *, application_id: str, - filter_entity: MetricsGetChartsRequestFilterEntity, + filter_entity: GetChartsMetricsRequestFilterEntity, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, filter_query: typing.Optional[str] = None, @@ -43,7 +43,7 @@ def get_charts( application_id : str Unique identifier of the application. - filter_entity : MetricsGetChartsRequestFilterEntity + filter_entity : GetChartsMetricsRequestFilterEntity Scope of the chart bundle to return. start_ts : typing.Optional[str] @@ -137,7 +137,7 @@ async def get_charts( workspace_id: str, *, application_id: str, - filter_entity: MetricsGetChartsRequestFilterEntity, + filter_entity: GetChartsMetricsRequestFilterEntity, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, filter_query: typing.Optional[str] = None, @@ -153,7 +153,7 @@ async def get_charts( application_id : str Unique identifier of the application. - filter_entity : MetricsGetChartsRequestFilterEntity + filter_entity : GetChartsMetricsRequestFilterEntity Scope of the chart bundle to return. start_ts : typing.Optional[str] diff --git a/src/truefoundry_sdk/internal/metrics/types/__init__.py b/src/truefoundry_sdk/internal/metrics/types/__init__.py index 61d728f1..65f06742 100644 --- a/src/truefoundry_sdk/internal/metrics/types/__init__.py +++ b/src/truefoundry_sdk/internal/metrics/types/__init__.py @@ -6,9 +6,9 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .metrics_get_charts_request_filter_entity import MetricsGetChartsRequestFilterEntity + from .get_charts_metrics_request_filter_entity import GetChartsMetricsRequestFilterEntity _dynamic_imports: typing.Dict[str, str] = { - "MetricsGetChartsRequestFilterEntity": ".metrics_get_charts_request_filter_entity" + "GetChartsMetricsRequestFilterEntity": ".get_charts_metrics_request_filter_entity" } @@ -33,4 +33,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["MetricsGetChartsRequestFilterEntity"] +__all__ = ["GetChartsMetricsRequestFilterEntity"] diff --git a/src/truefoundry_sdk/internal/metrics/types/metrics_get_charts_request_filter_entity.py b/src/truefoundry_sdk/internal/metrics/types/get_charts_metrics_request_filter_entity.py similarity index 69% rename from src/truefoundry_sdk/internal/metrics/types/metrics_get_charts_request_filter_entity.py rename to src/truefoundry_sdk/internal/metrics/types/get_charts_metrics_request_filter_entity.py index b0c1d9da..16a6fc82 100644 --- a/src/truefoundry_sdk/internal/metrics/types/metrics_get_charts_request_filter_entity.py +++ b/src/truefoundry_sdk/internal/metrics/types/get_charts_metrics_request_filter_entity.py @@ -7,19 +7,19 @@ T_Result = typing.TypeVar("T_Result") -class MetricsGetChartsRequestFilterEntity(enum.StrEnum): +class GetChartsMetricsRequestFilterEntity(enum.StrEnum): APPLICATION = "application" POD = "pod" JOB_RUN = "job-run" EVENT = "event" CLUSTER = "cluster" - _UNKNOWN = "__METRICSGETCHARTSREQUESTFILTERENTITY_UNKNOWN__" + _UNKNOWN = "__GETCHARTSMETRICSREQUESTFILTERENTITY_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "MetricsGetChartsRequestFilterEntity": + def _missing_(cls, value: typing.Any) -> "GetChartsMetricsRequestFilterEntity": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -33,14 +33,14 @@ def visit( cluster: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is MetricsGetChartsRequestFilterEntity.APPLICATION: + if self is GetChartsMetricsRequestFilterEntity.APPLICATION: return application() - if self is MetricsGetChartsRequestFilterEntity.POD: + if self is GetChartsMetricsRequestFilterEntity.POD: return pod() - if self is MetricsGetChartsRequestFilterEntity.JOB_RUN: + if self is GetChartsMetricsRequestFilterEntity.JOB_RUN: return job_run() - if self is MetricsGetChartsRequestFilterEntity.EVENT: + if self is GetChartsMetricsRequestFilterEntity.EVENT: return event() - if self is MetricsGetChartsRequestFilterEntity.CLUSTER: + if self is GetChartsMetricsRequestFilterEntity.CLUSTER: return cluster() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/internal/workflows/__init__.py b/src/truefoundry_sdk/internal/workflows/__init__.py index fb6d37ec..152c4081 100644 --- a/src/truefoundry_sdk/internal/workflows/__init__.py +++ b/src/truefoundry_sdk/internal/workflows/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import WorkflowsExecuteWorkflowResponse -_dynamic_imports: typing.Dict[str, str] = {"WorkflowsExecuteWorkflowResponse": ".types"} + from .types import ExecuteWorkflowWorkflowsResponse +_dynamic_imports: typing.Dict[str, str] = {"ExecuteWorkflowWorkflowsResponse": ".types"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["WorkflowsExecuteWorkflowResponse"] +__all__ = ["ExecuteWorkflowWorkflowsResponse"] diff --git a/src/truefoundry_sdk/internal/workflows/client.py b/src/truefoundry_sdk/internal/workflows/client.py index a4c9c8f5..bac4240f 100644 --- a/src/truefoundry_sdk/internal/workflows/client.py +++ b/src/truefoundry_sdk/internal/workflows/client.py @@ -5,7 +5,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.request_options import RequestOptions from .raw_client import AsyncRawWorkflowsClient, RawWorkflowsClient -from .types.workflows_execute_workflow_response import WorkflowsExecuteWorkflowResponse +from .types.execute_workflow_workflows_response import ExecuteWorkflowWorkflowsResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -33,7 +33,7 @@ def execute_workflow( inputs: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, inputs_literal_map: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> WorkflowsExecuteWorkflowResponse: + ) -> ExecuteWorkflowWorkflowsResponse: """ Execute a workflow for the specified application @@ -53,7 +53,7 @@ def execute_workflow( Returns ------- - WorkflowsExecuteWorkflowResponse + ExecuteWorkflowWorkflowsResponse Returns execution name of the workflow Examples @@ -96,7 +96,7 @@ async def execute_workflow( inputs: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, inputs_literal_map: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> WorkflowsExecuteWorkflowResponse: + ) -> ExecuteWorkflowWorkflowsResponse: """ Execute a workflow for the specified application @@ -116,7 +116,7 @@ async def execute_workflow( Returns ------- - WorkflowsExecuteWorkflowResponse + ExecuteWorkflowWorkflowsResponse Returns execution name of the workflow Examples diff --git a/src/truefoundry_sdk/internal/workflows/raw_client.py b/src/truefoundry_sdk/internal/workflows/raw_client.py index 01a14081..87001e76 100644 --- a/src/truefoundry_sdk/internal/workflows/raw_client.py +++ b/src/truefoundry_sdk/internal/workflows/raw_client.py @@ -12,7 +12,7 @@ from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.not_found_error import NotFoundError -from .types.workflows_execute_workflow_response import WorkflowsExecuteWorkflowResponse +from .types.execute_workflow_workflows_response import ExecuteWorkflowWorkflowsResponse from pydantic import ValidationError # this is used as the default value for optional parameters @@ -30,7 +30,7 @@ def execute_workflow( inputs: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, inputs_literal_map: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[WorkflowsExecuteWorkflowResponse]: + ) -> HttpResponse[ExecuteWorkflowWorkflowsResponse]: """ Execute a workflow for the specified application @@ -50,7 +50,7 @@ def execute_workflow( Returns ------- - HttpResponse[WorkflowsExecuteWorkflowResponse] + HttpResponse[ExecuteWorkflowWorkflowsResponse] Returns execution name of the workflow """ _response = self._client_wrapper.httpx_client.request( @@ -69,9 +69,9 @@ def execute_workflow( try: if 200 <= _response.status_code < 300: _data = typing.cast( - WorkflowsExecuteWorkflowResponse, + ExecuteWorkflowWorkflowsResponse, parse_obj_as( - type_=WorkflowsExecuteWorkflowResponse, # type: ignore + type_=ExecuteWorkflowWorkflowsResponse, # type: ignore object_=_response.json(), ), ) @@ -119,7 +119,7 @@ async def execute_workflow( inputs: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, inputs_literal_map: typing.Optional[typing.Dict[str, typing.Any]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[WorkflowsExecuteWorkflowResponse]: + ) -> AsyncHttpResponse[ExecuteWorkflowWorkflowsResponse]: """ Execute a workflow for the specified application @@ -139,7 +139,7 @@ async def execute_workflow( Returns ------- - AsyncHttpResponse[WorkflowsExecuteWorkflowResponse] + AsyncHttpResponse[ExecuteWorkflowWorkflowsResponse] Returns execution name of the workflow """ _response = await self._client_wrapper.httpx_client.request( @@ -158,9 +158,9 @@ async def execute_workflow( try: if 200 <= _response.status_code < 300: _data = typing.cast( - WorkflowsExecuteWorkflowResponse, + ExecuteWorkflowWorkflowsResponse, parse_obj_as( - type_=WorkflowsExecuteWorkflowResponse, # type: ignore + type_=ExecuteWorkflowWorkflowsResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/truefoundry_sdk/internal/workflows/types/__init__.py b/src/truefoundry_sdk/internal/workflows/types/__init__.py index b829ebce..9a4abda4 100644 --- a/src/truefoundry_sdk/internal/workflows/types/__init__.py +++ b/src/truefoundry_sdk/internal/workflows/types/__init__.py @@ -6,8 +6,8 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .workflows_execute_workflow_response import WorkflowsExecuteWorkflowResponse -_dynamic_imports: typing.Dict[str, str] = {"WorkflowsExecuteWorkflowResponse": ".workflows_execute_workflow_response"} + from .execute_workflow_workflows_response import ExecuteWorkflowWorkflowsResponse +_dynamic_imports: typing.Dict[str, str] = {"ExecuteWorkflowWorkflowsResponse": ".execute_workflow_workflows_response"} def __getattr__(attr_name: str) -> typing.Any: @@ -31,4 +31,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["WorkflowsExecuteWorkflowResponse"] +__all__ = ["ExecuteWorkflowWorkflowsResponse"] diff --git a/src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py b/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py similarity index 92% rename from src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py rename to src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py index 438fbed8..1c7c08bd 100644 --- a/src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py +++ b/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py @@ -8,7 +8,7 @@ from ....core.serialization import FieldMetadata -class WorkflowsExecuteWorkflowResponse(UniversalBaseModel): +class ExecuteWorkflowWorkflowsResponse(UniversalBaseModel): execution_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="executionName"), diff --git a/src/truefoundry_sdk/jobs/client.py b/src/truefoundry_sdk/jobs/client.py index 076eb848..1ba7c6ee 100644 --- a/src/truefoundry_sdk/jobs/client.py +++ b/src/truefoundry_sdk/jobs/client.py @@ -46,9 +46,9 @@ def list_runs( search_prefix: typing.Optional[str] = None, sort_by: typing.Optional[JobRunsSortBy] = None, order: typing.Optional[SortDirection] = None, - triggered_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + triggered_by: typing.Optional[typing.Sequence[str]] = None, status: typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] = None, - version_numbers: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + version_numbers: typing.Optional[typing.Sequence[float]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[JobRun, ListJobRunResponse]: """ @@ -74,13 +74,13 @@ def list_runs( order : typing.Optional[SortDirection] Sorting order - triggered_by : typing.Optional[typing.Union[str, typing.Sequence[str]]] + triggered_by : typing.Optional[typing.Sequence[str]] Array of subject slugs status : typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] Status of the job run - version_numbers : typing.Optional[typing.Union[float, typing.Sequence[float]]] + version_numbers : typing.Optional[typing.Sequence[float]] Version number of the deployment request_options : typing.Optional[RequestOptions] @@ -93,12 +93,7 @@ def list_runs( Examples -------- - from truefoundry_sdk import ( - JobRunsSortBy, - JobRunStatus, - SortDirection, - TrueFoundry, - ) + from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -108,12 +103,6 @@ def list_runs( job_id="jobId", limit=10, offset=0, - search_prefix="searchPrefix", - sort_by=JobRunsSortBy.START_TIME, - order=SortDirection.ASC, - triggered_by=["triggeredBy"], - status=[JobRunStatus.CREATED], - version_numbers=[1.1], ) for item in response: yield item @@ -328,9 +317,9 @@ async def list_runs( search_prefix: typing.Optional[str] = None, sort_by: typing.Optional[JobRunsSortBy] = None, order: typing.Optional[SortDirection] = None, - triggered_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + triggered_by: typing.Optional[typing.Sequence[str]] = None, status: typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] = None, - version_numbers: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + version_numbers: typing.Optional[typing.Sequence[float]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[JobRun, ListJobRunResponse]: """ @@ -356,13 +345,13 @@ async def list_runs( order : typing.Optional[SortDirection] Sorting order - triggered_by : typing.Optional[typing.Union[str, typing.Sequence[str]]] + triggered_by : typing.Optional[typing.Sequence[str]] Array of subject slugs status : typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] Status of the job run - version_numbers : typing.Optional[typing.Union[float, typing.Sequence[float]]] + version_numbers : typing.Optional[typing.Sequence[float]] Version number of the deployment request_options : typing.Optional[RequestOptions] @@ -377,12 +366,7 @@ async def list_runs( -------- import asyncio - from truefoundry_sdk import ( - AsyncTrueFoundry, - JobRunsSortBy, - JobRunStatus, - SortDirection, - ) + from truefoundry_sdk import AsyncTrueFoundry client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -395,12 +379,6 @@ async def main() -> None: job_id="jobId", limit=10, offset=0, - search_prefix="searchPrefix", - sort_by=JobRunsSortBy.START_TIME, - order=SortDirection.ASC, - triggered_by=["triggeredBy"], - status=[JobRunStatus.CREATED], - version_numbers=[1.1], ) async for item in response: yield item diff --git a/src/truefoundry_sdk/jobs/raw_client.py b/src/truefoundry_sdk/jobs/raw_client.py index d90df4d3..6515f34b 100644 --- a/src/truefoundry_sdk/jobs/raw_client.py +++ b/src/truefoundry_sdk/jobs/raw_client.py @@ -49,9 +49,9 @@ def list_runs( search_prefix: typing.Optional[str] = None, sort_by: typing.Optional[JobRunsSortBy] = None, order: typing.Optional[SortDirection] = None, - triggered_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + triggered_by: typing.Optional[typing.Sequence[str]] = None, status: typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] = None, - version_numbers: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + version_numbers: typing.Optional[typing.Sequence[float]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[JobRun, ListJobRunResponse]: """ @@ -77,13 +77,13 @@ def list_runs( order : typing.Optional[SortDirection] Sorting order - triggered_by : typing.Optional[typing.Union[str, typing.Sequence[str]]] + triggered_by : typing.Optional[typing.Sequence[str]] Array of subject slugs status : typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] Status of the job run - version_numbers : typing.Optional[typing.Union[float, typing.Sequence[float]]] + version_numbers : typing.Optional[typing.Sequence[float]] Version number of the deployment request_options : typing.Optional[RequestOptions] @@ -365,10 +365,10 @@ def trigger( "deploymentId": deployment_id, "applicationId": application_id, "input": convert_and_respect_annotation_metadata( - object_=input, annotation=TriggerJobRequestInput, direction="write" + object_=input, annotation=typing.Optional[TriggerJobRequestInput], direction="write" ), "metadata": convert_and_respect_annotation_metadata( - object_=metadata, annotation=Metadata, direction="write" + object_=metadata, annotation=typing.Optional[Metadata], direction="write" ), }, headers={ @@ -548,9 +548,9 @@ async def list_runs( search_prefix: typing.Optional[str] = None, sort_by: typing.Optional[JobRunsSortBy] = None, order: typing.Optional[SortDirection] = None, - triggered_by: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + triggered_by: typing.Optional[typing.Sequence[str]] = None, status: typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] = None, - version_numbers: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + version_numbers: typing.Optional[typing.Sequence[float]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[JobRun, ListJobRunResponse]: """ @@ -576,13 +576,13 @@ async def list_runs( order : typing.Optional[SortDirection] Sorting order - triggered_by : typing.Optional[typing.Union[str, typing.Sequence[str]]] + triggered_by : typing.Optional[typing.Sequence[str]] Array of subject slugs status : typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]] Status of the job run - version_numbers : typing.Optional[typing.Union[float, typing.Sequence[float]]] + version_numbers : typing.Optional[typing.Sequence[float]] Version number of the deployment request_options : typing.Optional[RequestOptions] @@ -867,10 +867,10 @@ async def trigger( "deploymentId": deployment_id, "applicationId": application_id, "input": convert_and_respect_annotation_metadata( - object_=input, annotation=TriggerJobRequestInput, direction="write" + object_=input, annotation=typing.Optional[TriggerJobRequestInput], direction="write" ), "metadata": convert_and_respect_annotation_metadata( - object_=metadata, annotation=Metadata, direction="write" + object_=metadata, annotation=typing.Optional[Metadata], direction="write" ), }, headers={ diff --git a/src/truefoundry_sdk/logs/client.py b/src/truefoundry_sdk/logs/client.py index 42d4cd30..8eb71cd5 100644 --- a/src/truefoundry_sdk/logs/client.py +++ b/src/truefoundry_sdk/logs/client.py @@ -40,7 +40,7 @@ def get( job_run_name: typing.Optional[str] = None, pod_name: typing.Optional[str] = None, container_name: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, pod_names_regex: typing.Optional[str] = None, search_filters: typing.Optional[str] = None, search_string: typing.Optional[str] = None, @@ -86,7 +86,7 @@ def get( container_name : typing.Optional[str] Name of the container whose logs to fetch. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex. pod_names_regex : typing.Optional[str] @@ -114,12 +114,7 @@ def get( Examples -------- - from truefoundry_sdk import ( - LogsSearchFilterType, - LogsSearchOperatorType, - LogsSortingDirection, - TrueFoundry, - ) + from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -128,21 +123,7 @@ def get( client.logs.get( start_ts="1779262323000000000", end_ts="1779348723000000000", - limit=1, - direction=LogsSortingDirection.ASC, - num_logs_to_ignore=1, - application_id="applicationId", - application_fqn="applicationFqn", - deployment_id="deploymentId", - job_run_name="jobRunName", - pod_name="podName", - container_name="containerName", - pod_names=["podNames"], - pod_names_regex="podNamesRegex", search_filters='[{"string":"error","type":"substring","operator":"equal"}]', - search_string="searchString", - search_type=LogsSearchFilterType.REGEX, - search_operator=LogsSearchOperatorType.EQUAL, ) """ _response = self._raw_client.get( @@ -197,7 +178,7 @@ async def get( job_run_name: typing.Optional[str] = None, pod_name: typing.Optional[str] = None, container_name: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, pod_names_regex: typing.Optional[str] = None, search_filters: typing.Optional[str] = None, search_string: typing.Optional[str] = None, @@ -243,7 +224,7 @@ async def get( container_name : typing.Optional[str] Name of the container whose logs to fetch. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex. pod_names_regex : typing.Optional[str] @@ -273,12 +254,7 @@ async def get( -------- import asyncio - from truefoundry_sdk import ( - AsyncTrueFoundry, - LogsSearchFilterType, - LogsSearchOperatorType, - LogsSortingDirection, - ) + from truefoundry_sdk import AsyncTrueFoundry client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -290,21 +266,7 @@ async def main() -> None: await client.logs.get( start_ts="1779262323000000000", end_ts="1779348723000000000", - limit=1, - direction=LogsSortingDirection.ASC, - num_logs_to_ignore=1, - application_id="applicationId", - application_fqn="applicationFqn", - deployment_id="deploymentId", - job_run_name="jobRunName", - pod_name="podName", - container_name="containerName", - pod_names=["podNames"], - pod_names_regex="podNamesRegex", search_filters='[{"string":"error","type":"substring","operator":"equal"}]', - search_string="searchString", - search_type=LogsSearchFilterType.REGEX, - search_operator=LogsSearchOperatorType.EQUAL, ) diff --git a/src/truefoundry_sdk/logs/raw_client.py b/src/truefoundry_sdk/logs/raw_client.py index 7bb3b54e..5f971dd3 100644 --- a/src/truefoundry_sdk/logs/raw_client.py +++ b/src/truefoundry_sdk/logs/raw_client.py @@ -35,7 +35,7 @@ def get( job_run_name: typing.Optional[str] = None, pod_name: typing.Optional[str] = None, container_name: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, pod_names_regex: typing.Optional[str] = None, search_filters: typing.Optional[str] = None, search_string: typing.Optional[str] = None, @@ -81,7 +81,7 @@ def get( container_name : typing.Optional[str] Name of the container whose logs to fetch. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex. pod_names_regex : typing.Optional[str] @@ -180,7 +180,7 @@ async def get( job_run_name: typing.Optional[str] = None, pod_name: typing.Optional[str] = None, container_name: typing.Optional[str] = None, - pod_names: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + pod_names: typing.Optional[typing.Sequence[str]] = None, pod_names_regex: typing.Optional[str] = None, search_filters: typing.Optional[str] = None, search_string: typing.Optional[str] = None, @@ -226,7 +226,7 @@ async def get( container_name : typing.Optional[str] Name of the container whose logs to fetch. - pod_names : typing.Optional[typing.Union[str, typing.Sequence[str]]] + pod_names : typing.Optional[typing.Sequence[str]] List of pod names whose logs to fetch. Cannot be used together with podName or podNamesRegex. pod_names_regex : typing.Optional[str] diff --git a/src/truefoundry_sdk/ml_repos/client.py b/src/truefoundry_sdk/ml_repos/client.py index 855cb8f8..1ac6ae0b 100644 --- a/src/truefoundry_sdk/ml_repos/client.py +++ b/src/truefoundry_sdk/ml_repos/client.py @@ -101,7 +101,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[MlRepo, ListMlReposResponse]: """ @@ -118,7 +118,7 @@ def list( name : typing.Optional[str] ML Repo Name - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -140,8 +140,6 @@ def list( response = client.ml_repos.list( limit=10, offset=0, - name="name", - attributes=["attributes"], ) for item in response: yield item @@ -307,7 +305,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[MlRepo, ListMlReposResponse]: """ @@ -324,7 +322,7 @@ async def list( name : typing.Optional[str] ML Repo Name - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -351,8 +349,6 @@ async def main() -> None: response = await client.ml_repos.list( limit=10, offset=0, - name="name", - attributes=["attributes"], ) async for item in response: yield item diff --git a/src/truefoundry_sdk/ml_repos/raw_client.py b/src/truefoundry_sdk/ml_repos/raw_client.py index bf810a46..bfa3fe9e 100644 --- a/src/truefoundry_sdk/ml_repos/raw_client.py +++ b/src/truefoundry_sdk/ml_repos/raw_client.py @@ -146,7 +146,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[MlRepo, ListMlReposResponse]: """ @@ -163,7 +163,7 @@ def list( name : typing.Optional[str] ML Repo Name - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -438,7 +438,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[MlRepo, ListMlReposResponse]: """ @@ -455,7 +455,7 @@ async def list( name : typing.Optional[str] ML Repo Name - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/model_versions/client.py b/src/truefoundry_sdk/model_versions/client.py index d289e110..6ac817dd 100644 --- a/src/truefoundry_sdk/model_versions/client.py +++ b/src/truefoundry_sdk/model_versions/client.py @@ -41,8 +41,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ModelVersion, ListModelVersionsResponse]: @@ -75,10 +75,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Filter model versions by associated run identifiers. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Filter model versions by associated run steps. include_internal_metadata : typing.Optional[bool] @@ -103,15 +103,6 @@ def list( response = client.model_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - model_id="model_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, ) for item in response: yield item @@ -273,8 +264,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ModelVersion, ListModelVersionsResponse]: @@ -307,10 +298,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Filter model versions by associated run identifiers. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Filter model versions by associated run steps. include_internal_metadata : typing.Optional[bool] @@ -340,15 +331,6 @@ async def main() -> None: response = await client.model_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - model_id="model_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, - run_ids=["run_ids"], - run_steps=[1.1], - include_internal_metadata=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/model_versions/raw_client.py b/src/truefoundry_sdk/model_versions/raw_client.py index e204c868..84132155 100644 --- a/src/truefoundry_sdk/model_versions/raw_client.py +++ b/src/truefoundry_sdk/model_versions/raw_client.py @@ -37,8 +37,8 @@ def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ModelVersion, ListModelVersionsResponse]: @@ -71,10 +71,10 @@ def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Filter model versions by associated run identifiers. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Filter model versions by associated run steps. include_internal_metadata : typing.Optional[bool] @@ -330,8 +330,8 @@ async def list( ml_repo_id: typing.Optional[str] = None, name: typing.Optional[str] = None, version: typing.Optional[int] = None, - run_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, - run_steps: typing.Optional[typing.Union[float, typing.Sequence[float]]] = None, + run_ids: typing.Optional[typing.Sequence[str]] = None, + run_steps: typing.Optional[typing.Sequence[float]] = None, include_internal_metadata: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ModelVersion, ListModelVersionsResponse]: @@ -364,10 +364,10 @@ async def list( version : typing.Optional[int] Version number (positive integer) to filter by. - run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + run_ids : typing.Optional[typing.Sequence[str]] Filter model versions by associated run identifiers. - run_steps : typing.Optional[typing.Union[float, typing.Sequence[float]]] + run_steps : typing.Optional[typing.Sequence[float]] Filter model versions by associated run steps. include_internal_metadata : typing.Optional[bool] diff --git a/src/truefoundry_sdk/models/client.py b/src/truefoundry_sdk/models/client.py index 52a673fe..6462e999 100644 --- a/src/truefoundry_sdk/models/client.py +++ b/src/truefoundry_sdk/models/client.py @@ -153,11 +153,6 @@ def list( response = client.models.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_models=True, ) for item in response: yield item @@ -372,11 +367,6 @@ async def main() -> None: response = await client.models.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - run_id="run_id", - include_empty_models=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/personal_access_tokens/client.py b/src/truefoundry_sdk/personal_access_tokens/client.py index ea571e94..8d911ea1 100644 --- a/src/truefoundry_sdk/personal_access_tokens/client.py +++ b/src/truefoundry_sdk/personal_access_tokens/client.py @@ -249,7 +249,6 @@ def get( ) client.personal_access_tokens.get( name="name", - team_name="teamName", ) """ _response = self._raw_client.get(name, team_name=team_name, request_options=request_options) @@ -525,7 +524,6 @@ async def get( async def main() -> None: await client.personal_access_tokens.get( name="name", - team_name="teamName", ) diff --git a/src/truefoundry_sdk/prompt_versions/client.py b/src/truefoundry_sdk/prompt_versions/client.py index f010b661..d402ad7e 100644 --- a/src/truefoundry_sdk/prompt_versions/client.py +++ b/src/truefoundry_sdk/prompt_versions/client.py @@ -91,12 +91,6 @@ def list( response = client.prompt_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - prompt_id="prompt_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) for item in response: yield item @@ -310,12 +304,6 @@ async def main() -> None: response = await client.prompt_versions.list( limit=10, offset=0, - tag="tag", - fqn="fqn", - prompt_id="prompt_id", - ml_repo_id="ml_repo_id", - name="name", - version=1, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/prompts/client.py b/src/truefoundry_sdk/prompts/client.py index f0d4286f..e18435e7 100644 --- a/src/truefoundry_sdk/prompts/client.py +++ b/src/truefoundry_sdk/prompts/client.py @@ -149,10 +149,6 @@ def list( response = client.prompts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_prompts=True, ) for item in response: yield item @@ -365,10 +361,6 @@ async def main() -> None: response = await client.prompts.list( limit=10, offset=0, - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - include_empty_prompts=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/secret_groups/client.py b/src/truefoundry_sdk/secret_groups/client.py index 521b8685..417d2fc3 100644 --- a/src/truefoundry_sdk/secret_groups/client.py +++ b/src/truefoundry_sdk/secret_groups/client.py @@ -40,7 +40,7 @@ def list( offset: typing.Optional[int] = 0, fqn: typing.Optional[str] = None, search: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[SecretGroup, ListSecretGroupResponse]: """ @@ -60,7 +60,7 @@ def list( search : typing.Optional[str] Search query - filters by secret group names that contain the search string - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -82,9 +82,6 @@ def list( response = client.secret_groups.list( limit=10, offset=0, - fqn="fqn", - search="search", - attributes=["attributes"], ) for item in response: yield item @@ -315,7 +312,6 @@ def delete( ) client.secret_groups.delete( id="id", - force_delete=True, ) """ _response = self._raw_client.delete(id, force_delete=force_delete, request_options=request_options) @@ -344,7 +340,7 @@ async def list( offset: typing.Optional[int] = 0, fqn: typing.Optional[str] = None, search: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[SecretGroup, ListSecretGroupResponse]: """ @@ -364,7 +360,7 @@ async def list( search : typing.Optional[str] Search query - filters by secret group names that contain the search string - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -391,9 +387,6 @@ async def main() -> None: response = await client.secret_groups.list( limit=10, offset=0, - fqn="fqn", - search="search", - attributes=["attributes"], ) async for item in response: yield item @@ -665,7 +658,6 @@ async def delete( async def main() -> None: await client.secret_groups.delete( id="id", - force_delete=True, ) diff --git a/src/truefoundry_sdk/secret_groups/raw_client.py b/src/truefoundry_sdk/secret_groups/raw_client.py index 74ee9734..b3b87ca4 100644 --- a/src/truefoundry_sdk/secret_groups/raw_client.py +++ b/src/truefoundry_sdk/secret_groups/raw_client.py @@ -43,7 +43,7 @@ def list( offset: typing.Optional[int] = 0, fqn: typing.Optional[str] = None, search: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[SecretGroup, ListSecretGroupResponse]: """ @@ -63,7 +63,7 @@ def list( search : typing.Optional[str] Search query - filters by secret group names that contain the search string - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -584,7 +584,7 @@ async def list( offset: typing.Optional[int] = 0, fqn: typing.Optional[str] = None, search: typing.Optional[str] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[SecretGroup, ListSecretGroupResponse]: """ @@ -604,7 +604,7 @@ async def list( search : typing.Optional[str] Search query - filters by secret group names that contain the search string - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/secrets/client.py b/src/truefoundry_sdk/secrets/client.py index aa725c52..058a63ac 100644 --- a/src/truefoundry_sdk/secrets/client.py +++ b/src/truefoundry_sdk/secrets/client.py @@ -159,7 +159,6 @@ def delete( ) client.secrets.delete( id="id", - force_delete=True, ) """ _response = self._raw_client.delete(id, force_delete=force_delete, request_options=request_options) @@ -333,7 +332,6 @@ async def delete( async def main() -> None: await client.secrets.delete( id="id", - force_delete=True, ) diff --git a/src/truefoundry_sdk/teams/client.py b/src/truefoundry_sdk/teams/client.py index 154f6250..5bc224a9 100644 --- a/src/truefoundry_sdk/teams/client.py +++ b/src/truefoundry_sdk/teams/client.py @@ -41,7 +41,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Team, ListTeamsResponse]: """ @@ -58,7 +58,7 @@ def list( role : typing.Optional[typing.Literal["manager"]] Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -80,7 +80,6 @@ def list( response = client.teams.list( limit=10, offset=0, - attributes=["attributes"], ) for item in response: yield item @@ -374,7 +373,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Team, ListTeamsResponse]: """ @@ -391,7 +390,7 @@ async def list( role : typing.Optional[typing.Literal["manager"]] Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -418,7 +417,6 @@ async def main() -> None: response = await client.teams.list( limit=10, offset=0, - attributes=["attributes"], ) async for item in response: yield item diff --git a/src/truefoundry_sdk/teams/raw_client.py b/src/truefoundry_sdk/teams/raw_client.py index 7f24d116..e4ed4446 100644 --- a/src/truefoundry_sdk/teams/raw_client.py +++ b/src/truefoundry_sdk/teams/raw_client.py @@ -42,7 +42,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Team, ListTeamsResponse]: """ @@ -59,7 +59,7 @@ def list( role : typing.Optional[typing.Literal["manager"]] Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -578,7 +578,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Team, ListTeamsResponse]: """ @@ -595,7 +595,7 @@ async def list( role : typing.Optional[typing.Literal["manager"]] Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] diff --git a/src/truefoundry_sdk/traces/raw_client.py b/src/truefoundry_sdk/traces/raw_client.py index 2c3d1d40..767cf23f 100644 --- a/src/truefoundry_sdk/traces/raw_client.py +++ b/src/truefoundry_sdk/traces/raw_client.py @@ -119,7 +119,9 @@ def query_spans( "tracingProjectFqn": tracing_project_fqn, "dataRoutingDestination": data_routing_destination, "filters": convert_and_respect_annotation_metadata( - object_=filters, annotation=typing.Sequence[QuerySpansRequestFiltersItem], direction="write" + object_=filters, + annotation=typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]], + direction="write", ), "includeFeedbacks": include_feedbacks, }, @@ -271,7 +273,9 @@ async def query_spans( "tracingProjectFqn": tracing_project_fqn, "dataRoutingDestination": data_routing_destination, "filters": convert_and_respect_annotation_metadata( - object_=filters, annotation=typing.Sequence[QuerySpansRequestFiltersItem], direction="write" + object_=filters, + annotation=typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]], + direction="write", ), "includeFeedbacks": include_feedbacks, }, diff --git a/src/truefoundry_sdk/users/client.py b/src/truefoundry_sdk/users/client.py index 3729c655..ef1faa3f 100644 --- a/src/truefoundry_sdk/users/client.py +++ b/src/truefoundry_sdk/users/client.py @@ -86,7 +86,6 @@ def list( limit=10, offset=0, query="john@example.com", - show_invalid_users=True, ) for item in response: yield item @@ -278,7 +277,6 @@ def delete( ) client.users.delete( id="jqfwg345gi25n5ju2yz5iz6m", - tenant_name="tenantName", ) """ _response = self._raw_client.delete(id, tenant_name=tenant_name, request_options=request_options) @@ -622,7 +620,6 @@ async def main() -> None: limit=10, offset=0, query="john@example.com", - show_invalid_users=True, ) async for item in response: yield item @@ -847,7 +844,6 @@ async def delete( async def main() -> None: await client.users.delete( id="jqfwg345gi25n5ju2yz5iz6m", - tenant_name="tenantName", ) diff --git a/src/truefoundry_sdk/virtual_accounts/client.py b/src/truefoundry_sdk/virtual_accounts/client.py index f7bfd510..ffb9e293 100644 --- a/src/truefoundry_sdk/virtual_accounts/client.py +++ b/src/truefoundry_sdk/virtual_accounts/client.py @@ -39,7 +39,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name_search_query: typing.Optional[str] = None, - owned_by_teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + owned_by_teams: typing.Optional[typing.Sequence[str]] = None, is_expired: typing.Optional[bool] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -58,7 +58,7 @@ def list( name_search_query : typing.Optional[str] Return virtual accounts with names that contain this string. - owned_by_teams : typing.Optional[typing.Union[str, typing.Sequence[str]]] + owned_by_teams : typing.Optional[typing.Sequence[str]] Comma-separated team names. Return virtual accounts owned by these teams. is_expired : typing.Optional[bool] @@ -87,8 +87,6 @@ def list( limit=10, offset=0, name_search_query="staging-bot", - owned_by_teams=["ownedByTeams"], - is_expired=True, filter='{"type":"AND","children":[{"column":"name","op":"STRING_CONTAINS","value":"bot"}]}', ) for item in response: @@ -390,7 +388,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name_search_query: typing.Optional[str] = None, - owned_by_teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + owned_by_teams: typing.Optional[typing.Sequence[str]] = None, is_expired: typing.Optional[bool] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -409,7 +407,7 @@ async def list( name_search_query : typing.Optional[str] Return virtual accounts with names that contain this string. - owned_by_teams : typing.Optional[typing.Union[str, typing.Sequence[str]]] + owned_by_teams : typing.Optional[typing.Sequence[str]] Comma-separated team names. Return virtual accounts owned by these teams. is_expired : typing.Optional[bool] @@ -443,8 +441,6 @@ async def main() -> None: limit=10, offset=0, name_search_query="staging-bot", - owned_by_teams=["ownedByTeams"], - is_expired=True, filter='{"type":"AND","children":[{"column":"name","op":"STRING_CONTAINS","value":"bot"}]}', ) async for item in response: diff --git a/src/truefoundry_sdk/virtual_accounts/raw_client.py b/src/truefoundry_sdk/virtual_accounts/raw_client.py index e8ce7b35..39b58d4a 100644 --- a/src/truefoundry_sdk/virtual_accounts/raw_client.py +++ b/src/truefoundry_sdk/virtual_accounts/raw_client.py @@ -39,7 +39,7 @@ def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name_search_query: typing.Optional[str] = None, - owned_by_teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + owned_by_teams: typing.Optional[typing.Sequence[str]] = None, is_expired: typing.Optional[bool] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -58,7 +58,7 @@ def list( name_search_query : typing.Optional[str] Return virtual accounts with names that contain this string. - owned_by_teams : typing.Optional[typing.Union[str, typing.Sequence[str]]] + owned_by_teams : typing.Optional[typing.Sequence[str]] Comma-separated team names. Return virtual accounts owned by these teams. is_expired : typing.Optional[bool] @@ -542,7 +542,7 @@ async def list( limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, name_search_query: typing.Optional[str] = None, - owned_by_teams: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + owned_by_teams: typing.Optional[typing.Sequence[str]] = None, is_expired: typing.Optional[bool] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, @@ -561,7 +561,7 @@ async def list( name_search_query : typing.Optional[str] Return virtual accounts with names that contain this string. - owned_by_teams : typing.Optional[typing.Union[str, typing.Sequence[str]]] + owned_by_teams : typing.Optional[typing.Sequence[str]] Comma-separated team names. Return virtual accounts owned by these teams. is_expired : typing.Optional[bool] diff --git a/src/truefoundry_sdk/workspaces/client.py b/src/truefoundry_sdk/workspaces/client.py index 00fd6e57..8936f6f4 100644 --- a/src/truefoundry_sdk/workspaces/client.py +++ b/src/truefoundry_sdk/workspaces/client.py @@ -40,7 +40,7 @@ def list( name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, include_cluster: typing.Optional[bool] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Workspace, ListWorkspacesResponse]: """ @@ -66,7 +66,7 @@ def list( include_cluster : typing.Optional[bool] When true, each workspace in the response includes summary information about its cluster. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -89,10 +89,6 @@ def list( limit=10, offset=0, cluster_id="jqfwg345gi25n5ju2yz5iz6m", - name="name", - fqn="fqn", - include_cluster=True, - attributes=["attributes"], ) for item in response: yield item @@ -203,7 +199,6 @@ def search( limit=10, offset=0, filter='[{"type":"name","operator":"STRING_CONTAINS","value":"prod"}]', - include_cluster=True, ) for item in response: yield item @@ -304,7 +299,7 @@ async def list( name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, include_cluster: typing.Optional[bool] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Workspace, ListWorkspacesResponse]: """ @@ -330,7 +325,7 @@ async def list( include_cluster : typing.Optional[bool] When true, each workspace in the response includes summary information about its cluster. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -358,10 +353,6 @@ async def main() -> None: limit=10, offset=0, cluster_id="jqfwg345gi25n5ju2yz5iz6m", - name="name", - fqn="fqn", - include_cluster=True, - attributes=["attributes"], ) async for item in response: yield item @@ -489,7 +480,6 @@ async def main() -> None: limit=10, offset=0, filter='[{"type":"name","operator":"STRING_CONTAINS","value":"prod"}]', - include_cluster=True, ) async for item in response: yield item diff --git a/src/truefoundry_sdk/workspaces/raw_client.py b/src/truefoundry_sdk/workspaces/raw_client.py index fe4ed132..f18b7f45 100644 --- a/src/truefoundry_sdk/workspaces/raw_client.py +++ b/src/truefoundry_sdk/workspaces/raw_client.py @@ -42,7 +42,7 @@ def list( name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, include_cluster: typing.Optional[bool] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Workspace, ListWorkspacesResponse]: """ @@ -68,7 +68,7 @@ def list( include_cluster : typing.Optional[bool] When true, each workspace in the response includes summary information about its cluster. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] @@ -438,7 +438,7 @@ async def list( name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, include_cluster: typing.Optional[bool] = None, - attributes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, + attributes: typing.Optional[typing.Sequence[str]] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Workspace, ListWorkspacesResponse]: """ @@ -464,7 +464,7 @@ async def list( include_cluster : typing.Optional[bool] When true, each workspace in the response includes summary information about its cluster. - attributes : typing.Optional[typing.Union[str, typing.Sequence[str]]] + attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. request_options : typing.Optional[RequestOptions] From 681ee5fb7a3d74703710a1af5c7185d0a84b7584 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:01:45 +0000 Subject: [PATCH 2/9] SDK regeneration --- .fern/metadata.json | 6 +- README.md | 2 +- poetry.lock | 8 +- pyproject.toml | 2 +- src/truefoundry_sdk/base_client.py | 8 +- src/truefoundry_sdk/core/http_client.py | 62 ++- src/truefoundry_sdk/core/http_sse/_api.py | 353 ++++++++++++++++-- .../core/http_sse/_decoders.py | 13 + src/truefoundry_sdk/core/request_options.py | 5 +- .../execute_workflow_workflows_response.py | 3 + .../types/addon_component_status.py | 8 + .../types/agent_version_metadata.py | 3 + src/truefoundry_sdk/types/application.py | 40 ++ .../types/application_summary.py | 15 + .../types/budget_v2in_not_in_filter.py | 4 + src/truefoundry_sdk/types/cluster_gateway.py | 4 + .../create_docker_repository_response.py | 3 + src/truefoundry_sdk/types/deployment.py | 39 ++ .../types/environment_manifest.py | 4 + src/truefoundry_sdk/types/event.py | 12 + .../types/gateway_configuration.py | 15 + src/truefoundry_sdk/types/gcp_api_key_auth.py | 3 + .../get_authenticated_vcsurl_response.py | 3 + ...et_docker_registry_credentials_response.py | 4 + src/truefoundry_sdk/types/graph.py | 4 + src/truefoundry_sdk/types/headers_override.py | 3 + src/truefoundry_sdk/types/http_error.py | 4 + .../types/is_cluster_connected_response.py | 3 + src/truefoundry_sdk/types/job_run.py | 47 +++ src/truefoundry_sdk/types/json_schema.py | 3 + .../types/list_files_request.py | 3 + src/truefoundry_sdk/types/log.py | 3 + .../types/mcp_tool_annotations.py | 7 + .../types/multi_part_upload.py | 4 + .../types/private_pricing_tier.py | 4 + .../types/prometheus_alert_rule.py | 4 + .../types/role_binding_permission.py | 8 + src/truefoundry_sdk/types/role_manifest.py | 8 + .../types/spark_job_trigger_input.py | 8 + src/truefoundry_sdk/types/subject.py | 23 ++ .../types/subject_permission.py | 31 ++ .../types/sync_token_in_secret_store_info.py | 4 + .../sync_virtual_account_token_response.py | 3 + src/truefoundry_sdk/types/team.py | 39 ++ src/truefoundry_sdk/types/team_manifest.py | 4 + src/truefoundry_sdk/types/team_subject_row.py | 11 + .../types/terminate_job_response.py | 3 + src/truefoundry_sdk/types/token_pagination.py | 7 + src/truefoundry_sdk/types/trace_span.py | 52 +++ .../types/trigger_job_run_response.py | 4 + .../types/true_foundry_apply_response.py | 4 + src/truefoundry_sdk/types/user.py | 3 + src/truefoundry_sdk/types/user_resource.py | 15 + src/truefoundry_sdk/types/user_team_info.py | 4 + src/truefoundry_sdk/types/virtual_account.py | 40 ++ src/truefoundry_sdk/types/workspace.py | 12 + tests/utils/test_http_client.py | 69 +++- 57 files changed, 996 insertions(+), 64 deletions(-) diff --git a/.fern/metadata.json b/.fern/metadata.json index 97b84166..90bc00dd 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "5.59.0", + "cliVersion": "5.82.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "5.15.0", + "generatorVersion": "5.24.0", "generatorConfig": { "package_name": "truefoundry_sdk", "use_request_defaults": "all", @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "68162af8093fdd989741251da8c28c5201afabec", + "originGitCommit": "f9c6a5aeafc0344a9a6141b6aae4fb58e2e186b6", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/README.md b/README.md index 222a387e..bbd9daa2 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ client = TrueFoundry(..., timeout=20.0) # Override timeout for a specific method client.applications.list(..., request_options={ - "timeout_in_seconds": 1 + "timeout": 1 }) ``` diff --git a/poetry.lock b/poetry.lock index 6c2130d5..aa93f6eb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -691,15 +691,15 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "httpx-aiohttp" -version = "0.1.8" +version = "0.1.12" description = "Aiohttp transport for HTTPX" optional = true python-versions = ">=3.8" groups = ["main"] markers = "extra == \"aiohttp\"" files = [ - {file = "httpx_aiohttp-0.1.8-py3-none-any.whl", hash = "sha256:b7bd958d1331f3759a38a0ba22ad29832cb63ca69498c17735228055bf78fa7e"}, - {file = "httpx_aiohttp-0.1.8.tar.gz", hash = "sha256:756c5e74cdb568c3248ba63fe82bfe8bbe64b928728720f7eaac64b3cf46f308"}, + {file = "httpx_aiohttp-0.1.12-py3-none-any.whl", hash = "sha256:5b0eac39a7f360fa7867a60bcb46bb1024eada9c01cbfecdb54dc1edb3fb7141"}, + {file = "httpx_aiohttp-0.1.12.tar.gz", hash = "sha256:81feec51fd82c0ecfa0e9aaf1b1a6c2591260d5e2bcbeb7eb0277a78e610df2c"}, ] [package.dependencies] @@ -2165,4 +2165,4 @@ aiohttp = ["aiohttp", "httpx-aiohttp"] [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "e7dbcbfca4561ac937abd01771decdedf9be4fc132741bacde30f25b01a9e74c" +content-hash = "6a199718f628e7df205629b66ba61c462504e648aae4e3914e863ca0467c4bf0" diff --git a/pyproject.toml b/pyproject.toml index 5a50a477..f807ba11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ Repository = 'https://github.com/truefoundry/truefoundry-python-sdk' python = ">=3.10" aiohttp = { version = ">=3.14.1,<4", optional = true, python = ">=3.10"} httpx = ">=0.21.2" -httpx-aiohttp = { version = "0.1.8", optional = true, python = ">=3.10"} +httpx-aiohttp = { version = "^0.1.8", optional = true, python = ">=3.10"} pydantic = ">= 1.9.2" pydantic-core = ">=2.18.2,<3.0.0" typing_extensions = ">= 4.0.0" diff --git a/src/truefoundry_sdk/base_client.py b/src/truefoundry_sdk/base_client.py index 754d4262..fb41737a 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -109,9 +109,7 @@ def __init__( httpx_client: typing.Optional[httpx.Client] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): - _defaulted_timeout = ( - timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read - ) + _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None _defaulted_max_retries = max_retries if max_retries is not None else 2 if api_key is None: raise ApiError(body="The client must be instantiated be either passing in api_key or setting TFY_API_KEY") @@ -587,9 +585,7 @@ def __init__( httpx_client: typing.Optional[httpx.AsyncClient] = None, logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): - _defaulted_timeout = ( - timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read - ) + _defaulted_timeout = timeout if timeout is not None else 60 if httpx_client is None else None _defaulted_max_retries = max_retries if max_retries is not None else 2 if api_key is None: raise ApiError(body="The client must be instantiated be either passing in api_key or setting TFY_API_KEY") diff --git a/src/truefoundry_sdk/core/http_client.py b/src/truefoundry_sdk/core/http_client.py index f686c571..409d2670 100644 --- a/src/truefoundry_sdk/core/http_client.py +++ b/src/truefoundry_sdk/core/http_client.py @@ -3,6 +3,7 @@ import asyncio import email.utils import re +import socket import time import typing from contextlib import asynccontextmanager, contextmanager @@ -23,6 +24,39 @@ JITTER_FACTOR = 0.2 # 20% random jitter +def get_keepalive_socket_options( + idle: int = 60, + intvl: int = 30, + cnt: int = 5, +) -> typing.List[typing.Tuple[int, int, int]]: + """ + Build TCP keepalive socket options for the current platform. + + Keepalive probes keep otherwise-idle connections alive so that long, + non-streaming requests survive idle-connection reaping by a firewall, + load balancer, or NAT. The available socket constants are OS-dependent, + so each option is guarded and only emitted when the platform defines it: + + - ``SO_KEEPALIVE`` is portable (Linux/macOS/Windows). + - The idle-before-first-probe knob is ``TCP_KEEPIDLE`` on Linux and modern + Windows, but ``TCP_KEEPALIVE`` on macOS. + - ``TCP_KEEPINTVL`` / ``TCP_KEEPCNT`` exist on Linux/macOS/modern Windows. + + Passing these tuples to ``httpx.HTTPTransport(socket_options=...)`` / + ``httpx.AsyncHTTPTransport(socket_options=...)`` applies them to every + connection the transport opens. + """ + opts: typing.List[typing.Tuple[int, int, int]] = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)] + idle_const = getattr(socket, "TCP_KEEPIDLE", None) or getattr(socket, "TCP_KEEPALIVE", None) + if idle_const: + opts.append((socket.IPPROTO_TCP, idle_const, idle)) + if hasattr(socket, "TCP_KEEPINTVL"): + opts.append((socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, intvl)) + if hasattr(socket, "TCP_KEEPCNT"): + opts.append((socket.IPPROTO_TCP, socket.TCP_KEEPCNT, cnt)) + return opts + + def _parse_retry_after(response_headers: httpx.Headers) -> typing.Optional[float]: """ This function parses the `Retry-After` header in a HTTP response and returns the number of seconds to wait. @@ -312,11 +346,14 @@ def request( force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) @@ -472,11 +509,14 @@ def stream( force_multipart: typing.Optional[bool] = None, ) -> typing.Iterator[httpx.Response]: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -601,11 +641,14 @@ async def request( force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -764,11 +807,14 @@ async def stream( force_multipart: typing.Optional[bool] = None, ) -> typing.AsyncIterator[httpx.Response]: base_url = self.get_base_url(base_url) - timeout = ( - request_options.get("timeout_in_seconds") + _timeout = ( + request_options.get("timeout") + if request_options is not None and request_options.get("timeout") is not None + else request_options.get("timeout_in_seconds") if request_options is not None and request_options.get("timeout_in_seconds") is not None else self.base_timeout() ) + timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) diff --git a/src/truefoundry_sdk/core/http_sse/_api.py b/src/truefoundry_sdk/core/http_sse/_api.py index 192ec0d9..9ca5602c 100644 --- a/src/truefoundry_sdk/core/http_sse/_api.py +++ b/src/truefoundry_sdk/core/http_sse/_api.py @@ -2,9 +2,20 @@ import codecs import re +import time from contextlib import asynccontextmanager, contextmanager -from typing import Any, AsyncGenerator, AsyncIterator, Iterator, Optional - +from typing import ( + Any, + AsyncContextManager, + AsyncGenerator, + AsyncIterator, + Callable, + ContextManager, + Iterator, + Optional, +) + +import anyio import httpx from ._decoders import SSEDecoder from ._exceptions import SSEError @@ -12,7 +23,16 @@ MAX_LINE_SIZE: int = 1_048_576 # 1 MiB +# Reconnection defaults, mirroring the TypeScript SDK's Stream implementation. +DEFAULT_MAX_RECONNECTION_ATTEMPTS: int = 5 +DEFAULT_RECONNECT_DELAY_MS: int = 1_000 +MAX_RECONNECT_DELAY_MS: int = 30_000 + +# A reconnect callback re-issues the original request (with a ``Last-Event-ID`` +# header set to the supplied event id) and returns a *context manager* yielding +# a fresh streaming ``httpx.Response``. Sync clients supply a sync context +# manager; async clients supply an async one. class EventSource: def __init__( self, @@ -21,22 +41,42 @@ def __init__( resumable: bool = False, stream_reconnection_enabled: bool = True, max_stream_reconnection_attempts: Optional[int] = None, + stream_terminator: Optional[str] = None, + reconnect: Optional[Callable[[str], Any]] = None, ) -> None: self._response = response self._resumable = resumable self._stream_reconnection_enabled = stream_reconnection_enabled self._max_stream_reconnection_attempts = max_stream_reconnection_attempts + self._stream_terminator = stream_terminator + self._reconnect = reconnect + + @staticmethod + def _is_event_stream(response: httpx.Response) -> bool: + content_type = response.headers.get("content-type", "").partition(";")[0] + return "text/event-stream" in content_type def _check_content_type(self) -> None: - content_type = self._response.headers.get("content-type", "").partition(";")[0] - if "text/event-stream" not in content_type: + if not self._is_event_stream(self._response): + content_type = self._response.headers.get("content-type", "").partition(";")[0] raise SSEError( f"Expected response header Content-Type to contain 'text/event-stream', got {content_type!r}" ) - def _get_charset(self) -> str: + def _is_reconnect_response_usable(self, response: httpx.Response) -> bool: + """Whether a reconnected response can be resumed as an SSE stream. + + ``httpx.stream`` does not raise on non-success status, so a resume that + returns an error page (e.g. ``200 text/html`` or a ``500`` body) would + otherwise be parsed as SSE and yield garbage/zero events. Such a + response is treated as a failed attempt (back off and retry) instead. + """ + return response.status_code < 400 and self._is_event_stream(response) + + def _get_charset(self, response: Optional[httpx.Response] = None) -> str: """Extract charset from Content-Type header, fallback to UTF-8.""" - content_type = self._response.headers.get("content-type", "") + resolved = response if response is not None else self._response + content_type = resolved.headers.get("content-type", "") # Parse charset parameter using regex charset_match = re.search(r"charset=([^;\s]+)", content_type, re.IGNORECASE) @@ -70,14 +110,83 @@ def _normalize_sse_line_endings(buf: str) -> str: return buf[:-1].replace("\r", "\n") + "\r" return buf.replace("\r", "\n") - def iter_sse(self) -> Iterator[ServerSentEvent]: - self._check_content_type() - decoder = SSEDecoder() - charset = self._get_charset() - text_decoder = codecs.getincrementaldecoder(charset)(errors="replace") - + def _new_text_decoder(self, response: Optional[httpx.Response] = None) -> "codecs.IncrementalDecoder": + return codecs.getincrementaldecoder(self._get_charset(response))(errors="replace") + + def _reconnect_applicable(self) -> bool: + """Whether reconnection is configured for this stream at all. + + This is the terminator-gating half of the reconnect decision, kept + separate from :meth:`_should_reconnect` (which additionally requires a + last *dispatched* id and an unexhausted attempt budget). The split lets + a mid-stream transport error terminate consistently: + - a stream that can never reconnect (non-resumable, no terminator, + disabled, or no callback) must re-raise the error to the caller, so a + truncated stream is not mistaken for a clean completion; + - a resumable stream that has merely run out of attempts (or has no id + to resume from) ends cleanly — the same way an exhausted empty/error + -body resume already does, matching the TypeScript ``return``. + """ + return ( + self._resumable + and self._stream_terminator is not None + and self._stream_reconnection_enabled + and self._reconnect is not None + ) + + def _should_reconnect(self, last_dispatched_id: Optional[str], reconnect_attempts: int) -> bool: + """Decide whether a prematurely-ended stream should be reconnected. + + Mirrors the TypeScript ``shouldReconnect`` gating: + - only resumable SSE endpoints with a configured terminator, reconnect + enabled, and a reconnect callback are eligible (see + :meth:`_reconnect_applicable`); + - a last *dispatched* event id must exist to resume from; + - the consecutive-failed-attempt cap must not be exceeded. + """ + if not self._reconnect_applicable(): + return False + if not last_dispatched_id: + return False + max_attempts = ( + self._max_stream_reconnection_attempts + if self._max_stream_reconnection_attempts is not None + else DEFAULT_MAX_RECONNECTION_ATTEMPTS + ) + if reconnect_attempts >= max_attempts: + return False + return True + + def _reconnect_delay_seconds(self, last_retry: Optional[int]) -> float: + """Backoff before a reconnect. + + Uses the server's most recent ``retry:`` directive (milliseconds) when + present, otherwise a default of ``DEFAULT_RECONNECT_DELAY_MS``, clamped + to ``MAX_RECONNECT_DELAY_MS``. + """ + base_ms = last_retry if (last_retry is not None and last_retry > 0) else DEFAULT_RECONNECT_DELAY_MS + return min(base_ms, MAX_RECONNECT_DELAY_MS) / 1000.0 + + def _sleep_before_reconnect(self, last_retry: Optional[int]) -> None: + # ``time.sleep`` blocks the calling thread but remains interruptible by + # signals (e.g. ``KeyboardInterrupt``), which propagate out and abort + # the reconnect without issuing another request. + time.sleep(self._reconnect_delay_seconds(last_retry)) + + async def _asleep_before_reconnect(self, last_retry: Optional[int]) -> None: + # ``anyio.sleep`` is cancellation-aware: if the consumer cancels the task + # or closes the async generator mid-delay, this raises (and no further + # request is issued) instead of blocking for the whole interval. + await anyio.sleep(self._reconnect_delay_seconds(last_retry)) + + def _decode_response( + self, + response: httpx.Response, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> Iterator[ServerSentEvent]: buf = "" - for chunk in self._response.iter_bytes(): + for chunk in response.iter_bytes(): buf += text_decoder.decode(chunk) buf = self._normalize_sse_line_endings(buf) @@ -92,34 +201,16 @@ def iter_sse(self) -> Iterator[ServerSentEvent]: f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" ) - # Flush any remaining bytes from the incremental decoder - buf += text_decoder.decode(b"", final=True) - buf = buf.replace("\r\n", "\n").replace("\r", "\n") - - if len(buf) > MAX_LINE_SIZE: - raise SSEError( - f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" - ) - - while "\n" in buf: - line, buf = buf.split("\n", 1) - sse = decoder.decode(line) - if sse is not None: - yield sse - - if buf.strip(): - sse = decoder.decode(buf) - if sse is not None: - yield sse - - async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: - self._check_content_type() - decoder = SSEDecoder() - charset = self._get_charset() - text_decoder = codecs.getincrementaldecoder(charset)(errors="replace") + yield from self._flush_decoder(buf, decoder, text_decoder) + async def _adecode_response( + self, + response: httpx.Response, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> AsyncGenerator[ServerSentEvent, None]: buf = "" - async for chunk in self._response.aiter_bytes(): + async for chunk in response.aiter_bytes(): buf += text_decoder.decode(chunk) buf = self._normalize_sse_line_endings(buf) @@ -134,6 +225,15 @@ async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: f"SSE line exceeded maximum size of {MAX_LINE_SIZE} characters without encountering a newline" ) + for sse in self._flush_decoder(buf, decoder, text_decoder): + yield sse + + def _flush_decoder( + self, + buf: str, + decoder: SSEDecoder, + text_decoder: "codecs.IncrementalDecoder", + ) -> Iterator[ServerSentEvent]: # Flush any remaining bytes from the incremental decoder buf += text_decoder.decode(b"", final=True) buf = buf.replace("\r\n", "\n").replace("\r", "\n") @@ -154,6 +254,181 @@ async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: if sse is not None: yield sse + def iter_sse(self) -> Iterator[ServerSentEvent]: + self._check_content_type() + decoder = SSEDecoder() + text_decoder = self._new_text_decoder() + + last_dispatched_id: Optional[str] = None + last_retry: Optional[int] = None + # Consecutive failed reconnection attempts. Reset to 0 whenever an event + # is successfully dispatched (reset-on-progress) — matching browser + # `EventSource` semantics: a server that emits >=1 event then drops on + # every connection can reconnect indefinitely. + reconnect_attempts = 0 + + # ``None`` means there is no live stream to read this iteration (e.g. a + # failed reconnect); the loop then re-evaluates the reconnect decision + # without re-reading an exhausted response. + response: Optional[httpx.Response] = self._response + # Context manager for a response we opened ourselves and must close. + # The initial response is owned by the caller, so it starts as None. + owned_cm: Optional[ContextManager[httpx.Response]] = None + try: + while True: + if response is not None: + events = self._decode_response(response, decoder, text_decoder) + while True: + try: + sse = next(events) + except StopIteration: + break + except SSEError: + # A protocol violation (e.g. an oversized line) is a + # genuine error, not a dropped connection; propagate it. + # Listed first because ``SSEError`` subclasses + # ``httpx.TransportError``. + raise + except httpx.TransportError: + # A transport error mid-stream (e.g. the server dropped + # the connection: ``ReadError``/``RemoteProtocolError``) + # is a premature end. Only swallow it when reconnection + # is configured for this stream; otherwise re-raise so a + # non-resumable stream still surfaces the error to the + # caller instead of looking like a clean completion. + # When reconnection is applicable but the attempt budget + # is exhausted, we ``break`` and end cleanly below — the + # same way an exhausted empty/error-body resume does, so + # give-up is consistent regardless of failure shape. + # ``next`` is used rather than ``for`` so this cannot + # swallow a ``GeneratorExit`` raised at a ``yield``. + if not self._reconnect_applicable(): + raise + break + yield sse + if sse.id: + last_dispatched_id = sse.id + if sse.retry is not None: + last_retry = sse.retry + reconnect_attempts = 0 + + if not self._should_reconnect(last_dispatched_id, reconnect_attempts): + return + reconnect_attempts += 1 + + self._sleep_before_reconnect(last_retry) + + # Close the previously-opened reconnect response before opening + # a new one so we never hold more than one extra connection. + if owned_cm is not None: + owned_cm.__exit__(None, None, None) + owned_cm = None + + assert self._reconnect is not None # guaranteed by _should_reconnect + try: + cm: ContextManager[httpx.Response] = self._reconnect(last_dispatched_id or "") + new_response = cm.__enter__() + except Exception: + # A failed reconnect consumes an attempt; back off and retry. + response = None + continue + owned_cm = cm + if new_response is None or not self._is_reconnect_response_usable(new_response): + # Null/empty body or a non-SSE/error response (e.g. 204/304, + # a 500, or an HTML error page): treat as a failed attempt. + response = None + continue + + response = new_response + # Drop any partial event left over from the dropped stream, but + # keep the last event id (per the SSE spec) and start a fresh + # incremental text decoder for the new connection. + decoder.reset_in_progress_event() + text_decoder = self._new_text_decoder(new_response) + finally: + if owned_cm is not None: + owned_cm.__exit__(None, None, None) + + async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: + self._check_content_type() + decoder = SSEDecoder() + text_decoder = self._new_text_decoder() + + last_dispatched_id: Optional[str] = None + last_retry: Optional[int] = None + reconnect_attempts = 0 + + response: Optional[httpx.Response] = self._response + owned_cm: Optional[AsyncContextManager[httpx.Response]] = None + try: + while True: + if response is not None: + events = self._adecode_response(response, decoder, text_decoder) + while True: + try: + sse = await events.__anext__() + except StopAsyncIteration: + break + except SSEError: + # A protocol violation (e.g. an oversized line) is a + # genuine error, not a dropped connection; propagate it. + # Listed first because ``SSEError`` subclasses + # ``httpx.TransportError``. + raise + except httpx.TransportError: + # A transport error mid-stream (e.g. the server dropped + # the connection: ``ReadError``/``RemoteProtocolError``) + # is a premature end. Only swallow it when reconnection + # is configured for this stream; otherwise re-raise so a + # non-resumable stream still surfaces the error to the + # caller instead of looking like a clean completion. + # When reconnection is applicable but the attempt budget + # is exhausted, we ``break`` and end cleanly below — the + # same way an exhausted empty/error-body resume does, so + # give-up is consistent regardless of failure shape. + if not self._reconnect_applicable(): + raise + break + yield sse + if sse.id: + last_dispatched_id = sse.id + if sse.retry is not None: + last_retry = sse.retry + reconnect_attempts = 0 + + if not self._should_reconnect(last_dispatched_id, reconnect_attempts): + return + reconnect_attempts += 1 + + await self._asleep_before_reconnect(last_retry) + + if owned_cm is not None: + await owned_cm.__aexit__(None, None, None) + owned_cm = None + + assert self._reconnect is not None # guaranteed by _should_reconnect + try: + cm: AsyncContextManager[httpx.Response] = self._reconnect(last_dispatched_id or "") + new_response = await cm.__aenter__() + except Exception: + response = None + continue + owned_cm = cm + if new_response is None or not self._is_reconnect_response_usable(new_response): + response = None + continue + + response = new_response + decoder.reset_in_progress_event() + text_decoder = self._new_text_decoder(new_response) + finally: + if owned_cm is not None: + # Shield the close so a cancellation delivered while reading a + # reconnected response still fully tears the connection down + # instead of leaking it until the client is closed. + with anyio.CancelScope(shield=True): + await owned_cm.__aexit__(None, None, None) + @contextmanager def connect_sse(client: httpx.Client, method: str, url: str, **kwargs: Any) -> Iterator[EventSource]: diff --git a/src/truefoundry_sdk/core/http_sse/_decoders.py b/src/truefoundry_sdk/core/http_sse/_decoders.py index 339b0890..1f6b35ec 100644 --- a/src/truefoundry_sdk/core/http_sse/_decoders.py +++ b/src/truefoundry_sdk/core/http_sse/_decoders.py @@ -12,6 +12,19 @@ def __init__(self) -> None: self._last_event_id = "" self._retry: Optional[int] = None + def reset_in_progress_event(self) -> None: + """Discard any partially-parsed (undispatched) event. + + Used when a stream ends mid-event before reconnecting: the buffered + ``event``/``data``/``retry`` fields of the never-dispatched event must + be dropped so they do not corrupt the first event of the reconnected + stream. Per the SSE spec the last event id is *not* reset here — it + persists across connections. + """ + self._event = "" + self._data = [] + self._retry = None + def decode(self, line: str) -> Optional[ServerSentEvent]: # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 diff --git a/src/truefoundry_sdk/core/request_options.py b/src/truefoundry_sdk/core/request_options.py index ebf17bcf..caa6f669 100644 --- a/src/truefoundry_sdk/core/request_options.py +++ b/src/truefoundry_sdk/core/request_options.py @@ -14,7 +14,9 @@ class RequestOptions(typing.TypedDict, total=False): This is used primarily as an optional final parameter for service functions. Attributes: - - timeout_in_seconds: int. The number of seconds to await an API call before timing out. + - timeout: float. The number of seconds to await an API call before timing out. + + - timeout_in_seconds: int. Deprecated alias for `timeout`; both are in seconds. Prefer `timeout`. - max_retries: int. The max number of retries to attempt if the API call fails. @@ -27,6 +29,7 @@ class RequestOptions(typing.TypedDict, total=False): - chunk_size: int. The size, in bytes, to process each chunk of data being streamed back within the response. This equates to leveraging `chunk_size` within `requests` or `httpx`, and is only leveraged for file downloads. """ + timeout: NotRequired[float] timeout_in_seconds: NotRequired[int] max_retries: NotRequired[int] additional_headers: NotRequired[typing.Dict[str, typing.Any]] diff --git a/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py b/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py index 1c7c08bd..d625267f 100644 --- a/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py +++ b/src/truefoundry_sdk/internal/workflows/types/execute_workflow_workflows_response.py @@ -14,6 +14,9 @@ class ExecuteWorkflowWorkflowsResponse(UniversalBaseModel): FieldMetadata(alias="executionName"), pydantic.Field(alias="executionName", description="The name of the execution"), ] = None + """ + The name of the execution + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/addon_component_status.py b/src/truefoundry_sdk/types/addon_component_status.py index 5361a1a3..8ae7df26 100644 --- a/src/truefoundry_sdk/types/addon_component_status.py +++ b/src/truefoundry_sdk/types/addon_component_status.py @@ -14,11 +14,19 @@ class AddonComponentStatus(UniversalBaseModel): FieldMetadata(alias="healthStatus"), pydantic.Field(alias="healthStatus", description="Health status of the addon"), ] = None + """ + Health status of the addon + """ + sync_status: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="syncStatus"), pydantic.Field(alias="syncStatus", description="Sync status of the addon"), ] = None + """ + Sync status of the addon + """ + installed: bool = pydantic.Field() """ Indicates whether the addon is installed diff --git a/src/truefoundry_sdk/types/agent_version_metadata.py b/src/truefoundry_sdk/types/agent_version_metadata.py index fc0ff46c..7c0e4ea6 100644 --- a/src/truefoundry_sdk/types/agent_version_metadata.py +++ b/src/truefoundry_sdk/types/agent_version_metadata.py @@ -17,6 +17,9 @@ class AgentVersionMetadata(UniversalBaseModel): description="Prompt template variables (variable name to default value) saved from the linked prompt version. Only set for agents with an instruction.", ), ] = None + """ + Prompt template variables (variable name to default value) saved from the linked prompt version. Only set for agents with an instruction. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/application.py b/src/truefoundry_sdk/types/application.py index f207676d..7e2c5ecc 100644 --- a/src/truefoundry_sdk/types/application.py +++ b/src/truefoundry_sdk/types/application.py @@ -47,11 +47,19 @@ class Application(UniversalBaseModel): alias="createdBySubject", description="Subject (user or service account) that created this application" ), ] + """ + Subject (user or service account) that created this application + """ + tenant_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName", description="Tenant this application belongs to"), ] = None + """ + Tenant this application belongs to + """ + metadata: typing.Optional[ApplicationMetadata] = pydantic.Field(default=None) """ Application metadata including pause state and sync info @@ -62,6 +70,10 @@ class Application(UniversalBaseModel): FieldMetadata(alias="lifecycleStage"), pydantic.Field(alias="lifecycleStage", description="Current lifecycle stage of the application"), ] + """ + Current lifecycle stage of the application + """ + workspace_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="workspaceId"), @@ -69,16 +81,28 @@ class Application(UniversalBaseModel): alias="workspaceId", description="Unique identifier of the workspace this application belongs to" ), ] = None + """ + Unique identifier of the workspace this application belongs to + """ + last_version: typing_extensions.Annotated[ typing.Optional[int], FieldMetadata(alias="lastVersion"), pydantic.Field(alias="lastVersion", description="Version number of the latest deployment"), ] = None + """ + Version number of the latest deployment + """ + active_version: typing_extensions.Annotated[ typing.Optional[int], FieldMetadata(alias="activeVersion"), pydantic.Field(alias="activeVersion", description="Version number of the currently active deployment"), ] = None + """ + Version number of the currently active deployment + """ + application_set_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="applicationSetId"), @@ -87,6 +111,10 @@ class Application(UniversalBaseModel): description="Unique identifier of the application set this application belongs to, if any", ), ] = None + """ + Unique identifier of the application set this application belongs to, if any + """ + created_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") ] = None @@ -108,16 +136,28 @@ class Application(UniversalBaseModel): FieldMetadata(alias="alertsSummary"), pydantic.Field(alias="alertsSummary", description="Summary of alerts for this application"), ] = None + """ + Summary of alerts for this application + """ + application_debug_infos: typing_extensions.Annotated[ typing.Optional[typing.List["ApplicationDebugInfo"]], FieldMetadata(alias="applicationDebugInfos"), pydantic.Field(alias="applicationDebugInfos", description="Debug infos for this application"), ] = None + """ + Debug infos for this application + """ + potential_problems: typing_extensions.Annotated[ typing.Optional[typing.List[ApplicationProblem]], FieldMetadata(alias="potentialProblems"), pydantic.Field(alias="potentialProblems", description="Potential problems with the application"), ] = None + """ + Potential problems with the application + """ + autopilot: typing.Dict[str, typing.Any] workspace_fqn: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="workspaceFqn"), pydantic.Field(alias="workspaceFqn") diff --git a/src/truefoundry_sdk/types/application_summary.py b/src/truefoundry_sdk/types/application_summary.py index 8526bca1..c0027bed 100644 --- a/src/truefoundry_sdk/types/application_summary.py +++ b/src/truefoundry_sdk/types/application_summary.py @@ -42,6 +42,10 @@ class ApplicationSummary(UniversalBaseModel): FieldMetadata(alias="lifecycleStage"), pydantic.Field(alias="lifecycleStage", description="Current lifecycle stage of the application"), ] + """ + Current lifecycle stage of the application + """ + workspace_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="workspaceId"), @@ -49,11 +53,19 @@ class ApplicationSummary(UniversalBaseModel): alias="workspaceId", description="Unique identifier of the workspace this application belongs to" ), ] = None + """ + Unique identifier of the workspace this application belongs to + """ + active_version: typing_extensions.Annotated[ typing.Optional[int], FieldMetadata(alias="activeVersion"), pydantic.Field(alias="activeVersion", description="Version number of the currently active deployment"), ] = None + """ + Version number of the currently active deployment + """ + application_set_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="applicationSetId"), @@ -62,6 +74,9 @@ class ApplicationSummary(UniversalBaseModel): description="Unique identifier of the application set this application belongs to, if any", ), ] = None + """ + Unique identifier of the application set this application belongs to, if any + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/budget_v2in_not_in_filter.py b/src/truefoundry_sdk/types/budget_v2in_not_in_filter.py index bd891a8a..1078c910 100644 --- a/src/truefoundry_sdk/types/budget_v2in_not_in_filter.py +++ b/src/truefoundry_sdk/types/budget_v2in_not_in_filter.py @@ -18,6 +18,10 @@ class BudgetV2InNotInFilter(UniversalBaseModel): FieldMetadata(alias="in"), pydantic.Field(alias="in", description="Match when the value is present in this list"), ] = None + """ + Match when the value is present in this list + """ + not_in: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ Match when the value is NOT present in this list diff --git a/src/truefoundry_sdk/types/cluster_gateway.py b/src/truefoundry_sdk/types/cluster_gateway.py index 355c1d13..8fa413b4 100644 --- a/src/truefoundry_sdk/types/cluster_gateway.py +++ b/src/truefoundry_sdk/types/cluster_gateway.py @@ -17,6 +17,10 @@ class ClusterGateway(UniversalBaseModel): FieldMetadata(alias="isTieBreaker"), pydantic.Field(alias="isTieBreaker", description="Used when there are 2 gateways with same host"), ] = None + """ + Used when there are 2 gateways with same host + """ + selector: typing.Dict[str, str] if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/create_docker_repository_response.py b/src/truefoundry_sdk/types/create_docker_repository_response.py index 7cbe2b32..db197dba 100644 --- a/src/truefoundry_sdk/types/create_docker_repository_response.py +++ b/src/truefoundry_sdk/types/create_docker_repository_response.py @@ -14,6 +14,9 @@ class CreateDockerRepositoryResponse(UniversalBaseModel): FieldMetadata(alias="repoName"), pydantic.Field(alias="repoName", description="Created Docker repository name"), ] + """ + Created Docker repository name + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/deployment.py b/src/truefoundry_sdk/types/deployment.py index 3689c22e..bfe5d39a 100644 --- a/src/truefoundry_sdk/types/deployment.py +++ b/src/truefoundry_sdk/types/deployment.py @@ -38,6 +38,10 @@ class Deployment(UniversalBaseModel): alias="applicationId", description="Unique identifier of the application this deployment belongs to" ), ] = None + """ + Unique identifier of the application this deployment belongs to + """ + manifest: DeploymentManifest = pydantic.Field() """ Deployment manifest defining the application configuration. @@ -55,26 +59,46 @@ class Deployment(UniversalBaseModel): alias="createdBySubject", description="Subject (user or service account) that created this deployment" ), ] + """ + Subject (user or service account) that created this deployment + """ + created_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Timestamp when the deployment was created"), ] = None + """ + Timestamp when the deployment was created + """ + updated_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt", description="Timestamp when the deployment was last updated"), ] = None + """ + Timestamp when the deployment was last updated + """ + deployment_builds: typing_extensions.Annotated[ typing.Optional[typing.List[BuildInfo]], FieldMetadata(alias="deploymentBuilds"), pydantic.Field(alias="deploymentBuilds", description="Build steps associated with this deployment"), ] = None + """ + Build steps associated with this deployment + """ + deployment_statuses: typing_extensions.Annotated[ typing.Optional[typing.List[DeploymentStatus]], FieldMetadata(alias="deploymentStatuses"), pydantic.Field(alias="deploymentStatuses", description="Full history of deployment status transitions"), ] = None + """ + Full history of deployment status transitions + """ + current_status_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="currentStatusId"), @@ -82,21 +106,36 @@ class Deployment(UniversalBaseModel): alias="currentStatusId", description="Unique identifier of the current deployment status record" ), ] = None + """ + Unique identifier of the current deployment status record + """ + current_status: typing_extensions.Annotated[ typing.Optional[DeploymentStatus], FieldMetadata(alias="currentStatus"), pydantic.Field(alias="currentStatus", description="Current deployment status object."), ] = None + """ + Current deployment status object. + """ + applied_recommendations: typing_extensions.Annotated[ typing.Optional[typing.List[Recommendation]], FieldMetadata(alias="appliedRecommendations"), pydantic.Field(alias="appliedRecommendations", description="Applied recommendations for this deployment"), ] = None + """ + Applied recommendations for this deployment + """ + created_by: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy", description="Slug of the subject that created this deployment"), ] = None + """ + Slug of the subject that created this deployment + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/environment_manifest.py b/src/truefoundry_sdk/types/environment_manifest.py index 583795ea..a0de4122 100644 --- a/src/truefoundry_sdk/types/environment_manifest.py +++ b/src/truefoundry_sdk/types/environment_manifest.py @@ -29,6 +29,10 @@ class EnvironmentManifest(UniversalBaseModel): alias="isProduction", description="Environment Type - Indicates if the environment is for production use" ), ] + """ + Environment Type - Indicates if the environment is for production use + """ + optimize_for: typing_extensions.Annotated[ EnvironmentOptimizeFor, FieldMetadata(alias="optimizeFor"), pydantic.Field(alias="optimizeFor") ] diff --git a/src/truefoundry_sdk/types/event.py b/src/truefoundry_sdk/types/event.py index 48e54e8c..5ef4cb85 100644 --- a/src/truefoundry_sdk/types/event.py +++ b/src/truefoundry_sdk/types/event.py @@ -21,16 +21,28 @@ class Event(UniversalBaseModel): FieldMetadata(alias="firstTimestamp"), pydantic.Field(alias="firstTimestamp", description="Timestamp when the event was first observed"), ] = None + """ + Timestamp when the event was first observed + """ + last_timestamp: typing_extensions.Annotated[ str, FieldMetadata(alias="lastTimestamp"), pydantic.Field(alias="lastTimestamp", description="Timestamp when the event was last observed"), ] + """ + Timestamp when the event was last observed + """ + involved_object: typing_extensions.Annotated[ EventInvolvedObject, FieldMetadata(alias="involvedObject"), pydantic.Field(alias="involvedObject", description="Details of the involved object"), ] + """ + Details of the involved object + """ + type: str = pydantic.Field() """ Type of the event diff --git a/src/truefoundry_sdk/types/gateway_configuration.py b/src/truefoundry_sdk/types/gateway_configuration.py index 3d31bf83..f6384929 100644 --- a/src/truefoundry_sdk/types/gateway_configuration.py +++ b/src/truefoundry_sdk/types/gateway_configuration.py @@ -22,6 +22,10 @@ class GatewayConfiguration(UniversalBaseModel): FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName", description="Tenant the gateway configuration belongs to."), ] + """ + Tenant the gateway configuration belongs to. + """ + type: str = pydantic.Field() """ Configuration type. @@ -40,16 +44,27 @@ class GatewayConfiguration(UniversalBaseModel): description="Principal (user or service account) that created or last updated this configuration.", ), ] + """ + Principal (user or service account) that created or last updated this configuration. + """ + created_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Creation timestamp."), ] = None + """ + Creation timestamp. + """ + updated_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt", description="Last-update timestamp."), ] = None + """ + Last-update timestamp. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/gcp_api_key_auth.py b/src/truefoundry_sdk/types/gcp_api_key_auth.py index a588d968..a2afef3a 100644 --- a/src/truefoundry_sdk/types/gcp_api_key_auth.py +++ b/src/truefoundry_sdk/types/gcp_api_key_auth.py @@ -23,6 +23,9 @@ class GcpApiKeyAuth(UniversalBaseModel): FieldMetadata(alias="apiKey"), pydantic.Field(alias="apiKey", description="The API key for Google Cloud authentication"), ] + """ + The API key for Google Cloud authentication + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py b/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py index 4f1d9f0d..ac24fa9d 100644 --- a/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py +++ b/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py @@ -14,6 +14,9 @@ class GetAuthenticatedVcsurlResponse(UniversalBaseModel): FieldMetadata(alias="authenticatedURL"), pydantic.Field(alias="authenticatedURL", description="Authenticated URL to access the repository"), ] + """ + Authenticated URL to access the repository + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/get_docker_registry_credentials_response.py b/src/truefoundry_sdk/types/get_docker_registry_credentials_response.py index a1860cb0..bbf5225b 100644 --- a/src/truefoundry_sdk/types/get_docker_registry_credentials_response.py +++ b/src/truefoundry_sdk/types/get_docker_registry_credentials_response.py @@ -17,6 +17,10 @@ class GetDockerRegistryCredentialsResponse(UniversalBaseModel): registry_url: typing_extensions.Annotated[ str, FieldMetadata(alias="registryUrl"), pydantic.Field(alias="registryUrl", description="Docker registry URL") ] + """ + Docker registry URL + """ + username: str = pydantic.Field() """ Docker registry username diff --git a/src/truefoundry_sdk/types/graph.py b/src/truefoundry_sdk/types/graph.py index ef0ff774..d6e6a741 100644 --- a/src/truefoundry_sdk/types/graph.py +++ b/src/truefoundry_sdk/types/graph.py @@ -30,6 +30,10 @@ class Graph(UniversalBaseModel): FieldMetadata(alias="chartType"), pydantic.Field(alias="chartType", description="Chart visualisation type."), ] + """ + Chart visualisation type. + """ + params: str = pydantic.Field() """ Opaque params string describing chart configuration to pass back to the corresponding chart data endpoint. diff --git a/src/truefoundry_sdk/types/headers_override.py b/src/truefoundry_sdk/types/headers_override.py index 63b3f548..df255776 100644 --- a/src/truefoundry_sdk/types/headers_override.py +++ b/src/truefoundry_sdk/types/headers_override.py @@ -23,6 +23,9 @@ class HeadersOverride(UniversalBaseModel): FieldMetadata(alias="set"), pydantic.Field(alias="set", description="Headers to add or overwrite in upstream request"), ] = None + """ + Headers to add or overwrite in upstream request + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/http_error.py b/src/truefoundry_sdk/types/http_error.py index 5f9fbe76..faf02551 100644 --- a/src/truefoundry_sdk/types/http_error.py +++ b/src/truefoundry_sdk/types/http_error.py @@ -13,6 +13,10 @@ class HttpError(UniversalBaseModel): status_code: typing_extensions.Annotated[ int, FieldMetadata(alias="statusCode"), pydantic.Field(alias="statusCode", description="HTTP Status Code") ] + """ + HTTP Status Code + """ + message: str = pydantic.Field() """ Error Message diff --git a/src/truefoundry_sdk/types/is_cluster_connected_response.py b/src/truefoundry_sdk/types/is_cluster_connected_response.py index 2de5d748..6ba2cf70 100644 --- a/src/truefoundry_sdk/types/is_cluster_connected_response.py +++ b/src/truefoundry_sdk/types/is_cluster_connected_response.py @@ -16,6 +16,9 @@ class IsClusterConnectedResponse(UniversalBaseModel): alias="isConnected", description="Whether the cluster agent is currently connected to the control plane." ), ] + """ + Whether the cluster agent is currently connected to the control plane. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/job_run.py b/src/truefoundry_sdk/types/job_run.py index ffbc32f0..1ce787b0 100644 --- a/src/truefoundry_sdk/types/job_run.py +++ b/src/truefoundry_sdk/types/job_run.py @@ -26,19 +26,35 @@ class JobRun(UniversalBaseModel): FieldMetadata(alias="applicationName"), pydantic.Field(alias="applicationName", description="Application Name"), ] + """ + Application Name + """ + deployment_version: typing_extensions.Annotated[ str, FieldMetadata(alias="deploymentVersion"), pydantic.Field(alias="deploymentVersion", description="Deployment Version"), ] + """ + Deployment Version + """ + created_at: typing_extensions.Annotated[ float, FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Created At") ] + """ + Created At + """ + end_time: typing_extensions.Annotated[ typing.Optional[float], FieldMetadata(alias="endTime"), pydantic.Field(alias="endTime", description="End Time of JobRun"), ] = None + """ + End Time of JobRun + """ + duration: typing.Optional[int] = pydantic.Field(default=None) """ Duration of JobRun @@ -52,6 +68,10 @@ class JobRun(UniversalBaseModel): total_retries: typing_extensions.Annotated[ int, FieldMetadata(alias="totalRetries"), pydantic.Field(alias="totalRetries", description="Total Retries") ] + """ + Total Retries + """ + error: typing.Optional[str] = pydantic.Field(default=None) """ Error @@ -67,34 +87,61 @@ class JobRun(UniversalBaseModel): FieldMetadata(alias="triggeredBy"), pydantic.Field(alias="triggeredBy", description="Triggered By"), ] = None + """ + Triggered By + """ + triggered_by_subject: typing_extensions.Annotated[ typing.Optional[Subject], FieldMetadata(alias="triggeredBySubject"), pydantic.Field(alias="triggeredBySubject", description="Triggered By Subject"), ] = None + """ + Triggered By Subject + """ + exit_code: typing_extensions.Annotated[ typing.Optional[int], FieldMetadata(alias="exitCode"), pydantic.Field(alias="exitCode", description="Exit Code") ] = None + """ + Exit Code + """ + spark_ui: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="sparkUi"), pydantic.Field(alias="sparkUi", description="Spark UI Url"), ] = None + """ + Spark UI Url + """ + application_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId", description="Application ID"), ] = None + """ + Application ID + """ + deployment_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="deploymentId"), pydantic.Field(alias="deploymentId", description="Deployment ID"), ] = None + """ + Deployment ID + """ + tenant_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName", description="Tenant Name"), ] = None + """ + Tenant Name + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/json_schema.py b/src/truefoundry_sdk/types/json_schema.py index 831dfb32..8a71696e 100644 --- a/src/truefoundry_sdk/types/json_schema.py +++ b/src/truefoundry_sdk/types/json_schema.py @@ -23,6 +23,9 @@ class JsonSchema(UniversalBaseModel): FieldMetadata(alias="schema"), pydantic.Field(alias="schema", description="JSON schema object defining the expected structure"), ] + """ + JSON schema object defining the expected structure + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/list_files_request.py b/src/truefoundry_sdk/types/list_files_request.py index da63264d..49000775 100644 --- a/src/truefoundry_sdk/types/list_files_request.py +++ b/src/truefoundry_sdk/types/list_files_request.py @@ -29,6 +29,9 @@ class ListFilesRequest(UniversalBaseModel): FieldMetadata(alias="pageToken"), pydantic.Field(alias="pageToken", description="Token to retrieve the next page of results"), ] = None + """ + Token to retrieve the next page of results + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/log.py b/src/truefoundry_sdk/types/log.py index 9e02862a..1affe0be 100644 --- a/src/truefoundry_sdk/types/log.py +++ b/src/truefoundry_sdk/types/log.py @@ -34,6 +34,9 @@ class Log(UniversalBaseModel): FieldMetadata(alias="containerName"), pydantic.Field(alias="containerName", description="Name of the container that emitted the log."), ] = None + """ + Name of the container that emitted the log. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/mcp_tool_annotations.py b/src/truefoundry_sdk/types/mcp_tool_annotations.py index f9370118..70aff60b 100644 --- a/src/truefoundry_sdk/types/mcp_tool_annotations.py +++ b/src/truefoundry_sdk/types/mcp_tool_annotations.py @@ -20,11 +20,18 @@ class McpToolAnnotations(UniversalBaseModel): alias="readOnlyHint", description="Indicates the tool only reads data and does not modify anything." ), ] = None + """ + Indicates the tool only reads data and does not modify anything. + """ + destructive_hint: typing_extensions.Annotated[ typing.Optional[bool], FieldMetadata(alias="destructiveHint"), pydantic.Field(alias="destructiveHint", description="Indicates the tool may perform destructive updates."), ] = None + """ + Indicates the tool may perform destructive updates. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/multi_part_upload.py b/src/truefoundry_sdk/types/multi_part_upload.py index be52bdee..4cfeaaea 100644 --- a/src/truefoundry_sdk/types/multi_part_upload.py +++ b/src/truefoundry_sdk/types/multi_part_upload.py @@ -33,6 +33,10 @@ class MultiPartUpload(UniversalBaseModel): alias="s3_compatible_upload_id", description="Upload identifier for S3-compatible storage providers." ), ] = None + """ + Upload identifier for S3-compatible storage providers. + """ + azure_blob_block_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ Block identifiers used for Azure Blob storage uploads. diff --git a/src/truefoundry_sdk/types/private_pricing_tier.py b/src/truefoundry_sdk/types/private_pricing_tier.py index 0e051964..038f1a13 100644 --- a/src/truefoundry_sdk/types/private_pricing_tier.py +++ b/src/truefoundry_sdk/types/private_pricing_tier.py @@ -22,6 +22,10 @@ class PrivatePricingTier(UniversalBaseModel): description="Token count threshold where this pricing tier begins (e.g., 200000 for 200k tokens)", ), ] + """ + Token count threshold where this pricing tier begins (e.g., 200000 for 200k tokens) + """ + cost_per_token: NonNegativeFloat if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/prometheus_alert_rule.py b/src/truefoundry_sdk/types/prometheus_alert_rule.py index 0dbb1fbc..158e5d78 100644 --- a/src/truefoundry_sdk/types/prometheus_alert_rule.py +++ b/src/truefoundry_sdk/types/prometheus_alert_rule.py @@ -37,6 +37,10 @@ class PrometheusAlertRule(UniversalBaseModel): description="The prometheus expression must remain true for this duration (in seconds) before the alert is triggered. If the condition becomes false before this time elapses, the alert will not fire.", ), ] + """ + The prometheus expression must remain true for this duration (in seconds) before the alert is triggered. If the condition becomes false before this time elapses, the alert will not fire. + """ + severity: AlertSeverity description: typing.Optional[str] = pydantic.Field(default=None) """ diff --git a/src/truefoundry_sdk/types/role_binding_permission.py b/src/truefoundry_sdk/types/role_binding_permission.py index 2be7a42d..d37be5fd 100644 --- a/src/truefoundry_sdk/types/role_binding_permission.py +++ b/src/truefoundry_sdk/types/role_binding_permission.py @@ -18,11 +18,19 @@ class RoleBindingPermission(UniversalBaseModel): FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Target resource kind (e.g. workspace, cluster, ml-repo)."), ] + """ + Target resource kind (e.g. workspace, cluster, ml-repo). + """ + resource_fqn: typing_extensions.Annotated[ str, FieldMetadata(alias="resourceFqn"), pydantic.Field(alias="resourceFqn", description="Fully qualified name of the resource."), ] + """ + Fully qualified name of the resource. + """ + role: str = pydantic.Field() """ Name of the role to bind (e.g. workspace-editor, model-user). diff --git a/src/truefoundry_sdk/types/role_manifest.py b/src/truefoundry_sdk/types/role_manifest.py index be75e241..19e86395 100644 --- a/src/truefoundry_sdk/types/role_manifest.py +++ b/src/truefoundry_sdk/types/role_manifest.py @@ -24,6 +24,10 @@ class RoleManifest(UniversalBaseModel): FieldMetadata(alias="displayName"), pydantic.Field(alias="displayName", description="Human-readable name for the role"), ] + """ + Human-readable name for the role + """ + description: str = pydantic.Field() """ Description of the role that explains its purpose and permissions @@ -34,6 +38,10 @@ class RoleManifest(UniversalBaseModel): FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Type of resource this role applies to"), ] + """ + Type of resource this role applies to + """ + permissions: typing.List[str] = pydantic.Field() """ Define the resource type and the corresponding actions this role can perform on the resource diff --git a/src/truefoundry_sdk/types/spark_job_trigger_input.py b/src/truefoundry_sdk/types/spark_job_trigger_input.py index 964ba8c4..d890344d 100644 --- a/src/truefoundry_sdk/types/spark_job_trigger_input.py +++ b/src/truefoundry_sdk/types/spark_job_trigger_input.py @@ -14,11 +14,19 @@ class SparkJobTriggerInput(UniversalBaseModel): FieldMetadata(alias="mainClass"), pydantic.Field(alias="mainClass", description="Main Class for Spark Job"), ] = None + """ + Main Class for Spark Job + """ + main_application_file: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="mainApplicationFile"), pydantic.Field(alias="mainApplicationFile", description="Main Application File for Spark Job"), ] = None + """ + Main Application File for Spark Job + """ + arguments: typing.Optional[str] = pydantic.Field(default=None) """ Arguments to pass to the main application file diff --git a/src/truefoundry_sdk/types/subject.py b/src/truefoundry_sdk/types/subject.py index 96152430..ae8fb8f8 100644 --- a/src/truefoundry_sdk/types/subject.py +++ b/src/truefoundry_sdk/types/subject.py @@ -13,24 +13,44 @@ class Subject(UniversalBaseModel): subject_id: typing_extensions.Annotated[ str, FieldMetadata(alias="subjectId"), pydantic.Field(alias="subjectId", description="Subject ID") ] + """ + Subject ID + """ + subject_type: typing_extensions.Annotated[ SubjectType, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType", description="Subject type") ] + """ + Subject type + """ + subject_slug: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="subjectSlug"), pydantic.Field(alias="subjectSlug", description="Subject slug"), ] = None + """ + Subject slug + """ + subject_display_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="subjectDisplayName"), pydantic.Field(alias="subjectDisplayName", description="Subject display name"), ] = None + """ + Subject display name + """ + subject_pat_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="subjectPatName"), pydantic.Field(alias="subjectPatName", description="Subject PAT name"), ] = None + """ + Subject PAT name + """ + subject_controller_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="subjectControllerName"), @@ -43,6 +63,9 @@ class Subject(UniversalBaseModel): alias="subjectExternalIdentitySlug", description="External identity slug (external_identity_id:sub:email)" ), ] = None + """ + External identity slug (external_identity_id:sub:email) + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/subject_permission.py b/src/truefoundry_sdk/types/subject_permission.py index df851765..6022a5e1 100644 --- a/src/truefoundry_sdk/types/subject_permission.py +++ b/src/truefoundry_sdk/types/subject_permission.py @@ -12,35 +12,66 @@ class SubjectPermission(UniversalBaseModel): resource_type: typing_extensions.Annotated[ str, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Resource Type") ] + """ + Resource Type + """ + resource_id: typing_extensions.Annotated[ str, FieldMetadata(alias="resourceId"), pydantic.Field(alias="resourceId", description="Resource ID") ] + """ + Resource ID + """ + resource_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="resourceName"), pydantic.Field(alias="resourceName", description="Resource Name (if available)"), ] = None + """ + Resource Name (if available) + """ + resource_fqn: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="resourceFqn"), pydantic.Field(alias="resourceFqn", description="Resource FQN (if available)"), ] = None + """ + Resource FQN (if available) + """ + role_id: typing_extensions.Annotated[ str, FieldMetadata(alias="roleId"), pydantic.Field(alias="roleId", description="Role ID") ] + """ + Role ID + """ + role_name: typing_extensions.Annotated[ str, FieldMetadata(alias="roleName"), pydantic.Field(alias="roleName", description="Role Name") ] + """ + Role Name + """ + subject_id: typing_extensions.Annotated[ str, FieldMetadata(alias="subjectId"), pydantic.Field(alias="subjectId", description="Subject ID (user or team)"), ] + """ + Subject ID (user or team) + """ + subject_type: typing_extensions.Annotated[ str, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType", description="Subject Type (user or team)"), ] + """ + Subject Type (user or team) + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py b/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py index bb2ded51..19d411a5 100644 --- a/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py +++ b/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py @@ -14,6 +14,10 @@ class SyncTokenInSecretStoreInfo(UniversalBaseModel): FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt", description="ISO timestamp of when the token was synced"), ] + """ + ISO timestamp of when the token was synced + """ + error: typing.Optional[str] = pydantic.Field(default=None) """ Error message if sync failed diff --git a/src/truefoundry_sdk/types/sync_virtual_account_token_response.py b/src/truefoundry_sdk/types/sync_virtual_account_token_response.py index f59eeccd..2fc6c50f 100644 --- a/src/truefoundry_sdk/types/sync_virtual_account_token_response.py +++ b/src/truefoundry_sdk/types/sync_virtual_account_token_response.py @@ -17,6 +17,9 @@ class SyncVirtualAccountTokenResponse(UniversalBaseModel): alias="syncTokenInSecretStoreInfo", description="Sync status including timestamp and error (if any)" ), ] + """ + Sync status including timestamp and error (if any) + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/team.py b/src/truefoundry_sdk/types/team.py index a7b12df1..9242567c 100644 --- a/src/truefoundry_sdk/types/team.py +++ b/src/truefoundry_sdk/types/team.py @@ -28,11 +28,19 @@ class Team(UniversalBaseModel): FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName", description="Tenant the team belongs to."), ] + """ + Tenant the team belongs to. + """ + account_id: typing_extensions.Annotated[ str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId", description="System-generated ID of the account that owns the team."), ] + """ + System-generated ID of the account that owns the team. + """ + created_by_subject: typing_extensions.Annotated[ Subject, FieldMetadata(alias="createdBySubject"), @@ -40,6 +48,10 @@ class Team(UniversalBaseModel): alias="createdBySubject", description="The subject (user or service account) that created the team." ), ] + """ + The subject (user or service account) that created the team. + """ + members: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ Email addresses of team members. @@ -50,11 +62,19 @@ class Team(UniversalBaseModel): FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Timestamp when the team was created."), ] + """ + Timestamp when the team was created. + """ + updated_at: typing_extensions.Annotated[ dt.datetime, FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt", description="Timestamp when the team was last updated."), ] + """ + Timestamp when the team was last updated. + """ + manifest: TeamManifest = pydantic.Field() """ The team manifest defining name, members, managers, and ownership. @@ -72,6 +92,10 @@ class Team(UniversalBaseModel): alias="isEditable", description="Whether the team can be edited. SCIM-managed teams may be non-editable." ), ] + """ + Whether the team can be edited. SCIM-managed teams may be non-editable. + """ + roles: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ Role names assigned to the team. @@ -85,6 +109,10 @@ class Team(UniversalBaseModel): description="Up to 5 team member emails, sourced from cache. Absent when the cache is unavailable.", ), ] = None + """ + Up to 5 team member emails, sourced from cache. Absent when the cache is unavailable. + """ + top_managers: typing_extensions.Annotated[ typing.Optional[typing.List[str]], FieldMetadata(alias="topManagers"), @@ -93,6 +121,10 @@ class Team(UniversalBaseModel): description="Up to 5 team manager emails, sourced from cache. Absent when the cache is unavailable.", ), ] = None + """ + Up to 5 team manager emails, sourced from cache. Absent when the cache is unavailable. + """ + total_member_count: typing_extensions.Annotated[ typing.Optional[float], FieldMetadata(alias="totalMemberCount"), @@ -101,6 +133,10 @@ class Team(UniversalBaseModel): description="Total number of team members, sourced from cache. Absent when the cache is unavailable.", ), ] = None + """ + Total number of team members, sourced from cache. Absent when the cache is unavailable. + """ + total_manager_count: typing_extensions.Annotated[ typing.Optional[float], FieldMetadata(alias="totalManagerCount"), @@ -109,6 +145,9 @@ class Team(UniversalBaseModel): description="Total number of team managers, sourced from cache. Absent when the cache is unavailable.", ), ] = None + """ + Total number of team managers, sourced from cache. Absent when the cache is unavailable. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/team_manifest.py b/src/truefoundry_sdk/types/team_manifest.py index ef1cbb31..b62e69f5 100644 --- a/src/truefoundry_sdk/types/team_manifest.py +++ b/src/truefoundry_sdk/types/team_manifest.py @@ -29,6 +29,10 @@ class TeamManifest(UniversalBaseModel): description="A human-readable label for the team in the UI. If omitted, the team name is shown.", ), ] = None + """ + A human-readable label for the team in the UI. If omitted, the team name is shown. + """ + description: typing.Optional[str] = pydantic.Field(default=None) """ A short description of the team and its purpose. diff --git a/src/truefoundry_sdk/types/team_subject_row.py b/src/truefoundry_sdk/types/team_subject_row.py index 29910a80..558dc4e8 100644 --- a/src/truefoundry_sdk/types/team_subject_row.py +++ b/src/truefoundry_sdk/types/team_subject_row.py @@ -15,16 +15,27 @@ class TeamSubjectRow(UniversalBaseModel): FieldMetadata(alias="subjectId"), pydantic.Field(alias="subjectId", description="System-generated ID of the subject."), ] + """ + System-generated ID of the subject. + """ + subject_slug: typing_extensions.Annotated[ str, FieldMetadata(alias="subjectSlug"), pydantic.Field(alias="subjectSlug", description="Human-readable slug of the subject (e.g. user email)."), ] + """ + Human-readable slug of the subject (e.g. user email). + """ + subject_type: typing_extensions.Annotated[ SubjectType, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType", description="Type of the subject."), ] + """ + Type of the subject. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/terminate_job_response.py b/src/truefoundry_sdk/types/terminate_job_response.py index 32fde267..ea11082d 100644 --- a/src/truefoundry_sdk/types/terminate_job_response.py +++ b/src/truefoundry_sdk/types/terminate_job_response.py @@ -20,6 +20,9 @@ class TerminateJobResponse(UniversalBaseModel): FieldMetadata(alias="jobRunStatus"), pydantic.Field(alias="jobRunStatus", description="Job run status"), ] + """ + Job run status + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/token_pagination.py b/src/truefoundry_sdk/types/token_pagination.py index cdfc5286..9ecf8f6f 100644 --- a/src/truefoundry_sdk/types/token_pagination.py +++ b/src/truefoundry_sdk/types/token_pagination.py @@ -19,11 +19,18 @@ class TokenPagination(UniversalBaseModel): FieldMetadata(alias="nextPageToken"), pydantic.Field(alias="nextPageToken", description="Base64 encoded token for the next page"), ] = None + """ + Base64 encoded token for the next page + """ + previous_page_token: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="previousPageToken"), pydantic.Field(alias="previousPageToken", description="Base64 encoded token for the previous page"), ] = None + """ + Base64 encoded token for the previous page + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/trace_span.py b/src/truefoundry_sdk/types/trace_span.py index 020a6b53..709e7623 100644 --- a/src/truefoundry_sdk/types/trace_span.py +++ b/src/truefoundry_sdk/types/trace_span.py @@ -15,24 +15,44 @@ class TraceSpan(UniversalBaseModel): FieldMetadata(alias="spanId"), pydantic.Field(alias="spanId", description="Unique identifier for the span within the trace."), ] + """ + Unique identifier for the span within the trace. + """ + trace_id: typing_extensions.Annotated[ str, FieldMetadata(alias="traceId"), pydantic.Field(alias="traceId", description="Unique identifier for the trace that contains this span."), ] + """ + Unique identifier for the trace that contains this span. + """ + parent_span_id: typing_extensions.Annotated[ str, FieldMetadata(alias="parentSpanId"), pydantic.Field(alias="parentSpanId", description="Identifier of the parent span in the trace hierarchy."), ] + """ + Identifier of the parent span in the trace hierarchy. + """ + service_name: typing_extensions.Annotated[ str, FieldMetadata(alias="serviceName"), pydantic.Field(alias="serviceName", description="Name of the service that generated this span."), ] + """ + Name of the service that generated this span. + """ + span_name: typing_extensions.Annotated[ str, FieldMetadata(alias="spanName"), pydantic.Field(alias="spanName", description="Name of the span") ] + """ + Name of the span + """ + span_kind: typing_extensions.Annotated[ str, FieldMetadata(alias="spanKind"), @@ -40,11 +60,19 @@ class TraceSpan(UniversalBaseModel): alias="spanKind", description="Type of span (e.g., CLIENT, SERVER, INTERNAL, PRODUCER, CONSUMER)." ), ] + """ + Type of span (e.g., CLIENT, SERVER, INTERNAL, PRODUCER, CONSUMER). + """ + scope_name: typing_extensions.Annotated[ str, FieldMetadata(alias="scopeName"), pydantic.Field(alias="scopeName", description="Name of the instrumentation scope that created this span."), ] + """ + Name of the instrumentation scope that created this span. + """ + scope_version: typing_extensions.Annotated[ str, FieldMetadata(alias="scopeVersion"), @@ -52,6 +80,10 @@ class TraceSpan(UniversalBaseModel): alias="scopeVersion", description="Version of the instrumentation scope that created this span." ), ] + """ + Version of the instrumentation scope that created this span. + """ + timestamp: str = pydantic.Field() """ Timestamp in ISO 8601 format (e.g., 2025-03-12T00:00:09.872Z). @@ -62,16 +94,28 @@ class TraceSpan(UniversalBaseModel): FieldMetadata(alias="durationNs"), pydantic.Field(alias="durationNs", description="Duration of the span in nanoseconds."), ] + """ + Duration of the span in nanoseconds. + """ + status_code: typing_extensions.Annotated[ str, FieldMetadata(alias="statusCode"), pydantic.Field(alias="statusCode", description="Status code of the span (e.g., OK, ERROR, UNSET)."), ] + """ + Status code of the span (e.g., OK, ERROR, UNSET). + """ + status_message: typing_extensions.Annotated[ str, FieldMetadata(alias="statusMessage"), pydantic.Field(alias="statusMessage", description="Human-readable status message describing the span result."), ] + """ + Human-readable status message describing the span result. + """ + span_attributes: typing_extensions.Annotated[ typing.Dict[str, typing.Any], FieldMetadata(alias="spanAttributes"), @@ -79,6 +123,10 @@ class TraceSpan(UniversalBaseModel): alias="spanAttributes", description="Key-value pairs containing additional metadata about the span." ), ] + """ + Key-value pairs containing additional metadata about the span. + """ + events: typing.List[typing.Dict[str, typing.Any]] = pydantic.Field() """ Array of events that occurred during the span execution. @@ -91,6 +139,10 @@ class TraceSpan(UniversalBaseModel): alias="createdBySubject", description="Subject (user or virtualaccount) that created this span." ), ] + """ + Subject (user or virtualaccount) that created this span. + """ + feedbacks: typing.Optional[typing.List[typing.List[typing.Any]]] = pydantic.Field(default=None) """ Gateway feedbacks associated with this span (if any). diff --git a/src/truefoundry_sdk/types/trigger_job_run_response.py b/src/truefoundry_sdk/types/trigger_job_run_response.py index df313aac..a9bf907d 100644 --- a/src/truefoundry_sdk/types/trigger_job_run_response.py +++ b/src/truefoundry_sdk/types/trigger_job_run_response.py @@ -18,6 +18,10 @@ class TriggerJobRunResponse(UniversalBaseModel): job_run_name: typing_extensions.Annotated[ str, FieldMetadata(alias="jobRunName"), pydantic.Field(alias="jobRunName", description="Name of the job run") ] + """ + Name of the job run + """ + data: JobRun = pydantic.Field() """ Details of the triggered job run diff --git a/src/truefoundry_sdk/types/true_foundry_apply_response.py b/src/truefoundry_sdk/types/true_foundry_apply_response.py index 715cce78..56faabe4 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_response.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_response.py @@ -16,6 +16,10 @@ class TrueFoundryApplyResponse(UniversalBaseModel): FieldMetadata(alias="existingManifest"), pydantic.Field(alias="existingManifest", description="The existing manifest of the resource"), ] = None + """ + The existing manifest of the resource + """ + action: typing.Optional[TrueFoundryApplyResponseAction] = pydantic.Field(default=None) """ The action performed: CREATE or UPDATE diff --git a/src/truefoundry_sdk/types/user.py b/src/truefoundry_sdk/types/user.py index 42c8f7da..1779d522 100644 --- a/src/truefoundry_sdk/types/user.py +++ b/src/truefoundry_sdk/types/user.py @@ -43,6 +43,9 @@ class User(UniversalBaseModel): FieldMetadata(alias="lastAccessedAt"), pydantic.Field(alias="lastAccessedAt", description="Timestamp when the user last accessed the platform."), ] = None + """ + Timestamp when the user last accessed the platform. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/user_resource.py b/src/truefoundry_sdk/types/user_resource.py index d597ab5e..ae00aae0 100644 --- a/src/truefoundry_sdk/types/user_resource.py +++ b/src/truefoundry_sdk/types/user_resource.py @@ -12,17 +12,32 @@ class UserResource(UniversalBaseModel): resource_type: typing_extensions.Annotated[ str, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Resource Type") ] + """ + Resource Type + """ + resource_id: typing_extensions.Annotated[ str, FieldMetadata(alias="resourceId"), pydantic.Field(alias="resourceId", description="Resource ID") ] + """ + Resource ID + """ + role_id: typing_extensions.Annotated[ str, FieldMetadata(alias="roleId"), pydantic.Field(alias="roleId", description="Role ID") ] + """ + Role ID + """ + resource_name: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="resourceName"), pydantic.Field(alias="resourceName", description="Resource Name (if available)"), ] = None + """ + Resource Name (if available) + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/user_team_info.py b/src/truefoundry_sdk/types/user_team_info.py index 00dccddc..e32f10a3 100644 --- a/src/truefoundry_sdk/types/user_team_info.py +++ b/src/truefoundry_sdk/types/user_team_info.py @@ -12,6 +12,10 @@ class UserTeamInfo(UniversalBaseModel): team_name: typing_extensions.Annotated[ str, FieldMetadata(alias="teamName"), pydantic.Field(alias="teamName", description="Name of the team") ] + """ + Name of the team + """ + roles: typing.List[str] = pydantic.Field() """ Roles of the user in the team diff --git a/src/truefoundry_sdk/types/virtual_account.py b/src/truefoundry_sdk/types/virtual_account.py index 594a3517..89a54da6 100644 --- a/src/truefoundry_sdk/types/virtual_account.py +++ b/src/truefoundry_sdk/types/virtual_account.py @@ -29,6 +29,10 @@ class VirtualAccount(UniversalBaseModel): FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName", description="Tenant the virtual account belongs to."), ] + """ + Tenant the virtual account belongs to. + """ + manifest: typing.Optional[VirtualAccountManifest] = pydantic.Field(default=None) """ The manifest defining name, permissions, ownership, and configuration. @@ -39,6 +43,10 @@ class VirtualAccount(UniversalBaseModel): FieldMetadata(alias="jwtId"), pydantic.Field(alias="jwtId", description="System-generated ID of the currently active JWT."), ] = None + """ + System-generated ID of the currently active JWT. + """ + created_by_subject: typing_extensions.Annotated[ Subject, FieldMetadata(alias="createdBySubject"), @@ -47,16 +55,28 @@ class VirtualAccount(UniversalBaseModel): description="The subject (user or service account) that created this virtual account.", ), ] + """ + The subject (user or service account) that created this virtual account. + """ + created_at: typing_extensions.Annotated[ dt.datetime, FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Timestamp when the virtual account was created."), ] + """ + Timestamp when the virtual account was created. + """ + updated_at: typing_extensions.Annotated[ dt.datetime, FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt", description="Timestamp when the virtual account was last updated."), ] + """ + Timestamp when the virtual account was last updated. + """ + last_accessed_at: typing_extensions.Annotated[ typing.Optional[dt.datetime], FieldMetadata(alias="lastAccessedAt"), @@ -64,11 +84,19 @@ class VirtualAccount(UniversalBaseModel): alias="lastAccessedAt", description="Timestamp when the virtual account was last used to authenticate." ), ] = None + """ + Timestamp when the virtual account was last used to authenticate. + """ + is_expired: typing_extensions.Annotated[ typing.Optional[bool], FieldMetadata(alias="isExpired"), pydantic.Field(alias="isExpired", description="Whether the virtual account token has expired."), ] = None + """ + Whether the virtual account token has expired. + """ + jwts: typing.Optional[typing.List[Jwt]] = pydantic.Field(default=None) """ JWT tokens associated with this virtual account. @@ -79,6 +107,10 @@ class VirtualAccount(UniversalBaseModel): FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId", description="ID of the account that owns this virtual account."), ] + """ + ID of the account that owns this virtual account. + """ + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ Additional metadata for the virtual account. @@ -89,11 +121,19 @@ class VirtualAccount(UniversalBaseModel): FieldMetadata(alias="roleIds"), pydantic.Field(alias="roleIds", description="Role IDs assigned to this virtual account."), ] = None + """ + Role IDs assigned to this virtual account. + """ + roles_with_resource: typing_extensions.Annotated[ typing.Optional[typing.List[RoleWithResource]], FieldMetadata(alias="rolesWithResource"), pydantic.Field(alias="rolesWithResource", description="Roles with their associated resources."), ] = None + """ + Roles with their associated resources. + """ + created_by: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") ] = None diff --git a/src/truefoundry_sdk/types/workspace.py b/src/truefoundry_sdk/types/workspace.py index 1b8391a4..1ede1564 100644 --- a/src/truefoundry_sdk/types/workspace.py +++ b/src/truefoundry_sdk/types/workspace.py @@ -28,6 +28,10 @@ class Workspace(UniversalBaseModel): FieldMetadata(alias="clusterId"), pydantic.Field(alias="clusterId", description="System-generated ID of the cluster this workspace belongs to."), ] + """ + System-generated ID of the cluster this workspace belongs to. + """ + created_by_subject: typing_extensions.Annotated[ Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") ] @@ -44,12 +48,20 @@ class Workspace(UniversalBaseModel): alias="environmentId", description="System-generated ID of the environment this workspace belongs to." ), ] = None + """ + System-generated ID of the environment this workspace belongs to. + """ + manifest: WorkspaceManifest account_id: typing_extensions.Annotated[ str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId", description="System-generated ID of the account."), ] + """ + System-generated ID of the account. + """ + is_system_ws: typing_extensions.Annotated[ typing.Optional[bool], FieldMetadata(alias="isSystemWs"), pydantic.Field(alias="isSystemWs") ] = None diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index b5af4987..cb69ac0b 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -1,6 +1,6 @@ # This file was auto-generated by Fern from our API Definition. -from typing import Any, Dict +from typing import Any, Dict, Tuple, cast from unittest.mock import AsyncMock, MagicMock, patch import httpx @@ -692,3 +692,70 @@ def test_should_not_retry_non_retryable_status_codes(status_code: int) -> None: def test_should_retry_599_upper_boundary() -> None: """Legacy mode retries on >= 500, which includes 599.""" assert _should_retry(_make_response(599)) is True + + +# --------------------------------------------------------------------------- +# RequestOptions timeout resolution tests (timeout / deprecated timeout_in_seconds) +# --------------------------------------------------------------------------- + + +def _sync_client_with_base_timeout(base_timeout: Any) -> Tuple[HttpClient, _DummySyncClient]: + dummy_client = _DummySyncClient() + http_client = HttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: base_timeout, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + ) + return http_client, dummy_client + + +def test_sync_request_options_timeout_used() -> None: + """The new `timeout` request option is passed through to httpx (in seconds).""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout": 30}) + assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_sync_request_options_timeout_in_seconds_still_works() -> None: + """The deprecated `timeout_in_seconds` request option remains backwards compatible.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 45 + + +def test_sync_request_options_timeout_takes_precedence() -> None: + """When both are set, `timeout` wins over `timeout_in_seconds` (same seconds unit).""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options={"timeout": 30, "timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_sync_request_options_timeout_falls_back_to_base() -> None: + """When neither key is set, the client-level base timeout is used.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + http_client.request(path="/test", method="GET", request_options=None) + assert dummy_client.last_request_kwargs["timeout"] == 60 + + +def test_sync_request_options_timeout_none_falls_back_to_deprecated() -> None: + """An explicit `timeout=None` (dynamic caller) falls back to the deprecated `timeout_in_seconds`.""" + http_client, dummy_client = _sync_client_with_base_timeout(60) + request_options = cast(RequestOptions, {"timeout": None, "timeout_in_seconds": 45}) + http_client.request(path="/test", method="GET", request_options=request_options) + assert dummy_client.last_request_kwargs["timeout"] == 45 + + +@pytest.mark.asyncio +async def test_async_request_options_timeout_takes_precedence() -> None: + """Async: `timeout` wins over the deprecated `timeout_in_seconds`.""" + dummy_client = _DummyAsyncClient() + http_client = AsyncHttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: 60, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + async_base_headers=None, + ) + await http_client.request(path="/test", method="GET", request_options={"timeout": 30, "timeout_in_seconds": 45}) + assert dummy_client.last_request_kwargs["timeout"] == 30 From 9e3ad50610632c6f9fa3bf2bee9c5373fb260cd1 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:13:39 +0000 Subject: [PATCH 3/9] SDK regeneration --- .fern/metadata.json | 2 +- reference.md | 900 +++++++++++++++--- src/truefoundry_sdk/__init__.py | 242 ++++- src/truefoundry_sdk/agents/client.py | 77 ++ src/truefoundry_sdk/agents/raw_client.py | 154 +++ src/truefoundry_sdk/base_client.py | 19 + .../gateway_budgets/__init__.py | 37 + src/truefoundry_sdk/gateway_budgets/client.py | 670 +++++++++++++ .../gateway_budgets/raw_client.py | 835 ++++++++++++++++ .../gateway_budgets/types/__init__.py | 38 + .../create_or_update_budget_dto_manifest.py | 8 + .../list_gateway_budgets_request_type.py | 34 + ..._gateway_config_ai_gateway_request_type.py | 4 + src/truefoundry_sdk/secret_groups/client.py | 4 +- .../secret_groups/raw_client.py | 4 +- src/truefoundry_sdk/types/__init__.py | 233 ++++- src/truefoundry_sdk/types/agent.py | 14 + src/truefoundry_sdk/types/agent_channel.py | 36 + ...logging_when.py => agent_channel_agent.py} | 8 +- .../types/agent_channel_config.py | 5 + .../types/agent_channel_manifest.py | 35 + .../types/agent_channel_slack_auth.py | 5 + .../agent_channel_slack_bot_token_auth.py | 31 + .../types/agent_channel_slack_config.py | 39 + src/truefoundry_sdk/types/agent_identity.py | 38 + .../types/agent_identity_manifest.py | 4 +- .../types/ai21provider_account.py | 8 +- .../types/alert_config_entity.py | 16 + .../types/anthropic_provider_account.py | 13 +- .../aws_bedrock_mantle_provider_account.py | 13 +- .../types/aws_bedrock_provider_account.py | 13 +- .../aws_claude_platform_provider_account.py | 13 +- .../types/aws_sagemaker_provider_account.py | 8 +- .../types/azure_foundry_provider_account.py | 10 +- .../types/azure_open_ai_provider_account.py | 10 +- .../types/baseten_provider_account.py | 8 +- .../types/budget_entity_usage_dto.py | 27 + .../types/budget_usage_entry_dto.py | 49 + .../types/budget_usage_entry_dto_mode.py | 42 + .../types/budget_usage_entry_dto_type.py | 38 + .../types/budget_usage_response_dto.py | 22 + src/truefoundry_sdk/types/budget_v2alert.py | 5 - src/truefoundry_sdk/types/budget_v2limits.py | 5 + .../types/budget_v2override_limits.py | 5 + .../types/budget_v2when_team_scoped.py | 1 + .../types/budget_v2when_tenant_scoped.py | 1 + .../types/cartesia_provider_account.py | 10 +- .../types/cerebras_provider_account.py | 10 +- .../types/cloudera_provider_account.py | 10 +- .../types/cohere_provider_account.py | 10 +- .../complexity_based_load_balance_target.py | 55 ++ ...mplexity_based_load_balance_target_tier.py | 42 + .../types/complexity_based_load_balancing.py | 42 + ..._load_balancing_classification_strategy.py | 10 + .../types/complexity_sticky_routing.py | 31 + .../types/custom_endpoint_provider_account.py | 4 +- .../types/databricks_provider_account.py | 10 +- .../types/deepgram_provider_account.py | 10 +- .../types/deepinfra_provider_account.py | 10 +- src/truefoundry_sdk/types/deployment_build.py | 4 +- ...d_status.py => deployment_build_status.py} | 12 +- .../types/eleven_labs_provider_account.py | 10 +- .../types/external_identity_provider.py | 39 + src/truefoundry_sdk/types/gateway_budget.py | 77 ++ .../types/gateway_budget_manifest.py | 8 + src/truefoundry_sdk/types/gateway_config.py | 2 +- .../types/gateway_installation.py | 45 + .../types/gateway_logging_config.py | 20 +- .../types/gcp_gke_integration.py | 8 +- .../types/gcp_gke_integration_location.py | 726 ++++++++++++++ src/truefoundry_sdk/types/gcp_region.py | 124 ++- .../get_agent_identity_token_response.py | 21 + .../types/google_gemini_provider_account.py | 10 +- .../types/google_vertex_provider_account.py | 10 +- .../types/groq_provider_account.py | 10 +- .../types/guardrail_config_group.py | 2 +- .../types/guardrail_config_integrations.py | 2 + src/truefoundry_sdk/types/guardrails_rule.py | 2 +- .../types/hashicorp_app_role_auth.py | 5 + .../types/header_routing_config.py | 5 +- .../heuristic_classification_strategy.py | 25 + .../types/heuristic_fallback_strategy.py | 25 + src/truefoundry_sdk/types/i_change.py | 4 +- ...i_change_operation.py => i_change_type.py} | 12 +- .../identity_provider_backed_identity.py | 4 +- .../types/identity_provider_mapping.py | 6 +- src/truefoundry_sdk/types/in_not_in.py | 38 + src/truefoundry_sdk/types/job_run_status.py | 4 + .../types/llm_classification_strategy.py | 41 + ...assification_strategy_fallback_strategy.py | 8 + src/truefoundry_sdk/types/logging_when.py | 28 + src/truefoundry_sdk/types/mcp_server.py | 64 ++ .../types/mcp_server_auth_status_info.py | 33 + .../mcp_server_auth_status_info_method.py | 38 + .../mcp_server_auth_status_info_status.py | 38 + .../types/mcp_server_o_auth2.py | 17 +- .../types/mcp_server_o_auth2grant_type.py | 8 + ...er_o_auth2provider_okta_id_jag_settings.py | 21 + ...cp_server_o_auth2provider_okta_settings.py | 21 + .../types/mistral_ai_provider_account.py | 10 +- ..._rule.py => noma_security_api_key_auth.py} | 14 +- .../types/noma_security_guardrail_config.py | 56 ++ .../noma_security_guardrail_config_config.py | 36 + .../types/nomic_provider_account.py | 10 +- .../types/ollama_provider_account.py | 10 +- .../types/open_router_provider_account.py | 10 +- .../types/openai_provider_account.py | 10 +- .../types/palm_provider_account.py | 10 +- src/truefoundry_sdk/types/period_usage_dto.py | 41 + .../types/permission_set_v2.py | 25 + .../types/permission_set_v2resource_type.py | 194 ++++ .../types/perplexity_ai_provider_account.py | 10 +- src/truefoundry_sdk/types/policy.py | 38 + src/truefoundry_sdk/types/policy_version.py | 27 + src/truefoundry_sdk/types/provider_account.py | 59 ++ .../types/provider_account_provider.py | 254 +++++ .../types/provider_integration.py | 63 ++ .../types/provider_integration_type.py | 70 ++ src/truefoundry_sdk/types/redaction.py | 32 + src/truefoundry_sdk/types/role.py | 108 +++ src/truefoundry_sdk/types/role_binding.py | 40 + .../types/role_binding_subject.py | 4 +- .../types/role_binding_subject_type.py | 6 +- ...resource_type.py => role_resource_type.py} | 98 +- .../types/role_with_resource_resource_type.py | 12 + .../types/samba_nova_provider_account.py | 10 +- .../self_hosted_model_provider_account.py | 6 +- src/truefoundry_sdk/types/settings.py | 28 + .../types/smallest_ai_provider_account.py | 10 +- .../snowflake_cortex_provider_account.py | 10 +- src/truefoundry_sdk/types/spark_job.py | 6 + .../types/spark_job_trigger.py | 8 + .../types/static_fallback_strategy.py | 31 + .../static_fallback_strategy_default_tier.py | 42 + src/truefoundry_sdk/types/subject.py | 6 +- .../types/subject_subject_type.py | 54 ++ src/truefoundry_sdk/types/subject_type.py | 4 - .../types/team_budget_config.py | 4 +- .../types/team_budget_config_mode.py | 6 +- .../types/tenant_budget_config.py | 4 +- .../types/tenant_budget_config_mode.py | 6 +- .../types/together_ai_provider_account.py | 10 +- src/truefoundry_sdk/types/tracing_project.py | 44 + .../true_foundry_agent_git_source_skill.py | 45 + .../types/true_foundry_agent_mcp_server.py | 49 +- .../true_foundry_agent_mcp_server_inline.py | 60 ++ .../true_foundry_agent_mcp_server_registry.py | 55 ++ .../true_foundry_agent_sandbox_auth_data.py | 5 + .../true_foundry_agent_sandbox_auth_inject.py | 5 + ...foundry_agent_sandbox_auth_inject_match.py | 21 + ...e_foundry_agent_sandbox_basic_auth_data.py | 35 + .../true_foundry_agent_sandbox_config.py | 2 + ...e_foundry_agent_sandbox_git_auth_inject.py | 30 + ...ue_foundry_agent_sandbox_network_policy.py | 22 + .../types/true_foundry_agent_skill.py | 24 +- .../true_foundry_agent_true_foundry_skill.py | 35 + .../types/true_foundry_agent_user_message.py | 4 +- .../true_foundry_apply_request_manifest.py | 2 + .../types/true_foundry_apply_response.py | 10 +- .../types/true_foundry_apply_response_data.py | 63 ++ ...oundry_apply_response_existing_manifest.py | 2 + .../true_foundry_delete_request_manifest.py | 2 + src/truefoundry_sdk/types/vertex_region.py | 124 ++- .../types/virtual_model_model_type.py | 4 + .../types/wafer_provider_account.py | 10 +- .../types/xai_provider_account.py | 8 +- src/truefoundry_sdk/users/__init__.py | 30 + src/truefoundry_sdk/users/client.py | 26 +- src/truefoundry_sdk/users/raw_client.py | 20 +- src/truefoundry_sdk/users/types/__init__.py | 36 + ...update_user_roles_request_resource_type.py | 198 ++++ 171 files changed, 7453 insertions(+), 624 deletions(-) create mode 100644 src/truefoundry_sdk/gateway_budgets/__init__.py create mode 100644 src/truefoundry_sdk/gateway_budgets/client.py create mode 100644 src/truefoundry_sdk/gateway_budgets/raw_client.py create mode 100644 src/truefoundry_sdk/gateway_budgets/types/__init__.py create mode 100644 src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py create mode 100644 src/truefoundry_sdk/gateway_budgets/types/list_gateway_budgets_request_type.py create mode 100644 src/truefoundry_sdk/types/agent_channel.py rename src/truefoundry_sdk/types/{gateway_logging_when.py => agent_channel_agent.py} (70%) create mode 100644 src/truefoundry_sdk/types/agent_channel_config.py create mode 100644 src/truefoundry_sdk/types/agent_channel_manifest.py create mode 100644 src/truefoundry_sdk/types/agent_channel_slack_auth.py create mode 100644 src/truefoundry_sdk/types/agent_channel_slack_bot_token_auth.py create mode 100644 src/truefoundry_sdk/types/agent_channel_slack_config.py create mode 100644 src/truefoundry_sdk/types/agent_identity.py create mode 100644 src/truefoundry_sdk/types/alert_config_entity.py create mode 100644 src/truefoundry_sdk/types/budget_entity_usage_dto.py create mode 100644 src/truefoundry_sdk/types/budget_usage_entry_dto.py create mode 100644 src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py create mode 100644 src/truefoundry_sdk/types/budget_usage_entry_dto_type.py create mode 100644 src/truefoundry_sdk/types/budget_usage_response_dto.py create mode 100644 src/truefoundry_sdk/types/complexity_based_load_balance_target.py create mode 100644 src/truefoundry_sdk/types/complexity_based_load_balance_target_tier.py create mode 100644 src/truefoundry_sdk/types/complexity_based_load_balancing.py create mode 100644 src/truefoundry_sdk/types/complexity_based_load_balancing_classification_strategy.py create mode 100644 src/truefoundry_sdk/types/complexity_sticky_routing.py rename src/truefoundry_sdk/types/{build_status.py => deployment_build_status.py} (73%) create mode 100644 src/truefoundry_sdk/types/external_identity_provider.py create mode 100644 src/truefoundry_sdk/types/gateway_budget.py create mode 100644 src/truefoundry_sdk/types/gateway_budget_manifest.py create mode 100644 src/truefoundry_sdk/types/gateway_installation.py create mode 100644 src/truefoundry_sdk/types/gcp_gke_integration_location.py create mode 100644 src/truefoundry_sdk/types/get_agent_identity_token_response.py create mode 100644 src/truefoundry_sdk/types/heuristic_classification_strategy.py create mode 100644 src/truefoundry_sdk/types/heuristic_fallback_strategy.py rename src/truefoundry_sdk/types/{i_change_operation.py => i_change_type.py} (75%) create mode 100644 src/truefoundry_sdk/types/in_not_in.py create mode 100644 src/truefoundry_sdk/types/llm_classification_strategy.py create mode 100644 src/truefoundry_sdk/types/llm_classification_strategy_fallback_strategy.py create mode 100644 src/truefoundry_sdk/types/logging_when.py create mode 100644 src/truefoundry_sdk/types/mcp_server.py create mode 100644 src/truefoundry_sdk/types/mcp_server_auth_status_info.py create mode 100644 src/truefoundry_sdk/types/mcp_server_auth_status_info_method.py create mode 100644 src/truefoundry_sdk/types/mcp_server_auth_status_info_status.py create mode 100644 src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_id_jag_settings.py create mode 100644 src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_settings.py rename src/truefoundry_sdk/types/{gateway_logging_rule.py => noma_security_api_key_auth.py} (60%) create mode 100644 src/truefoundry_sdk/types/noma_security_guardrail_config.py create mode 100644 src/truefoundry_sdk/types/noma_security_guardrail_config_config.py create mode 100644 src/truefoundry_sdk/types/period_usage_dto.py create mode 100644 src/truefoundry_sdk/types/permission_set_v2.py create mode 100644 src/truefoundry_sdk/types/permission_set_v2resource_type.py create mode 100644 src/truefoundry_sdk/types/policy.py create mode 100644 src/truefoundry_sdk/types/policy_version.py create mode 100644 src/truefoundry_sdk/types/provider_account.py create mode 100644 src/truefoundry_sdk/types/provider_account_provider.py create mode 100644 src/truefoundry_sdk/types/provider_integration.py create mode 100644 src/truefoundry_sdk/types/provider_integration_type.py create mode 100644 src/truefoundry_sdk/types/redaction.py create mode 100644 src/truefoundry_sdk/types/role.py create mode 100644 src/truefoundry_sdk/types/role_binding.py rename src/truefoundry_sdk/types/{resource_type.py => role_resource_type.py} (65%) create mode 100644 src/truefoundry_sdk/types/settings.py create mode 100644 src/truefoundry_sdk/types/spark_job_trigger.py create mode 100644 src/truefoundry_sdk/types/static_fallback_strategy.py create mode 100644 src/truefoundry_sdk/types/static_fallback_strategy_default_tier.py create mode 100644 src/truefoundry_sdk/types/subject_subject_type.py create mode 100644 src/truefoundry_sdk/types/tracing_project.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_git_source_skill.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_mcp_server_inline.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_mcp_server_registry.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_data.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject_match.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_basic_auth_data.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_git_auth_inject.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_sandbox_network_policy.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_true_foundry_skill.py create mode 100644 src/truefoundry_sdk/types/true_foundry_apply_response_data.py create mode 100644 src/truefoundry_sdk/users/types/__init__.py create mode 100644 src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py diff --git a/.fern/metadata.json b/.fern/metadata.json index 90bc00dd..be583736 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "f9c6a5aeafc0344a9a6141b6aae4fb58e2e186b6", + "originGitCommit": "60bec551303af343ab2a767a3ce1e8aa67328b1a", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/reference.md b/reference.md index de656f91..add83836 100644 --- a/reference.md +++ b/reference.md @@ -527,7 +527,7 @@ client.users.update_roles(
-**resource_type:** `typing.Optional[ResourceType]` — Resource type scope for the role assignment. +**resource_type:** `typing.Optional[UpdateUserRolesRequestResourceType]` — Resource type scope for the role assignment.
@@ -687,6 +687,14 @@ client.users.delete(
+**force_delete:** `typing.Optional[bool]` — When true, force-deletes the user by automatically removing all resource collaborations and team memberships. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -912,7 +920,596 @@ client.users.activate(
-**email:** `str` — Email of the user to activate. +**email:** `str` — Email of the user to activate. + +
+
+ +
+
+ +**tenant_name:** `typing.Optional[str]` — Tenant name override. Defaults to the caller's tenant when omitted. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+ + + +
client.users.change_password(...) -> ChangePasswordResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Change the password for the authenticated user. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.users.change_password( + login_id="user@example.com", + new_password="newPassword", + old_password="oldPassword", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**login_id:** `str` — Email address of the user changing their password. + +
+
+ +
+
+ +**new_password:** `str` — New password (minimum 8 characters). + +
+
+ +
+
+ +**old_password:** `str` — Current password of the user for verification. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.users.get_resources(...) -> GetUserResourcesResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all resources where the user is a collaborator. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.users.get_resources( + id="jqfwg345gi25n5ju2yz5iz6m", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated user ID. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.users.get_permissions(...) -> GetUserPermissionsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all role bindings for a user, including team-inherited bindings. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.users.get_permissions( + id="jqfwg345gi25n5ju2yz5iz6m", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated user ID. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.users.get_teams(...) -> GetUserTeamsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all teams a user belongs to, including their role in each team. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.users.get_teams( + id="jqfwg345gi25n5ju2yz5iz6m", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated user ID. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Teams +
client.teams.list(...) -> ListTeamsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List teams accessible to the current user. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.teams.list( + limit=10, + offset=0, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Number of items per page + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of items to skip + +
+
+ +
+
+ +**role:** `typing.Optional[typing.Literal]` — Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). + +
+
+ +
+
+ +**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.teams.create_or_update(...) -> GetTeamResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create a new team or update an existing one using the provided TeamManifest. Matching is by name — if the name matches an existing team it is updated, otherwise a new one is created. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry, TeamManifest + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.teams.create_or_update( + manifest=TeamManifest( + type="team", + name="name", + members=[ + "members" + ], + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**manifest:** `TeamManifest` — The team manifest describing the team to create or update. + +
+
+ +
+
+ +**dry_run:** `typing.Optional[bool]` — When true, validate the request without persisting any changes. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.teams.list_members(...) -> ListTeamMembersResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List users who are members of a team. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.teams.list_members( + id="jqfwg345gi25n5ju2yz5iz6m", + limit=10, + offset=0, + filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated team ID. + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Number of items per page + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -920,7 +1517,7 @@ client.users.activate(
-**tenant_name:** `typing.Optional[str]` — Tenant name override. Defaults to the caller's tenant when omitted. +**filter:** `typing.Optional[str]` — JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`).
@@ -940,7 +1537,7 @@ client.users.activate(
-
client.users.change_password(...) -> ChangePasswordResponse +
client.teams.list_managers(...) -> ListTeamManagersResponse
@@ -952,7 +1549,7 @@ client.users.activate(
-Change the password for the authenticated user. +List users who hold the team-manager role on a team.
@@ -974,10 +1571,11 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.users.change_password( - login_id="user@example.com", - new_password="newPassword", - old_password="oldPassword", +client.teams.list_managers( + id="jqfwg345gi25n5ju2yz5iz6m", + limit=10, + offset=0, + filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", ) ``` @@ -994,7 +1592,7 @@ client.users.change_password(
-**login_id:** `str` — Email address of the user changing their password. +**id:** `str` — System-generated team ID.
@@ -1002,7 +1600,7 @@ client.users.change_password(
-**new_password:** `str` — New password (minimum 8 characters). +**limit:** `typing.Optional[int]` — Number of items per page
@@ -1010,7 +1608,15 @@ client.users.change_password(
-**old_password:** `str` — Current password of the user for verification. +**offset:** `typing.Optional[int]` — Number of items to skip + +
+
+ +
+
+ +**filter:** `typing.Optional[str]` — JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`).
@@ -1030,7 +1636,7 @@ client.users.change_password(
-
client.users.get_resources(...) -> GetUserResourcesResponse +
client.teams.get(...) -> GetTeamResponse
@@ -1042,7 +1648,7 @@ client.users.change_password(
-Get all resources where the user is a collaborator. +Get a single team by its ID.
@@ -1064,7 +1670,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.users.get_resources( +client.teams.get( id="jqfwg345gi25n5ju2yz5iz6m", ) @@ -1082,7 +1688,7 @@ client.users.get_resources(
-**id:** `str` — System-generated user ID. +**id:** `str` — System-generated team ID.
@@ -1102,7 +1708,7 @@ client.users.get_resources(
-
client.users.get_permissions(...) -> GetUserPermissionsResponse +
client.teams.delete(...) -> DeleteTeamResponse
@@ -1114,7 +1720,7 @@ client.users.get_resources(
-Get all role bindings for a user, including team-inherited bindings. +Permanently delete the team with the given ID. This action is irreversible.
@@ -1136,7 +1742,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.users.get_permissions( +client.teams.delete( id="jqfwg345gi25n5ju2yz5iz6m", ) @@ -1154,7 +1760,7 @@ client.users.get_permissions(
-**id:** `str` — System-generated user ID. +**id:** `str` — System-generated team ID.
@@ -1174,7 +1780,7 @@ client.users.get_permissions(
-
client.users.get_teams(...) -> GetUserTeamsResponse +
client.teams.get_permissions(...) -> GetTeamPermissionsResponse
@@ -1186,7 +1792,7 @@ client.users.get_permissions(
-Get all teams a user belongs to, including their role in each team. +Get all role bindings associated with a team.
@@ -1208,7 +1814,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.users.get_teams( +client.teams.get_permissions( id="jqfwg345gi25n5ju2yz5iz6m", ) @@ -1226,7 +1832,7 @@ client.users.get_teams(
-**id:** `str` — System-generated user ID. +**id:** `str` — System-generated team ID.
@@ -1246,8 +1852,8 @@ client.users.get_teams(
-## Teams -
client.teams.list(...) -> ListTeamsResponse +## GatewayBudgets +
client.gateway_budgets.list(...) -> typing.List[GatewayBudget]
@@ -1259,7 +1865,7 @@ client.users.get_teams(
-List teams accessible to the current user. +Returns all budgets for the tenant. Supports filtering by type and team_name.
@@ -1281,10 +1887,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.list( - limit=10, - offset=0, -) +client.gateway_budgets.list() ``` @@ -1300,23 +1903,7 @@ client.teams.list(
-**limit:** `typing.Optional[int]` — Number of items per page - -
-
- -
-
- -**offset:** `typing.Optional[int]` — Number of items to skip - -
-
- -
-
- -**role:** `typing.Optional[typing.Literal]` — Filter to teams where the caller holds this role. `manager` returns teams the caller can manage (team managers and admins). +**type:** `typing.Optional[ListGatewayBudgetsRequestType]` — Filter by budget type. One of tenant-budget-config | team-budget-config.
@@ -1324,7 +1911,7 @@ client.teams.list(
-**attributes:** `typing.Optional[typing.List[str]]` — Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. +**team_name:** `typing.Optional[str]` — Filter by team_name (only meaningful for team-budget-config).
@@ -1344,7 +1931,7 @@ client.teams.list(
-
client.teams.create_or_update(...) -> GetTeamResponse +
client.gateway_budgets.create_or_update(...) -> GatewayBudget
@@ -1356,7 +1943,7 @@ client.teams.list(
-Create a new team or update an existing one using the provided TeamManifest. Matching is by name — if the name matches an existing team it is updated, otherwise a new one is created. +Creates or updates a budget manifest for the tenant. Budgets are upserted by `manifest.name` (unique per tenant).
@@ -1371,20 +1958,22 @@ Create a new team or update an existing one using the provided TeamManifest. Mat
```python -from truefoundry_sdk import TrueFoundry, TeamManifest +from truefoundry_sdk import TrueFoundry, TenantBudgetConfig, BudgetV2Limits, BudgetV2AppliesToAggregate, TenantBudgetConfigMode client = TrueFoundry( api_key="", base_url="https://yourhost.com/path/to/api", ) -client.teams.create_or_update( - manifest=TeamManifest( - type="team", +client.gateway_budgets.create_or_update( + manifest=TenantBudgetConfig( + type="tenant-budget-config", name="name", - members=[ - "members" - ], + limits=BudgetV2Limits(), + applies_to=BudgetV2AppliesToAggregate( + type="aggregate", + ), + mode=TenantBudgetConfigMode.ENFORCE, ), ) @@ -1402,7 +1991,7 @@ client.teams.create_or_update(
-**manifest:** `TeamManifest` — The team manifest describing the team to create or update. +**manifest:** `CreateOrUpdateBudgetDtoManifest` — The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema.
@@ -1410,7 +1999,7 @@ client.teams.create_or_update(
-**dry_run:** `typing.Optional[bool]` — When true, validate the request without persisting any changes. +**dry_run:** `typing.Optional[bool]` — When `true`, validates the manifest without persisting changes.
@@ -1430,7 +2019,7 @@ client.teams.create_or_update(
-
client.teams.list_members(...) -> ListTeamMembersResponse +
client.gateway_budgets.get_my_usage() -> BudgetUsageResponseDto
@@ -1442,7 +2031,7 @@ client.teams.create_or_update(
-List users who are members of a team. +Returns every per-user budget that currently applies to the caller, with current usage per period.
@@ -1464,12 +2053,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.list_members( - id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, - offset=0, - filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", -) +client.gateway_budgets.get_my_usage() ``` @@ -1485,38 +2069,6 @@ client.teams.list_members(
-**id:** `str` — System-generated team ID. - -
-
- -
-
- -**limit:** `typing.Optional[int]` — Number of items per page - -
-
- -
-
- -**offset:** `typing.Optional[int]` — Number of items to skip - -
-
- -
-
- -**filter:** `typing.Optional[str]` — JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1529,7 +2081,7 @@ client.teams.list_members(
-
client.teams.list_managers(...) -> ListTeamManagersResponse +
client.gateway_budgets.simulate(...) -> BudgetUsageResponseDto
@@ -1541,7 +2093,7 @@ client.teams.list_members(
-List users who hold the team-manager role on a team. +Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage.
@@ -1563,12 +2115,7 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.list_managers( - id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, - offset=0, - filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", -) +client.gateway_budgets.simulate() ``` @@ -1584,7 +2131,7 @@ client.teams.list_managers(
-**id:** `str` — System-generated team ID. +**user:** `typing.Optional[str]` — User email to simulate as.
@@ -1592,7 +2139,7 @@ client.teams.list_managers(
-**limit:** `typing.Optional[int]` — Number of items per page +**virtual_account:** `typing.Optional[str]` — Virtual account slug to simulate as. Use this instead of `user` for virtual-account budgets.
@@ -1600,7 +2147,7 @@ client.teams.list_managers(
-**offset:** `typing.Optional[int]` — Number of items to skip +**team:** `typing.Optional[str]` — Single team to simulate membership of. Use `teams` to pass multiple teams.
@@ -1608,7 +2155,23 @@ client.teams.list_managers(
-**filter:** `typing.Optional[str]` — JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). +**teams:** `typing.Optional[typing.List[str]]` — All teams the simulated user belongs to. Merged with `team` when both are provided. + +
+
+ +
+
+ +**model:** `typing.Optional[str]` — Model to simulate. + +
+
+ +
+
+ +**metadata:** `typing.Optional[typing.Dict[str, str]]` — Request metadata key/value pairs to simulate.
@@ -1628,7 +2191,7 @@ client.teams.list_managers(
-
client.teams.get(...) -> GetTeamResponse +
client.gateway_budgets.get(...) -> GatewayBudget
@@ -1640,7 +2203,7 @@ client.teams.list_managers(
-Get a single team by its ID. +Returns a single budget by id.
@@ -1662,8 +2225,8 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.get( - id="jqfwg345gi25n5ju2yz5iz6m", +client.gateway_budgets.get( + id="id", ) ``` @@ -1680,7 +2243,7 @@ client.teams.get(
-**id:** `str` — System-generated team ID. +**id:** `str` — The budget id to retrieve or delete.
@@ -1700,7 +2263,7 @@ client.teams.get(
-
client.teams.delete(...) -> DeleteTeamResponse +
client.gateway_budgets.delete(...)
@@ -1712,7 +2275,7 @@ client.teams.get(
-Permanently delete the team with the given ID. This action is irreversible. +Permanently deletes a budget manifest.
@@ -1734,8 +2297,8 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.delete( - id="jqfwg345gi25n5ju2yz5iz6m", +client.gateway_budgets.delete( + id="id", ) ``` @@ -1752,7 +2315,7 @@ client.teams.delete(
-**id:** `str` — System-generated team ID. +**id:** `str` — The budget id to retrieve or delete.
@@ -1772,7 +2335,7 @@ client.teams.delete(
-
client.teams.get_permissions(...) -> GetTeamPermissionsResponse +
client.gateway_budgets.get_leaderboard(...) -> BudgetUsageResponseDto
@@ -1784,7 +2347,7 @@ client.teams.delete(
-Get all role bindings associated with a team. +Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null).
@@ -1806,8 +2369,9 @@ client = TrueFoundry( base_url="https://yourhost.com/path/to/api", ) -client.teams.get_permissions( - id="jqfwg345gi25n5ju2yz5iz6m", +client.gateway_budgets.get_leaderboard( + id="id", + limit=50, ) ``` @@ -1824,7 +2388,15 @@ client.teams.get_permissions(
-**id:** `str` — System-generated team ID. +**id:** `str` — The budget id to retrieve or delete. + +
+
+ +
+
+ +**limit:** `typing.Optional[float]` — Maximum number of entries to return. Defaults to 500 and is capped at 500.
@@ -5958,7 +6530,7 @@ client.secret_groups.list(
-**search:** `typing.Optional[str]` — Search query - filters by secret group names that contain the search string +**search:** `typing.Optional[str]` — Search query - filters by secret group names or secret names that contain the search string
@@ -6969,6 +7541,78 @@ client.agents.delete(
+ + +
+ +
client.agents.get_token(...) -> GetAgentIdentityTokenResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.agents.get_token( + id="jqfwg345gi25n5ju2yz5iz6m", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated agent ID. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 9c86a112..0b4b0d2f 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -17,7 +17,15 @@ AddonComponentName, AddonComponentStatus, Agent, + AgentChannel, + AgentChannelAgent, + AgentChannelConfig, + AgentChannelManifest, + AgentChannelSlackAuth, + AgentChannelSlackBotTokenAuth, + AgentChannelSlackConfig, AgentFramework, + AgentIdentity, AgentIdentityAutoRotate, AgentIdentityConfig, AgentIdentityManifest, @@ -45,6 +53,7 @@ AktoTokenAuth, Alert, AlertConfig, + AlertConfigEntity, AlertConfigResource, AlertConfigResourceType, AlertSeverity, @@ -187,8 +196,13 @@ BlueGreen, BudgetAlert, BudgetConfig, + BudgetEntityUsageDto, BudgetLimitUnit, BudgetRule, + BudgetUsageEntryDto, + BudgetUsageEntryDtoMode, + BudgetUsageEntryDtoType, + BudgetUsageResponseDto, BudgetV2Alert, BudgetV2AppliesTo, BudgetV2AppliesToAggregate, @@ -213,7 +227,6 @@ BuildBuildSpec, BuildInfo, BuildSecret, - BuildStatus, Canary, CanaryStep, CartesiaApiKeyAuth, @@ -255,6 +268,11 @@ CohereProviderAccount, Collaborator, CommonToolsSettings, + ComplexityBasedLoadBalanceTarget, + ComplexityBasedLoadBalanceTargetTier, + ComplexityBasedLoadBalancing, + ComplexityBasedLoadBalancingClassificationStrategy, + ComplexityStickyRouting, Config, ContainerTaskConfig, ContainerTaskConfigImage, @@ -328,6 +346,7 @@ DeleteWorkspaceResponse, Deployment, DeploymentBuild, + DeploymentBuildStatus, DeploymentManifest, DeploymentStatus, DeploymentStatusValue, @@ -363,6 +382,7 @@ EventInvolvedObject, ExactMatchCacheConfig, ExternalBlobStorageSource, + ExternalIdentityProvider, FastAiFramework, FiddlerGuardType, FiddlerGuardrailConfig, @@ -383,6 +403,8 @@ ForwardAction, Function, FunctionSchema, + GatewayBudget, + GatewayBudgetManifest, GatewayConfig, GatewayConfiguration, GatewayDataAccessConfig, @@ -399,9 +421,8 @@ GatewayDataRoutingConfigDestinationStorage, GatewayDataRoutingConfigDestinationStorageStorage, GatewayDataType, + GatewayInstallation, GatewayLoggingConfig, - GatewayLoggingRule, - GatewayLoggingWhen, GatewayMetadataConfig, GatewayMetadataRule, GatewayMetadataWhen, @@ -415,6 +436,7 @@ GcpGcr, GcpGcs, GcpGkeIntegration, + GcpGkeIntegrationLocation, GcpGsm, GcpIntegrations, GcpKeyFileAuth, @@ -424,6 +446,7 @@ GcpTpu, GeminiModel, GenericSecretStoreIntegration, + GetAgentIdentityTokenResponse, GetAgentResponse, GetAgentSkillResponse, GetAgentSkillVersionResponse, @@ -517,13 +540,15 @@ Helm, HelmRepo, HelmSource, + HeuristicClassificationStrategy, + HeuristicFallbackStrategy, HostedA2AAgent, HttpError, HttpErrorCode, HttpProbe, HuggingfaceArtifactSource, IChange, - IChangeOperation, + IChangeType, IdentityProviderBackedIdentity, IdentityProviderMapping, Image, @@ -531,6 +556,7 @@ ImageContentPart, ImageContentPartImageUrl, ImageContentPartImageUrlUrl, + InNotIn, InNotInOperator, InNotInOperatorCondition, InferMethodName, @@ -614,6 +640,8 @@ ListUsersResponse, ListVirtualAccountResponse, ListWorkspacesResponse, + LlmClassificationStrategy, + LlmClassificationStrategyFallbackStrategy, LoadBalanceTarget, LoadBalancingConfig, LoadBalancingRule, @@ -627,12 +655,17 @@ LoggingModeAlways, LoggingModeHeaderControlled, LoggingModeNever, + LoggingWhen, LogsResponse, LogsSearchFilterType, LogsSearchOperatorType, LogsSortingDirection, Manual, + McpServer, McpServerAuth, + McpServerAuthStatusInfo, + McpServerAuthStatusInfoMethod, + McpServerAuthStatusInfoStatus, McpServerEnvAuth, McpServerEnvAuthAuthLevel, McpServerHeaderAuth, @@ -647,6 +680,8 @@ McpServerOAuth2JwtSource, McpServerOAuth2Provider, McpServerOAuth2ProviderAuth0Settings, + McpServerOAuth2ProviderOktaIdJagSettings, + McpServerOAuth2ProviderOktaSettings, McpServerPassthrough, McpServerProviderAccount, McpServerSource, @@ -697,6 +732,9 @@ NodeSelectorCapacityType, Nodepool, NodepoolSelector, + NomaSecurityApiKeyAuth, + NomaSecurityGuardrailConfig, + NomaSecurityGuardrailConfigConfig, NomicIntegrations, NomicKeyAuth, NomicModel, @@ -792,6 +830,9 @@ PerMinuteOfAudioCostMetricValue, PerThousandEmbeddingTokensCostMetric, PerThousandTokensCostMetric, + PeriodUsageDto, + PermissionSetV2, + PermissionSetV2ResourceType, Permissions, PerplexityAiKeyAuth, PerplexityAiModel, @@ -801,6 +842,7 @@ PersonalAccessTokenManifestTokenType, Pip, Poetry, + Policy, PolicyActions, PolicyEntityTypes, PolicyFilters, @@ -809,6 +851,7 @@ PolicyManifestOperation, PolicyMutationOperation, PolicyValidationOperation, + PolicyVersion, Port, PortAppProtocol, PortAuth, @@ -824,7 +867,11 @@ Prompt, PromptSource, PromptVersion, + ProviderAccount, + ProviderAccountProvider, ProviderAccounts, + ProviderIntegration, + ProviderIntegrationType, PublicCostMetric, PySparkTaskConfig, PyTorchFramework, @@ -845,6 +892,7 @@ RateLimitUnit, RateLimitWhen, Recommendation, + Redaction, RefusalContentPart, RegexConstraint, RegexGuardrailConfig, @@ -855,7 +903,6 @@ RemoteMcpServerManifest, RemoteSource, RemoteSpecSource, - ResourceType, Resources, ResourcesDevicesItem, ResourcesNode, @@ -865,11 +912,14 @@ ResponseFormatText, RetryConfig, RevokeAllPersonalAccessTokenResponse, + Role, + RoleBinding, RoleBindingManifest, RoleBindingPermission, RoleBindingSubject, RoleBindingSubjectType, RoleManifest, + RoleResourceType, RoleWithResource, RoleWithResourceResourceType, Rolling, @@ -917,6 +967,7 @@ SessionAccount, SessionActor, SessionTeam, + Settings, SignedUrl, SklearnFramework, SklearnModelSchema, @@ -968,6 +1019,7 @@ SparkJobPythonNotebookEntrypoint, SparkJobScalaEntrypoint, SparkJobScalaNotebookEntrypoint, + SparkJobTrigger, SparkJobTriggerInput, SqlSanitizerGuardrailConfig, SqlSanitizerGuardrailConfigConfig, @@ -979,6 +1031,8 @@ SshServer, SshServerConfig, StageArtifactResponse, + StaticFallbackStrategy, + StaticFallbackStrategyDefaultTier, StaticVolumeConfig, StatsModelsFramework, StdioMcpServerManifest, @@ -992,6 +1046,7 @@ SubjectConditionGroup, SubjectConditionGroupOperator, SubjectPermission, + SubjectSubjectType, SubjectType, SyncTokenInSecretStoreInfo, SyncVirtualAccountTokenResponse, @@ -1036,6 +1091,7 @@ ToolMessageContent, ToolSchema, TraceSpan, + TracingProject, TracingProjectControlPlaneManagedStorage, TracingProjectCustomerManagedStorage, TracingProjectManifest, @@ -1052,19 +1108,30 @@ TrueFoundryAgentContextManagementConfig, TrueFoundryAgentDynamicSubAgentsConfig, TrueFoundryAgentGenerativeUiConfig, + TrueFoundryAgentGitSourceSkill, TrueFoundryAgentLargeToolResponseConfig, TrueFoundryAgentManifest, TrueFoundryAgentMcpServer, + TrueFoundryAgentMcpServerInline, + TrueFoundryAgentMcpServerRegistry, TrueFoundryAgentModel, TrueFoundryAgentModelParams, TrueFoundryAgentResponseFormat, + TrueFoundryAgentSandboxAuthData, + TrueFoundryAgentSandboxAuthInject, + TrueFoundryAgentSandboxAuthInjectMatch, + TrueFoundryAgentSandboxBasicAuthData, TrueFoundryAgentSandboxConfig, + TrueFoundryAgentSandboxGitAuthInject, + TrueFoundryAgentSandboxNetworkPolicy, TrueFoundryAgentSkill, + TrueFoundryAgentTrueFoundrySkill, TrueFoundryAgentUserMessage, TrueFoundryAgentVariable, TrueFoundryApplyRequestManifest, TrueFoundryApplyResponse, TrueFoundryApplyResponseAction, + TrueFoundryApplyResponseData, TrueFoundryApplyResponseExistingManifest, TrueFoundryArtifactSource, TrueFoundryDbssm, @@ -1174,6 +1241,7 @@ data_directories, environments, events, + gateway_budgets, internal, jobs, logs, @@ -1201,9 +1269,11 @@ ) from .artifact_versions import StageArtifactRequestManifest from .client import AsyncTrueFoundry, TrueFoundry + from .gateway_budgets import CreateOrUpdateBudgetDtoManifest, ListGatewayBudgetsRequestType from .jobs import TriggerJobRequestInput from .personal_access_tokens import CreatePersonalAccessTokenRequestTokenType from .traces import QuerySpansRequestFiltersItem + from .users import UpdateUserRolesRequestResourceType from .version import __version__ _dynamic_imports: typing.Dict[str, str] = { "A2AAgentSkill": ".types", @@ -1216,7 +1286,15 @@ "AddonComponentName": ".types", "AddonComponentStatus": ".types", "Agent": ".types", + "AgentChannel": ".types", + "AgentChannelAgent": ".types", + "AgentChannelConfig": ".types", + "AgentChannelManifest": ".types", + "AgentChannelSlackAuth": ".types", + "AgentChannelSlackBotTokenAuth": ".types", + "AgentChannelSlackConfig": ".types", "AgentFramework": ".types", + "AgentIdentity": ".types", "AgentIdentityAutoRotate": ".types", "AgentIdentityConfig": ".types", "AgentIdentityManifest": ".types", @@ -1244,6 +1322,7 @@ "AktoTokenAuth": ".types", "Alert": ".types", "AlertConfig": ".types", + "AlertConfigEntity": ".types", "AlertConfigResource": ".types", "AlertConfigResourceType": ".types", "AlertSeverity": ".types", @@ -1388,8 +1467,13 @@ "BlueGreen": ".types", "BudgetAlert": ".types", "BudgetConfig": ".types", + "BudgetEntityUsageDto": ".types", "BudgetLimitUnit": ".types", "BudgetRule": ".types", + "BudgetUsageEntryDto": ".types", + "BudgetUsageEntryDtoMode": ".types", + "BudgetUsageEntryDtoType": ".types", + "BudgetUsageResponseDto": ".types", "BudgetV2Alert": ".types", "BudgetV2AppliesTo": ".types", "BudgetV2AppliesToAggregate": ".types", @@ -1414,7 +1498,6 @@ "BuildBuildSpec": ".types", "BuildInfo": ".types", "BuildSecret": ".types", - "BuildStatus": ".types", "Canary": ".types", "CanaryStep": ".types", "CancelDeploymentApplicationsResponse": ".applications", @@ -1457,6 +1540,11 @@ "CohereProviderAccount": ".types", "Collaborator": ".types", "CommonToolsSettings": ".types", + "ComplexityBasedLoadBalanceTarget": ".types", + "ComplexityBasedLoadBalanceTargetTier": ".types", + "ComplexityBasedLoadBalancing": ".types", + "ComplexityBasedLoadBalancingClassificationStrategy": ".types", + "ComplexityStickyRouting": ".types", "Config": ".types", "ConflictError": ".errors", "ContainerTaskConfig": ".types", @@ -1466,6 +1554,7 @@ "CpuUtilizationMetric": ".types", "CreateDockerRepositoryResponse": ".types", "CreateMultiPartUploadRequest": ".types", + "CreateOrUpdateBudgetDtoManifest": ".gateway_budgets", "CreatePersonalAccessTokenRequestTokenType": ".personal_access_tokens", "CreatePersonalAccessTokenResponse": ".types", "CreateRunResponse": ".types", @@ -1534,6 +1623,7 @@ "DeleteWorkspaceResponse": ".types", "Deployment": ".types", "DeploymentBuild": ".types", + "DeploymentBuildStatus": ".types", "DeploymentManifest": ".types", "DeploymentStatus": ".types", "DeploymentStatusValue": ".types", @@ -1570,6 +1660,7 @@ "ExactMatchCacheConfig": ".types", "ExpectationFailedError": ".errors", "ExternalBlobStorageSource": ".types", + "ExternalIdentityProvider": ".types", "FailedDependencyError": ".errors", "FastAiFramework": ".types", "FiddlerGuardType": ".types", @@ -1592,6 +1683,8 @@ "ForwardAction": ".types", "Function": ".types", "FunctionSchema": ".types", + "GatewayBudget": ".types", + "GatewayBudgetManifest": ".types", "GatewayConfig": ".types", "GatewayConfiguration": ".types", "GatewayDataAccessConfig": ".types", @@ -1608,9 +1701,8 @@ "GatewayDataRoutingConfigDestinationStorage": ".types", "GatewayDataRoutingConfigDestinationStorageStorage": ".types", "GatewayDataType": ".types", + "GatewayInstallation": ".types", "GatewayLoggingConfig": ".types", - "GatewayLoggingRule": ".types", - "GatewayLoggingWhen": ".types", "GatewayMetadataConfig": ".types", "GatewayMetadataRule": ".types", "GatewayMetadataWhen": ".types", @@ -1624,6 +1716,7 @@ "GcpGcr": ".types", "GcpGcs": ".types", "GcpGkeIntegration": ".types", + "GcpGkeIntegrationLocation": ".types", "GcpGsm": ".types", "GcpIntegrations": ".types", "GcpKeyFileAuth": ".types", @@ -1633,6 +1726,7 @@ "GcpTpu": ".types", "GeminiModel": ".types", "GenericSecretStoreIntegration": ".types", + "GetAgentIdentityTokenResponse": ".types", "GetAgentResponse": ".types", "GetAgentSkillResponse": ".types", "GetAgentSkillVersionResponse": ".types", @@ -1726,13 +1820,15 @@ "Helm": ".types", "HelmRepo": ".types", "HelmSource": ".types", + "HeuristicClassificationStrategy": ".types", + "HeuristicFallbackStrategy": ".types", "HostedA2AAgent": ".types", "HttpError": ".types", "HttpErrorCode": ".types", "HttpProbe": ".types", "HuggingfaceArtifactSource": ".types", "IChange": ".types", - "IChangeOperation": ".types", + "IChangeType": ".types", "IdentityProviderBackedIdentity": ".types", "IdentityProviderMapping": ".types", "Image": ".types", @@ -1740,6 +1836,7 @@ "ImageContentPart": ".types", "ImageContentPartImageUrl": ".types", "ImageContentPartImageUrlUrl": ".types", + "InNotIn": ".types", "InNotInOperator": ".types", "InNotInOperatorCondition": ".types", "InferMethodName": ".types", @@ -1811,6 +1908,7 @@ "ListEnvironmentsResponse": ".types", "ListFilesRequest": ".types", "ListFilesResponse": ".types", + "ListGatewayBudgetsRequestType": ".gateway_budgets", "ListJobRunResponse": ".types", "ListMetricHistoryResponse": ".types", "ListMlReposResponse": ".types", @@ -1827,6 +1925,8 @@ "ListUsersResponse": ".types", "ListVirtualAccountResponse": ".types", "ListWorkspacesResponse": ".types", + "LlmClassificationStrategy": ".types", + "LlmClassificationStrategyFallbackStrategy": ".types", "LoadBalanceTarget": ".types", "LoadBalancingConfig": ".types", "LoadBalancingRule": ".types", @@ -1840,12 +1940,17 @@ "LoggingModeAlways": ".types", "LoggingModeHeaderControlled": ".types", "LoggingModeNever": ".types", + "LoggingWhen": ".types", "LogsResponse": ".types", "LogsSearchFilterType": ".types", "LogsSearchOperatorType": ".types", "LogsSortingDirection": ".types", "Manual": ".types", + "McpServer": ".types", "McpServerAuth": ".types", + "McpServerAuthStatusInfo": ".types", + "McpServerAuthStatusInfoMethod": ".types", + "McpServerAuthStatusInfoStatus": ".types", "McpServerEnvAuth": ".types", "McpServerEnvAuthAuthLevel": ".types", "McpServerHeaderAuth": ".types", @@ -1860,6 +1965,8 @@ "McpServerOAuth2JwtSource": ".types", "McpServerOAuth2Provider": ".types", "McpServerOAuth2ProviderAuth0Settings": ".types", + "McpServerOAuth2ProviderOktaIdJagSettings": ".types", + "McpServerOAuth2ProviderOktaSettings": ".types", "McpServerPassthrough": ".types", "McpServerProviderAccount": ".types", "McpServerSource": ".types", @@ -1911,6 +2018,9 @@ "NodeSelectorCapacityType": ".types", "Nodepool": ".types", "NodepoolSelector": ".types", + "NomaSecurityApiKeyAuth": ".types", + "NomaSecurityGuardrailConfig": ".types", + "NomaSecurityGuardrailConfigConfig": ".types", "NomicIntegrations": ".types", "NomicKeyAuth": ".types", "NomicModel": ".types", @@ -2008,6 +2118,9 @@ "PerMinuteOfAudioCostMetricValue": ".types", "PerThousandEmbeddingTokensCostMetric": ".types", "PerThousandTokensCostMetric": ".types", + "PeriodUsageDto": ".types", + "PermissionSetV2": ".types", + "PermissionSetV2ResourceType": ".types", "Permissions": ".types", "PerplexityAiKeyAuth": ".types", "PerplexityAiModel": ".types", @@ -2017,6 +2130,7 @@ "PersonalAccessTokenManifestTokenType": ".types", "Pip": ".types", "Poetry": ".types", + "Policy": ".types", "PolicyActions": ".types", "PolicyEntityTypes": ".types", "PolicyFilters": ".types", @@ -2025,6 +2139,7 @@ "PolicyManifestOperation": ".types", "PolicyMutationOperation": ".types", "PolicyValidationOperation": ".types", + "PolicyVersion": ".types", "Port": ".types", "PortAppProtocol": ".types", "PortAuth": ".types", @@ -2040,7 +2155,11 @@ "Prompt": ".types", "PromptSource": ".types", "PromptVersion": ".types", + "ProviderAccount": ".types", + "ProviderAccountProvider": ".types", "ProviderAccounts": ".types", + "ProviderIntegration": ".types", + "ProviderIntegrationType": ".types", "PublicCostMetric": ".types", "PySparkTaskConfig": ".types", "PyTorchFramework": ".types", @@ -2062,6 +2181,7 @@ "RateLimitUnit": ".types", "RateLimitWhen": ".types", "Recommendation": ".types", + "Redaction": ".types", "RefusalContentPart": ".types", "RegexConstraint": ".types", "RegexGuardrailConfig": ".types", @@ -2072,7 +2192,6 @@ "RemoteMcpServerManifest": ".types", "RemoteSource": ".types", "RemoteSpecSource": ".types", - "ResourceType": ".types", "Resources": ".types", "ResourcesDevicesItem": ".types", "ResourcesNode": ".types", @@ -2082,11 +2201,14 @@ "ResponseFormatText": ".types", "RetryConfig": ".types", "RevokeAllPersonalAccessTokenResponse": ".types", + "Role": ".types", + "RoleBinding": ".types", "RoleBindingManifest": ".types", "RoleBindingPermission": ".types", "RoleBindingSubject": ".types", "RoleBindingSubjectType": ".types", "RoleManifest": ".types", + "RoleResourceType": ".types", "RoleWithResource": ".types", "RoleWithResourceResourceType": ".types", "Rolling": ".types", @@ -2134,6 +2256,7 @@ "SessionAccount": ".types", "SessionActor": ".types", "SessionTeam": ".types", + "Settings": ".types", "SignedUrl": ".types", "SklearnFramework": ".types", "SklearnModelSchema": ".types", @@ -2185,6 +2308,7 @@ "SparkJobPythonNotebookEntrypoint": ".types", "SparkJobScalaEntrypoint": ".types", "SparkJobScalaNotebookEntrypoint": ".types", + "SparkJobTrigger": ".types", "SparkJobTriggerInput": ".types", "SqlSanitizerGuardrailConfig": ".types", "SqlSanitizerGuardrailConfigConfig": ".types", @@ -2197,6 +2321,8 @@ "SshServerConfig": ".types", "StageArtifactRequestManifest": ".artifact_versions", "StageArtifactResponse": ".types", + "StaticFallbackStrategy": ".types", + "StaticFallbackStrategyDefaultTier": ".types", "StaticVolumeConfig": ".types", "StatsModelsFramework": ".types", "StdioMcpServerManifest": ".types", @@ -2210,6 +2336,7 @@ "SubjectConditionGroup": ".types", "SubjectConditionGroupOperator": ".types", "SubjectPermission": ".types", + "SubjectSubjectType": ".types", "SubjectType": ".types", "SyncTokenInSecretStoreInfo": ".types", "SyncVirtualAccountTokenResponse": ".types", @@ -2254,6 +2381,7 @@ "ToolMessageContent": ".types", "ToolSchema": ".types", "TraceSpan": ".types", + "TracingProject": ".types", "TracingProjectControlPlaneManagedStorage": ".types", "TracingProjectCustomerManagedStorage": ".types", "TracingProjectManifest": ".types", @@ -2272,19 +2400,30 @@ "TrueFoundryAgentContextManagementConfig": ".types", "TrueFoundryAgentDynamicSubAgentsConfig": ".types", "TrueFoundryAgentGenerativeUiConfig": ".types", + "TrueFoundryAgentGitSourceSkill": ".types", "TrueFoundryAgentLargeToolResponseConfig": ".types", "TrueFoundryAgentManifest": ".types", "TrueFoundryAgentMcpServer": ".types", + "TrueFoundryAgentMcpServerInline": ".types", + "TrueFoundryAgentMcpServerRegistry": ".types", "TrueFoundryAgentModel": ".types", "TrueFoundryAgentModelParams": ".types", "TrueFoundryAgentResponseFormat": ".types", + "TrueFoundryAgentSandboxAuthData": ".types", + "TrueFoundryAgentSandboxAuthInject": ".types", + "TrueFoundryAgentSandboxAuthInjectMatch": ".types", + "TrueFoundryAgentSandboxBasicAuthData": ".types", "TrueFoundryAgentSandboxConfig": ".types", + "TrueFoundryAgentSandboxGitAuthInject": ".types", + "TrueFoundryAgentSandboxNetworkPolicy": ".types", "TrueFoundryAgentSkill": ".types", + "TrueFoundryAgentTrueFoundrySkill": ".types", "TrueFoundryAgentUserMessage": ".types", "TrueFoundryAgentVariable": ".types", "TrueFoundryApplyRequestManifest": ".types", "TrueFoundryApplyResponse": ".types", "TrueFoundryApplyResponseAction": ".types", + "TrueFoundryApplyResponseData": ".types", "TrueFoundryApplyResponseExistingManifest": ".types", "TrueFoundryArtifactSource": ".types", "TrueFoundryDbssm": ".types", @@ -2303,6 +2442,7 @@ "UnprocessableEntityError": ".errors", "UpdateRunResponse": ".types", "UpdateSecretInput": ".types", + "UpdateUserRolesRequestResourceType": ".users", "UpdateUserRolesResponse": ".types", "UpgradeData": ".types", "UploadSpecSource": ".types", @@ -2382,6 +2522,7 @@ "data_directories": ".data_directories", "environments": ".environments", "events": ".events", + "gateway_budgets": ".gateway_budgets", "internal": ".internal", "jobs": ".jobs", "logs": ".logs", @@ -2434,7 +2575,15 @@ def __dir__(): "AddonComponentName", "AddonComponentStatus", "Agent", + "AgentChannel", + "AgentChannelAgent", + "AgentChannelConfig", + "AgentChannelManifest", + "AgentChannelSlackAuth", + "AgentChannelSlackBotTokenAuth", + "AgentChannelSlackConfig", "AgentFramework", + "AgentIdentity", "AgentIdentityAutoRotate", "AgentIdentityConfig", "AgentIdentityManifest", @@ -2462,6 +2611,7 @@ def __dir__(): "AktoTokenAuth", "Alert", "AlertConfig", + "AlertConfigEntity", "AlertConfigResource", "AlertConfigResourceType", "AlertSeverity", @@ -2606,8 +2756,13 @@ def __dir__(): "BlueGreen", "BudgetAlert", "BudgetConfig", + "BudgetEntityUsageDto", "BudgetLimitUnit", "BudgetRule", + "BudgetUsageEntryDto", + "BudgetUsageEntryDtoMode", + "BudgetUsageEntryDtoType", + "BudgetUsageResponseDto", "BudgetV2Alert", "BudgetV2AppliesTo", "BudgetV2AppliesToAggregate", @@ -2632,7 +2787,6 @@ def __dir__(): "BuildBuildSpec", "BuildInfo", "BuildSecret", - "BuildStatus", "Canary", "CanaryStep", "CancelDeploymentApplicationsResponse", @@ -2675,6 +2829,11 @@ def __dir__(): "CohereProviderAccount", "Collaborator", "CommonToolsSettings", + "ComplexityBasedLoadBalanceTarget", + "ComplexityBasedLoadBalanceTargetTier", + "ComplexityBasedLoadBalancing", + "ComplexityBasedLoadBalancingClassificationStrategy", + "ComplexityStickyRouting", "Config", "ConflictError", "ContainerTaskConfig", @@ -2684,6 +2843,7 @@ def __dir__(): "CpuUtilizationMetric", "CreateDockerRepositoryResponse", "CreateMultiPartUploadRequest", + "CreateOrUpdateBudgetDtoManifest", "CreatePersonalAccessTokenRequestTokenType", "CreatePersonalAccessTokenResponse", "CreateRunResponse", @@ -2752,6 +2912,7 @@ def __dir__(): "DeleteWorkspaceResponse", "Deployment", "DeploymentBuild", + "DeploymentBuildStatus", "DeploymentManifest", "DeploymentStatus", "DeploymentStatusValue", @@ -2788,6 +2949,7 @@ def __dir__(): "ExactMatchCacheConfig", "ExpectationFailedError", "ExternalBlobStorageSource", + "ExternalIdentityProvider", "FailedDependencyError", "FastAiFramework", "FiddlerGuardType", @@ -2810,6 +2972,8 @@ def __dir__(): "ForwardAction", "Function", "FunctionSchema", + "GatewayBudget", + "GatewayBudgetManifest", "GatewayConfig", "GatewayConfiguration", "GatewayDataAccessConfig", @@ -2826,9 +2990,8 @@ def __dir__(): "GatewayDataRoutingConfigDestinationStorage", "GatewayDataRoutingConfigDestinationStorageStorage", "GatewayDataType", + "GatewayInstallation", "GatewayLoggingConfig", - "GatewayLoggingRule", - "GatewayLoggingWhen", "GatewayMetadataConfig", "GatewayMetadataRule", "GatewayMetadataWhen", @@ -2842,6 +3005,7 @@ def __dir__(): "GcpGcr", "GcpGcs", "GcpGkeIntegration", + "GcpGkeIntegrationLocation", "GcpGsm", "GcpIntegrations", "GcpKeyFileAuth", @@ -2851,6 +3015,7 @@ def __dir__(): "GcpTpu", "GeminiModel", "GenericSecretStoreIntegration", + "GetAgentIdentityTokenResponse", "GetAgentResponse", "GetAgentSkillResponse", "GetAgentSkillVersionResponse", @@ -2944,13 +3109,15 @@ def __dir__(): "Helm", "HelmRepo", "HelmSource", + "HeuristicClassificationStrategy", + "HeuristicFallbackStrategy", "HostedA2AAgent", "HttpError", "HttpErrorCode", "HttpProbe", "HuggingfaceArtifactSource", "IChange", - "IChangeOperation", + "IChangeType", "IdentityProviderBackedIdentity", "IdentityProviderMapping", "Image", @@ -2958,6 +3125,7 @@ def __dir__(): "ImageContentPart", "ImageContentPartImageUrl", "ImageContentPartImageUrlUrl", + "InNotIn", "InNotInOperator", "InNotInOperatorCondition", "InferMethodName", @@ -3029,6 +3197,7 @@ def __dir__(): "ListEnvironmentsResponse", "ListFilesRequest", "ListFilesResponse", + "ListGatewayBudgetsRequestType", "ListJobRunResponse", "ListMetricHistoryResponse", "ListMlReposResponse", @@ -3045,6 +3214,8 @@ def __dir__(): "ListUsersResponse", "ListVirtualAccountResponse", "ListWorkspacesResponse", + "LlmClassificationStrategy", + "LlmClassificationStrategyFallbackStrategy", "LoadBalanceTarget", "LoadBalancingConfig", "LoadBalancingRule", @@ -3058,12 +3229,17 @@ def __dir__(): "LoggingModeAlways", "LoggingModeHeaderControlled", "LoggingModeNever", + "LoggingWhen", "LogsResponse", "LogsSearchFilterType", "LogsSearchOperatorType", "LogsSortingDirection", "Manual", + "McpServer", "McpServerAuth", + "McpServerAuthStatusInfo", + "McpServerAuthStatusInfoMethod", + "McpServerAuthStatusInfoStatus", "McpServerEnvAuth", "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", @@ -3078,6 +3254,8 @@ def __dir__(): "McpServerOAuth2JwtSource", "McpServerOAuth2Provider", "McpServerOAuth2ProviderAuth0Settings", + "McpServerOAuth2ProviderOktaIdJagSettings", + "McpServerOAuth2ProviderOktaSettings", "McpServerPassthrough", "McpServerProviderAccount", "McpServerSource", @@ -3129,6 +3307,9 @@ def __dir__(): "NodeSelectorCapacityType", "Nodepool", "NodepoolSelector", + "NomaSecurityApiKeyAuth", + "NomaSecurityGuardrailConfig", + "NomaSecurityGuardrailConfigConfig", "NomicIntegrations", "NomicKeyAuth", "NomicModel", @@ -3226,6 +3407,9 @@ def __dir__(): "PerMinuteOfAudioCostMetricValue", "PerThousandEmbeddingTokensCostMetric", "PerThousandTokensCostMetric", + "PeriodUsageDto", + "PermissionSetV2", + "PermissionSetV2ResourceType", "Permissions", "PerplexityAiKeyAuth", "PerplexityAiModel", @@ -3235,6 +3419,7 @@ def __dir__(): "PersonalAccessTokenManifestTokenType", "Pip", "Poetry", + "Policy", "PolicyActions", "PolicyEntityTypes", "PolicyFilters", @@ -3243,6 +3428,7 @@ def __dir__(): "PolicyManifestOperation", "PolicyMutationOperation", "PolicyValidationOperation", + "PolicyVersion", "Port", "PortAppProtocol", "PortAuth", @@ -3258,7 +3444,11 @@ def __dir__(): "Prompt", "PromptSource", "PromptVersion", + "ProviderAccount", + "ProviderAccountProvider", "ProviderAccounts", + "ProviderIntegration", + "ProviderIntegrationType", "PublicCostMetric", "PySparkTaskConfig", "PyTorchFramework", @@ -3280,6 +3470,7 @@ def __dir__(): "RateLimitUnit", "RateLimitWhen", "Recommendation", + "Redaction", "RefusalContentPart", "RegexConstraint", "RegexGuardrailConfig", @@ -3290,7 +3481,6 @@ def __dir__(): "RemoteMcpServerManifest", "RemoteSource", "RemoteSpecSource", - "ResourceType", "Resources", "ResourcesDevicesItem", "ResourcesNode", @@ -3300,11 +3490,14 @@ def __dir__(): "ResponseFormatText", "RetryConfig", "RevokeAllPersonalAccessTokenResponse", + "Role", + "RoleBinding", "RoleBindingManifest", "RoleBindingPermission", "RoleBindingSubject", "RoleBindingSubjectType", "RoleManifest", + "RoleResourceType", "RoleWithResource", "RoleWithResourceResourceType", "Rolling", @@ -3352,6 +3545,7 @@ def __dir__(): "SessionAccount", "SessionActor", "SessionTeam", + "Settings", "SignedUrl", "SklearnFramework", "SklearnModelSchema", @@ -3403,6 +3597,7 @@ def __dir__(): "SparkJobPythonNotebookEntrypoint", "SparkJobScalaEntrypoint", "SparkJobScalaNotebookEntrypoint", + "SparkJobTrigger", "SparkJobTriggerInput", "SqlSanitizerGuardrailConfig", "SqlSanitizerGuardrailConfigConfig", @@ -3415,6 +3610,8 @@ def __dir__(): "SshServerConfig", "StageArtifactRequestManifest", "StageArtifactResponse", + "StaticFallbackStrategy", + "StaticFallbackStrategyDefaultTier", "StaticVolumeConfig", "StatsModelsFramework", "StdioMcpServerManifest", @@ -3428,6 +3625,7 @@ def __dir__(): "SubjectConditionGroup", "SubjectConditionGroupOperator", "SubjectPermission", + "SubjectSubjectType", "SubjectType", "SyncTokenInSecretStoreInfo", "SyncVirtualAccountTokenResponse", @@ -3472,6 +3670,7 @@ def __dir__(): "ToolMessageContent", "ToolSchema", "TraceSpan", + "TracingProject", "TracingProjectControlPlaneManagedStorage", "TracingProjectCustomerManagedStorage", "TracingProjectManifest", @@ -3490,19 +3689,30 @@ def __dir__(): "TrueFoundryAgentContextManagementConfig", "TrueFoundryAgentDynamicSubAgentsConfig", "TrueFoundryAgentGenerativeUiConfig", + "TrueFoundryAgentGitSourceSkill", "TrueFoundryAgentLargeToolResponseConfig", "TrueFoundryAgentManifest", "TrueFoundryAgentMcpServer", + "TrueFoundryAgentMcpServerInline", + "TrueFoundryAgentMcpServerRegistry", "TrueFoundryAgentModel", "TrueFoundryAgentModelParams", "TrueFoundryAgentResponseFormat", + "TrueFoundryAgentSandboxAuthData", + "TrueFoundryAgentSandboxAuthInject", + "TrueFoundryAgentSandboxAuthInjectMatch", + "TrueFoundryAgentSandboxBasicAuthData", "TrueFoundryAgentSandboxConfig", + "TrueFoundryAgentSandboxGitAuthInject", + "TrueFoundryAgentSandboxNetworkPolicy", "TrueFoundryAgentSkill", + "TrueFoundryAgentTrueFoundrySkill", "TrueFoundryAgentUserMessage", "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", "TrueFoundryApplyResponse", "TrueFoundryApplyResponseAction", + "TrueFoundryApplyResponseData", "TrueFoundryApplyResponseExistingManifest", "TrueFoundryArtifactSource", "TrueFoundryDbssm", @@ -3521,6 +3731,7 @@ def __dir__(): "UnprocessableEntityError", "UpdateRunResponse", "UpdateSecretInput", + "UpdateUserRolesRequestResourceType", "UpdateUserRolesResponse", "UpgradeData", "UploadSpecSource", @@ -3600,6 +3811,7 @@ def __dir__(): "data_directories", "environments", "events", + "gateway_budgets", "internal", "jobs", "logs", diff --git a/src/truefoundry_sdk/agents/client.py b/src/truefoundry_sdk/agents/client.py index 1998e35c..2d1bf459 100644 --- a/src/truefoundry_sdk/agents/client.py +++ b/src/truefoundry_sdk/agents/client.py @@ -7,6 +7,7 @@ from ..core.request_options import RequestOptions from ..types.agent import Agent from ..types.agent_manifest import AgentManifest +from ..types.get_agent_identity_token_response import GetAgentIdentityTokenResponse from ..types.get_agent_response import GetAgentResponse from ..types.get_agent_version_response import GetAgentVersionResponse from ..types.list_agents_response import ListAgentsResponse @@ -225,6 +226,40 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = _response = self._raw_client.delete(id, request_options=request_options) return _response.data + def get_token( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentIdentityTokenResponse: + """ + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + + Parameters + ---------- + id : str + System-generated agent ID. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The TrueFoundry-backed token for the agent's identity. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agents.get_token( + id="jqfwg345gi25n5ju2yz5iz6m", + ) + """ + _response = self._raw_client.get_token(id, request_options=request_options) + return _response.data + class AsyncAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -466,3 +501,45 @@ async def main() -> None: """ _response = await self._raw_client.delete(id, request_options=request_options) return _response.data + + async def get_token( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentIdentityTokenResponse: + """ + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + + Parameters + ---------- + id : str + System-generated agent ID. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The TrueFoundry-backed token for the agent's identity. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.agents.get_token( + id="jqfwg345gi25n5ju2yz5iz6m", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_token(id, request_options=request_options) + return _response.data diff --git a/src/truefoundry_sdk/agents/raw_client.py b/src/truefoundry_sdk/agents/raw_client.py index d7622515..706dd887 100644 --- a/src/truefoundry_sdk/agents/raw_client.py +++ b/src/truefoundry_sdk/agents/raw_client.py @@ -17,8 +17,10 @@ from ..errors.internal_server_error import InternalServerError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError +from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..types.agent import Agent from ..types.agent_manifest import AgentManifest +from ..types.get_agent_identity_token_response import GetAgentIdentityTokenResponse from ..types.get_agent_response import GetAgentResponse from ..types.get_agent_version_response import GetAgentVersionResponse from ..types.http_error import HttpError @@ -389,6 +391,82 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def get_token( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetAgentIdentityTokenResponse]: + """ + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + + Parameters + ---------- + id : str + System-generated agent ID. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentIdentityTokenResponse] + The TrueFoundry-backed token for the agent's identity. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/token", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + class AsyncRawAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -753,3 +831,79 @@ async def delete( status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_token( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetAgentIdentityTokenResponse]: + """ + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + + Parameters + ---------- + id : str + System-generated agent ID. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentIdentityTokenResponse] + The TrueFoundry-backed token for the agent's identity. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/token", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/truefoundry_sdk/base_client.py b/src/truefoundry_sdk/base_client.py index fb41737a..5e7ee69e 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -30,6 +30,7 @@ from .data_directories.client import AsyncDataDirectoriesClient, DataDirectoriesClient from .environments.client import AsyncEnvironmentsClient, EnvironmentsClient from .events.client import AsyncEventsClient, EventsClient + from .gateway_budgets.client import AsyncGatewayBudgetsClient, GatewayBudgetsClient from .internal.client import AsyncInternalClient, InternalClient from .jobs.client import AsyncJobsClient, JobsClient from .logs.client import AsyncLogsClient, LogsClient @@ -132,6 +133,7 @@ def __init__( self._internal: typing.Optional[InternalClient] = None self._users: typing.Optional[UsersClient] = None self._teams: typing.Optional[TeamsClient] = None + self._gateway_budgets: typing.Optional[GatewayBudgetsClient] = None self._personal_access_tokens: typing.Optional[PersonalAccessTokensClient] = None self._virtual_accounts: typing.Optional[VirtualAccountsClient] = None self._clusters: typing.Optional[ClustersClient] = None @@ -288,6 +290,14 @@ def teams(self): self._teams = TeamsClient(client_wrapper=self._client_wrapper) return self._teams + @property + def gateway_budgets(self): + if self._gateway_budgets is None: + from .gateway_budgets.client import GatewayBudgetsClient # noqa: E402 + + self._gateway_budgets = GatewayBudgetsClient(client_wrapper=self._client_wrapper) + return self._gateway_budgets + @property def personal_access_tokens(self): if self._personal_access_tokens is None: @@ -607,6 +617,7 @@ def __init__( self._internal: typing.Optional[AsyncInternalClient] = None self._users: typing.Optional[AsyncUsersClient] = None self._teams: typing.Optional[AsyncTeamsClient] = None + self._gateway_budgets: typing.Optional[AsyncGatewayBudgetsClient] = None self._personal_access_tokens: typing.Optional[AsyncPersonalAccessTokensClient] = None self._virtual_accounts: typing.Optional[AsyncVirtualAccountsClient] = None self._clusters: typing.Optional[AsyncClustersClient] = None @@ -779,6 +790,14 @@ def teams(self): self._teams = AsyncTeamsClient(client_wrapper=self._client_wrapper) return self._teams + @property + def gateway_budgets(self): + if self._gateway_budgets is None: + from .gateway_budgets.client import AsyncGatewayBudgetsClient # noqa: E402 + + self._gateway_budgets = AsyncGatewayBudgetsClient(client_wrapper=self._client_wrapper) + return self._gateway_budgets + @property def personal_access_tokens(self): if self._personal_access_tokens is None: diff --git a/src/truefoundry_sdk/gateway_budgets/__init__.py b/src/truefoundry_sdk/gateway_budgets/__init__.py new file mode 100644 index 00000000..da962d04 --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/__init__.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import CreateOrUpdateBudgetDtoManifest, ListGatewayBudgetsRequestType +_dynamic_imports: typing.Dict[str, str] = { + "CreateOrUpdateBudgetDtoManifest": ".types", + "ListGatewayBudgetsRequestType": ".types", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["CreateOrUpdateBudgetDtoManifest", "ListGatewayBudgetsRequestType"] diff --git a/src/truefoundry_sdk/gateway_budgets/client.py b/src/truefoundry_sdk/gateway_budgets/client.py new file mode 100644 index 00000000..25ede7a4 --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/client.py @@ -0,0 +1,670 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.budget_usage_response_dto import BudgetUsageResponseDto +from ..types.gateway_budget import GatewayBudget +from .raw_client import AsyncRawGatewayBudgetsClient, RawGatewayBudgetsClient +from .types.create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest +from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class GatewayBudgetsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawGatewayBudgetsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawGatewayBudgetsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawGatewayBudgetsClient + """ + return self._raw_client + + def list( + self, + *, + type: typing.Optional[ListGatewayBudgetsRequestType] = None, + team_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[GatewayBudget]: + """ + Returns all budgets for the tenant. Supports filtering by type and team_name. + + Parameters + ---------- + type : typing.Optional[ListGatewayBudgetsRequestType] + Filter by budget type. One of tenant-budget-config | team-budget-config. + + team_name : typing.Optional[str] + Filter by team_name (only meaningful for team-budget-config). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[GatewayBudget] + List of budgets. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.list() + """ + _response = self._raw_client.list(type=type, team_name=team_name, request_options=request_options) + return _response.data + + def create_or_update( + self, + *, + manifest: CreateOrUpdateBudgetDtoManifest, + dry_run: typing.Optional[bool] = False, + request_options: typing.Optional[RequestOptions] = None, + ) -> GatewayBudget: + """ + Creates or updates a budget manifest for the tenant. Budgets are upserted by `manifest.name` (unique per tenant). + + Parameters + ---------- + manifest : CreateOrUpdateBudgetDtoManifest + The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. + + dry_run : typing.Optional[bool] + When `true`, validates the manifest without persisting changes. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GatewayBudget + The created or updated budget. + + Examples + -------- + from truefoundry_sdk import ( + BudgetV2AppliesToAggregate, + BudgetV2Limits, + TenantBudgetConfig, + TenantBudgetConfigMode, + TrueFoundry, + ) + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.create_or_update( + manifest=TenantBudgetConfig( + name="name", + limits=BudgetV2Limits(), + applies_to=BudgetV2AppliesToAggregate(), + mode=TenantBudgetConfigMode.ENFORCE, + ), + ) + """ + _response = self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) + return _response.data + + def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponseDto: + """ + Returns every per-user budget that currently applies to the caller, with current usage per period. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The caller-scoped budget usage. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.get_my_usage() + """ + _response = self._raw_client.get_my_usage(request_options=request_options) + return _response.data + + def simulate( + self, + *, + user: typing.Optional[str] = OMIT, + virtual_account: typing.Optional[str] = OMIT, + team: typing.Optional[str] = OMIT, + teams: typing.Optional[typing.Sequence[str]] = OMIT, + model: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> BudgetUsageResponseDto: + """ + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + + Parameters + ---------- + user : typing.Optional[str] + User email to simulate as. + + virtual_account : typing.Optional[str] + Virtual account slug to simulate as. Use this instead of `user` for virtual-account budgets. + + team : typing.Optional[str] + Single team to simulate membership of. Use `teams` to pass multiple teams. + + teams : typing.Optional[typing.Sequence[str]] + All teams the simulated user belongs to. Merged with `team` when both are provided. + + model : typing.Optional[str] + Model to simulate. + + metadata : typing.Optional[typing.Dict[str, str]] + Request metadata key/value pairs to simulate. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The budgets matching the selection. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.simulate() + """ + _response = self._raw_client.simulate( + user=user, + virtual_account=virtual_account, + team=team, + teams=teams, + model=model, + metadata=metadata, + request_options=request_options, + ) + return _response.data + + def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GatewayBudget: + """ + Returns a single budget by id. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GatewayBudget + The requested budget. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.get( + id="id", + ) + """ + _response = self._raw_client.get(id, request_options=request_options) + return _response.data + + def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + """ + Permanently deletes a budget manifest. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.delete( + id="id", + ) + """ + _response = self._raw_client.delete(id, request_options=request_options) + return _response.data + + def get_leaderboard( + self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None + ) -> BudgetUsageResponseDto: + """ + Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + limit : typing.Optional[float] + Maximum number of entries to return. Defaults to 500 and is capped at 500. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The budget leaderboard. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.gateway_budgets.get_leaderboard( + id="id", + limit=50.0, + ) + """ + _response = self._raw_client.get_leaderboard(id, limit=limit, request_options=request_options) + return _response.data + + +class AsyncGatewayBudgetsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawGatewayBudgetsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawGatewayBudgetsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawGatewayBudgetsClient + """ + return self._raw_client + + async def list( + self, + *, + type: typing.Optional[ListGatewayBudgetsRequestType] = None, + team_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[GatewayBudget]: + """ + Returns all budgets for the tenant. Supports filtering by type and team_name. + + Parameters + ---------- + type : typing.Optional[ListGatewayBudgetsRequestType] + Filter by budget type. One of tenant-budget-config | team-budget-config. + + team_name : typing.Optional[str] + Filter by team_name (only meaningful for team-budget-config). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[GatewayBudget] + List of budgets. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.list() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list(type=type, team_name=team_name, request_options=request_options) + return _response.data + + async def create_or_update( + self, + *, + manifest: CreateOrUpdateBudgetDtoManifest, + dry_run: typing.Optional[bool] = False, + request_options: typing.Optional[RequestOptions] = None, + ) -> GatewayBudget: + """ + Creates or updates a budget manifest for the tenant. Budgets are upserted by `manifest.name` (unique per tenant). + + Parameters + ---------- + manifest : CreateOrUpdateBudgetDtoManifest + The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. + + dry_run : typing.Optional[bool] + When `true`, validates the manifest without persisting changes. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GatewayBudget + The created or updated budget. + + Examples + -------- + import asyncio + + from truefoundry_sdk import ( + AsyncTrueFoundry, + BudgetV2AppliesToAggregate, + BudgetV2Limits, + TenantBudgetConfig, + TenantBudgetConfigMode, + ) + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.create_or_update( + manifest=TenantBudgetConfig( + name="name", + limits=BudgetV2Limits(), + applies_to=BudgetV2AppliesToAggregate(), + mode=TenantBudgetConfigMode.ENFORCE, + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) + return _response.data + + async def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponseDto: + """ + Returns every per-user budget that currently applies to the caller, with current usage per period. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The caller-scoped budget usage. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.get_my_usage() + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_my_usage(request_options=request_options) + return _response.data + + async def simulate( + self, + *, + user: typing.Optional[str] = OMIT, + virtual_account: typing.Optional[str] = OMIT, + team: typing.Optional[str] = OMIT, + teams: typing.Optional[typing.Sequence[str]] = OMIT, + model: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> BudgetUsageResponseDto: + """ + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + + Parameters + ---------- + user : typing.Optional[str] + User email to simulate as. + + virtual_account : typing.Optional[str] + Virtual account slug to simulate as. Use this instead of `user` for virtual-account budgets. + + team : typing.Optional[str] + Single team to simulate membership of. Use `teams` to pass multiple teams. + + teams : typing.Optional[typing.Sequence[str]] + All teams the simulated user belongs to. Merged with `team` when both are provided. + + model : typing.Optional[str] + Model to simulate. + + metadata : typing.Optional[typing.Dict[str, str]] + Request metadata key/value pairs to simulate. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The budgets matching the selection. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.simulate() + + + asyncio.run(main()) + """ + _response = await self._raw_client.simulate( + user=user, + virtual_account=virtual_account, + team=team, + teams=teams, + model=model, + metadata=metadata, + request_options=request_options, + ) + return _response.data + + async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GatewayBudget: + """ + Returns a single budget by id. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GatewayBudget + The requested budget. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.get( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(id, request_options=request_options) + return _response.data + + async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + """ + Permanently deletes a budget manifest. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.delete( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete(id, request_options=request_options) + return _response.data + + async def get_leaderboard( + self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None + ) -> BudgetUsageResponseDto: + """ + Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + limit : typing.Optional[float] + Maximum number of entries to return. Defaults to 500 and is capped at 500. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BudgetUsageResponseDto + The budget leaderboard. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.gateway_budgets.get_leaderboard( + id="id", + limit=50.0, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_leaderboard(id, limit=limit, request_options=request_options) + return _response.data diff --git a/src/truefoundry_sdk/gateway_budgets/raw_client.py b/src/truefoundry_sdk/gateway_budgets/raw_client.py new file mode 100644 index 00000000..573fe84a --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/raw_client.py @@ -0,0 +1,835 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import encode_path_param +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..types.budget_usage_response_dto import BudgetUsageResponseDto +from ..types.gateway_budget import GatewayBudget +from .types.create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest +from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawGatewayBudgetsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + *, + type: typing.Optional[ListGatewayBudgetsRequestType] = None, + team_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.List[GatewayBudget]]: + """ + Returns all budgets for the tenant. Supports filtering by type and team_name. + + Parameters + ---------- + type : typing.Optional[ListGatewayBudgetsRequestType] + Filter by budget type. One of tenant-budget-config | team-budget-config. + + team_name : typing.Optional[str] + Filter by team_name (only meaningful for team-budget-config). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[GatewayBudget]] + List of budgets. + """ + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets", + method="GET", + params={ + "type": type, + "team_name": team_name, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[GatewayBudget], + parse_obj_as( + type_=typing.List[GatewayBudget], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_or_update( + self, + *, + manifest: CreateOrUpdateBudgetDtoManifest, + dry_run: typing.Optional[bool] = False, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[GatewayBudget]: + """ + Creates or updates a budget manifest for the tenant. Budgets are upserted by `manifest.name` (unique per tenant). + + Parameters + ---------- + manifest : CreateOrUpdateBudgetDtoManifest + The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. + + dry_run : typing.Optional[bool] + When `true`, validates the manifest without persisting changes. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GatewayBudget] + The created or updated budget. + """ + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets", + method="PUT", + json={ + "manifest": convert_and_respect_annotation_metadata( + object_=manifest, annotation=CreateOrUpdateBudgetDtoManifest, direction="write" + ), + "dryRun": dry_run, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GatewayBudget, + parse_obj_as( + type_=GatewayBudget, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_my_usage( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[BudgetUsageResponseDto]: + """ + Returns every per-user budget that currently applies to the caller, with current usage per period. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BudgetUsageResponseDto] + The caller-scoped budget usage. + """ + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets/my-usage", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def simulate( + self, + *, + user: typing.Optional[str] = OMIT, + virtual_account: typing.Optional[str] = OMIT, + team: typing.Optional[str] = OMIT, + teams: typing.Optional[typing.Sequence[str]] = OMIT, + model: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[BudgetUsageResponseDto]: + """ + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + + Parameters + ---------- + user : typing.Optional[str] + User email to simulate as. + + virtual_account : typing.Optional[str] + Virtual account slug to simulate as. Use this instead of `user` for virtual-account budgets. + + team : typing.Optional[str] + Single team to simulate membership of. Use `teams` to pass multiple teams. + + teams : typing.Optional[typing.Sequence[str]] + All teams the simulated user belongs to. Merged with `team` when both are provided. + + model : typing.Optional[str] + Model to simulate. + + metadata : typing.Optional[typing.Dict[str, str]] + Request metadata key/value pairs to simulate. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BudgetUsageResponseDto] + The budgets matching the selection. + """ + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets/simulate", + method="POST", + json={ + "user": user, + "virtual_account": virtual_account, + "team": team, + "teams": teams, + "model": model, + "metadata": metadata, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[GatewayBudget]: + """ + Returns a single budget by id. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GatewayBudget] + The requested budget. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GatewayBudget, + parse_obj_as( + type_=GatewayBudget, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[None]: + """ + Permanently deletes a budget manifest. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_leaderboard( + self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[BudgetUsageResponseDto]: + """ + Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + limit : typing.Optional[float] + Maximum number of entries to return. Defaults to 500 and is capped at 500. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BudgetUsageResponseDto] + The budget leaderboard. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}/leaderboard", + method="GET", + params={ + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawGatewayBudgetsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + *, + type: typing.Optional[ListGatewayBudgetsRequestType] = None, + team_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.List[GatewayBudget]]: + """ + Returns all budgets for the tenant. Supports filtering by type and team_name. + + Parameters + ---------- + type : typing.Optional[ListGatewayBudgetsRequestType] + Filter by budget type. One of tenant-budget-config | team-budget-config. + + team_name : typing.Optional[str] + Filter by team_name (only meaningful for team-budget-config). + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[GatewayBudget]] + List of budgets. + """ + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets", + method="GET", + params={ + "type": type, + "team_name": team_name, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[GatewayBudget], + parse_obj_as( + type_=typing.List[GatewayBudget], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_or_update( + self, + *, + manifest: CreateOrUpdateBudgetDtoManifest, + dry_run: typing.Optional[bool] = False, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[GatewayBudget]: + """ + Creates or updates a budget manifest for the tenant. Budgets are upserted by `manifest.name` (unique per tenant). + + Parameters + ---------- + manifest : CreateOrUpdateBudgetDtoManifest + The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. + + dry_run : typing.Optional[bool] + When `true`, validates the manifest without persisting changes. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GatewayBudget] + The created or updated budget. + """ + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets", + method="PUT", + json={ + "manifest": convert_and_respect_annotation_metadata( + object_=manifest, annotation=CreateOrUpdateBudgetDtoManifest, direction="write" + ), + "dryRun": dry_run, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GatewayBudget, + parse_obj_as( + type_=GatewayBudget, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_my_usage( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + """ + Returns every per-user budget that currently applies to the caller, with current usage per period. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BudgetUsageResponseDto] + The caller-scoped budget usage. + """ + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets/my-usage", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def simulate( + self, + *, + user: typing.Optional[str] = OMIT, + virtual_account: typing.Optional[str] = OMIT, + team: typing.Optional[str] = OMIT, + teams: typing.Optional[typing.Sequence[str]] = OMIT, + model: typing.Optional[str] = OMIT, + metadata: typing.Optional[typing.Dict[str, str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + """ + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + + Parameters + ---------- + user : typing.Optional[str] + User email to simulate as. + + virtual_account : typing.Optional[str] + Virtual account slug to simulate as. Use this instead of `user` for virtual-account budgets. + + team : typing.Optional[str] + Single team to simulate membership of. Use `teams` to pass multiple teams. + + teams : typing.Optional[typing.Sequence[str]] + All teams the simulated user belongs to. Merged with `team` when both are provided. + + model : typing.Optional[str] + Model to simulate. + + metadata : typing.Optional[typing.Dict[str, str]] + Request metadata key/value pairs to simulate. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BudgetUsageResponseDto] + The budgets matching the selection. + """ + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/llm-gateway/budgets/simulate", + method="POST", + json={ + "user": user, + "virtual_account": virtual_account, + "team": team, + "teams": teams, + "model": model, + "metadata": metadata, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GatewayBudget]: + """ + Returns a single budget by id. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GatewayBudget] + The requested budget. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GatewayBudget, + parse_obj_as( + type_=GatewayBudget, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Permanently deletes a budget manifest. + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_leaderboard( + self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + """ + Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). + + Parameters + ---------- + id : str + The budget id to retrieve or delete. + + limit : typing.Optional[float] + Maximum number of entries to return. Defaults to 500 and is capped at 500. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BudgetUsageResponseDto] + The budget leaderboard. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/llm-gateway/budgets/{encode_path_param(id)}/leaderboard", + method="GET", + params={ + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BudgetUsageResponseDto, + parse_obj_as( + type_=BudgetUsageResponseDto, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/truefoundry_sdk/gateway_budgets/types/__init__.py b/src/truefoundry_sdk/gateway_budgets/types/__init__.py new file mode 100644 index 00000000..530f6ec5 --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/types/__init__.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest + from .list_gateway_budgets_request_type import ListGatewayBudgetsRequestType +_dynamic_imports: typing.Dict[str, str] = { + "CreateOrUpdateBudgetDtoManifest": ".create_or_update_budget_dto_manifest", + "ListGatewayBudgetsRequestType": ".list_gateway_budgets_request_type", +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["CreateOrUpdateBudgetDtoManifest", "ListGatewayBudgetsRequestType"] diff --git a/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py b/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py new file mode 100644 index 00000000..d8da804d --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...types.team_budget_config import TeamBudgetConfig +from ...types.tenant_budget_config import TenantBudgetConfig + +CreateOrUpdateBudgetDtoManifest = typing.Union[TenantBudgetConfig, TeamBudgetConfig] diff --git a/src/truefoundry_sdk/gateway_budgets/types/list_gateway_budgets_request_type.py b/src/truefoundry_sdk/gateway_budgets/types/list_gateway_budgets_request_type.py new file mode 100644 index 00000000..8d0451a7 --- /dev/null +++ b/src/truefoundry_sdk/gateway_budgets/types/list_gateway_budgets_request_type.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core import enum + +T_Result = typing.TypeVar("T_Result") + + +class ListGatewayBudgetsRequestType(enum.StrEnum): + TENANT_BUDGET_CONFIG = "tenant-budget-config" + TEAM_BUDGET_CONFIG = "team-budget-config" + _UNKNOWN = "__LISTGATEWAYBUDGETSREQUESTTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "ListGatewayBudgetsRequestType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + tenant_budget_config: typing.Callable[[], T_Result], + team_budget_config: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is ListGatewayBudgetsRequestType.TENANT_BUDGET_CONFIG: + return tenant_budget_config() + if self is ListGatewayBudgetsRequestType.TEAM_BUDGET_CONFIG: + return team_budget_config() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py b/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py index 66e195d3..0dfde411 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py +++ b/src/truefoundry_sdk/internal/ai_gateway/types/get_gateway_config_ai_gateway_request_type.py @@ -19,6 +19,7 @@ class GetGatewayConfigAiGatewayRequestType(enum.StrEnum): GATEWAY_GLOBAL_SETTINGS = "gateway-global-settings" GATEWAY_DATA_ACCESS_CONFIG = "gateway-data-access-config" GATEWAY_DATA_ROUTING_CONFIG = "gateway-data-routing-config" + GATEWAY_LOGGING_CONFIG = "gateway-logging-config" _UNKNOWN = "__GETGATEWAYCONFIGAIGATEWAYREQUESTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -43,6 +44,7 @@ def visit( gateway_global_settings: typing.Callable[[], T_Result], gateway_data_access_config: typing.Callable[[], T_Result], gateway_data_routing_config: typing.Callable[[], T_Result], + gateway_logging_config: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_RATE_LIMITING_CONFIG: @@ -67,4 +69,6 @@ def visit( return gateway_data_access_config() if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_DATA_ROUTING_CONFIG: return gateway_data_routing_config() + if self is GetGatewayConfigAiGatewayRequestType.GATEWAY_LOGGING_CONFIG: + return gateway_logging_config() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/secret_groups/client.py b/src/truefoundry_sdk/secret_groups/client.py index 417d2fc3..82dccb92 100644 --- a/src/truefoundry_sdk/secret_groups/client.py +++ b/src/truefoundry_sdk/secret_groups/client.py @@ -58,7 +58,7 @@ def list( Fqn of secret group. search : typing.Optional[str] - Search query - filters by secret group names that contain the search string + Search query - filters by secret group names or secret names that contain the search string attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. @@ -358,7 +358,7 @@ async def list( Fqn of secret group. search : typing.Optional[str] - Search query - filters by secret group names that contain the search string + Search query - filters by secret group names or secret names that contain the search string attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. diff --git a/src/truefoundry_sdk/secret_groups/raw_client.py b/src/truefoundry_sdk/secret_groups/raw_client.py index b3b87ca4..ba564abe 100644 --- a/src/truefoundry_sdk/secret_groups/raw_client.py +++ b/src/truefoundry_sdk/secret_groups/raw_client.py @@ -61,7 +61,7 @@ def list( Fqn of secret group. search : typing.Optional[str] - Search query - filters by secret group names that contain the search string + Search query - filters by secret group names or secret names that contain the search string attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. @@ -602,7 +602,7 @@ async def list( Fqn of secret group. search : typing.Optional[str] - Search query - filters by secret group names that contain the search string + Search query - filters by secret group names or secret names that contain the search string attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. id,name). When provided, only the specified fields are fetched. `id` is always included. diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index a643f21e..6da2cb02 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -19,7 +19,15 @@ from .addon_component_name import AddonComponentName from .addon_component_status import AddonComponentStatus from .agent import Agent + from .agent_channel import AgentChannel + from .agent_channel_agent import AgentChannelAgent + from .agent_channel_config import AgentChannelConfig + from .agent_channel_manifest import AgentChannelManifest + from .agent_channel_slack_auth import AgentChannelSlackAuth + from .agent_channel_slack_bot_token_auth import AgentChannelSlackBotTokenAuth + from .agent_channel_slack_config import AgentChannelSlackConfig from .agent_framework import AgentFramework + from .agent_identity import AgentIdentity from .agent_identity_auto_rotate import AgentIdentityAutoRotate from .agent_identity_config import AgentIdentityConfig from .agent_identity_manifest import AgentIdentityManifest @@ -47,6 +55,7 @@ from .akto_token_auth import AktoTokenAuth from .alert import Alert from .alert_config import AlertConfig + from .alert_config_entity import AlertConfigEntity from .alert_config_resource import AlertConfigResource from .alert_config_resource_type import AlertConfigResourceType from .alert_severity import AlertSeverity @@ -189,8 +198,13 @@ from .blue_green import BlueGreen from .budget_alert import BudgetAlert from .budget_config import BudgetConfig + from .budget_entity_usage_dto import BudgetEntityUsageDto from .budget_limit_unit import BudgetLimitUnit from .budget_rule import BudgetRule + from .budget_usage_entry_dto import BudgetUsageEntryDto + from .budget_usage_entry_dto_mode import BudgetUsageEntryDtoMode + from .budget_usage_entry_dto_type import BudgetUsageEntryDtoType + from .budget_usage_response_dto import BudgetUsageResponseDto from .budget_v2alert import BudgetV2Alert from .budget_v2applies_to import BudgetV2AppliesTo from .budget_v2applies_to_aggregate import BudgetV2AppliesToAggregate @@ -215,7 +229,6 @@ from .build_build_spec import BuildBuildSpec from .build_info import BuildInfo from .build_secret import BuildSecret - from .build_status import BuildStatus from .canary import Canary from .canary_step import CanaryStep from .cartesia_api_key_auth import CartesiaApiKeyAuth @@ -257,6 +270,13 @@ from .cohere_provider_account import CohereProviderAccount from .collaborator import Collaborator from .common_tools_settings import CommonToolsSettings + from .complexity_based_load_balance_target import ComplexityBasedLoadBalanceTarget + from .complexity_based_load_balance_target_tier import ComplexityBasedLoadBalanceTargetTier + from .complexity_based_load_balancing import ComplexityBasedLoadBalancing + from .complexity_based_load_balancing_classification_strategy import ( + ComplexityBasedLoadBalancingClassificationStrategy, + ) + from .complexity_sticky_routing import ComplexityStickyRouting from .config import Config from .container_task_config import ContainerTaskConfig from .container_task_config_image import ContainerTaskConfigImage @@ -330,6 +350,7 @@ from .delete_workspace_response import DeleteWorkspaceResponse from .deployment import Deployment from .deployment_build import DeploymentBuild + from .deployment_build_status import DeploymentBuildStatus from .deployment_manifest import DeploymentManifest from .deployment_status import DeploymentStatus from .deployment_status_value import DeploymentStatusValue @@ -365,6 +386,7 @@ from .event_involved_object import EventInvolvedObject from .exact_match_cache_config import ExactMatchCacheConfig from .external_blob_storage_source import ExternalBlobStorageSource + from .external_identity_provider import ExternalIdentityProvider from .fast_ai_framework import FastAiFramework from .fiddler_guard_type import FiddlerGuardType from .fiddler_guardrail_config import FiddlerGuardrailConfig @@ -385,6 +407,8 @@ from .forward_action import ForwardAction from .function import Function from .function_schema import FunctionSchema + from .gateway_budget import GatewayBudget + from .gateway_budget_manifest import GatewayBudgetManifest from .gateway_config import GatewayConfig from .gateway_configuration import GatewayConfiguration from .gateway_data_access_config import GatewayDataAccessConfig @@ -413,9 +437,8 @@ GatewayDataRoutingConfigDestinationStorageStorage, ) from .gateway_data_type import GatewayDataType + from .gateway_installation import GatewayInstallation from .gateway_logging_config import GatewayLoggingConfig - from .gateway_logging_rule import GatewayLoggingRule - from .gateway_logging_when import GatewayLoggingWhen from .gateway_metadata_config import GatewayMetadataConfig from .gateway_metadata_rule import GatewayMetadataRule from .gateway_metadata_when import GatewayMetadataWhen @@ -429,6 +452,7 @@ from .gcp_gcr import GcpGcr from .gcp_gcs import GcpGcs from .gcp_gke_integration import GcpGkeIntegration + from .gcp_gke_integration_location import GcpGkeIntegrationLocation from .gcp_gsm import GcpGsm from .gcp_integrations import GcpIntegrations from .gcp_key_file_auth import GcpKeyFileAuth @@ -438,6 +462,7 @@ from .gcp_tpu import GcpTpu from .gemini_model import GeminiModel from .generic_secret_store_integration import GenericSecretStoreIntegration + from .get_agent_identity_token_response import GetAgentIdentityTokenResponse from .get_agent_response import GetAgentResponse from .get_agent_skill_response import GetAgentSkillResponse from .get_agent_skill_version_response import GetAgentSkillVersionResponse @@ -533,13 +558,15 @@ from .helm import Helm from .helm_repo import HelmRepo from .helm_source import HelmSource + from .heuristic_classification_strategy import HeuristicClassificationStrategy + from .heuristic_fallback_strategy import HeuristicFallbackStrategy from .hosted_a2a_agent import HostedA2AAgent from .http_error import HttpError from .http_error_code import HttpErrorCode from .http_probe import HttpProbe from .huggingface_artifact_source import HuggingfaceArtifactSource from .i_change import IChange - from .i_change_operation import IChangeOperation + from .i_change_type import IChangeType from .identity_provider_backed_identity import IdentityProviderBackedIdentity from .identity_provider_mapping import IdentityProviderMapping from .image import Image @@ -547,6 +574,7 @@ from .image_content_part import ImageContentPart from .image_content_part_image_url import ImageContentPartImageUrl from .image_content_part_image_url_url import ImageContentPartImageUrlUrl + from .in_not_in import InNotIn from .in_not_in_operator import InNotInOperator from .in_not_in_operator_condition import InNotInOperatorCondition from .infer_method_name import InferMethodName @@ -630,6 +658,8 @@ from .list_users_response import ListUsersResponse from .list_virtual_account_response import ListVirtualAccountResponse from .list_workspaces_response import ListWorkspacesResponse + from .llm_classification_strategy import LlmClassificationStrategy + from .llm_classification_strategy_fallback_strategy import LlmClassificationStrategyFallbackStrategy from .load_balance_target import LoadBalanceTarget from .load_balancing_config import LoadBalancingConfig from .load_balancing_rule import LoadBalancingRule @@ -643,12 +673,17 @@ from .logging_mode_always import LoggingModeAlways from .logging_mode_header_controlled import LoggingModeHeaderControlled from .logging_mode_never import LoggingModeNever + from .logging_when import LoggingWhen from .logs_response import LogsResponse from .logs_search_filter_type import LogsSearchFilterType from .logs_search_operator_type import LogsSearchOperatorType from .logs_sorting_direction import LogsSortingDirection from .manual import Manual + from .mcp_server import McpServer from .mcp_server_auth import McpServerAuth + from .mcp_server_auth_status_info import McpServerAuthStatusInfo + from .mcp_server_auth_status_info_method import McpServerAuthStatusInfoMethod + from .mcp_server_auth_status_info_status import McpServerAuthStatusInfoStatus from .mcp_server_env_auth import McpServerEnvAuth from .mcp_server_env_auth_auth_level import McpServerEnvAuthAuthLevel from .mcp_server_header_auth import McpServerHeaderAuth @@ -663,6 +698,8 @@ from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource from .mcp_server_o_auth2provider import McpServerOAuth2Provider from .mcp_server_o_auth2provider_auth0settings import McpServerOAuth2ProviderAuth0Settings + from .mcp_server_o_auth2provider_okta_id_jag_settings import McpServerOAuth2ProviderOktaIdJagSettings + from .mcp_server_o_auth2provider_okta_settings import McpServerOAuth2ProviderOktaSettings from .mcp_server_passthrough import McpServerPassthrough from .mcp_server_provider_account import McpServerProviderAccount from .mcp_server_source import McpServerSource @@ -713,6 +750,9 @@ from .node_selector_capacity_type import NodeSelectorCapacityType from .nodepool import Nodepool from .nodepool_selector import NodepoolSelector + from .noma_security_api_key_auth import NomaSecurityApiKeyAuth + from .noma_security_guardrail_config import NomaSecurityGuardrailConfig + from .noma_security_guardrail_config_config import NomaSecurityGuardrailConfigConfig from .nomic_integrations import NomicIntegrations from .nomic_key_auth import NomicKeyAuth from .nomic_model import NomicModel @@ -808,6 +848,9 @@ from .per_minute_of_audio_cost_metric_value import PerMinuteOfAudioCostMetricValue from .per_thousand_embedding_tokens_cost_metric import PerThousandEmbeddingTokensCostMetric from .per_thousand_tokens_cost_metric import PerThousandTokensCostMetric + from .period_usage_dto import PeriodUsageDto + from .permission_set_v2 import PermissionSetV2 + from .permission_set_v2resource_type import PermissionSetV2ResourceType from .permissions import Permissions from .perplexity_ai_key_auth import PerplexityAiKeyAuth from .perplexity_ai_model import PerplexityAiModel @@ -817,6 +860,7 @@ from .personal_access_token_manifest_token_type import PersonalAccessTokenManifestTokenType from .pip import Pip from .poetry import Poetry + from .policy import Policy from .policy_actions import PolicyActions from .policy_entity_types import PolicyEntityTypes from .policy_filters import PolicyFilters @@ -825,6 +869,7 @@ from .policy_manifest_operation import PolicyManifestOperation from .policy_mutation_operation import PolicyMutationOperation from .policy_validation_operation import PolicyValidationOperation + from .policy_version import PolicyVersion from .port import Port from .port_app_protocol import PortAppProtocol from .port_auth import PortAuth @@ -840,7 +885,11 @@ from .prompt import Prompt from .prompt_source import PromptSource from .prompt_version import PromptVersion + from .provider_account import ProviderAccount + from .provider_account_provider import ProviderAccountProvider from .provider_accounts import ProviderAccounts + from .provider_integration import ProviderIntegration + from .provider_integration_type import ProviderIntegrationType from .public_cost_metric import PublicCostMetric from .py_spark_task_config import PySparkTaskConfig from .py_torch_framework import PyTorchFramework @@ -861,6 +910,7 @@ from .rate_limit_unit import RateLimitUnit from .rate_limit_when import RateLimitWhen from .recommendation import Recommendation + from .redaction import Redaction from .refusal_content_part import RefusalContentPart from .regex_constraint import RegexConstraint from .regex_guardrail_config import RegexGuardrailConfig @@ -871,18 +921,20 @@ from .remote_mcp_server_manifest import RemoteMcpServerManifest from .remote_source import RemoteSource from .remote_spec_source import RemoteSpecSource - from .resource_type import ResourceType from .response_format_json_object import ResponseFormatJsonObject from .response_format_json_schema import ResponseFormatJsonSchema from .response_format_json_schema_json_schema import ResponseFormatJsonSchemaJsonSchema from .response_format_text import ResponseFormatText from .retry_config import RetryConfig from .revoke_all_personal_access_token_response import RevokeAllPersonalAccessTokenResponse + from .role import Role + from .role_binding import RoleBinding from .role_binding_manifest import RoleBindingManifest from .role_binding_permission import RoleBindingPermission from .role_binding_subject import RoleBindingSubject from .role_binding_subject_type import RoleBindingSubjectType from .role_manifest import RoleManifest + from .role_resource_type import RoleResourceType from .role_with_resource import RoleWithResource from .role_with_resource_resource_type import RoleWithResourceResourceType from .rolling import Rolling @@ -930,6 +982,7 @@ from .session_account import SessionAccount from .session_actor import SessionActor from .session_team import SessionTeam + from .settings import Settings from .signed_url import SignedUrl from .sklearn_framework import SklearnFramework from .sklearn_model_schema import SklearnModelSchema @@ -981,6 +1034,7 @@ from .spark_job_python_notebook_entrypoint import SparkJobPythonNotebookEntrypoint from .spark_job_scala_entrypoint import SparkJobScalaEntrypoint from .spark_job_scala_notebook_entrypoint import SparkJobScalaNotebookEntrypoint + from .spark_job_trigger import SparkJobTrigger from .spark_job_trigger_input import SparkJobTriggerInput from .sql_sanitizer_guardrail_config import SqlSanitizerGuardrailConfig from .sql_sanitizer_guardrail_config_config import SqlSanitizerGuardrailConfigConfig @@ -992,6 +1046,8 @@ from .ssh_server import SshServer from .ssh_server_config import SshServerConfig from .stage_artifact_response import StageArtifactResponse + from .static_fallback_strategy import StaticFallbackStrategy + from .static_fallback_strategy_default_tier import StaticFallbackStrategyDefaultTier from .static_volume_config import StaticVolumeConfig from .stats_models_framework import StatsModelsFramework from .stdio_mcp_server_manifest import StdioMcpServerManifest @@ -1005,6 +1061,7 @@ from .subject_condition_group import SubjectConditionGroup from .subject_condition_group_operator import SubjectConditionGroupOperator from .subject_permission import SubjectPermission + from .subject_subject_type import SubjectSubjectType from .subject_type import SubjectType from .sync_token_in_secret_store_info import SyncTokenInSecretStoreInfo from .sync_virtual_account_token_response import SyncVirtualAccountTokenResponse @@ -1049,6 +1106,7 @@ from .tool_message_content import ToolMessageContent from .tool_schema import ToolSchema from .trace_span import TraceSpan + from .tracing_project import TracingProject from .tracing_project_control_plane_managed_storage import TracingProjectControlPlaneManagedStorage from .tracing_project_customer_managed_storage import TracingProjectCustomerManagedStorage from .tracing_project_manifest import TracingProjectManifest @@ -1065,19 +1123,30 @@ from .true_foundry_agent_context_management_config import TrueFoundryAgentContextManagementConfig from .true_foundry_agent_dynamic_sub_agents_config import TrueFoundryAgentDynamicSubAgentsConfig from .true_foundry_agent_generative_ui_config import TrueFoundryAgentGenerativeUiConfig + from .true_foundry_agent_git_source_skill import TrueFoundryAgentGitSourceSkill from .true_foundry_agent_large_tool_response_config import TrueFoundryAgentLargeToolResponseConfig from .true_foundry_agent_manifest import TrueFoundryAgentManifest from .true_foundry_agent_mcp_server import TrueFoundryAgentMcpServer + from .true_foundry_agent_mcp_server_inline import TrueFoundryAgentMcpServerInline + from .true_foundry_agent_mcp_server_registry import TrueFoundryAgentMcpServerRegistry from .true_foundry_agent_model import TrueFoundryAgentModel from .true_foundry_agent_model_params import TrueFoundryAgentModelParams from .true_foundry_agent_response_format import TrueFoundryAgentResponseFormat + from .true_foundry_agent_sandbox_auth_data import TrueFoundryAgentSandboxAuthData + from .true_foundry_agent_sandbox_auth_inject import TrueFoundryAgentSandboxAuthInject + from .true_foundry_agent_sandbox_auth_inject_match import TrueFoundryAgentSandboxAuthInjectMatch + from .true_foundry_agent_sandbox_basic_auth_data import TrueFoundryAgentSandboxBasicAuthData from .true_foundry_agent_sandbox_config import TrueFoundryAgentSandboxConfig + from .true_foundry_agent_sandbox_git_auth_inject import TrueFoundryAgentSandboxGitAuthInject + from .true_foundry_agent_sandbox_network_policy import TrueFoundryAgentSandboxNetworkPolicy from .true_foundry_agent_skill import TrueFoundryAgentSkill + from .true_foundry_agent_true_foundry_skill import TrueFoundryAgentTrueFoundrySkill from .true_foundry_agent_user_message import TrueFoundryAgentUserMessage from .true_foundry_agent_variable import TrueFoundryAgentVariable from .true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest from .true_foundry_apply_response import TrueFoundryApplyResponse from .true_foundry_apply_response_action import TrueFoundryApplyResponseAction + from .true_foundry_apply_response_data import TrueFoundryApplyResponseData from .true_foundry_apply_response_existing_manifest import TrueFoundryApplyResponseExistingManifest from .true_foundry_artifact_source import TrueFoundryArtifactSource from .true_foundry_dbssm import TrueFoundryDbssm @@ -1170,7 +1239,15 @@ "AddonComponentName": ".addon_component_name", "AddonComponentStatus": ".addon_component_status", "Agent": ".agent", + "AgentChannel": ".agent_channel", + "AgentChannelAgent": ".agent_channel_agent", + "AgentChannelConfig": ".agent_channel_config", + "AgentChannelManifest": ".agent_channel_manifest", + "AgentChannelSlackAuth": ".agent_channel_slack_auth", + "AgentChannelSlackBotTokenAuth": ".agent_channel_slack_bot_token_auth", + "AgentChannelSlackConfig": ".agent_channel_slack_config", "AgentFramework": ".agent_framework", + "AgentIdentity": ".agent_identity", "AgentIdentityAutoRotate": ".agent_identity_auto_rotate", "AgentIdentityConfig": ".agent_identity_config", "AgentIdentityManifest": ".agent_identity_manifest", @@ -1198,6 +1275,7 @@ "AktoTokenAuth": ".akto_token_auth", "Alert": ".alert", "AlertConfig": ".alert_config", + "AlertConfigEntity": ".alert_config_entity", "AlertConfigResource": ".alert_config_resource", "AlertConfigResourceType": ".alert_config_resource_type", "AlertSeverity": ".alert_severity", @@ -1340,8 +1418,13 @@ "BlueGreen": ".blue_green", "BudgetAlert": ".budget_alert", "BudgetConfig": ".budget_config", + "BudgetEntityUsageDto": ".budget_entity_usage_dto", "BudgetLimitUnit": ".budget_limit_unit", "BudgetRule": ".budget_rule", + "BudgetUsageEntryDto": ".budget_usage_entry_dto", + "BudgetUsageEntryDtoMode": ".budget_usage_entry_dto_mode", + "BudgetUsageEntryDtoType": ".budget_usage_entry_dto_type", + "BudgetUsageResponseDto": ".budget_usage_response_dto", "BudgetV2Alert": ".budget_v2alert", "BudgetV2AppliesTo": ".budget_v2applies_to", "BudgetV2AppliesToAggregate": ".budget_v2applies_to_aggregate", @@ -1366,7 +1449,6 @@ "BuildBuildSpec": ".build_build_spec", "BuildInfo": ".build_info", "BuildSecret": ".build_secret", - "BuildStatus": ".build_status", "Canary": ".canary", "CanaryStep": ".canary_step", "CartesiaApiKeyAuth": ".cartesia_api_key_auth", @@ -1408,6 +1490,11 @@ "CohereProviderAccount": ".cohere_provider_account", "Collaborator": ".collaborator", "CommonToolsSettings": ".common_tools_settings", + "ComplexityBasedLoadBalanceTarget": ".complexity_based_load_balance_target", + "ComplexityBasedLoadBalanceTargetTier": ".complexity_based_load_balance_target_tier", + "ComplexityBasedLoadBalancing": ".complexity_based_load_balancing", + "ComplexityBasedLoadBalancingClassificationStrategy": ".complexity_based_load_balancing_classification_strategy", + "ComplexityStickyRouting": ".complexity_sticky_routing", "Config": ".config", "ContainerTaskConfig": ".container_task_config", "ContainerTaskConfigImage": ".container_task_config_image", @@ -1481,6 +1568,7 @@ "DeleteWorkspaceResponse": ".delete_workspace_response", "Deployment": ".deployment", "DeploymentBuild": ".deployment_build", + "DeploymentBuildStatus": ".deployment_build_status", "DeploymentManifest": ".deployment_manifest", "DeploymentStatus": ".deployment_status", "DeploymentStatusValue": ".deployment_status_value", @@ -1516,6 +1604,7 @@ "EventInvolvedObject": ".event_involved_object", "ExactMatchCacheConfig": ".exact_match_cache_config", "ExternalBlobStorageSource": ".external_blob_storage_source", + "ExternalIdentityProvider": ".external_identity_provider", "FastAiFramework": ".fast_ai_framework", "FiddlerGuardType": ".fiddler_guard_type", "FiddlerGuardrailConfig": ".fiddler_guardrail_config", @@ -1536,6 +1625,8 @@ "ForwardAction": ".forward_action", "Function": ".function", "FunctionSchema": ".function_schema", + "GatewayBudget": ".gateway_budget", + "GatewayBudgetManifest": ".gateway_budget_manifest", "GatewayConfig": ".gateway_config", "GatewayConfiguration": ".gateway_configuration", "GatewayDataAccessConfig": ".gateway_data_access_config", @@ -1552,9 +1643,8 @@ "GatewayDataRoutingConfigDestinationStorage": ".gateway_data_routing_config_destination_storage", "GatewayDataRoutingConfigDestinationStorageStorage": ".gateway_data_routing_config_destination_storage_storage", "GatewayDataType": ".gateway_data_type", + "GatewayInstallation": ".gateway_installation", "GatewayLoggingConfig": ".gateway_logging_config", - "GatewayLoggingRule": ".gateway_logging_rule", - "GatewayLoggingWhen": ".gateway_logging_when", "GatewayMetadataConfig": ".gateway_metadata_config", "GatewayMetadataRule": ".gateway_metadata_rule", "GatewayMetadataWhen": ".gateway_metadata_when", @@ -1568,6 +1658,7 @@ "GcpGcr": ".gcp_gcr", "GcpGcs": ".gcp_gcs", "GcpGkeIntegration": ".gcp_gke_integration", + "GcpGkeIntegrationLocation": ".gcp_gke_integration_location", "GcpGsm": ".gcp_gsm", "GcpIntegrations": ".gcp_integrations", "GcpKeyFileAuth": ".gcp_key_file_auth", @@ -1577,6 +1668,7 @@ "GcpTpu": ".gcp_tpu", "GeminiModel": ".gemini_model", "GenericSecretStoreIntegration": ".generic_secret_store_integration", + "GetAgentIdentityTokenResponse": ".get_agent_identity_token_response", "GetAgentResponse": ".get_agent_response", "GetAgentSkillResponse": ".get_agent_skill_response", "GetAgentSkillVersionResponse": ".get_agent_skill_version_response", @@ -1670,13 +1762,15 @@ "Helm": ".helm", "HelmRepo": ".helm_repo", "HelmSource": ".helm_source", + "HeuristicClassificationStrategy": ".heuristic_classification_strategy", + "HeuristicFallbackStrategy": ".heuristic_fallback_strategy", "HostedA2AAgent": ".hosted_a2a_agent", "HttpError": ".http_error", "HttpErrorCode": ".http_error_code", "HttpProbe": ".http_probe", "HuggingfaceArtifactSource": ".huggingface_artifact_source", "IChange": ".i_change", - "IChangeOperation": ".i_change_operation", + "IChangeType": ".i_change_type", "IdentityProviderBackedIdentity": ".identity_provider_backed_identity", "IdentityProviderMapping": ".identity_provider_mapping", "Image": ".image", @@ -1684,6 +1778,7 @@ "ImageContentPart": ".image_content_part", "ImageContentPartImageUrl": ".image_content_part_image_url", "ImageContentPartImageUrlUrl": ".image_content_part_image_url_url", + "InNotIn": ".in_not_in", "InNotInOperator": ".in_not_in_operator", "InNotInOperatorCondition": ".in_not_in_operator_condition", "InferMethodName": ".infer_method_name", @@ -1767,6 +1862,8 @@ "ListUsersResponse": ".list_users_response", "ListVirtualAccountResponse": ".list_virtual_account_response", "ListWorkspacesResponse": ".list_workspaces_response", + "LlmClassificationStrategy": ".llm_classification_strategy", + "LlmClassificationStrategyFallbackStrategy": ".llm_classification_strategy_fallback_strategy", "LoadBalanceTarget": ".load_balance_target", "LoadBalancingConfig": ".load_balancing_config", "LoadBalancingRule": ".load_balancing_rule", @@ -1780,12 +1877,17 @@ "LoggingModeAlways": ".logging_mode_always", "LoggingModeHeaderControlled": ".logging_mode_header_controlled", "LoggingModeNever": ".logging_mode_never", + "LoggingWhen": ".logging_when", "LogsResponse": ".logs_response", "LogsSearchFilterType": ".logs_search_filter_type", "LogsSearchOperatorType": ".logs_search_operator_type", "LogsSortingDirection": ".logs_sorting_direction", "Manual": ".manual", + "McpServer": ".mcp_server", "McpServerAuth": ".mcp_server_auth", + "McpServerAuthStatusInfo": ".mcp_server_auth_status_info", + "McpServerAuthStatusInfoMethod": ".mcp_server_auth_status_info_method", + "McpServerAuthStatusInfoStatus": ".mcp_server_auth_status_info_status", "McpServerEnvAuth": ".mcp_server_env_auth", "McpServerEnvAuthAuthLevel": ".mcp_server_env_auth_auth_level", "McpServerHeaderAuth": ".mcp_server_header_auth", @@ -1800,6 +1902,8 @@ "McpServerOAuth2JwtSource": ".mcp_server_o_auth2jwt_source", "McpServerOAuth2Provider": ".mcp_server_o_auth2provider", "McpServerOAuth2ProviderAuth0Settings": ".mcp_server_o_auth2provider_auth0settings", + "McpServerOAuth2ProviderOktaIdJagSettings": ".mcp_server_o_auth2provider_okta_id_jag_settings", + "McpServerOAuth2ProviderOktaSettings": ".mcp_server_o_auth2provider_okta_settings", "McpServerPassthrough": ".mcp_server_passthrough", "McpServerProviderAccount": ".mcp_server_provider_account", "McpServerSource": ".mcp_server_source", @@ -1850,6 +1954,9 @@ "NodeSelectorCapacityType": ".node_selector_capacity_type", "Nodepool": ".nodepool", "NodepoolSelector": ".nodepool_selector", + "NomaSecurityApiKeyAuth": ".noma_security_api_key_auth", + "NomaSecurityGuardrailConfig": ".noma_security_guardrail_config", + "NomaSecurityGuardrailConfigConfig": ".noma_security_guardrail_config_config", "NomicIntegrations": ".nomic_integrations", "NomicKeyAuth": ".nomic_key_auth", "NomicModel": ".nomic_model", @@ -1945,6 +2052,9 @@ "PerMinuteOfAudioCostMetricValue": ".per_minute_of_audio_cost_metric_value", "PerThousandEmbeddingTokensCostMetric": ".per_thousand_embedding_tokens_cost_metric", "PerThousandTokensCostMetric": ".per_thousand_tokens_cost_metric", + "PeriodUsageDto": ".period_usage_dto", + "PermissionSetV2": ".permission_set_v2", + "PermissionSetV2ResourceType": ".permission_set_v2resource_type", "Permissions": ".permissions", "PerplexityAiKeyAuth": ".perplexity_ai_key_auth", "PerplexityAiModel": ".perplexity_ai_model", @@ -1954,6 +2064,7 @@ "PersonalAccessTokenManifestTokenType": ".personal_access_token_manifest_token_type", "Pip": ".pip", "Poetry": ".poetry", + "Policy": ".policy", "PolicyActions": ".policy_actions", "PolicyEntityTypes": ".policy_entity_types", "PolicyFilters": ".policy_filters", @@ -1962,6 +2073,7 @@ "PolicyManifestOperation": ".policy_manifest_operation", "PolicyMutationOperation": ".policy_mutation_operation", "PolicyValidationOperation": ".policy_validation_operation", + "PolicyVersion": ".policy_version", "Port": ".port", "PortAppProtocol": ".port_app_protocol", "PortAuth": ".port_auth", @@ -1977,7 +2089,11 @@ "Prompt": ".prompt", "PromptSource": ".prompt_source", "PromptVersion": ".prompt_version", + "ProviderAccount": ".provider_account", + "ProviderAccountProvider": ".provider_account_provider", "ProviderAccounts": ".provider_accounts", + "ProviderIntegration": ".provider_integration", + "ProviderIntegrationType": ".provider_integration_type", "PublicCostMetric": ".public_cost_metric", "PySparkTaskConfig": ".py_spark_task_config", "PyTorchFramework": ".py_torch_framework", @@ -1998,6 +2114,7 @@ "RateLimitUnit": ".rate_limit_unit", "RateLimitWhen": ".rate_limit_when", "Recommendation": ".recommendation", + "Redaction": ".redaction", "RefusalContentPart": ".refusal_content_part", "RegexConstraint": ".regex_constraint", "RegexGuardrailConfig": ".regex_guardrail_config", @@ -2008,7 +2125,6 @@ "RemoteMcpServerManifest": ".remote_mcp_server_manifest", "RemoteSource": ".remote_source", "RemoteSpecSource": ".remote_spec_source", - "ResourceType": ".resource_type", "Resources": ".resources", "ResourcesDevicesItem": ".resources_devices_item", "ResourcesNode": ".resources_node", @@ -2018,11 +2134,14 @@ "ResponseFormatText": ".response_format_text", "RetryConfig": ".retry_config", "RevokeAllPersonalAccessTokenResponse": ".revoke_all_personal_access_token_response", + "Role": ".role", + "RoleBinding": ".role_binding", "RoleBindingManifest": ".role_binding_manifest", "RoleBindingPermission": ".role_binding_permission", "RoleBindingSubject": ".role_binding_subject", "RoleBindingSubjectType": ".role_binding_subject_type", "RoleManifest": ".role_manifest", + "RoleResourceType": ".role_resource_type", "RoleWithResource": ".role_with_resource", "RoleWithResourceResourceType": ".role_with_resource_resource_type", "Rolling": ".rolling", @@ -2070,6 +2189,7 @@ "SessionAccount": ".session_account", "SessionActor": ".session_actor", "SessionTeam": ".session_team", + "Settings": ".settings", "SignedUrl": ".signed_url", "SklearnFramework": ".sklearn_framework", "SklearnModelSchema": ".sklearn_model_schema", @@ -2121,6 +2241,7 @@ "SparkJobPythonNotebookEntrypoint": ".spark_job_python_notebook_entrypoint", "SparkJobScalaEntrypoint": ".spark_job_scala_entrypoint", "SparkJobScalaNotebookEntrypoint": ".spark_job_scala_notebook_entrypoint", + "SparkJobTrigger": ".spark_job_trigger", "SparkJobTriggerInput": ".spark_job_trigger_input", "SqlSanitizerGuardrailConfig": ".sql_sanitizer_guardrail_config", "SqlSanitizerGuardrailConfigConfig": ".sql_sanitizer_guardrail_config_config", @@ -2132,6 +2253,8 @@ "SshServer": ".ssh_server", "SshServerConfig": ".ssh_server_config", "StageArtifactResponse": ".stage_artifact_response", + "StaticFallbackStrategy": ".static_fallback_strategy", + "StaticFallbackStrategyDefaultTier": ".static_fallback_strategy_default_tier", "StaticVolumeConfig": ".static_volume_config", "StatsModelsFramework": ".stats_models_framework", "StdioMcpServerManifest": ".stdio_mcp_server_manifest", @@ -2145,6 +2268,7 @@ "SubjectConditionGroup": ".subject_condition_group", "SubjectConditionGroupOperator": ".subject_condition_group_operator", "SubjectPermission": ".subject_permission", + "SubjectSubjectType": ".subject_subject_type", "SubjectType": ".subject_type", "SyncTokenInSecretStoreInfo": ".sync_token_in_secret_store_info", "SyncVirtualAccountTokenResponse": ".sync_virtual_account_token_response", @@ -2189,6 +2313,7 @@ "ToolMessageContent": ".tool_message_content", "ToolSchema": ".tool_schema", "TraceSpan": ".trace_span", + "TracingProject": ".tracing_project", "TracingProjectControlPlaneManagedStorage": ".tracing_project_control_plane_managed_storage", "TracingProjectCustomerManagedStorage": ".tracing_project_customer_managed_storage", "TracingProjectManifest": ".tracing_project_manifest", @@ -2205,19 +2330,30 @@ "TrueFoundryAgentContextManagementConfig": ".true_foundry_agent_context_management_config", "TrueFoundryAgentDynamicSubAgentsConfig": ".true_foundry_agent_dynamic_sub_agents_config", "TrueFoundryAgentGenerativeUiConfig": ".true_foundry_agent_generative_ui_config", + "TrueFoundryAgentGitSourceSkill": ".true_foundry_agent_git_source_skill", "TrueFoundryAgentLargeToolResponseConfig": ".true_foundry_agent_large_tool_response_config", "TrueFoundryAgentManifest": ".true_foundry_agent_manifest", "TrueFoundryAgentMcpServer": ".true_foundry_agent_mcp_server", + "TrueFoundryAgentMcpServerInline": ".true_foundry_agent_mcp_server_inline", + "TrueFoundryAgentMcpServerRegistry": ".true_foundry_agent_mcp_server_registry", "TrueFoundryAgentModel": ".true_foundry_agent_model", "TrueFoundryAgentModelParams": ".true_foundry_agent_model_params", "TrueFoundryAgentResponseFormat": ".true_foundry_agent_response_format", + "TrueFoundryAgentSandboxAuthData": ".true_foundry_agent_sandbox_auth_data", + "TrueFoundryAgentSandboxAuthInject": ".true_foundry_agent_sandbox_auth_inject", + "TrueFoundryAgentSandboxAuthInjectMatch": ".true_foundry_agent_sandbox_auth_inject_match", + "TrueFoundryAgentSandboxBasicAuthData": ".true_foundry_agent_sandbox_basic_auth_data", "TrueFoundryAgentSandboxConfig": ".true_foundry_agent_sandbox_config", + "TrueFoundryAgentSandboxGitAuthInject": ".true_foundry_agent_sandbox_git_auth_inject", + "TrueFoundryAgentSandboxNetworkPolicy": ".true_foundry_agent_sandbox_network_policy", "TrueFoundryAgentSkill": ".true_foundry_agent_skill", + "TrueFoundryAgentTrueFoundrySkill": ".true_foundry_agent_true_foundry_skill", "TrueFoundryAgentUserMessage": ".true_foundry_agent_user_message", "TrueFoundryAgentVariable": ".true_foundry_agent_variable", "TrueFoundryApplyRequestManifest": ".true_foundry_apply_request_manifest", "TrueFoundryApplyResponse": ".true_foundry_apply_response", "TrueFoundryApplyResponseAction": ".true_foundry_apply_response_action", + "TrueFoundryApplyResponseData": ".true_foundry_apply_response_data", "TrueFoundryApplyResponseExistingManifest": ".true_foundry_apply_response_existing_manifest", "TrueFoundryArtifactSource": ".true_foundry_artifact_source", "TrueFoundryDbssm": ".true_foundry_dbssm", @@ -2334,7 +2470,15 @@ def __dir__(): "AddonComponentName", "AddonComponentStatus", "Agent", + "AgentChannel", + "AgentChannelAgent", + "AgentChannelConfig", + "AgentChannelManifest", + "AgentChannelSlackAuth", + "AgentChannelSlackBotTokenAuth", + "AgentChannelSlackConfig", "AgentFramework", + "AgentIdentity", "AgentIdentityAutoRotate", "AgentIdentityConfig", "AgentIdentityManifest", @@ -2362,6 +2506,7 @@ def __dir__(): "AktoTokenAuth", "Alert", "AlertConfig", + "AlertConfigEntity", "AlertConfigResource", "AlertConfigResourceType", "AlertSeverity", @@ -2504,8 +2649,13 @@ def __dir__(): "BlueGreen", "BudgetAlert", "BudgetConfig", + "BudgetEntityUsageDto", "BudgetLimitUnit", "BudgetRule", + "BudgetUsageEntryDto", + "BudgetUsageEntryDtoMode", + "BudgetUsageEntryDtoType", + "BudgetUsageResponseDto", "BudgetV2Alert", "BudgetV2AppliesTo", "BudgetV2AppliesToAggregate", @@ -2530,7 +2680,6 @@ def __dir__(): "BuildBuildSpec", "BuildInfo", "BuildSecret", - "BuildStatus", "Canary", "CanaryStep", "CartesiaApiKeyAuth", @@ -2572,6 +2721,11 @@ def __dir__(): "CohereProviderAccount", "Collaborator", "CommonToolsSettings", + "ComplexityBasedLoadBalanceTarget", + "ComplexityBasedLoadBalanceTargetTier", + "ComplexityBasedLoadBalancing", + "ComplexityBasedLoadBalancingClassificationStrategy", + "ComplexityStickyRouting", "Config", "ContainerTaskConfig", "ContainerTaskConfigImage", @@ -2645,6 +2799,7 @@ def __dir__(): "DeleteWorkspaceResponse", "Deployment", "DeploymentBuild", + "DeploymentBuildStatus", "DeploymentManifest", "DeploymentStatus", "DeploymentStatusValue", @@ -2680,6 +2835,7 @@ def __dir__(): "EventInvolvedObject", "ExactMatchCacheConfig", "ExternalBlobStorageSource", + "ExternalIdentityProvider", "FastAiFramework", "FiddlerGuardType", "FiddlerGuardrailConfig", @@ -2700,6 +2856,8 @@ def __dir__(): "ForwardAction", "Function", "FunctionSchema", + "GatewayBudget", + "GatewayBudgetManifest", "GatewayConfig", "GatewayConfiguration", "GatewayDataAccessConfig", @@ -2716,9 +2874,8 @@ def __dir__(): "GatewayDataRoutingConfigDestinationStorage", "GatewayDataRoutingConfigDestinationStorageStorage", "GatewayDataType", + "GatewayInstallation", "GatewayLoggingConfig", - "GatewayLoggingRule", - "GatewayLoggingWhen", "GatewayMetadataConfig", "GatewayMetadataRule", "GatewayMetadataWhen", @@ -2732,6 +2889,7 @@ def __dir__(): "GcpGcr", "GcpGcs", "GcpGkeIntegration", + "GcpGkeIntegrationLocation", "GcpGsm", "GcpIntegrations", "GcpKeyFileAuth", @@ -2741,6 +2899,7 @@ def __dir__(): "GcpTpu", "GeminiModel", "GenericSecretStoreIntegration", + "GetAgentIdentityTokenResponse", "GetAgentResponse", "GetAgentSkillResponse", "GetAgentSkillVersionResponse", @@ -2834,13 +2993,15 @@ def __dir__(): "Helm", "HelmRepo", "HelmSource", + "HeuristicClassificationStrategy", + "HeuristicFallbackStrategy", "HostedA2AAgent", "HttpError", "HttpErrorCode", "HttpProbe", "HuggingfaceArtifactSource", "IChange", - "IChangeOperation", + "IChangeType", "IdentityProviderBackedIdentity", "IdentityProviderMapping", "Image", @@ -2848,6 +3009,7 @@ def __dir__(): "ImageContentPart", "ImageContentPartImageUrl", "ImageContentPartImageUrlUrl", + "InNotIn", "InNotInOperator", "InNotInOperatorCondition", "InferMethodName", @@ -2931,6 +3093,8 @@ def __dir__(): "ListUsersResponse", "ListVirtualAccountResponse", "ListWorkspacesResponse", + "LlmClassificationStrategy", + "LlmClassificationStrategyFallbackStrategy", "LoadBalanceTarget", "LoadBalancingConfig", "LoadBalancingRule", @@ -2944,12 +3108,17 @@ def __dir__(): "LoggingModeAlways", "LoggingModeHeaderControlled", "LoggingModeNever", + "LoggingWhen", "LogsResponse", "LogsSearchFilterType", "LogsSearchOperatorType", "LogsSortingDirection", "Manual", + "McpServer", "McpServerAuth", + "McpServerAuthStatusInfo", + "McpServerAuthStatusInfoMethod", + "McpServerAuthStatusInfoStatus", "McpServerEnvAuth", "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", @@ -2964,6 +3133,8 @@ def __dir__(): "McpServerOAuth2JwtSource", "McpServerOAuth2Provider", "McpServerOAuth2ProviderAuth0Settings", + "McpServerOAuth2ProviderOktaIdJagSettings", + "McpServerOAuth2ProviderOktaSettings", "McpServerPassthrough", "McpServerProviderAccount", "McpServerSource", @@ -3014,6 +3185,9 @@ def __dir__(): "NodeSelectorCapacityType", "Nodepool", "NodepoolSelector", + "NomaSecurityApiKeyAuth", + "NomaSecurityGuardrailConfig", + "NomaSecurityGuardrailConfigConfig", "NomicIntegrations", "NomicKeyAuth", "NomicModel", @@ -3109,6 +3283,9 @@ def __dir__(): "PerMinuteOfAudioCostMetricValue", "PerThousandEmbeddingTokensCostMetric", "PerThousandTokensCostMetric", + "PeriodUsageDto", + "PermissionSetV2", + "PermissionSetV2ResourceType", "Permissions", "PerplexityAiKeyAuth", "PerplexityAiModel", @@ -3118,6 +3295,7 @@ def __dir__(): "PersonalAccessTokenManifestTokenType", "Pip", "Poetry", + "Policy", "PolicyActions", "PolicyEntityTypes", "PolicyFilters", @@ -3126,6 +3304,7 @@ def __dir__(): "PolicyManifestOperation", "PolicyMutationOperation", "PolicyValidationOperation", + "PolicyVersion", "Port", "PortAppProtocol", "PortAuth", @@ -3141,7 +3320,11 @@ def __dir__(): "Prompt", "PromptSource", "PromptVersion", + "ProviderAccount", + "ProviderAccountProvider", "ProviderAccounts", + "ProviderIntegration", + "ProviderIntegrationType", "PublicCostMetric", "PySparkTaskConfig", "PyTorchFramework", @@ -3162,6 +3345,7 @@ def __dir__(): "RateLimitUnit", "RateLimitWhen", "Recommendation", + "Redaction", "RefusalContentPart", "RegexConstraint", "RegexGuardrailConfig", @@ -3172,7 +3356,6 @@ def __dir__(): "RemoteMcpServerManifest", "RemoteSource", "RemoteSpecSource", - "ResourceType", "Resources", "ResourcesDevicesItem", "ResourcesNode", @@ -3182,11 +3365,14 @@ def __dir__(): "ResponseFormatText", "RetryConfig", "RevokeAllPersonalAccessTokenResponse", + "Role", + "RoleBinding", "RoleBindingManifest", "RoleBindingPermission", "RoleBindingSubject", "RoleBindingSubjectType", "RoleManifest", + "RoleResourceType", "RoleWithResource", "RoleWithResourceResourceType", "Rolling", @@ -3234,6 +3420,7 @@ def __dir__(): "SessionAccount", "SessionActor", "SessionTeam", + "Settings", "SignedUrl", "SklearnFramework", "SklearnModelSchema", @@ -3285,6 +3472,7 @@ def __dir__(): "SparkJobPythonNotebookEntrypoint", "SparkJobScalaEntrypoint", "SparkJobScalaNotebookEntrypoint", + "SparkJobTrigger", "SparkJobTriggerInput", "SqlSanitizerGuardrailConfig", "SqlSanitizerGuardrailConfigConfig", @@ -3296,6 +3484,8 @@ def __dir__(): "SshServer", "SshServerConfig", "StageArtifactResponse", + "StaticFallbackStrategy", + "StaticFallbackStrategyDefaultTier", "StaticVolumeConfig", "StatsModelsFramework", "StdioMcpServerManifest", @@ -3309,6 +3499,7 @@ def __dir__(): "SubjectConditionGroup", "SubjectConditionGroupOperator", "SubjectPermission", + "SubjectSubjectType", "SubjectType", "SyncTokenInSecretStoreInfo", "SyncVirtualAccountTokenResponse", @@ -3353,6 +3544,7 @@ def __dir__(): "ToolMessageContent", "ToolSchema", "TraceSpan", + "TracingProject", "TracingProjectControlPlaneManagedStorage", "TracingProjectCustomerManagedStorage", "TracingProjectManifest", @@ -3369,19 +3561,30 @@ def __dir__(): "TrueFoundryAgentContextManagementConfig", "TrueFoundryAgentDynamicSubAgentsConfig", "TrueFoundryAgentGenerativeUiConfig", + "TrueFoundryAgentGitSourceSkill", "TrueFoundryAgentLargeToolResponseConfig", "TrueFoundryAgentManifest", "TrueFoundryAgentMcpServer", + "TrueFoundryAgentMcpServerInline", + "TrueFoundryAgentMcpServerRegistry", "TrueFoundryAgentModel", "TrueFoundryAgentModelParams", "TrueFoundryAgentResponseFormat", + "TrueFoundryAgentSandboxAuthData", + "TrueFoundryAgentSandboxAuthInject", + "TrueFoundryAgentSandboxAuthInjectMatch", + "TrueFoundryAgentSandboxBasicAuthData", "TrueFoundryAgentSandboxConfig", + "TrueFoundryAgentSandboxGitAuthInject", + "TrueFoundryAgentSandboxNetworkPolicy", "TrueFoundryAgentSkill", + "TrueFoundryAgentTrueFoundrySkill", "TrueFoundryAgentUserMessage", "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", "TrueFoundryApplyResponse", "TrueFoundryApplyResponseAction", + "TrueFoundryApplyResponseData", "TrueFoundryApplyResponseExistingManifest", "TrueFoundryArtifactSource", "TrueFoundryDbssm", diff --git a/src/truefoundry_sdk/types/agent.py b/src/truefoundry_sdk/types/agent.py index 751c4a78..338b3fda 100644 --- a/src/truefoundry_sdk/types/agent.py +++ b/src/truefoundry_sdk/types/agent.py @@ -36,6 +36,20 @@ class Agent(UniversalBaseModel): created_by_subject: typing_extensions.Annotated[ Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") ] + manifest: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Copy of the agent manifest (v2). + """ + + agent_identity_id: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="agentIdentityId"), + pydantic.Field(alias="agentIdentityId", description="ID of the agent identity created for this agent."), + ] = None + """ + ID of the agent identity created for this agent. + """ + created_by: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") ] = None diff --git a/src/truefoundry_sdk/types/agent_channel.py b/src/truefoundry_sdk/types/agent_channel.py new file mode 100644 index 00000000..86a66b49 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class AgentChannel(UniversalBaseModel): + id: str = pydantic.Field() + """ + System-generated agent channel id. + """ + + manifest: typing.Dict[str, typing.Any] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/gateway_logging_when.py b/src/truefoundry_sdk/types/agent_channel_agent.py similarity index 70% rename from src/truefoundry_sdk/types/gateway_logging_when.py rename to src/truefoundry_sdk/types/agent_channel_agent.py index f1fc633d..30e42295 100644 --- a/src/truefoundry_sdk/types/gateway_logging_when.py +++ b/src/truefoundry_sdk/types/agent_channel_agent.py @@ -6,14 +6,14 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class GatewayLoggingWhen(UniversalBaseModel): +class AgentChannelAgent(UniversalBaseModel): """ - Rule Conditions + Agent """ - subjects: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + name: str = pydantic.Field() """ - List of subjects that this rule applies to + The name of the agent this channel routes messages to. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/agent_channel_config.py b/src/truefoundry_sdk/types/agent_channel_config.py new file mode 100644 index 00000000..c36b67f1 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel_config.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .agent_channel_slack_config import AgentChannelSlackConfig + +AgentChannelConfig = AgentChannelSlackConfig diff --git a/src/truefoundry_sdk/types/agent_channel_manifest.py b/src/truefoundry_sdk/types/agent_channel_manifest.py new file mode 100644 index 00000000..202d8e31 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel_manifest.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_channel_agent import AgentChannelAgent +from .agent_channel_config import AgentChannelConfig + + +class AgentChannelManifest(UniversalBaseModel): + """ + Expose an agent over a chat channel (e.g. Slack) with no integration code. + """ + + type: typing.Literal["agent-channel"] = pydantic.Field(default="agent-channel") + """ + +value=agent-channel + """ + + name: str = pydantic.Field() + """ + The name of the agent channel. + """ + + agent: AgentChannelAgent + channel: AgentChannelConfig + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/agent_channel_slack_auth.py b/src/truefoundry_sdk/types/agent_channel_slack_auth.py new file mode 100644 index 00000000..ba825ff3 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel_slack_auth.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .agent_channel_slack_bot_token_auth import AgentChannelSlackBotTokenAuth + +AgentChannelSlackAuth = AgentChannelSlackBotTokenAuth diff --git a/src/truefoundry_sdk/types/agent_channel_slack_bot_token_auth.py b/src/truefoundry_sdk/types/agent_channel_slack_bot_token_auth.py new file mode 100644 index 00000000..e47d5570 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel_slack_bot_token_auth.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AgentChannelSlackBotTokenAuth(UniversalBaseModel): + """ + Provide the Slack bot token directly. + """ + + type: typing.Literal["bot-token"] = pydantic.Field(default="bot-token") + """ + +value=bot-token + +uiType=Hidden + """ + + bot_token: str = pydantic.Field() + """ + Slack bot token (xoxb-…) used to post replies. Requires chat:write, chat:write.public. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/agent_channel_slack_config.py b/src/truefoundry_sdk/types/agent_channel_slack_config.py new file mode 100644 index 00000000..4ea6158d --- /dev/null +++ b/src/truefoundry_sdk/types/agent_channel_slack_config.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_channel_slack_auth import AgentChannelSlackAuth + + +class AgentChannelSlackConfig(UniversalBaseModel): + """ + Reach the agent from a Slack app (one Slack app per channel). + """ + + type: typing.Literal["slack"] = pydantic.Field(default="slack") + """ + +uiType=Hidden + +value=slack + """ + + app_id: str = pydantic.Field() + """ + The Slack app id (api_app_id). Inbound events are routed to this channel by app id. + """ + + signing_secret: str = pydantic.Field() + """ + Slack app signing secret, used to verify inbound event request signatures. App-level; common to all auth methods. + """ + + auth: AgentChannelSlackAuth + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/agent_identity.py b/src/truefoundry_sdk/types/agent_identity.py new file mode 100644 index 00000000..51f5175b --- /dev/null +++ b/src/truefoundry_sdk/types/agent_identity.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class AgentIdentity(UniversalBaseModel): + id: typing.Optional[str] = None + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + manifest: typing.Dict[str, typing.Any] = pydantic.Field() + """ + Agent identity manifest + """ + + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + created_at: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] + updated_at: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/agent_identity_manifest.py b/src/truefoundry_sdk/types/agent_identity_manifest.py index 7dc96363..127cd799 100644 --- a/src/truefoundry_sdk/types/agent_identity_manifest.py +++ b/src/truefoundry_sdk/types/agent_identity_manifest.py @@ -28,8 +28,8 @@ class AgentIdentityManifest(UniversalBaseModel): """ owned_by: typing_extensions.Annotated[ - AgentIdentityOwnedBy, FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") - ] + typing.Optional[AgentIdentityOwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/ai21provider_account.py b/src/truefoundry_sdk/types/ai21provider_account.py index bb5c640d..6eac5e38 100644 --- a/src/truefoundry_sdk/types/ai21provider_account.py +++ b/src/truefoundry_sdk/types/ai21provider_account.py @@ -24,18 +24,18 @@ class Ai21ProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the AI21 provider account + The name of the AI21 model account """ auth_data: Ai21KeyAuth integrations: typing.Optional[typing.List[Ai21Integrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the AI21 provider account + List of integrations that are associated with the AI21 model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class Ai21ProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/alert_config_entity.py b/src/truefoundry_sdk/types/alert_config_entity.py new file mode 100644 index 00000000..b2b9e98c --- /dev/null +++ b/src/truefoundry_sdk/types/alert_config_entity.py @@ -0,0 +1,16 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class AlertConfigEntity(UniversalBaseModel): + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/anthropic_provider_account.py b/src/truefoundry_sdk/types/anthropic_provider_account.py index 8e240af4..99be120a 100644 --- a/src/truefoundry_sdk/types/anthropic_provider_account.py +++ b/src/truefoundry_sdk/types/anthropic_provider_account.py @@ -24,18 +24,23 @@ class AnthropicProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Anthropic provider account + The name of the Anthropic model account """ auth_data: typing.Optional[AnthropicKeyAuth] = None + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional custom base URL for the Anthropic API. Must include the version path, e.g. https://my-proxy.example.com/v1. When set, requests are sent here instead of the default https://api.anthropic.com/v1. + """ + integrations: typing.Optional[typing.List[AnthropicIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the Anthropic provider account + List of integrations that are associated with the Anthropic model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +48,7 @@ class AnthropicProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py b/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py index 6008107d..8b57f301 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py +++ b/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py @@ -27,10 +27,15 @@ class AwsBedrockMantleProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the AWS Bedrock Mantle provider account + The name of the AWS Bedrock Mantle model account """ region: AwsRegion + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional custom base URL (e.g. a VPC/PrivateLink endpoint) for AWS Bedrock Mantle. When set, requests are sent here instead of the default bedrock-mantle.{region}.api.aws host. + """ + auth_data: typing.Optional[AwsBedrockMantleProviderAccountAuthData] = pydantic.Field(default=None) """ Authentication data for the AWS account @@ -38,12 +43,12 @@ class AwsBedrockMantleProviderAccount(UniversalBaseModel): integrations: typing.List[AwsBedrockMantleIntegrations] = pydantic.Field() """ - List of integrations that are associated with the AWS Bedrock Mantle provider account + List of integrations that are associated with the AWS Bedrock Mantle model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -51,7 +56,7 @@ class AwsBedrockMantleProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/aws_bedrock_provider_account.py b/src/truefoundry_sdk/types/aws_bedrock_provider_account.py index bac1a9fc..05414627 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_provider_account.py +++ b/src/truefoundry_sdk/types/aws_bedrock_provider_account.py @@ -25,10 +25,15 @@ class AwsBedrockProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the AWS Bedrock provider account + The name of the AWS Bedrock model account """ region: AwsRegion + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional custom base URL (e.g. a VPC/PrivateLink endpoint) for AWS Bedrock. When set, requests are sent here instead of the default bedrock-runtime.{region}.amazonaws.com host. + """ + auth_data: typing.Optional[AwsBedrockProviderAccountAuthData] = pydantic.Field(default=None) """ Authentication data for the AWS account @@ -36,12 +41,12 @@ class AwsBedrockProviderAccount(UniversalBaseModel): integrations: typing.List[BedrockModel] = pydantic.Field() """ - List of integrations that are associated with the AWS Bedrock provider account + List of integrations that are associated with the AWS Bedrock model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -49,7 +54,7 @@ class AwsBedrockProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/aws_claude_platform_provider_account.py b/src/truefoundry_sdk/types/aws_claude_platform_provider_account.py index a5158a98..e2947d4c 100644 --- a/src/truefoundry_sdk/types/aws_claude_platform_provider_account.py +++ b/src/truefoundry_sdk/types/aws_claude_platform_provider_account.py @@ -27,7 +27,7 @@ class AwsClaudePlatformProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the AWS Claude Platform provider account + The name of the AWS Claude Platform model account """ workspace_id: str = pydantic.Field() @@ -36,6 +36,11 @@ class AwsClaudePlatformProviderAccount(UniversalBaseModel): """ region: AwsRegion + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional custom base URL (e.g. a VPC/PrivateLink endpoint) for Claude Platform on AWS. Must include the version path, e.g. https://my-endpoint.example.com/v1. When set, requests are sent here instead of the default aws-external-anthropic.{region}.api.aws/v1 host. + """ + auth_data: typing.Optional[AwsClaudePlatformProviderAccountAuthData] = pydantic.Field(default=None) """ Authentication data for the AWS account. Supports SigV4 (access key or assumed role) and API key authentication. @@ -43,12 +48,12 @@ class AwsClaudePlatformProviderAccount(UniversalBaseModel): integrations: typing.Optional[typing.List[AwsClaudePlatformIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the AWS Claude Platform provider account + List of integrations that are associated with the AWS Claude Platform model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -56,7 +61,7 @@ class AwsClaudePlatformProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py b/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py index 734774ab..82f67355 100644 --- a/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py +++ b/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py @@ -25,7 +25,7 @@ class AwsSagemakerProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Sagemaker provider account + The name of the Sagemaker model account """ region: AwsRegion @@ -36,12 +36,12 @@ class AwsSagemakerProviderAccount(UniversalBaseModel): integrations: typing.List[SagemakerModel] = pydantic.Field() """ - List of integrations that are associated with the Sagemaker provider account + List of integrations that are associated with the Sagemaker model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -49,7 +49,7 @@ class AwsSagemakerProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/azure_foundry_provider_account.py b/src/truefoundry_sdk/types/azure_foundry_provider_account.py index b6638236..0758ebe4 100644 --- a/src/truefoundry_sdk/types/azure_foundry_provider_account.py +++ b/src/truefoundry_sdk/types/azure_foundry_provider_account.py @@ -13,7 +13,7 @@ class AzureFoundryProviderAccount(UniversalBaseModel): """ - Azure AI Foundry Provider Account + Azure AI Foundry Model Account """ type: typing.Literal["provider-account/azure-foundry"] = pydantic.Field(default="provider-account/azure-foundry") @@ -23,17 +23,17 @@ class AzureFoundryProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Azure AI Foundry provider account + The name of the Azure AI Foundry model account """ integrations: typing.List[AzureFoundryModel] = pydantic.Field() """ - List of integrations that are associated with the Azure Foundry provider account + List of integrations that are associated with the Azure Foundry model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -41,7 +41,7 @@ class AzureFoundryProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/azure_open_ai_provider_account.py b/src/truefoundry_sdk/types/azure_open_ai_provider_account.py index 6616242a..6f3f8a46 100644 --- a/src/truefoundry_sdk/types/azure_open_ai_provider_account.py +++ b/src/truefoundry_sdk/types/azure_open_ai_provider_account.py @@ -14,7 +14,7 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): """ - Azure OpenAI Provider Account + Azure OpenAI Model Account """ type: typing.Literal["provider-account/azure-openai"] = pydantic.Field(default="provider-account/azure-openai") @@ -24,7 +24,7 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Azure OpenAI provider account + The name of the Azure OpenAI model account """ azure_endpoint: str = pydantic.Field() @@ -39,12 +39,12 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): integrations: typing.List[AzureOpenAiModel] = pydantic.Field() """ - List of integrations that are associated with the Azure OpenAI provider account + List of integrations that are associated with the Azure OpenAI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -52,7 +52,7 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/baseten_provider_account.py b/src/truefoundry_sdk/types/baseten_provider_account.py index c8e130d8..c17c52ff 100644 --- a/src/truefoundry_sdk/types/baseten_provider_account.py +++ b/src/truefoundry_sdk/types/baseten_provider_account.py @@ -24,18 +24,18 @@ class BasetenProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Baseten provider account + The name of the Baseten model account """ auth_data: BasetenKeyAuth integrations: typing.Optional[typing.List[BasetenIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the Baseten provider account + List of integrations that are associated with the Baseten model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class BasetenProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/budget_entity_usage_dto.py b/src/truefoundry_sdk/types/budget_entity_usage_dto.py new file mode 100644 index 00000000..b4a932cd --- /dev/null +++ b/src/truefoundry_sdk/types/budget_entity_usage_dto.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .period_usage_dto import PeriodUsageDto + + +class BudgetEntityUsageDto(UniversalBaseModel): + entity: typing.Optional[str] = pydantic.Field(default=None) + """ + Entity counter this usage maps to; null for aggregate budgets. + """ + + periods: typing.Dict[str, PeriodUsageDto] = pydantic.Field() + """ + Per-period usage keyed by period (cost_per_day, cost_per_month, ...). + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto.py b/src/truefoundry_sdk/types/budget_usage_entry_dto.py new file mode 100644 index 00000000..640ad1bc --- /dev/null +++ b/src/truefoundry_sdk/types/budget_usage_entry_dto.py @@ -0,0 +1,49 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .budget_entity_usage_dto import BudgetEntityUsageDto +from .budget_usage_entry_dto_mode import BudgetUsageEntryDtoMode +from .budget_usage_entry_dto_type import BudgetUsageEntryDtoType + + +class BudgetUsageEntryDto(UniversalBaseModel): + name: str = pydantic.Field() + """ + Human-readable name of the budget. + """ + + type: BudgetUsageEntryDtoType = pydantic.Field() + """ + Budget type. + """ + + team_name: typing.Optional[str] = pydantic.Field(default=None) + """ + Team that owns the budget; null for tenant-budget-config. + """ + + applies_to: str = pydantic.Field() + """ + How counters are partitioned (per-user, per-model, per-virtual-account, aggregate, or metadata:). + """ + + mode: BudgetUsageEntryDtoMode = pydantic.Field() + """ + Budget mode. + """ + + entities: typing.List[BudgetEntityUsageDto] = pydantic.Field() + """ + Per-entity usage for this budget. For my-usage and simulate this contains a single entity; leaderboard-style endpoints may return many. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py b/src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py new file mode 100644 index 00000000..a8cc75dd --- /dev/null +++ b/src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class BudgetUsageEntryDtoMode(enum.StrEnum): + """ + Budget mode. + """ + + ENFORCE = "enforce" + AUDIT = "audit" + ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" + _UNKNOWN = "__BUDGETUSAGEENTRYDTOMODE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryDtoMode": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + enforce: typing.Callable[[], T_Result], + audit: typing.Callable[[], T_Result], + enforce_with_low_priority: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is BudgetUsageEntryDtoMode.ENFORCE: + return enforce() + if self is BudgetUsageEntryDtoMode.AUDIT: + return audit() + if self is BudgetUsageEntryDtoMode.ENFORCE_WITH_LOW_PRIORITY: + return enforce_with_low_priority() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto_type.py b/src/truefoundry_sdk/types/budget_usage_entry_dto_type.py new file mode 100644 index 00000000..1078aeb6 --- /dev/null +++ b/src/truefoundry_sdk/types/budget_usage_entry_dto_type.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class BudgetUsageEntryDtoType(enum.StrEnum): + """ + Budget type. + """ + + TENANT_BUDGET_CONFIG = "tenant-budget-config" + TEAM_BUDGET_CONFIG = "team-budget-config" + _UNKNOWN = "__BUDGETUSAGEENTRYDTOTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryDtoType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + tenant_budget_config: typing.Callable[[], T_Result], + team_budget_config: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is BudgetUsageEntryDtoType.TENANT_BUDGET_CONFIG: + return tenant_budget_config() + if self is BudgetUsageEntryDtoType.TEAM_BUDGET_CONFIG: + return team_budget_config() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/budget_usage_response_dto.py b/src/truefoundry_sdk/types/budget_usage_response_dto.py new file mode 100644 index 00000000..ccc7c699 --- /dev/null +++ b/src/truefoundry_sdk/types/budget_usage_response_dto.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .budget_usage_entry_dto import BudgetUsageEntryDto + + +class BudgetUsageResponseDto(UniversalBaseModel): + matched: typing.List[BudgetUsageEntryDto] = pydantic.Field() + """ + Budgets that apply, with current usage. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/budget_v2alert.py b/src/truefoundry_sdk/types/budget_v2alert.py index 5938e2bf..391c830f 100644 --- a/src/truefoundry_sdk/types/budget_v2alert.py +++ b/src/truefoundry_sdk/types/budget_v2alert.py @@ -17,11 +17,6 @@ class BudgetV2Alert(UniversalBaseModel): List of usage percentages (0-100) at which alerts should be triggered. Default thresholds are [75, 90, 95, 100]. """ - notify_breaching_user: typing.Optional[bool] = pydantic.Field(default=False) - """ - Notify the user who caused the breach. Only applies to per-user budgets. - """ - notification_target: typing.Optional[typing.List[NotificationTarget]] = pydantic.Field(default=None) """ Select where to send budget alert notifications diff --git a/src/truefoundry_sdk/types/budget_v2limits.py b/src/truefoundry_sdk/types/budget_v2limits.py index e054d5e0..e7d6ace3 100644 --- a/src/truefoundry_sdk/types/budget_v2limits.py +++ b/src/truefoundry_sdk/types/budget_v2limits.py @@ -31,6 +31,11 @@ class BudgetV2Limits(UniversalBaseModel): Maximum quarterly cost in USD """ + cost_per_lifetime: typing.Optional[float] = pydantic.Field(default=None) + """ + Maximum lifetime cost in USD. Mutually exclusive with the day/week/month/quarter limits. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/budget_v2override_limits.py b/src/truefoundry_sdk/types/budget_v2override_limits.py index ff230f90..bf752b8b 100644 --- a/src/truefoundry_sdk/types/budget_v2override_limits.py +++ b/src/truefoundry_sdk/types/budget_v2override_limits.py @@ -31,6 +31,11 @@ class BudgetV2OverrideLimits(UniversalBaseModel): Override quarterly cost cap in USD """ + cost_per_lifetime: typing.Optional[float] = pydantic.Field(default=None) + """ + Override lifetime cost cap in USD + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/budget_v2when_team_scoped.py b/src/truefoundry_sdk/types/budget_v2when_team_scoped.py index ed666b56..e2bb2625 100644 --- a/src/truefoundry_sdk/types/budget_v2when_team_scoped.py +++ b/src/truefoundry_sdk/types/budget_v2when_team_scoped.py @@ -15,6 +15,7 @@ class BudgetV2WhenTeamScoped(UniversalBaseModel): subjects: typing.Optional[BudgetV2SubjectsTeamScoped] = None models: typing.Optional[BudgetV2InNotInFilter] = None + provider_accounts: typing.Optional[BudgetV2InNotInFilter] = None metadata: typing.Optional[typing.Dict[str, BudgetV2InNotInFilter]] = pydantic.Field(default=None) """ Filter by metadata key-value pairs this budget applies to diff --git a/src/truefoundry_sdk/types/budget_v2when_tenant_scoped.py b/src/truefoundry_sdk/types/budget_v2when_tenant_scoped.py index eeab56c3..6bc22e11 100644 --- a/src/truefoundry_sdk/types/budget_v2when_tenant_scoped.py +++ b/src/truefoundry_sdk/types/budget_v2when_tenant_scoped.py @@ -15,6 +15,7 @@ class BudgetV2WhenTenantScoped(UniversalBaseModel): subjects: typing.Optional[BudgetV2SubjectsTenantScoped] = None models: typing.Optional[BudgetV2InNotInFilter] = None + provider_accounts: typing.Optional[BudgetV2InNotInFilter] = None metadata: typing.Optional[typing.Dict[str, BudgetV2InNotInFilter]] = pydantic.Field(default=None) """ Filter by metadata key-value pairs this budget applies to diff --git a/src/truefoundry_sdk/types/cartesia_provider_account.py b/src/truefoundry_sdk/types/cartesia_provider_account.py index b5eb5801..a894aa9f 100644 --- a/src/truefoundry_sdk/types/cartesia_provider_account.py +++ b/src/truefoundry_sdk/types/cartesia_provider_account.py @@ -15,7 +15,7 @@ class CartesiaProviderAccount(UniversalBaseModel): """ - Cartesia Provider Account + Cartesia Model Account """ type: typing.Literal["provider-account/cartesia"] = pydantic.Field(default="provider-account/cartesia") @@ -25,7 +25,7 @@ class CartesiaProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Cartesia provider account + The name of the Cartesia model account """ base_url: typing.Optional[str] = pydantic.Field(default=None) @@ -41,12 +41,12 @@ class CartesiaProviderAccount(UniversalBaseModel): auth_data: CartesiaApiKeyAuth integrations: typing.List[CartesiaModel] = pydantic.Field() """ - List of integrations that are associated with the Cartesia provider account + List of integrations that are associated with the Cartesia model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -54,7 +54,7 @@ class CartesiaProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/cerebras_provider_account.py b/src/truefoundry_sdk/types/cerebras_provider_account.py index c15cfee5..c5a071b2 100644 --- a/src/truefoundry_sdk/types/cerebras_provider_account.py +++ b/src/truefoundry_sdk/types/cerebras_provider_account.py @@ -14,7 +14,7 @@ class CerebrasProviderAccount(UniversalBaseModel): """ - Cerebras Provider Account + Cerebras Model Account """ type: typing.Literal["provider-account/cerebras"] = pydantic.Field(default="provider-account/cerebras") @@ -24,18 +24,18 @@ class CerebrasProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Cerebras provider account + The name of the Cerebras model account """ auth_data: CerebrasKeyAuth integrations: typing.Optional[typing.List[CerebrasIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the Cerebras provider account + List of integrations that are associated with the Cerebras model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class CerebrasProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/cloudera_provider_account.py b/src/truefoundry_sdk/types/cloudera_provider_account.py index e3909737..c49b360f 100644 --- a/src/truefoundry_sdk/types/cloudera_provider_account.py +++ b/src/truefoundry_sdk/types/cloudera_provider_account.py @@ -14,7 +14,7 @@ class ClouderaProviderAccount(UniversalBaseModel): """ - Cloudera Provider Account + Cloudera Model Account """ type: typing.Literal["provider-account/cloudera"] = pydantic.Field(default="provider-account/cloudera") @@ -24,7 +24,7 @@ class ClouderaProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Cloudera provider account + The name of the Cloudera model account """ auth_data: ClouderaProviderAccountAuthData = pydantic.Field() @@ -34,12 +34,12 @@ class ClouderaProviderAccount(UniversalBaseModel): integrations: typing.List[ClouderaIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Cloudera provider account + List of integrations that are associated with the Cloudera model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -47,7 +47,7 @@ class ClouderaProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/cohere_provider_account.py b/src/truefoundry_sdk/types/cohere_provider_account.py index c536e422..9c0df4f4 100644 --- a/src/truefoundry_sdk/types/cohere_provider_account.py +++ b/src/truefoundry_sdk/types/cohere_provider_account.py @@ -14,7 +14,7 @@ class CohereProviderAccount(UniversalBaseModel): """ - Cohere Provider Account + Cohere Model Account """ type: typing.Literal["provider-account/cohere"] = pydantic.Field(default="provider-account/cohere") @@ -24,18 +24,18 @@ class CohereProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Cohere provider account + The name of the Cohere model account """ auth_data: CohereKeyAuth integrations: typing.Optional[typing.List[CohereIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the Cohere provider account + List of integrations that are associated with the Cohere model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class CohereProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/complexity_based_load_balance_target.py b/src/truefoundry_sdk/types/complexity_based_load_balance_target.py new file mode 100644 index 00000000..7f3c802a --- /dev/null +++ b/src/truefoundry_sdk/types/complexity_based_load_balance_target.py @@ -0,0 +1,55 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .complexity_based_load_balance_target_tier import ComplexityBasedLoadBalanceTargetTier +from .headers_override import HeadersOverride +from .retry_config import RetryConfig + + +class ComplexityBasedLoadBalanceTarget(UniversalBaseModel): + """ + A target model together with the single complexity tier it serves. A model may appear at most once across a rule's targets (one model cannot serve more than one tier). + """ + + target: str = pydantic.Field() + """ + Target model or provider FQN + """ + + tier: ComplexityBasedLoadBalanceTargetTier = pydantic.Field() + """ + Complexity tier this target serves. Each target serves exactly one tier; a model must not be listed under more than one tier. + """ + + retry_config: typing.Optional[RetryConfig] = None + fallback_status_codes: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Status Codes for which the request will fallback to other tiers. If the status code is not present in fallback_status_codes, it fails immediately. + """ + + fallback_candidate: typing.Optional[bool] = pydantic.Field(default=True) + """ + Whether this target is a fallback candidate. If set to false, this model will not be considered as a fallback option for other tiers of this rule. + """ + + override_params: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Optional parameters to override in the request + """ + + headers_override: typing.Optional[HeadersOverride] = None + metadata_match: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Optional metadata key-value pairs that must match incoming request metadata headers for this target to be considered for routing. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/complexity_based_load_balance_target_tier.py b/src/truefoundry_sdk/types/complexity_based_load_balance_target_tier.py new file mode 100644 index 00000000..5ad1eb67 --- /dev/null +++ b/src/truefoundry_sdk/types/complexity_based_load_balance_target_tier.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class ComplexityBasedLoadBalanceTargetTier(enum.StrEnum): + """ + Complexity tier this target serves. Each target serves exactly one tier; a model must not be listed under more than one tier. + """ + + SIMPLE = "simple" + MEDIUM = "medium" + COMPLEX = "complex" + _UNKNOWN = "__COMPLEXITYBASEDLOADBALANCETARGETTIER_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "ComplexityBasedLoadBalanceTargetTier": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + simple: typing.Callable[[], T_Result], + medium: typing.Callable[[], T_Result], + complex_: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is ComplexityBasedLoadBalanceTargetTier.SIMPLE: + return simple() + if self is ComplexityBasedLoadBalanceTargetTier.MEDIUM: + return medium() + if self is ComplexityBasedLoadBalanceTargetTier.COMPLEX: + return complex_() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/complexity_based_load_balancing.py b/src/truefoundry_sdk/types/complexity_based_load_balancing.py new file mode 100644 index 00000000..08b4765a --- /dev/null +++ b/src/truefoundry_sdk/types/complexity_based_load_balancing.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .complexity_based_load_balance_target import ComplexityBasedLoadBalanceTarget +from .complexity_based_load_balancing_classification_strategy import ComplexityBasedLoadBalancingClassificationStrategy +from .complexity_sticky_routing import ComplexityStickyRouting + + +class ComplexityBasedLoadBalancing(UniversalBaseModel): + """ + Complexity-based Load Balancing + """ + + type: typing.Literal["complexity-based-routing"] = pydantic.Field(default="complexity-based-routing") + """ + Routing Type + """ + + classification_strategy: typing.Optional[ComplexityBasedLoadBalancingClassificationStrategy] = pydantic.Field( + default=None + ) + """ + How requests are classified into complexity tiers. Defaults to the heuristic classifier. + """ + + load_balance_targets: typing.List[ComplexityBasedLoadBalanceTarget] = pydantic.Field() + """ + List of targets for complexity-based load balancing. Each target serves a single tier; a model must not appear under more than one tier. + """ + + sticky_routing: typing.Optional[ComplexityStickyRouting] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/complexity_based_load_balancing_classification_strategy.py b/src/truefoundry_sdk/types/complexity_based_load_balancing_classification_strategy.py new file mode 100644 index 00000000..c49bc72c --- /dev/null +++ b/src/truefoundry_sdk/types/complexity_based_load_balancing_classification_strategy.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .heuristic_classification_strategy import HeuristicClassificationStrategy +from .llm_classification_strategy import LlmClassificationStrategy + +ComplexityBasedLoadBalancingClassificationStrategy = typing.Union[ + HeuristicClassificationStrategy, LlmClassificationStrategy +] diff --git a/src/truefoundry_sdk/types/complexity_sticky_routing.py b/src/truefoundry_sdk/types/complexity_sticky_routing.py new file mode 100644 index 00000000..11758dd8 --- /dev/null +++ b/src/truefoundry_sdk/types/complexity_sticky_routing.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .sticky_session_identifier import StickySessionIdentifier + + +class ComplexityStickyRouting(UniversalBaseModel): + """ + Sticky routing for complexity-based routing. A session is pinned to the tier/target chosen on its first classified turn for up to ttl_seconds (5 minutes to 1 hour). + """ + + ttl_seconds: int = pydantic.Field() + """ + Sticky mapping TTL in seconds. Minimum 5 minutes, maximum 1 hour. + """ + + session_identifiers: typing.List[StickySessionIdentifier] = pydantic.Field() + """ + List of identifier selectors used to build sticky key + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_endpoint_provider_account.py b/src/truefoundry_sdk/types/custom_endpoint_provider_account.py index 9a5d4bfb..8f81859c 100644 --- a/src/truefoundry_sdk/types/custom_endpoint_provider_account.py +++ b/src/truefoundry_sdk/types/custom_endpoint_provider_account.py @@ -28,7 +28,7 @@ class CustomEndpointProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the custom endpoint provider account. + The name of the custom endpoint model account. """ endpoint_type: typing.Optional[CustomEndpointProviderAccountEndpointType] = pydantic.Field(default=None) @@ -49,7 +49,7 @@ class CustomEndpointProviderAccount(UniversalBaseModel): auth_data: typing.Optional[CustomHeaderAuth] = None integrations: typing.List[CustomEndpointIntegrations] = pydantic.Field() """ - List of endpoint integrations associated with this provider account. + List of endpoint integrations associated with this model account. """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) diff --git a/src/truefoundry_sdk/types/databricks_provider_account.py b/src/truefoundry_sdk/types/databricks_provider_account.py index 14e2f550..997efb2b 100644 --- a/src/truefoundry_sdk/types/databricks_provider_account.py +++ b/src/truefoundry_sdk/types/databricks_provider_account.py @@ -14,7 +14,7 @@ class DatabricksProviderAccount(UniversalBaseModel): """ - Databricks Provider Account + Databricks Model Account """ type: typing.Literal["provider-account/databricks"] = pydantic.Field(default="provider-account/databricks") @@ -24,7 +24,7 @@ class DatabricksProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Databricks provider account + The name of the Databricks model account """ auth_data: DatabricksProviderAccountAuthData = pydantic.Field() @@ -39,12 +39,12 @@ class DatabricksProviderAccount(UniversalBaseModel): integrations: typing.List[DatabricksIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Databricks provider account + List of integrations that are associated with the Databricks model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -52,7 +52,7 @@ class DatabricksProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/deepgram_provider_account.py b/src/truefoundry_sdk/types/deepgram_provider_account.py index df596469..384eff85 100644 --- a/src/truefoundry_sdk/types/deepgram_provider_account.py +++ b/src/truefoundry_sdk/types/deepgram_provider_account.py @@ -14,7 +14,7 @@ class DeepgramProviderAccount(UniversalBaseModel): """ - Deepgram Provider Account + Deepgram Model Account """ type: typing.Literal["provider-account/deepgram"] = pydantic.Field(default="provider-account/deepgram") @@ -24,7 +24,7 @@ class DeepgramProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Deepgram provider account + The name of the Deepgram model account """ auth_data: DeepgramApiKeyAuth @@ -35,12 +35,12 @@ class DeepgramProviderAccount(UniversalBaseModel): integrations: typing.List[DeepgramModel] = pydantic.Field() """ - List of integrations that are associated with the Deepgram provider account + List of integrations that are associated with the Deepgram model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -48,7 +48,7 @@ class DeepgramProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/deepinfra_provider_account.py b/src/truefoundry_sdk/types/deepinfra_provider_account.py index ccdb6a5a..94cc9226 100644 --- a/src/truefoundry_sdk/types/deepinfra_provider_account.py +++ b/src/truefoundry_sdk/types/deepinfra_provider_account.py @@ -14,7 +14,7 @@ class DeepinfraProviderAccount(UniversalBaseModel): """ - DeepInfra Provider Account + DeepInfra Model Account """ type: typing.Literal["provider-account/deepinfra"] = pydantic.Field(default="provider-account/deepinfra") @@ -24,18 +24,18 @@ class DeepinfraProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the DeepInfra provider account + The name of the DeepInfra model account """ auth_data: DeepinfraKeyAuth integrations: typing.Optional[typing.List[DeepinfraIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the DeepInfra provider account + List of integrations that are associated with the DeepInfra model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class DeepinfraProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/deployment_build.py b/src/truefoundry_sdk/types/deployment_build.py index 629b8486..03f6b8b7 100644 --- a/src/truefoundry_sdk/types/deployment_build.py +++ b/src/truefoundry_sdk/types/deployment_build.py @@ -8,7 +8,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata from .build_info import BuildInfo -from .build_status import BuildStatus +from .deployment_build_status import DeploymentBuildStatus class DeploymentBuild(UniversalBaseModel): @@ -27,7 +27,7 @@ class DeploymentBuild(UniversalBaseModel): typing.Optional[str], FieldMetadata(alias="imageUri"), pydantic.Field(alias="imageUri") ] = None name: typing.Optional[str] = None - status: typing.Optional[BuildStatus] = None + status: typing.Optional[DeploymentBuildStatus] = None get_logs_url: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="getLogsUrl"), pydantic.Field(alias="getLogsUrl") ] = None diff --git a/src/truefoundry_sdk/types/build_status.py b/src/truefoundry_sdk/types/deployment_build_status.py similarity index 73% rename from src/truefoundry_sdk/types/build_status.py rename to src/truefoundry_sdk/types/deployment_build_status.py index 21488f56..adf58664 100644 --- a/src/truefoundry_sdk/types/build_status.py +++ b/src/truefoundry_sdk/types/deployment_build_status.py @@ -7,17 +7,17 @@ T_Result = typing.TypeVar("T_Result") -class BuildStatus(enum.StrEnum): +class DeploymentBuildStatus(enum.StrEnum): STARTED = "STARTED" SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" - _UNKNOWN = "__BUILDSTATUS_UNKNOWN__" + _UNKNOWN = "__DEPLOYMENTBUILDSTATUS_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "BuildStatus": + def _missing_(cls, value: typing.Any) -> "DeploymentBuildStatus": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -29,10 +29,10 @@ def visit( failed: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is BuildStatus.STARTED: + if self is DeploymentBuildStatus.STARTED: return started() - if self is BuildStatus.SUCCEEDED: + if self is DeploymentBuildStatus.SUCCEEDED: return succeeded() - if self is BuildStatus.FAILED: + if self is DeploymentBuildStatus.FAILED: return failed() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/eleven_labs_provider_account.py b/src/truefoundry_sdk/types/eleven_labs_provider_account.py index 8093ab87..4731a134 100644 --- a/src/truefoundry_sdk/types/eleven_labs_provider_account.py +++ b/src/truefoundry_sdk/types/eleven_labs_provider_account.py @@ -14,7 +14,7 @@ class ElevenLabsProviderAccount(UniversalBaseModel): """ - ElevenLabs Provider Account + ElevenLabs Model Account """ type: typing.Literal["provider-account/elevenlabs"] = pydantic.Field(default="provider-account/elevenlabs") @@ -24,7 +24,7 @@ class ElevenLabsProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the ElevenLabs provider account + The name of the ElevenLabs model account """ auth_data: ElevenLabsApiKeyAuth @@ -35,12 +35,12 @@ class ElevenLabsProviderAccount(UniversalBaseModel): integrations: typing.List[ElevenLabsModel] = pydantic.Field() """ - List of integrations that are associated with the ElevenLabs provider account + List of integrations that are associated with the ElevenLabs model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -48,7 +48,7 @@ class ElevenLabsProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/external_identity_provider.py b/src/truefoundry_sdk/types/external_identity_provider.py new file mode 100644 index 00000000..ced09872 --- /dev/null +++ b/src/truefoundry_sdk/types/external_identity_provider.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class ExternalIdentityProvider(UniversalBaseModel): + id: typing.Optional[str] = None + fqn: str + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + manifest: typing.Dict[str, typing.Any] = pydantic.Field() + """ + External identity provider manifest + """ + + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/gateway_budget.py b/src/truefoundry_sdk/types/gateway_budget.py new file mode 100644 index 00000000..e9e71788 --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_budget.py @@ -0,0 +1,77 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .gateway_budget_manifest import GatewayBudgetManifest +from .subject import Subject + + +class GatewayBudget(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + System-generated Budget ID. + """ + + tenant_name: typing_extensions.Annotated[ + str, + FieldMetadata(alias="tenantName"), + pydantic.Field(alias="tenantName", description="Tenant the budget belongs to."), + ] + """ + Tenant the budget belongs to. + """ + + name: str = pydantic.Field() + """ + Budget name (unique per tenant). + """ + + type: str = pydantic.Field() + """ + Budget type (tenant-budget-config | team-budget-config). + """ + + manifest: GatewayBudgetManifest = pydantic.Field() + """ + The budget manifest. + """ + + created_by_subject: typing_extensions.Annotated[ + Subject, + FieldMetadata(alias="createdBySubject"), + pydantic.Field(alias="createdBySubject", description="Principal that created or last updated this budget."), + ] + """ + Principal that created or last updated this budget. + """ + + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], + FieldMetadata(alias="createdAt"), + pydantic.Field(alias="createdAt", description="Creation timestamp."), + ] = None + """ + Creation timestamp. + """ + + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], + FieldMetadata(alias="updatedAt"), + pydantic.Field(alias="updatedAt", description="Last-update timestamp."), + ] = None + """ + Last-update timestamp. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/gateway_budget_manifest.py b/src/truefoundry_sdk/types/gateway_budget_manifest.py new file mode 100644 index 00000000..67e04ec4 --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_budget_manifest.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .team_budget_config import TeamBudgetConfig +from .tenant_budget_config import TenantBudgetConfig + +GatewayBudgetManifest = typing.Union[TenantBudgetConfig, TeamBudgetConfig] diff --git a/src/truefoundry_sdk/types/gateway_config.py b/src/truefoundry_sdk/types/gateway_config.py index 720ea765..acdd9163 100644 --- a/src/truefoundry_sdk/types/gateway_config.py +++ b/src/truefoundry_sdk/types/gateway_config.py @@ -24,8 +24,8 @@ TeamBudgetConfig, GatewayOtelConfig, GatewayMetadataConfig, - GatewayLoggingConfig, GlobalSettings, GatewayDataAccessConfig, GatewayDataRoutingConfig, + GatewayLoggingConfig, ] diff --git a/src/truefoundry_sdk/types/gateway_installation.py b/src/truefoundry_sdk/types/gateway_installation.py new file mode 100644 index 00000000..1f77c96d --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_installation.py @@ -0,0 +1,45 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class GatewayInstallation(UniversalBaseModel): + id: str = pydantic.Field() + """ + System-generated gateway installation ID. + """ + + service_account_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="serviceAccountId"), pydantic.Field(alias="serviceAccountId") + ] = None + manifest: typing.Dict[str, typing.Any] + enabled: bool + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + created_by_subject: typing_extensions.Annotated[ + typing.Optional[Subject], FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] = None + created_at: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] + updated_at: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] + is_default: typing_extensions.Annotated[bool, FieldMetadata(alias="isDefault"), pydantic.Field(alias="isDefault")] + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/gateway_logging_config.py b/src/truefoundry_sdk/types/gateway_logging_config.py index fa23aff3..07ba19b6 100644 --- a/src/truefoundry_sdk/types/gateway_logging_config.py +++ b/src/truefoundry_sdk/types/gateway_logging_config.py @@ -4,7 +4,8 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .gateway_logging_rule import GatewayLoggingRule +from .logging_when import LoggingWhen +from .redaction import Redaction class GatewayLoggingConfig(UniversalBaseModel): @@ -12,22 +13,25 @@ class GatewayLoggingConfig(UniversalBaseModel): Logging Configuration """ - name: str = pydantic.Field() + type: typing.Literal["gateway-logging-config"] = pydantic.Field(default="gateway-logging-config") """ - Name of the logging configuration + +value=gateway-logging-config + +sort=1 """ - type: typing.Literal["gateway-logging-config"] = pydantic.Field(default="gateway-logging-config") + name: str = pydantic.Field() """ - +value=gateway-logging-config - +sort=2 + Unique name for this logging configuration """ - rules: typing.List[GatewayLoggingRule] = pydantic.Field() + when: typing.Optional[LoggingWhen] = None + log: bool = pydantic.Field() """ - List of logging rules + Whether requests matched by this config should be logged. """ + redact_with: typing.Optional[Redaction] = None + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/gcp_gke_integration.py b/src/truefoundry_sdk/types/gcp_gke_integration.py index d28657f4..950a7a81 100644 --- a/src/truefoundry_sdk/types/gcp_gke_integration.py +++ b/src/truefoundry_sdk/types/gcp_gke_integration.py @@ -4,8 +4,8 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .gcp_gke_integration_location import GcpGkeIntegrationLocation from .gcp_key_file_auth import GcpKeyFileAuth -from .gcp_region import GcpRegion class GcpGkeIntegration(UniversalBaseModel): @@ -25,7 +25,11 @@ class GcpGkeIntegration(UniversalBaseModel): The name of the integration that will be displayed in the TrueFoundry UI. """ - location: GcpRegion + location: GcpGkeIntegrationLocation = pydantic.Field() + """ + The location of the cluster. + """ + cluster_name: str = pydantic.Field() """ Name of the cluster given in the cloud account. diff --git a/src/truefoundry_sdk/types/gcp_gke_integration_location.py b/src/truefoundry_sdk/types/gcp_gke_integration_location.py new file mode 100644 index 00000000..6dbd1ac7 --- /dev/null +++ b/src/truefoundry_sdk/types/gcp_gke_integration_location.py @@ -0,0 +1,726 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class GcpGkeIntegrationLocation(enum.StrEnum): + """ + The location of the cluster. + """ + + GLOBAL = "global" + AFRICA_SOUTH1 = "africa-south1" + ASIA_EAST1 = "asia-east1" + ASIA_EAST2 = "asia-east2" + ASIA_NORTHEAST1 = "asia-northeast1" + ASIA_NORTHEAST2 = "asia-northeast2" + ASIA_NORTHEAST3 = "asia-northeast3" + ASIA_SOUTH1 = "asia-south1" + ASIA_SOUTH2 = "asia-south2" + ASIA_SOUTHEAST1 = "asia-southeast1" + ASIA_SOUTHEAST2 = "asia-southeast2" + ASIA_SOUTHEAST3 = "asia-southeast3" + AUSTRALIA_SOUTHEAST1 = "australia-southeast1" + AUSTRALIA_SOUTHEAST2 = "australia-southeast2" + EUROPE_CENTRAL2 = "europe-central2" + EUROPE_NORTH1 = "europe-north1" + EUROPE_NORTH2 = "europe-north2" + EUROPE_SOUTHWEST1 = "europe-southwest1" + EUROPE_WEST1 = "europe-west1" + EUROPE_WEST2 = "europe-west2" + EUROPE_WEST3 = "europe-west3" + EUROPE_WEST4 = "europe-west4" + EUROPE_WEST6 = "europe-west6" + EUROPE_WEST8 = "europe-west8" + EUROPE_WEST9 = "europe-west9" + EUROPE_WEST10 = "europe-west10" + EUROPE_WEST12 = "europe-west12" + ME_CENTRAL1 = "me-central1" + ME_CENTRAL2 = "me-central2" + ME_WEST1 = "me-west1" + NORTHAMERICA_NORTHEAST1 = "northamerica-northeast1" + NORTHAMERICA_NORTHEAST2 = "northamerica-northeast2" + NORTHAMERICA_SOUTH1 = "northamerica-south1" + SOUTHAMERICA_EAST1 = "southamerica-east1" + SOUTHAMERICA_WEST1 = "southamerica-west1" + US_CENTRAL1 = "us-central1" + US_EAST1 = "us-east1" + US_EAST4 = "us-east4" + US_EAST5 = "us-east5" + US_SOUTH1 = "us-south1" + US_WEST1 = "us-west1" + US_WEST2 = "us-west2" + US_WEST3 = "us-west3" + US_WEST4 = "us-west4" + AFRICA_SOUTH1A = "africa-south1-a" + AFRICA_SOUTH1B = "africa-south1-b" + AFRICA_SOUTH1C = "africa-south1-c" + ASIA_EAST1A = "asia-east1-a" + ASIA_EAST1B = "asia-east1-b" + ASIA_EAST1C = "asia-east1-c" + ASIA_EAST2A = "asia-east2-a" + ASIA_EAST2B = "asia-east2-b" + ASIA_EAST2C = "asia-east2-c" + ASIA_NORTHEAST1A = "asia-northeast1-a" + ASIA_NORTHEAST1B = "asia-northeast1-b" + ASIA_NORTHEAST1C = "asia-northeast1-c" + ASIA_NORTHEAST2A = "asia-northeast2-a" + ASIA_NORTHEAST2B = "asia-northeast2-b" + ASIA_NORTHEAST2C = "asia-northeast2-c" + ASIA_NORTHEAST3A = "asia-northeast3-a" + ASIA_NORTHEAST3B = "asia-northeast3-b" + ASIA_NORTHEAST3C = "asia-northeast3-c" + ASIA_SOUTH1A = "asia-south1-a" + ASIA_SOUTH1B = "asia-south1-b" + ASIA_SOUTH1C = "asia-south1-c" + ASIA_SOUTH2A = "asia-south2-a" + ASIA_SOUTH2B = "asia-south2-b" + ASIA_SOUTH2C = "asia-south2-c" + ASIA_SOUTHEAST1A = "asia-southeast1-a" + ASIA_SOUTHEAST1B = "asia-southeast1-b" + ASIA_SOUTHEAST1C = "asia-southeast1-c" + ASIA_SOUTHEAST2A = "asia-southeast2-a" + ASIA_SOUTHEAST2B = "asia-southeast2-b" + ASIA_SOUTHEAST2C = "asia-southeast2-c" + ASIA_SOUTHEAST3A = "asia-southeast3-a" + ASIA_SOUTHEAST3B = "asia-southeast3-b" + ASIA_SOUTHEAST3C = "asia-southeast3-c" + AUSTRALIA_SOUTHEAST1A = "australia-southeast1-a" + AUSTRALIA_SOUTHEAST1B = "australia-southeast1-b" + AUSTRALIA_SOUTHEAST1C = "australia-southeast1-c" + AUSTRALIA_SOUTHEAST2A = "australia-southeast2-a" + AUSTRALIA_SOUTHEAST2B = "australia-southeast2-b" + AUSTRALIA_SOUTHEAST2C = "australia-southeast2-c" + EUROPE_CENTRAL2A = "europe-central2-a" + EUROPE_CENTRAL2B = "europe-central2-b" + EUROPE_CENTRAL2C = "europe-central2-c" + EUROPE_NORTH1A = "europe-north1-a" + EUROPE_NORTH1B = "europe-north1-b" + EUROPE_NORTH1C = "europe-north1-c" + EUROPE_NORTH2A = "europe-north2-a" + EUROPE_NORTH2B = "europe-north2-b" + EUROPE_NORTH2C = "europe-north2-c" + EUROPE_SOUTHWEST1A = "europe-southwest1-a" + EUROPE_SOUTHWEST1B = "europe-southwest1-b" + EUROPE_SOUTHWEST1C = "europe-southwest1-c" + EUROPE_WEST1B = "europe-west1-b" + EUROPE_WEST1C = "europe-west1-c" + EUROPE_WEST1D = "europe-west1-d" + EUROPE_WEST2A = "europe-west2-a" + EUROPE_WEST2B = "europe-west2-b" + EUROPE_WEST2C = "europe-west2-c" + EUROPE_WEST3A = "europe-west3-a" + EUROPE_WEST3B = "europe-west3-b" + EUROPE_WEST3C = "europe-west3-c" + EUROPE_WEST4A = "europe-west4-a" + EUROPE_WEST4B = "europe-west4-b" + EUROPE_WEST4C = "europe-west4-c" + EUROPE_WEST6A = "europe-west6-a" + EUROPE_WEST6B = "europe-west6-b" + EUROPE_WEST6C = "europe-west6-c" + EUROPE_WEST8A = "europe-west8-a" + EUROPE_WEST8B = "europe-west8-b" + EUROPE_WEST8C = "europe-west8-c" + EUROPE_WEST9A = "europe-west9-a" + EUROPE_WEST9B = "europe-west9-b" + EUROPE_WEST9C = "europe-west9-c" + EUROPE_WEST10A = "europe-west10-a" + EUROPE_WEST10B = "europe-west10-b" + EUROPE_WEST10C = "europe-west10-c" + EUROPE_WEST12A = "europe-west12-a" + EUROPE_WEST12B = "europe-west12-b" + EUROPE_WEST12C = "europe-west12-c" + ME_CENTRAL1A = "me-central1-a" + ME_CENTRAL1B = "me-central1-b" + ME_CENTRAL1C = "me-central1-c" + ME_CENTRAL2A = "me-central2-a" + ME_CENTRAL2B = "me-central2-b" + ME_CENTRAL2C = "me-central2-c" + ME_WEST1A = "me-west1-a" + ME_WEST1B = "me-west1-b" + ME_WEST1C = "me-west1-c" + NORTHAMERICA_NORTHEAST1A = "northamerica-northeast1-a" + NORTHAMERICA_NORTHEAST1B = "northamerica-northeast1-b" + NORTHAMERICA_NORTHEAST1C = "northamerica-northeast1-c" + NORTHAMERICA_NORTHEAST2A = "northamerica-northeast2-a" + NORTHAMERICA_NORTHEAST2B = "northamerica-northeast2-b" + NORTHAMERICA_NORTHEAST2C = "northamerica-northeast2-c" + NORTHAMERICA_SOUTH1A = "northamerica-south1-a" + NORTHAMERICA_SOUTH1B = "northamerica-south1-b" + NORTHAMERICA_SOUTH1C = "northamerica-south1-c" + SOUTHAMERICA_EAST1A = "southamerica-east1-a" + SOUTHAMERICA_EAST1B = "southamerica-east1-b" + SOUTHAMERICA_EAST1C = "southamerica-east1-c" + SOUTHAMERICA_WEST1A = "southamerica-west1-a" + SOUTHAMERICA_WEST1B = "southamerica-west1-b" + SOUTHAMERICA_WEST1C = "southamerica-west1-c" + US_CENTRAL1A = "us-central1-a" + US_CENTRAL1B = "us-central1-b" + US_CENTRAL1C = "us-central1-c" + US_CENTRAL1F = "us-central1-f" + US_EAST1B = "us-east1-b" + US_EAST1C = "us-east1-c" + US_EAST1D = "us-east1-d" + US_EAST4A = "us-east4-a" + US_EAST4B = "us-east4-b" + US_EAST4C = "us-east4-c" + US_EAST5A = "us-east5-a" + US_EAST5B = "us-east5-b" + US_EAST5C = "us-east5-c" + US_SOUTH1A = "us-south1-a" + US_SOUTH1B = "us-south1-b" + US_SOUTH1C = "us-south1-c" + US_WEST1A = "us-west1-a" + US_WEST1B = "us-west1-b" + US_WEST1C = "us-west1-c" + US_WEST2A = "us-west2-a" + US_WEST2B = "us-west2-b" + US_WEST2C = "us-west2-c" + US_WEST3A = "us-west3-a" + US_WEST3B = "us-west3-b" + US_WEST3C = "us-west3-c" + US_WEST4A = "us-west4-a" + US_WEST4B = "us-west4-b" + US_WEST4C = "us-west4-c" + _UNKNOWN = "__GCPGKEINTEGRATIONLOCATION_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "GcpGkeIntegrationLocation": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + global_: typing.Callable[[], T_Result], + africa_south1: typing.Callable[[], T_Result], + asia_east1: typing.Callable[[], T_Result], + asia_east2: typing.Callable[[], T_Result], + asia_northeast1: typing.Callable[[], T_Result], + asia_northeast2: typing.Callable[[], T_Result], + asia_northeast3: typing.Callable[[], T_Result], + asia_south1: typing.Callable[[], T_Result], + asia_south2: typing.Callable[[], T_Result], + asia_southeast1: typing.Callable[[], T_Result], + asia_southeast2: typing.Callable[[], T_Result], + asia_southeast3: typing.Callable[[], T_Result], + australia_southeast1: typing.Callable[[], T_Result], + australia_southeast2: typing.Callable[[], T_Result], + europe_central2: typing.Callable[[], T_Result], + europe_north1: typing.Callable[[], T_Result], + europe_north2: typing.Callable[[], T_Result], + europe_southwest1: typing.Callable[[], T_Result], + europe_west1: typing.Callable[[], T_Result], + europe_west2: typing.Callable[[], T_Result], + europe_west3: typing.Callable[[], T_Result], + europe_west4: typing.Callable[[], T_Result], + europe_west6: typing.Callable[[], T_Result], + europe_west8: typing.Callable[[], T_Result], + europe_west9: typing.Callable[[], T_Result], + europe_west10: typing.Callable[[], T_Result], + europe_west12: typing.Callable[[], T_Result], + me_central1: typing.Callable[[], T_Result], + me_central2: typing.Callable[[], T_Result], + me_west1: typing.Callable[[], T_Result], + northamerica_northeast1: typing.Callable[[], T_Result], + northamerica_northeast2: typing.Callable[[], T_Result], + northamerica_south1: typing.Callable[[], T_Result], + southamerica_east1: typing.Callable[[], T_Result], + southamerica_west1: typing.Callable[[], T_Result], + us_central1: typing.Callable[[], T_Result], + us_east1: typing.Callable[[], T_Result], + us_east4: typing.Callable[[], T_Result], + us_east5: typing.Callable[[], T_Result], + us_south1: typing.Callable[[], T_Result], + us_west1: typing.Callable[[], T_Result], + us_west2: typing.Callable[[], T_Result], + us_west3: typing.Callable[[], T_Result], + us_west4: typing.Callable[[], T_Result], + africa_south1a: typing.Callable[[], T_Result], + africa_south1b: typing.Callable[[], T_Result], + africa_south1c: typing.Callable[[], T_Result], + asia_east1a: typing.Callable[[], T_Result], + asia_east1b: typing.Callable[[], T_Result], + asia_east1c: typing.Callable[[], T_Result], + asia_east2a: typing.Callable[[], T_Result], + asia_east2b: typing.Callable[[], T_Result], + asia_east2c: typing.Callable[[], T_Result], + asia_northeast1a: typing.Callable[[], T_Result], + asia_northeast1b: typing.Callable[[], T_Result], + asia_northeast1c: typing.Callable[[], T_Result], + asia_northeast2a: typing.Callable[[], T_Result], + asia_northeast2b: typing.Callable[[], T_Result], + asia_northeast2c: typing.Callable[[], T_Result], + asia_northeast3a: typing.Callable[[], T_Result], + asia_northeast3b: typing.Callable[[], T_Result], + asia_northeast3c: typing.Callable[[], T_Result], + asia_south1a: typing.Callable[[], T_Result], + asia_south1b: typing.Callable[[], T_Result], + asia_south1c: typing.Callable[[], T_Result], + asia_south2a: typing.Callable[[], T_Result], + asia_south2b: typing.Callable[[], T_Result], + asia_south2c: typing.Callable[[], T_Result], + asia_southeast1a: typing.Callable[[], T_Result], + asia_southeast1b: typing.Callable[[], T_Result], + asia_southeast1c: typing.Callable[[], T_Result], + asia_southeast2a: typing.Callable[[], T_Result], + asia_southeast2b: typing.Callable[[], T_Result], + asia_southeast2c: typing.Callable[[], T_Result], + asia_southeast3a: typing.Callable[[], T_Result], + asia_southeast3b: typing.Callable[[], T_Result], + asia_southeast3c: typing.Callable[[], T_Result], + australia_southeast1a: typing.Callable[[], T_Result], + australia_southeast1b: typing.Callable[[], T_Result], + australia_southeast1c: typing.Callable[[], T_Result], + australia_southeast2a: typing.Callable[[], T_Result], + australia_southeast2b: typing.Callable[[], T_Result], + australia_southeast2c: typing.Callable[[], T_Result], + europe_central2a: typing.Callable[[], T_Result], + europe_central2b: typing.Callable[[], T_Result], + europe_central2c: typing.Callable[[], T_Result], + europe_north1a: typing.Callable[[], T_Result], + europe_north1b: typing.Callable[[], T_Result], + europe_north1c: typing.Callable[[], T_Result], + europe_north2a: typing.Callable[[], T_Result], + europe_north2b: typing.Callable[[], T_Result], + europe_north2c: typing.Callable[[], T_Result], + europe_southwest1a: typing.Callable[[], T_Result], + europe_southwest1b: typing.Callable[[], T_Result], + europe_southwest1c: typing.Callable[[], T_Result], + europe_west1b: typing.Callable[[], T_Result], + europe_west1c: typing.Callable[[], T_Result], + europe_west1d: typing.Callable[[], T_Result], + europe_west2a: typing.Callable[[], T_Result], + europe_west2b: typing.Callable[[], T_Result], + europe_west2c: typing.Callable[[], T_Result], + europe_west3a: typing.Callable[[], T_Result], + europe_west3b: typing.Callable[[], T_Result], + europe_west3c: typing.Callable[[], T_Result], + europe_west4a: typing.Callable[[], T_Result], + europe_west4b: typing.Callable[[], T_Result], + europe_west4c: typing.Callable[[], T_Result], + europe_west6a: typing.Callable[[], T_Result], + europe_west6b: typing.Callable[[], T_Result], + europe_west6c: typing.Callable[[], T_Result], + europe_west8a: typing.Callable[[], T_Result], + europe_west8b: typing.Callable[[], T_Result], + europe_west8c: typing.Callable[[], T_Result], + europe_west9a: typing.Callable[[], T_Result], + europe_west9b: typing.Callable[[], T_Result], + europe_west9c: typing.Callable[[], T_Result], + europe_west10a: typing.Callable[[], T_Result], + europe_west10b: typing.Callable[[], T_Result], + europe_west10c: typing.Callable[[], T_Result], + europe_west12a: typing.Callable[[], T_Result], + europe_west12b: typing.Callable[[], T_Result], + europe_west12c: typing.Callable[[], T_Result], + me_central1a: typing.Callable[[], T_Result], + me_central1b: typing.Callable[[], T_Result], + me_central1c: typing.Callable[[], T_Result], + me_central2a: typing.Callable[[], T_Result], + me_central2b: typing.Callable[[], T_Result], + me_central2c: typing.Callable[[], T_Result], + me_west1a: typing.Callable[[], T_Result], + me_west1b: typing.Callable[[], T_Result], + me_west1c: typing.Callable[[], T_Result], + northamerica_northeast1a: typing.Callable[[], T_Result], + northamerica_northeast1b: typing.Callable[[], T_Result], + northamerica_northeast1c: typing.Callable[[], T_Result], + northamerica_northeast2a: typing.Callable[[], T_Result], + northamerica_northeast2b: typing.Callable[[], T_Result], + northamerica_northeast2c: typing.Callable[[], T_Result], + northamerica_south1a: typing.Callable[[], T_Result], + northamerica_south1b: typing.Callable[[], T_Result], + northamerica_south1c: typing.Callable[[], T_Result], + southamerica_east1a: typing.Callable[[], T_Result], + southamerica_east1b: typing.Callable[[], T_Result], + southamerica_east1c: typing.Callable[[], T_Result], + southamerica_west1a: typing.Callable[[], T_Result], + southamerica_west1b: typing.Callable[[], T_Result], + southamerica_west1c: typing.Callable[[], T_Result], + us_central1a: typing.Callable[[], T_Result], + us_central1b: typing.Callable[[], T_Result], + us_central1c: typing.Callable[[], T_Result], + us_central1f: typing.Callable[[], T_Result], + us_east1b: typing.Callable[[], T_Result], + us_east1c: typing.Callable[[], T_Result], + us_east1d: typing.Callable[[], T_Result], + us_east4a: typing.Callable[[], T_Result], + us_east4b: typing.Callable[[], T_Result], + us_east4c: typing.Callable[[], T_Result], + us_east5a: typing.Callable[[], T_Result], + us_east5b: typing.Callable[[], T_Result], + us_east5c: typing.Callable[[], T_Result], + us_south1a: typing.Callable[[], T_Result], + us_south1b: typing.Callable[[], T_Result], + us_south1c: typing.Callable[[], T_Result], + us_west1a: typing.Callable[[], T_Result], + us_west1b: typing.Callable[[], T_Result], + us_west1c: typing.Callable[[], T_Result], + us_west2a: typing.Callable[[], T_Result], + us_west2b: typing.Callable[[], T_Result], + us_west2c: typing.Callable[[], T_Result], + us_west3a: typing.Callable[[], T_Result], + us_west3b: typing.Callable[[], T_Result], + us_west3c: typing.Callable[[], T_Result], + us_west4a: typing.Callable[[], T_Result], + us_west4b: typing.Callable[[], T_Result], + us_west4c: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is GcpGkeIntegrationLocation.GLOBAL: + return global_() + if self is GcpGkeIntegrationLocation.AFRICA_SOUTH1: + return africa_south1() + if self is GcpGkeIntegrationLocation.ASIA_EAST1: + return asia_east1() + if self is GcpGkeIntegrationLocation.ASIA_EAST2: + return asia_east2() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST1: + return asia_northeast1() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST2: + return asia_northeast2() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST3: + return asia_northeast3() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH1: + return asia_south1() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH2: + return asia_south2() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST1: + return asia_southeast1() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST2: + return asia_southeast2() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST3: + return asia_southeast3() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST1: + return australia_southeast1() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST2: + return australia_southeast2() + if self is GcpGkeIntegrationLocation.EUROPE_CENTRAL2: + return europe_central2() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH1: + return europe_north1() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH2: + return europe_north2() + if self is GcpGkeIntegrationLocation.EUROPE_SOUTHWEST1: + return europe_southwest1() + if self is GcpGkeIntegrationLocation.EUROPE_WEST1: + return europe_west1() + if self is GcpGkeIntegrationLocation.EUROPE_WEST2: + return europe_west2() + if self is GcpGkeIntegrationLocation.EUROPE_WEST3: + return europe_west3() + if self is GcpGkeIntegrationLocation.EUROPE_WEST4: + return europe_west4() + if self is GcpGkeIntegrationLocation.EUROPE_WEST6: + return europe_west6() + if self is GcpGkeIntegrationLocation.EUROPE_WEST8: + return europe_west8() + if self is GcpGkeIntegrationLocation.EUROPE_WEST9: + return europe_west9() + if self is GcpGkeIntegrationLocation.EUROPE_WEST10: + return europe_west10() + if self is GcpGkeIntegrationLocation.EUROPE_WEST12: + return europe_west12() + if self is GcpGkeIntegrationLocation.ME_CENTRAL1: + return me_central1() + if self is GcpGkeIntegrationLocation.ME_CENTRAL2: + return me_central2() + if self is GcpGkeIntegrationLocation.ME_WEST1: + return me_west1() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST1: + return northamerica_northeast1() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST2: + return northamerica_northeast2() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_SOUTH1: + return northamerica_south1() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_EAST1: + return southamerica_east1() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_WEST1: + return southamerica_west1() + if self is GcpGkeIntegrationLocation.US_CENTRAL1: + return us_central1() + if self is GcpGkeIntegrationLocation.US_EAST1: + return us_east1() + if self is GcpGkeIntegrationLocation.US_EAST4: + return us_east4() + if self is GcpGkeIntegrationLocation.US_EAST5: + return us_east5() + if self is GcpGkeIntegrationLocation.US_SOUTH1: + return us_south1() + if self is GcpGkeIntegrationLocation.US_WEST1: + return us_west1() + if self is GcpGkeIntegrationLocation.US_WEST2: + return us_west2() + if self is GcpGkeIntegrationLocation.US_WEST3: + return us_west3() + if self is GcpGkeIntegrationLocation.US_WEST4: + return us_west4() + if self is GcpGkeIntegrationLocation.AFRICA_SOUTH1A: + return africa_south1a() + if self is GcpGkeIntegrationLocation.AFRICA_SOUTH1B: + return africa_south1b() + if self is GcpGkeIntegrationLocation.AFRICA_SOUTH1C: + return africa_south1c() + if self is GcpGkeIntegrationLocation.ASIA_EAST1A: + return asia_east1a() + if self is GcpGkeIntegrationLocation.ASIA_EAST1B: + return asia_east1b() + if self is GcpGkeIntegrationLocation.ASIA_EAST1C: + return asia_east1c() + if self is GcpGkeIntegrationLocation.ASIA_EAST2A: + return asia_east2a() + if self is GcpGkeIntegrationLocation.ASIA_EAST2B: + return asia_east2b() + if self is GcpGkeIntegrationLocation.ASIA_EAST2C: + return asia_east2c() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST1A: + return asia_northeast1a() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST1B: + return asia_northeast1b() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST1C: + return asia_northeast1c() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST2A: + return asia_northeast2a() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST2B: + return asia_northeast2b() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST2C: + return asia_northeast2c() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST3A: + return asia_northeast3a() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST3B: + return asia_northeast3b() + if self is GcpGkeIntegrationLocation.ASIA_NORTHEAST3C: + return asia_northeast3c() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH1A: + return asia_south1a() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH1B: + return asia_south1b() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH1C: + return asia_south1c() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH2A: + return asia_south2a() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH2B: + return asia_south2b() + if self is GcpGkeIntegrationLocation.ASIA_SOUTH2C: + return asia_south2c() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST1A: + return asia_southeast1a() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST1B: + return asia_southeast1b() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST1C: + return asia_southeast1c() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST2A: + return asia_southeast2a() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST2B: + return asia_southeast2b() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST2C: + return asia_southeast2c() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST3A: + return asia_southeast3a() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST3B: + return asia_southeast3b() + if self is GcpGkeIntegrationLocation.ASIA_SOUTHEAST3C: + return asia_southeast3c() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST1A: + return australia_southeast1a() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST1B: + return australia_southeast1b() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST1C: + return australia_southeast1c() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST2A: + return australia_southeast2a() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST2B: + return australia_southeast2b() + if self is GcpGkeIntegrationLocation.AUSTRALIA_SOUTHEAST2C: + return australia_southeast2c() + if self is GcpGkeIntegrationLocation.EUROPE_CENTRAL2A: + return europe_central2a() + if self is GcpGkeIntegrationLocation.EUROPE_CENTRAL2B: + return europe_central2b() + if self is GcpGkeIntegrationLocation.EUROPE_CENTRAL2C: + return europe_central2c() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH1A: + return europe_north1a() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH1B: + return europe_north1b() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH1C: + return europe_north1c() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH2A: + return europe_north2a() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH2B: + return europe_north2b() + if self is GcpGkeIntegrationLocation.EUROPE_NORTH2C: + return europe_north2c() + if self is GcpGkeIntegrationLocation.EUROPE_SOUTHWEST1A: + return europe_southwest1a() + if self is GcpGkeIntegrationLocation.EUROPE_SOUTHWEST1B: + return europe_southwest1b() + if self is GcpGkeIntegrationLocation.EUROPE_SOUTHWEST1C: + return europe_southwest1c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST1B: + return europe_west1b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST1C: + return europe_west1c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST1D: + return europe_west1d() + if self is GcpGkeIntegrationLocation.EUROPE_WEST2A: + return europe_west2a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST2B: + return europe_west2b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST2C: + return europe_west2c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST3A: + return europe_west3a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST3B: + return europe_west3b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST3C: + return europe_west3c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST4A: + return europe_west4a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST4B: + return europe_west4b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST4C: + return europe_west4c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST6A: + return europe_west6a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST6B: + return europe_west6b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST6C: + return europe_west6c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST8A: + return europe_west8a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST8B: + return europe_west8b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST8C: + return europe_west8c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST9A: + return europe_west9a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST9B: + return europe_west9b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST9C: + return europe_west9c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST10A: + return europe_west10a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST10B: + return europe_west10b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST10C: + return europe_west10c() + if self is GcpGkeIntegrationLocation.EUROPE_WEST12A: + return europe_west12a() + if self is GcpGkeIntegrationLocation.EUROPE_WEST12B: + return europe_west12b() + if self is GcpGkeIntegrationLocation.EUROPE_WEST12C: + return europe_west12c() + if self is GcpGkeIntegrationLocation.ME_CENTRAL1A: + return me_central1a() + if self is GcpGkeIntegrationLocation.ME_CENTRAL1B: + return me_central1b() + if self is GcpGkeIntegrationLocation.ME_CENTRAL1C: + return me_central1c() + if self is GcpGkeIntegrationLocation.ME_CENTRAL2A: + return me_central2a() + if self is GcpGkeIntegrationLocation.ME_CENTRAL2B: + return me_central2b() + if self is GcpGkeIntegrationLocation.ME_CENTRAL2C: + return me_central2c() + if self is GcpGkeIntegrationLocation.ME_WEST1A: + return me_west1a() + if self is GcpGkeIntegrationLocation.ME_WEST1B: + return me_west1b() + if self is GcpGkeIntegrationLocation.ME_WEST1C: + return me_west1c() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST1A: + return northamerica_northeast1a() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST1B: + return northamerica_northeast1b() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST1C: + return northamerica_northeast1c() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST2A: + return northamerica_northeast2a() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST2B: + return northamerica_northeast2b() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_NORTHEAST2C: + return northamerica_northeast2c() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_SOUTH1A: + return northamerica_south1a() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_SOUTH1B: + return northamerica_south1b() + if self is GcpGkeIntegrationLocation.NORTHAMERICA_SOUTH1C: + return northamerica_south1c() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_EAST1A: + return southamerica_east1a() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_EAST1B: + return southamerica_east1b() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_EAST1C: + return southamerica_east1c() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_WEST1A: + return southamerica_west1a() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_WEST1B: + return southamerica_west1b() + if self is GcpGkeIntegrationLocation.SOUTHAMERICA_WEST1C: + return southamerica_west1c() + if self is GcpGkeIntegrationLocation.US_CENTRAL1A: + return us_central1a() + if self is GcpGkeIntegrationLocation.US_CENTRAL1B: + return us_central1b() + if self is GcpGkeIntegrationLocation.US_CENTRAL1C: + return us_central1c() + if self is GcpGkeIntegrationLocation.US_CENTRAL1F: + return us_central1f() + if self is GcpGkeIntegrationLocation.US_EAST1B: + return us_east1b() + if self is GcpGkeIntegrationLocation.US_EAST1C: + return us_east1c() + if self is GcpGkeIntegrationLocation.US_EAST1D: + return us_east1d() + if self is GcpGkeIntegrationLocation.US_EAST4A: + return us_east4a() + if self is GcpGkeIntegrationLocation.US_EAST4B: + return us_east4b() + if self is GcpGkeIntegrationLocation.US_EAST4C: + return us_east4c() + if self is GcpGkeIntegrationLocation.US_EAST5A: + return us_east5a() + if self is GcpGkeIntegrationLocation.US_EAST5B: + return us_east5b() + if self is GcpGkeIntegrationLocation.US_EAST5C: + return us_east5c() + if self is GcpGkeIntegrationLocation.US_SOUTH1A: + return us_south1a() + if self is GcpGkeIntegrationLocation.US_SOUTH1B: + return us_south1b() + if self is GcpGkeIntegrationLocation.US_SOUTH1C: + return us_south1c() + if self is GcpGkeIntegrationLocation.US_WEST1A: + return us_west1a() + if self is GcpGkeIntegrationLocation.US_WEST1B: + return us_west1b() + if self is GcpGkeIntegrationLocation.US_WEST1C: + return us_west1c() + if self is GcpGkeIntegrationLocation.US_WEST2A: + return us_west2a() + if self is GcpGkeIntegrationLocation.US_WEST2B: + return us_west2b() + if self is GcpGkeIntegrationLocation.US_WEST2C: + return us_west2c() + if self is GcpGkeIntegrationLocation.US_WEST3A: + return us_west3a() + if self is GcpGkeIntegrationLocation.US_WEST3B: + return us_west3b() + if self is GcpGkeIntegrationLocation.US_WEST3C: + return us_west3c() + if self is GcpGkeIntegrationLocation.US_WEST4A: + return us_west4a() + if self is GcpGkeIntegrationLocation.US_WEST4B: + return us_west4b() + if self is GcpGkeIntegrationLocation.US_WEST4C: + return us_west4c() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/gcp_region.py b/src/truefoundry_sdk/types/gcp_region.py index 5ce12af1..347aad52 100644 --- a/src/truefoundry_sdk/types/gcp_region.py +++ b/src/truefoundry_sdk/types/gcp_region.py @@ -9,18 +9,7 @@ class GcpRegion(enum.StrEnum): GLOBAL = "global" - NORTHAMERICA_NORTHEAST1 = "northamerica-northeast1" - NORTHAMERICA_NORTHEAST2 = "northamerica-northeast2" - SOUTHAMERICA_EAST1 = "southamerica-east1" - US_CENTRAL1 = "us-central1" - US_EAST1 = "us-east1" - US_EAST4 = "us-east4" - US_EAST5 = "us-east5" - US_SOUTH1 = "us-south1" - US_WEST1 = "us-west1" - US_WEST2 = "us-west2" - US_WEST3 = "us-west3" - US_WEST4 = "us-west4" + AFRICA_SOUTH1 = "africa-south1" ASIA_EAST1 = "asia-east1" ASIA_EAST2 = "asia-east2" ASIA_NORTHEAST1 = "asia-northeast1" @@ -30,10 +19,12 @@ class GcpRegion(enum.StrEnum): ASIA_SOUTH2 = "asia-south2" ASIA_SOUTHEAST1 = "asia-southeast1" ASIA_SOUTHEAST2 = "asia-southeast2" + ASIA_SOUTHEAST3 = "asia-southeast3" AUSTRALIA_SOUTHEAST1 = "australia-southeast1" AUSTRALIA_SOUTHEAST2 = "australia-southeast2" EUROPE_CENTRAL2 = "europe-central2" EUROPE_NORTH1 = "europe-north1" + EUROPE_NORTH2 = "europe-north2" EUROPE_SOUTHWEST1 = "europe-southwest1" EUROPE_WEST1 = "europe-west1" EUROPE_WEST2 = "europe-west2" @@ -42,9 +33,25 @@ class GcpRegion(enum.StrEnum): EUROPE_WEST6 = "europe-west6" EUROPE_WEST8 = "europe-west8" EUROPE_WEST9 = "europe-west9" + EUROPE_WEST10 = "europe-west10" + EUROPE_WEST12 = "europe-west12" ME_CENTRAL1 = "me-central1" ME_CENTRAL2 = "me-central2" ME_WEST1 = "me-west1" + NORTHAMERICA_NORTHEAST1 = "northamerica-northeast1" + NORTHAMERICA_NORTHEAST2 = "northamerica-northeast2" + NORTHAMERICA_SOUTH1 = "northamerica-south1" + SOUTHAMERICA_EAST1 = "southamerica-east1" + SOUTHAMERICA_WEST1 = "southamerica-west1" + US_CENTRAL1 = "us-central1" + US_EAST1 = "us-east1" + US_EAST4 = "us-east4" + US_EAST5 = "us-east5" + US_SOUTH1 = "us-south1" + US_WEST1 = "us-west1" + US_WEST2 = "us-west2" + US_WEST3 = "us-west3" + US_WEST4 = "us-west4" _UNKNOWN = "__GCPREGION_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -59,18 +66,7 @@ def _missing_(cls, value: typing.Any) -> "GcpRegion": def visit( self, global_: typing.Callable[[], T_Result], - northamerica_northeast1: typing.Callable[[], T_Result], - northamerica_northeast2: typing.Callable[[], T_Result], - southamerica_east1: typing.Callable[[], T_Result], - us_central1: typing.Callable[[], T_Result], - us_east1: typing.Callable[[], T_Result], - us_east4: typing.Callable[[], T_Result], - us_east5: typing.Callable[[], T_Result], - us_south1: typing.Callable[[], T_Result], - us_west1: typing.Callable[[], T_Result], - us_west2: typing.Callable[[], T_Result], - us_west3: typing.Callable[[], T_Result], - us_west4: typing.Callable[[], T_Result], + africa_south1: typing.Callable[[], T_Result], asia_east1: typing.Callable[[], T_Result], asia_east2: typing.Callable[[], T_Result], asia_northeast1: typing.Callable[[], T_Result], @@ -80,10 +76,12 @@ def visit( asia_south2: typing.Callable[[], T_Result], asia_southeast1: typing.Callable[[], T_Result], asia_southeast2: typing.Callable[[], T_Result], + asia_southeast3: typing.Callable[[], T_Result], australia_southeast1: typing.Callable[[], T_Result], australia_southeast2: typing.Callable[[], T_Result], europe_central2: typing.Callable[[], T_Result], europe_north1: typing.Callable[[], T_Result], + europe_north2: typing.Callable[[], T_Result], europe_southwest1: typing.Callable[[], T_Result], europe_west1: typing.Callable[[], T_Result], europe_west2: typing.Callable[[], T_Result], @@ -92,37 +90,31 @@ def visit( europe_west6: typing.Callable[[], T_Result], europe_west8: typing.Callable[[], T_Result], europe_west9: typing.Callable[[], T_Result], + europe_west10: typing.Callable[[], T_Result], + europe_west12: typing.Callable[[], T_Result], me_central1: typing.Callable[[], T_Result], me_central2: typing.Callable[[], T_Result], me_west1: typing.Callable[[], T_Result], + northamerica_northeast1: typing.Callable[[], T_Result], + northamerica_northeast2: typing.Callable[[], T_Result], + northamerica_south1: typing.Callable[[], T_Result], + southamerica_east1: typing.Callable[[], T_Result], + southamerica_west1: typing.Callable[[], T_Result], + us_central1: typing.Callable[[], T_Result], + us_east1: typing.Callable[[], T_Result], + us_east4: typing.Callable[[], T_Result], + us_east5: typing.Callable[[], T_Result], + us_south1: typing.Callable[[], T_Result], + us_west1: typing.Callable[[], T_Result], + us_west2: typing.Callable[[], T_Result], + us_west3: typing.Callable[[], T_Result], + us_west4: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is GcpRegion.GLOBAL: return global_() - if self is GcpRegion.NORTHAMERICA_NORTHEAST1: - return northamerica_northeast1() - if self is GcpRegion.NORTHAMERICA_NORTHEAST2: - return northamerica_northeast2() - if self is GcpRegion.SOUTHAMERICA_EAST1: - return southamerica_east1() - if self is GcpRegion.US_CENTRAL1: - return us_central1() - if self is GcpRegion.US_EAST1: - return us_east1() - if self is GcpRegion.US_EAST4: - return us_east4() - if self is GcpRegion.US_EAST5: - return us_east5() - if self is GcpRegion.US_SOUTH1: - return us_south1() - if self is GcpRegion.US_WEST1: - return us_west1() - if self is GcpRegion.US_WEST2: - return us_west2() - if self is GcpRegion.US_WEST3: - return us_west3() - if self is GcpRegion.US_WEST4: - return us_west4() + if self is GcpRegion.AFRICA_SOUTH1: + return africa_south1() if self is GcpRegion.ASIA_EAST1: return asia_east1() if self is GcpRegion.ASIA_EAST2: @@ -141,6 +133,8 @@ def visit( return asia_southeast1() if self is GcpRegion.ASIA_SOUTHEAST2: return asia_southeast2() + if self is GcpRegion.ASIA_SOUTHEAST3: + return asia_southeast3() if self is GcpRegion.AUSTRALIA_SOUTHEAST1: return australia_southeast1() if self is GcpRegion.AUSTRALIA_SOUTHEAST2: @@ -149,6 +143,8 @@ def visit( return europe_central2() if self is GcpRegion.EUROPE_NORTH1: return europe_north1() + if self is GcpRegion.EUROPE_NORTH2: + return europe_north2() if self is GcpRegion.EUROPE_SOUTHWEST1: return europe_southwest1() if self is GcpRegion.EUROPE_WEST1: @@ -165,10 +161,42 @@ def visit( return europe_west8() if self is GcpRegion.EUROPE_WEST9: return europe_west9() + if self is GcpRegion.EUROPE_WEST10: + return europe_west10() + if self is GcpRegion.EUROPE_WEST12: + return europe_west12() if self is GcpRegion.ME_CENTRAL1: return me_central1() if self is GcpRegion.ME_CENTRAL2: return me_central2() if self is GcpRegion.ME_WEST1: return me_west1() + if self is GcpRegion.NORTHAMERICA_NORTHEAST1: + return northamerica_northeast1() + if self is GcpRegion.NORTHAMERICA_NORTHEAST2: + return northamerica_northeast2() + if self is GcpRegion.NORTHAMERICA_SOUTH1: + return northamerica_south1() + if self is GcpRegion.SOUTHAMERICA_EAST1: + return southamerica_east1() + if self is GcpRegion.SOUTHAMERICA_WEST1: + return southamerica_west1() + if self is GcpRegion.US_CENTRAL1: + return us_central1() + if self is GcpRegion.US_EAST1: + return us_east1() + if self is GcpRegion.US_EAST4: + return us_east4() + if self is GcpRegion.US_EAST5: + return us_east5() + if self is GcpRegion.US_SOUTH1: + return us_south1() + if self is GcpRegion.US_WEST1: + return us_west1() + if self is GcpRegion.US_WEST2: + return us_west2() + if self is GcpRegion.US_WEST3: + return us_west3() + if self is GcpRegion.US_WEST4: + return us_west4() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/get_agent_identity_token_response.py b/src/truefoundry_sdk/types/get_agent_identity_token_response.py new file mode 100644 index 00000000..6c30ef70 --- /dev/null +++ b/src/truefoundry_sdk/types/get_agent_identity_token_response.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class GetAgentIdentityTokenResponse(UniversalBaseModel): + token: str = pydantic.Field() + """ + The TrueFoundry-backed agent identity token. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/google_gemini_provider_account.py b/src/truefoundry_sdk/types/google_gemini_provider_account.py index 90a83596..8d842a76 100644 --- a/src/truefoundry_sdk/types/google_gemini_provider_account.py +++ b/src/truefoundry_sdk/types/google_gemini_provider_account.py @@ -14,7 +14,7 @@ class GoogleGeminiProviderAccount(UniversalBaseModel): """ - Google Gemini Provider Account + Google Gemini Model Account """ type: typing.Literal["provider-account/google-gemini"] = pydantic.Field(default="provider-account/google-gemini") @@ -24,18 +24,18 @@ class GoogleGeminiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Google Gemini provider account + The name of the Google Gemini model account """ auth_data: GcpApiKeyAuth integrations: typing.List[GeminiModel] = pydantic.Field() """ - List of integrations that are associated with the Google Gemini provider account + List of integrations that are associated with the Google Gemini model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class GoogleGeminiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/google_vertex_provider_account.py b/src/truefoundry_sdk/types/google_vertex_provider_account.py index f502dfae..d96508dc 100644 --- a/src/truefoundry_sdk/types/google_vertex_provider_account.py +++ b/src/truefoundry_sdk/types/google_vertex_provider_account.py @@ -15,7 +15,7 @@ class GoogleVertexProviderAccount(UniversalBaseModel): """ - Google Vertex Provider Account + Google Vertex Model Account """ type: typing.Literal["provider-account/google-vertex"] = pydantic.Field(default="provider-account/google-vertex") @@ -25,7 +25,7 @@ class GoogleVertexProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Google Vertex provider account + The name of the Google Vertex model account """ project_id: str = pydantic.Field() @@ -41,12 +41,12 @@ class GoogleVertexProviderAccount(UniversalBaseModel): integrations: typing.List[VertexModel] = pydantic.Field() """ - List of integrations that are associated with the Google Vertex provider account + List of integrations that are associated with the Google Vertex model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -54,7 +54,7 @@ class GoogleVertexProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/groq_provider_account.py b/src/truefoundry_sdk/types/groq_provider_account.py index df08c4e6..5f7c147d 100644 --- a/src/truefoundry_sdk/types/groq_provider_account.py +++ b/src/truefoundry_sdk/types/groq_provider_account.py @@ -14,7 +14,7 @@ class GroqProviderAccount(UniversalBaseModel): """ - Groq Provider Account + Groq Model Account """ type: typing.Literal["provider-account/groq"] = pydantic.Field(default="provider-account/groq") @@ -24,18 +24,18 @@ class GroqProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Groq provider account + The name of the Groq model account """ auth_data: GroqKeyAuth integrations: typing.List[GroqIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Groq provider account + List of integrations that are associated with the Groq model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class GroqProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/guardrail_config_group.py b/src/truefoundry_sdk/types/guardrail_config_group.py index 1f178721..3705997a 100644 --- a/src/truefoundry_sdk/types/guardrail_config_group.py +++ b/src/truefoundry_sdk/types/guardrail_config_group.py @@ -13,7 +13,7 @@ class GuardrailConfigGroup(UniversalBaseModel): """ - Guardrail Configs Group + Guardrail Group """ type: typing.Literal["provider-account/guardrail-config-group"] = pydantic.Field( diff --git a/src/truefoundry_sdk/types/guardrail_config_integrations.py b/src/truefoundry_sdk/types/guardrail_config_integrations.py index c537535a..11d9e179 100644 --- a/src/truefoundry_sdk/types/guardrail_config_integrations.py +++ b/src/truefoundry_sdk/types/guardrail_config_integrations.py @@ -15,6 +15,7 @@ from .fiddler_guardrail_config import FiddlerGuardrailConfig from .google_model_armor_guardrail_config import GoogleModelArmorGuardrailConfig from .gray_swan_cygnal_guardrail_config import GraySwanCygnalGuardrailConfig +from .noma_security_guardrail_config import NomaSecurityGuardrailConfig from .opa_guardrail_config import OpaGuardrailConfig from .open_ai_moderations_guardrail_config import OpenAiModerationsGuardrailConfig from .palo_alto_prisma_airs_guardrail_config import PaloAltoPrismaAirsGuardrailConfig @@ -52,6 +53,7 @@ OpaGuardrailConfig, GoogleModelArmorGuardrailConfig, GraySwanCygnalGuardrailConfig, + NomaSecurityGuardrailConfig, AktoGuardrailConfig, TrojAiGuardrailConfig, ] diff --git a/src/truefoundry_sdk/types/guardrails_rule.py b/src/truefoundry_sdk/types/guardrails_rule.py index 7e390f8a..63d65bbb 100644 --- a/src/truefoundry_sdk/types/guardrails_rule.py +++ b/src/truefoundry_sdk/types/guardrails_rule.py @@ -40,7 +40,7 @@ class GuardrailsRule(UniversalBaseModel): custom_error_message: typing.Optional[str] = pydantic.Field(default=None) """ - Optional message returned to the client when a guardrail in this rule blocks a request. Use {{guardrail_message}} to include the default guardrail failure message. + Optional message returned to the client when a guardrail in this rule blocks a request. Supported placeholders: {{guardrail_message}} (default guardrail failure detail), {{failed_guardrails}} (comma-separated list of the guardrails that failed). """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/hashicorp_app_role_auth.py b/src/truefoundry_sdk/types/hashicorp_app_role_auth.py index 1f233987..065eb92e 100644 --- a/src/truefoundry_sdk/types/hashicorp_app_role_auth.py +++ b/src/truefoundry_sdk/types/hashicorp_app_role_auth.py @@ -26,6 +26,11 @@ class HashicorpAppRoleAuth(UniversalBaseModel): AppRole secret ID for Vault authentication. """ + role_path: typing.Optional[str] = pydantic.Field(default="approle") + """ + Optional app role path which is used to authenticate the app role. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/header_routing_config.py b/src/truefoundry_sdk/types/header_routing_config.py index 3e26afdf..98f9867c 100644 --- a/src/truefoundry_sdk/types/header_routing_config.py +++ b/src/truefoundry_sdk/types/header_routing_config.py @@ -2,8 +2,11 @@ import typing +from .complexity_based_load_balancing import ComplexityBasedLoadBalancing from .latency_based_load_balancing import LatencyBasedLoadBalancing from .priority_based_load_balancing import PriorityBasedLoadBalancing from .weight_based_load_balancing import WeightBasedLoadBalancing -HeaderRoutingConfig = typing.Union[WeightBasedLoadBalancing, LatencyBasedLoadBalancing, PriorityBasedLoadBalancing] +HeaderRoutingConfig = typing.Union[ + WeightBasedLoadBalancing, LatencyBasedLoadBalancing, PriorityBasedLoadBalancing, ComplexityBasedLoadBalancing +] diff --git a/src/truefoundry_sdk/types/heuristic_classification_strategy.py b/src/truefoundry_sdk/types/heuristic_classification_strategy.py new file mode 100644 index 00000000..550377ff --- /dev/null +++ b/src/truefoundry_sdk/types/heuristic_classification_strategy.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class HeuristicClassificationStrategy(UniversalBaseModel): + """ + Fast, in-process heuristic classifier. Runs with zero added latency and no classifier model. This is the default strategy. + """ + + type: typing.Literal["heuristic"] = pydantic.Field(default="heuristic") + """ + Strategy + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/heuristic_fallback_strategy.py b/src/truefoundry_sdk/types/heuristic_fallback_strategy.py new file mode 100644 index 00000000..c47824e4 --- /dev/null +++ b/src/truefoundry_sdk/types/heuristic_fallback_strategy.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class HeuristicFallbackStrategy(UniversalBaseModel): + """ + On classifier timeout or error, fall back to the built-in heuristic classifier. + """ + + type: typing.Literal["heuristic"] = pydantic.Field(default="heuristic") + """ + Fallback Type + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/i_change.py b/src/truefoundry_sdk/types/i_change.py index 97ec6c12..999b7e95 100644 --- a/src/truefoundry_sdk/types/i_change.py +++ b/src/truefoundry_sdk/types/i_change.py @@ -8,11 +8,11 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata -from .i_change_operation import IChangeOperation +from .i_change_type import IChangeType class IChange(UniversalBaseModel): - type: IChangeOperation + type: IChangeType key: str value: typing.Optional[typing.Dict[str, typing.Any]] = None old_value: typing_extensions.Annotated[ diff --git a/src/truefoundry_sdk/types/i_change_operation.py b/src/truefoundry_sdk/types/i_change_type.py similarity index 75% rename from src/truefoundry_sdk/types/i_change_operation.py rename to src/truefoundry_sdk/types/i_change_type.py index a64a9013..04d74379 100644 --- a/src/truefoundry_sdk/types/i_change_operation.py +++ b/src/truefoundry_sdk/types/i_change_type.py @@ -7,17 +7,17 @@ T_Result = typing.TypeVar("T_Result") -class IChangeOperation(enum.StrEnum): +class IChangeType(enum.StrEnum): REMOVE = "REMOVE" ADD = "ADD" UPDATE = "UPDATE" - _UNKNOWN = "__ICHANGEOPERATION_UNKNOWN__" + _UNKNOWN = "__ICHANGETYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "IChangeOperation": + def _missing_(cls, value: typing.Any) -> "IChangeType": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -29,10 +29,10 @@ def visit( update: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is IChangeOperation.REMOVE: + if self is IChangeType.REMOVE: return remove() - if self is IChangeOperation.ADD: + if self is IChangeType.ADD: return add() - if self is IChangeOperation.UPDATE: + if self is IChangeType.UPDATE: return update() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/identity_provider_backed_identity.py b/src/truefoundry_sdk/types/identity_provider_backed_identity.py index f714c47f..41e8b2c1 100644 --- a/src/truefoundry_sdk/types/identity_provider_backed_identity.py +++ b/src/truefoundry_sdk/types/identity_provider_backed_identity.py @@ -12,9 +12,9 @@ class IdentityProviderBackedIdentity(UniversalBaseModel): Identity resolved from tokens issued by an external identity provider """ - type: typing.Literal["idp-backed"] = pydantic.Field(default="idp-backed") + type: typing.Literal["identity-provider-backed"] = pydantic.Field(default="identity-provider-backed") """ - +value=idp-backed + +value=identity-provider-backed """ identity_provider_mapping: typing.List[AgentIdentityProviderMapping] = pydantic.Field() diff --git a/src/truefoundry_sdk/types/identity_provider_mapping.py b/src/truefoundry_sdk/types/identity_provider_mapping.py index d7c5d0bc..e477883c 100644 --- a/src/truefoundry_sdk/types/identity_provider_mapping.py +++ b/src/truefoundry_sdk/types/identity_provider_mapping.py @@ -8,17 +8,17 @@ class IdentityProviderMapping(UniversalBaseModel): """ - Configuration for mapping IdP claim values to this virtual account + Map specific claim values from an external IdP token (e.g., Okta, Azure AD) to this agent identity. """ identity_provider: str = pydantic.Field() """ - Name of the external identity provider + Must already be configured under Platform → Identity Providers. Choosing a SPIRE provider means this agent's credential is an attested JWT-SVID from its runtime. """ value: str = pydantic.Field() """ - Claim value that should resolve to this virtual account + The value that must appear in the subject claim of the IdP token for this mapping to match. For example, a service account email or a group name. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/in_not_in.py b/src/truefoundry_sdk/types/in_not_in.py new file mode 100644 index 00000000..8c966adc --- /dev/null +++ b/src/truefoundry_sdk/types/in_not_in.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata + + +class InNotIn(UniversalBaseModel): + """ + In/Not-In Filter + """ + + in_: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], + FieldMetadata(alias="in"), + pydantic.Field( + alias="in", description='Match when the value is present in this list. Absent or ["*"] means all.' + ), + ] = None + """ + Match when the value is present in this list. Absent or ["*"] means all. + """ + + not_in: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Match when the value is NOT present in this list. A value listed here never matches. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/job_run_status.py b/src/truefoundry_sdk/types/job_run_status.py index 22b22f7f..6c2b33b1 100644 --- a/src/truefoundry_sdk/types/job_run_status.py +++ b/src/truefoundry_sdk/types/job_run_status.py @@ -8,6 +8,10 @@ class JobRunStatus(enum.StrEnum): + """ + Status of JobRun + """ + CREATED = "CREATED" SCHEDULED = "SCHEDULED" RUNNING = "RUNNING" diff --git a/src/truefoundry_sdk/types/llm_classification_strategy.py b/src/truefoundry_sdk/types/llm_classification_strategy.py new file mode 100644 index 00000000..79f8b7ce --- /dev/null +++ b/src/truefoundry_sdk/types/llm_classification_strategy.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .llm_classification_strategy_fallback_strategy import LlmClassificationStrategyFallbackStrategy + + +class LlmClassificationStrategy(UniversalBaseModel): + """ + Classify each request by calling a fast chat model. On timeout or error the gateway applies the configured fallback strategy. + """ + + type: typing.Literal["llm-classifier"] = pydantic.Field(default="llm-classifier") + """ + Strategy + """ + + model: str = pydantic.Field() + """ + Catalog model FQN used to classify request complexity. Must be resolvable by this tenant, must be a catalog model (not a virtual model), and must be a chat model. + """ + + timeout_ms: typing.Optional[int] = pydantic.Field(default=2000) + """ + Maximum time to wait for the classifier response in milliseconds before applying the fallback strategy. + """ + + fallback_strategy: typing.Optional[LlmClassificationStrategyFallbackStrategy] = pydantic.Field(default=None) + """ + Fallback strategy applied when the classifier fails. Defaults to the heuristic classifier. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/llm_classification_strategy_fallback_strategy.py b/src/truefoundry_sdk/types/llm_classification_strategy_fallback_strategy.py new file mode 100644 index 00000000..87270b70 --- /dev/null +++ b/src/truefoundry_sdk/types/llm_classification_strategy_fallback_strategy.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .heuristic_fallback_strategy import HeuristicFallbackStrategy +from .static_fallback_strategy import StaticFallbackStrategy + +LlmClassificationStrategyFallbackStrategy = typing.Union[HeuristicFallbackStrategy, StaticFallbackStrategy] diff --git a/src/truefoundry_sdk/types/logging_when.py b/src/truefoundry_sdk/types/logging_when.py new file mode 100644 index 00000000..98fce42d --- /dev/null +++ b/src/truefoundry_sdk/types/logging_when.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .in_not_in import InNotIn + + +class LoggingWhen(UniversalBaseModel): + """ + Conditions + """ + + subjects: typing.Optional[InNotIn] = None + models: typing.Optional[InNotIn] = None + metadata: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Metadata key-value pairs this config applies to (exact match) + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server.py b/src/truefoundry_sdk/types/mcp_server.py new file mode 100644 index 00000000..11d78a37 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server.py @@ -0,0 +1,64 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .mcp_server_auth_status_info import McpServerAuthStatusInfo +from .subject import Subject + + +class McpServer(UniversalBaseModel): + id: typing.Optional[str] = None + fqn: str + manifest: typing.Dict[str, typing.Any] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + tools: typing.Optional[typing.List[typing.Dict[str, typing.Any]]] = None + spec_endpoints: typing_extensions.Annotated[ + typing.Optional[typing.List[typing.Dict[str, typing.Any]]], + FieldMetadata(alias="specEndpoints"), + pydantic.Field(alias="specEndpoints"), + ] = None + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + proxy_url: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="proxyUrl"), + pydantic.Field(alias="proxyUrl", description="Proxy URL for accessing the MCP server"), + ] = None + """ + Proxy URL for accessing the MCP server + """ + + auth_status: typing_extensions.Annotated[ + typing.Optional[McpServerAuthStatusInfo], + FieldMetadata(alias="authStatus"), + pydantic.Field(alias="authStatus", description="Authentication status for the MCP server"), + ] = None + """ + Authentication status for the MCP server + """ + + is_auth_override_supported: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="isAuthOverrideSupported"), + pydantic.Field(alias="isAuthOverrideSupported"), + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_auth_status_info.py b/src/truefoundry_sdk/types/mcp_server_auth_status_info.py new file mode 100644 index 00000000..bbb25da8 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_auth_status_info.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .mcp_server_auth_status_info_method import McpServerAuthStatusInfoMethod +from .mcp_server_auth_status_info_status import McpServerAuthStatusInfoStatus + + +class McpServerAuthStatusInfo(UniversalBaseModel): + status: McpServerAuthStatusInfoStatus = pydantic.Field() + """ + Whether the user is authenticated or unauthenticated for this MCP server + """ + + method: typing.Optional[McpServerAuthStatusInfoMethod] = pydantic.Field(default=None) + """ + Authentication method used (e.g. OAuth, auth-override) + """ + + message: typing.Optional[str] = pydantic.Field(default=None) + """ + Human-readable message providing additional context about the authentication status + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_auth_status_info_method.py b/src/truefoundry_sdk/types/mcp_server_auth_status_info_method.py new file mode 100644 index 00000000..48fb2e59 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_auth_status_info_method.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class McpServerAuthStatusInfoMethod(enum.StrEnum): + """ + Authentication method used (e.g. OAuth, auth-override) + """ + + OAUTH = "oauth" + AUTH_OVERRIDE = "auth-override" + _UNKNOWN = "__MCPSERVERAUTHSTATUSINFOMETHOD_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "McpServerAuthStatusInfoMethod": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + oauth: typing.Callable[[], T_Result], + auth_override: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is McpServerAuthStatusInfoMethod.OAUTH: + return oauth() + if self is McpServerAuthStatusInfoMethod.AUTH_OVERRIDE: + return auth_override() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_auth_status_info_status.py b/src/truefoundry_sdk/types/mcp_server_auth_status_info_status.py new file mode 100644 index 00000000..74dcd28f --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_auth_status_info_status.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class McpServerAuthStatusInfoStatus(enum.StrEnum): + """ + Whether the user is authenticated or unauthenticated for this MCP server + """ + + AUTHENTICATED = "authenticated" + UNAUTHENTICATED = "unauthenticated" + _UNKNOWN = "__MCPSERVERAUTHSTATUSINFOSTATUS_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "McpServerAuthStatusInfoStatus": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + authenticated: typing.Callable[[], T_Result], + unauthenticated: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is McpServerAuthStatusInfoStatus.AUTHENTICATED: + return authenticated() + if self is McpServerAuthStatusInfoStatus.UNAUTHENTICATED: + return unauthenticated() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2.py b/src/truefoundry_sdk/types/mcp_server_o_auth2.py index c766df25..03a42fb3 100644 --- a/src/truefoundry_sdk/types/mcp_server_o_auth2.py +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2.py @@ -8,9 +8,13 @@ from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource from .mcp_server_o_auth2provider import McpServerOAuth2Provider from .mcp_server_o_auth2provider_auth0settings import McpServerOAuth2ProviderAuth0Settings +from .mcp_server_o_auth2provider_okta_id_jag_settings import McpServerOAuth2ProviderOktaIdJagSettings +from .mcp_server_o_auth2provider_okta_settings import McpServerOAuth2ProviderOktaSettings -class McpServerOAuth2(McpServerOAuth2ProviderAuth0Settings): +class McpServerOAuth2( + McpServerOAuth2ProviderAuth0Settings, McpServerOAuth2ProviderOktaSettings, McpServerOAuth2ProviderOktaIdJagSettings +): """ OAuth2 """ @@ -30,7 +34,7 @@ class McpServerOAuth2(McpServerOAuth2ProviderAuth0Settings): URL for the authorization request """ - token_url: str = pydantic.Field() + token_url: typing.Optional[str] = pydantic.Field(default=None) """ The endpoint to exchange auth code for tokens. """ @@ -55,6 +59,11 @@ class McpServerOAuth2(McpServerOAuth2ProviderAuth0Settings): URL to fetch token expiry (RFC 7662) when the provider does not return expires_in (e.g. Salesforce). Requires client_id and client_secret. """ + include_resource: typing.Optional[bool] = pydantic.Field(default=None) + """ + When enabled, the MCP server URL is sent as the resource parameter (RFC 8707) on both authorization and token endpoint requests. + """ + provider: McpServerOAuth2Provider = pydantic.Field() """ Select the OAuth provider. Provider-specific configuration (e.g. Auth0 organization) is unlocked based on this value. @@ -67,7 +76,7 @@ class McpServerOAuth2(McpServerOAuth2ProviderAuth0Settings): List of supported PKCE code challenge methods (S256 only) """ - jwt_source: McpServerOAuth2JwtSource = pydantic.Field() + jwt_source: typing.Optional[McpServerOAuth2JwtSource] = pydantic.Field(default=None) """ Source of the JWT token to be used for verification. """ @@ -79,7 +88,7 @@ class McpServerOAuth2(McpServerOAuth2ProviderAuth0Settings): additional_token_params: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) """ - Extra key/value pairs sent on every token endpoint request (e.g. Auth0 'audience'). + Extra key/value pairs sent on every token endpoint request (e.g. Auth0 'organization'). """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py index 184eccd6..fcdf4bf5 100644 --- a/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py @@ -14,6 +14,8 @@ class McpServerOAuth2GrantType(enum.StrEnum): AUTHORIZATION_CODE = "authorization_code" CLIENT_CREDENTIALS = "client_credentials" + TOKEN_EXCHANGE = "token_exchange" + ID_JAG = "id_jag" _UNKNOWN = "__MCPSERVEROAUTH2GRANTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -29,10 +31,16 @@ def visit( self, authorization_code: typing.Callable[[], T_Result], client_credentials: typing.Callable[[], T_Result], + token_exchange: typing.Callable[[], T_Result], + id_jag: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is McpServerOAuth2GrantType.AUTHORIZATION_CODE: return authorization_code() if self is McpServerOAuth2GrantType.CLIENT_CREDENTIALS: return client_credentials() + if self is McpServerOAuth2GrantType.TOKEN_EXCHANGE: + return token_exchange() + if self is McpServerOAuth2GrantType.ID_JAG: + return id_jag() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_id_jag_settings.py b/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_id_jag_settings.py new file mode 100644 index 00000000..b8ca3403 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_id_jag_settings.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class McpServerOAuth2ProviderOktaIdJagSettings(UniversalBaseModel): + issuer_uri: typing.Optional[str] = pydantic.Field(default=None) + """ + Issuer URI of the authorization server the ID-JAG token is issued for. Sent as the 'audience' parameter on the ID-JAG token exchange. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_settings.py b/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_settings.py new file mode 100644 index 00000000..0c77c1cb --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2provider_okta_settings.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class McpServerOAuth2ProviderOktaSettings(UniversalBaseModel): + audience: typing.Optional[str] = pydantic.Field(default=None) + """ + Okta target audience (RFC 8693 'audience'). Required when the token_exchange grant type is used with the okta provider. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mistral_ai_provider_account.py b/src/truefoundry_sdk/types/mistral_ai_provider_account.py index 93f1f3a4..31d05dd4 100644 --- a/src/truefoundry_sdk/types/mistral_ai_provider_account.py +++ b/src/truefoundry_sdk/types/mistral_ai_provider_account.py @@ -14,7 +14,7 @@ class MistralAiProviderAccount(UniversalBaseModel): """ - Mistral AI Provider Account + Mistral AI Model Account """ type: typing.Literal["provider-account/mistral-ai"] = pydantic.Field(default="provider-account/mistral-ai") @@ -24,18 +24,18 @@ class MistralAiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Mistral AI provider account + The name of the Mistral AI model account """ auth_data: MistralAiKeyAuth integrations: typing.List[MistralAiIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Mistral AI provider account + List of integrations that are associated with the Mistral AI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class MistralAiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/gateway_logging_rule.py b/src/truefoundry_sdk/types/noma_security_api_key_auth.py similarity index 60% rename from src/truefoundry_sdk/types/gateway_logging_rule.py rename to src/truefoundry_sdk/types/noma_security_api_key_auth.py index 3306215d..0f403acf 100644 --- a/src/truefoundry_sdk/types/gateway_logging_rule.py +++ b/src/truefoundry_sdk/types/noma_security_api_key_auth.py @@ -4,23 +4,21 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .gateway_logging_when import GatewayLoggingWhen -class GatewayLoggingRule(UniversalBaseModel): +class NomaSecurityApiKeyAuth(UniversalBaseModel): """ - Logging Rule + Noma Security API Key Auth """ - id: str = pydantic.Field() + type: typing.Literal["api-key"] = pydantic.Field(default="api-key") """ - Unique identifier for the rule + +value=api-key """ - when: GatewayLoggingWhen - tracing_project_fqn: str = pydantic.Field() + api_key: str = pydantic.Field() """ - FQN of the tracing project to send logs to + Noma API key for AI-DR scan access """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config.py b/src/truefoundry_sdk/types/noma_security_guardrail_config.py new file mode 100644 index 00000000..e9952e1d --- /dev/null +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .enforcing_strategy import EnforcingStrategy +from .noma_security_api_key_auth import NomaSecurityApiKeyAuth +from .noma_security_guardrail_config_config import NomaSecurityGuardrailConfigConfig + + +class NomaSecurityGuardrailConfig(UniversalBaseModel): + """ + Noma Security + """ + + name: str = pydantic.Field() + """ + The name of the Guardrail Config. + """ + + description: typing.Optional[str] = pydantic.Field( + default="Noma AI-DR for prompt, response, and tool content safety scanning" + ) + """ + Optional description for this Guardrail Config. + """ + + type: typing.Literal["integration/guardrail-config/noma-security"] = pydantic.Field( + default="integration/guardrail-config/noma-security" + ) + """ + +uiType=Hidden + +value=integration/guardrail-config/noma-security + """ + + auth_data: NomaSecurityApiKeyAuth + operation: typing.Literal["validate"] = pydantic.Field(default="validate") + """ + The operation type for this guardrail. Noma Security guardrails can only be used for validation. + """ + + enforcing_strategy: EnforcingStrategy + config: NomaSecurityGuardrailConfigConfig = pydantic.Field() + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py new file mode 100644 index 00000000..8629ae1e --- /dev/null +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class NomaSecurityGuardrailConfigConfig(UniversalBaseModel): + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional override for the Noma AI-DR base URL. Defaults to https://api.noma.security if not provided. Use https://app.sandbox.noma.security for sandbox testing. + """ + + application_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Value sent in x-noma-context.applicationId for traceability. Defaults to truefoundry if not provided. + """ + + user_id_metadata_key: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional request metadata key used to populate x-noma-context.userId. Defaults to gateway when not set. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/nomic_provider_account.py b/src/truefoundry_sdk/types/nomic_provider_account.py index 1d71fdab..7bee2116 100644 --- a/src/truefoundry_sdk/types/nomic_provider_account.py +++ b/src/truefoundry_sdk/types/nomic_provider_account.py @@ -14,7 +14,7 @@ class NomicProviderAccount(UniversalBaseModel): """ - Nomic Provider Account + Nomic Model Account """ type: typing.Literal["provider-account/nomic"] = pydantic.Field(default="provider-account/nomic") @@ -24,18 +24,18 @@ class NomicProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Nomic provider account + The name of the Nomic model account """ auth_data: NomicKeyAuth integrations: typing.List[NomicIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Nomic provider account + List of integrations that are associated with the Nomic model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class NomicProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/ollama_provider_account.py b/src/truefoundry_sdk/types/ollama_provider_account.py index 2a5ce6a7..cc41aabe 100644 --- a/src/truefoundry_sdk/types/ollama_provider_account.py +++ b/src/truefoundry_sdk/types/ollama_provider_account.py @@ -14,7 +14,7 @@ class OllamaProviderAccount(UniversalBaseModel): """ - Ollama Provider Account + Ollama Model Account """ type: typing.Literal["provider-account/ollama"] = pydantic.Field(default="provider-account/ollama") @@ -24,18 +24,18 @@ class OllamaProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Ollama provider account + The name of the Ollama model account """ auth_data: OllamaKeyAuth integrations: typing.List[OllamaIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Ollama provider account + List of integrations that are associated with the Ollama model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class OllamaProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/open_router_provider_account.py b/src/truefoundry_sdk/types/open_router_provider_account.py index fc877281..f6ed6ad0 100644 --- a/src/truefoundry_sdk/types/open_router_provider_account.py +++ b/src/truefoundry_sdk/types/open_router_provider_account.py @@ -14,7 +14,7 @@ class OpenRouterProviderAccount(UniversalBaseModel): """ - OpenRouter Provider Account + OpenRouter Model Account """ type: typing.Literal["provider-account/openrouter"] = pydantic.Field(default="provider-account/openrouter") @@ -24,18 +24,18 @@ class OpenRouterProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the OpenRouter provider account + The name of the OpenRouter model account """ auth_data: OpenRouterApiKeyAuth integrations: typing.List[OpenRouterIntegrations] = pydantic.Field() """ - List of integrations that are associated with the OpenRouter provider account + List of integrations that are associated with the OpenRouter model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class OpenRouterProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/openai_provider_account.py b/src/truefoundry_sdk/types/openai_provider_account.py index f3d77b0b..67d7efc3 100644 --- a/src/truefoundry_sdk/types/openai_provider_account.py +++ b/src/truefoundry_sdk/types/openai_provider_account.py @@ -14,7 +14,7 @@ class OpenaiProviderAccount(UniversalBaseModel): """ - OpenAI Provider Account + OpenAI Model Account """ type: typing.Literal["provider-account/openai"] = pydantic.Field(default="provider-account/openai") @@ -24,7 +24,7 @@ class OpenaiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the OpenAI provider account + The name of the OpenAI model account """ auth_data: typing.Optional[OpenaiApiKeyAuth] = None @@ -35,12 +35,12 @@ class OpenaiProviderAccount(UniversalBaseModel): integrations: typing.List[OpenAiIntegrations] = pydantic.Field() """ - List of integrations that are associated with the OpenAI provider account + List of integrations that are associated with the OpenAI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -48,7 +48,7 @@ class OpenaiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/palm_provider_account.py b/src/truefoundry_sdk/types/palm_provider_account.py index 20cdf4f2..be744cde 100644 --- a/src/truefoundry_sdk/types/palm_provider_account.py +++ b/src/truefoundry_sdk/types/palm_provider_account.py @@ -14,7 +14,7 @@ class PalmProviderAccount(UniversalBaseModel): """ - PaLM Provider Account + PaLM Model Account """ type: typing.Literal["provider-account/palm"] = pydantic.Field(default="provider-account/palm") @@ -24,18 +24,18 @@ class PalmProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the PaLM provider account + The name of the PaLM model account """ auth_data: PalmKeyAuth integrations: typing.List[PalmIntegrations] = pydantic.Field() """ - List of integrations that are associated with the PaLM provider account + List of integrations that are associated with the PaLM model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class PalmProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/period_usage_dto.py b/src/truefoundry_sdk/types/period_usage_dto.py new file mode 100644 index 00000000..38aa65ff --- /dev/null +++ b/src/truefoundry_sdk/types/period_usage_dto.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class PeriodUsageDto(UniversalBaseModel): + limit: float = pydantic.Field() + """ + Resolved (override-aware) cost limit for the period. + """ + + used: float = pydantic.Field() + """ + Cost used in the current window of the period. + """ + + percentage: float = pydantic.Field() + """ + Usage as a percentage of the limit, capped at 100. + """ + + start: float = pydantic.Field() + """ + Current window start, Unix epoch seconds (UTC). + """ + + end: float = pydantic.Field() + """ + Current window end, Unix epoch seconds (UTC, inclusive). + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/permission_set_v2.py b/src/truefoundry_sdk/types/permission_set_v2.py new file mode 100644 index 00000000..46bed880 --- /dev/null +++ b/src/truefoundry_sdk/types/permission_set_v2.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .permission_set_v2resource_type import PermissionSetV2ResourceType + + +class PermissionSetV2(UniversalBaseModel): + id: typing.Optional[str] = None + resource_type: typing_extensions.Annotated[ + PermissionSetV2ResourceType, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType") + ] + permissions: typing.List[str] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/permission_set_v2resource_type.py b/src/truefoundry_sdk/types/permission_set_v2resource_type.py new file mode 100644 index 00000000..a71c7163 --- /dev/null +++ b/src/truefoundry_sdk/types/permission_set_v2resource_type.py @@ -0,0 +1,194 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class PermissionSetV2ResourceType(enum.StrEnum): + ROLE = "role" + ACCOUNT = "account" + CLUSTER = "cluster" + WORKSPACE = "workspace" + ENVIRONMENT = "environment" + SECRET_GROUP = "secret-group" + DEPLOYMENT = "deployment" + APPLICATION = "application" + SECRET = "secret" + DOCKER_REGISTRY = "docker-registry" + TENANT = "tenant" + VCS_INTEGRATION = "vcs-integration" + MLF_PROJECT = "mlf-project" + REPOSITORY = "repository" + PROVIDER_INTEGRATION = "provider-integration" + TEAM = "team" + SERVICE_ACCOUNT = "service-account" + LLM_GATEWAY = "llm-gateway" + POLICY = "policy" + ROLE_BINDING = "role-binding" + SETTINGS = "settings" + PROVIDER_ACCOUNT = "provider-account" + USER = "user" + ALERT_CONFIG = "alert-config" + ALERT_RULE = "alert-rule" + GATEWAY_CONFIG = "gateway-config" + GATEWAY_CONTROLS = "gateway-controls" + GATEWAY_BUDGET = "gateway-budget" + GATEWAY_POLICY = "gateway-policy" + GATEWAY_APPROVAL_REQUEST = "gateway-approval-request" + TRACING_PROJECT = "tracing-project" + TRACING_APPLICATION = "tracing-application" + AGENT = "agent" + AGENT_APP = "agent-app" + AGENT_CHANNEL = "agent-channel" + GATEWAY_INSTALLATION = "gateway-installation" + VIRTUAL_ACCOUNT = "virtual-account" + SSO_BASED_IDENTITY = "sso-based-identity" + EXTERNAL_IDENTITY = "external-identity" + MCP_SERVER = "mcp-server" + EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" + AGENT_IDENTITY = "agent-identity" + _UNKNOWN = "__PERMISSIONSETV2RESOURCETYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "PermissionSetV2ResourceType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + role: typing.Callable[[], T_Result], + account: typing.Callable[[], T_Result], + cluster: typing.Callable[[], T_Result], + workspace: typing.Callable[[], T_Result], + environment: typing.Callable[[], T_Result], + secret_group: typing.Callable[[], T_Result], + deployment: typing.Callable[[], T_Result], + application: typing.Callable[[], T_Result], + secret: typing.Callable[[], T_Result], + docker_registry: typing.Callable[[], T_Result], + tenant: typing.Callable[[], T_Result], + vcs_integration: typing.Callable[[], T_Result], + mlf_project: typing.Callable[[], T_Result], + repository: typing.Callable[[], T_Result], + provider_integration: typing.Callable[[], T_Result], + team: typing.Callable[[], T_Result], + service_account: typing.Callable[[], T_Result], + llm_gateway: typing.Callable[[], T_Result], + policy: typing.Callable[[], T_Result], + role_binding: typing.Callable[[], T_Result], + settings: typing.Callable[[], T_Result], + provider_account: typing.Callable[[], T_Result], + user: typing.Callable[[], T_Result], + alert_config: typing.Callable[[], T_Result], + alert_rule: typing.Callable[[], T_Result], + gateway_config: typing.Callable[[], T_Result], + gateway_controls: typing.Callable[[], T_Result], + gateway_budget: typing.Callable[[], T_Result], + gateway_policy: typing.Callable[[], T_Result], + gateway_approval_request: typing.Callable[[], T_Result], + tracing_project: typing.Callable[[], T_Result], + tracing_application: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], + agent_app: typing.Callable[[], T_Result], + agent_channel: typing.Callable[[], T_Result], + gateway_installation: typing.Callable[[], T_Result], + virtual_account: typing.Callable[[], T_Result], + sso_based_identity: typing.Callable[[], T_Result], + external_identity: typing.Callable[[], T_Result], + mcp_server: typing.Callable[[], T_Result], + external_identity_provider: typing.Callable[[], T_Result], + agent_identity: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is PermissionSetV2ResourceType.ROLE: + return role() + if self is PermissionSetV2ResourceType.ACCOUNT: + return account() + if self is PermissionSetV2ResourceType.CLUSTER: + return cluster() + if self is PermissionSetV2ResourceType.WORKSPACE: + return workspace() + if self is PermissionSetV2ResourceType.ENVIRONMENT: + return environment() + if self is PermissionSetV2ResourceType.SECRET_GROUP: + return secret_group() + if self is PermissionSetV2ResourceType.DEPLOYMENT: + return deployment() + if self is PermissionSetV2ResourceType.APPLICATION: + return application() + if self is PermissionSetV2ResourceType.SECRET: + return secret() + if self is PermissionSetV2ResourceType.DOCKER_REGISTRY: + return docker_registry() + if self is PermissionSetV2ResourceType.TENANT: + return tenant() + if self is PermissionSetV2ResourceType.VCS_INTEGRATION: + return vcs_integration() + if self is PermissionSetV2ResourceType.MLF_PROJECT: + return mlf_project() + if self is PermissionSetV2ResourceType.REPOSITORY: + return repository() + if self is PermissionSetV2ResourceType.PROVIDER_INTEGRATION: + return provider_integration() + if self is PermissionSetV2ResourceType.TEAM: + return team() + if self is PermissionSetV2ResourceType.SERVICE_ACCOUNT: + return service_account() + if self is PermissionSetV2ResourceType.LLM_GATEWAY: + return llm_gateway() + if self is PermissionSetV2ResourceType.POLICY: + return policy() + if self is PermissionSetV2ResourceType.ROLE_BINDING: + return role_binding() + if self is PermissionSetV2ResourceType.SETTINGS: + return settings() + if self is PermissionSetV2ResourceType.PROVIDER_ACCOUNT: + return provider_account() + if self is PermissionSetV2ResourceType.USER: + return user() + if self is PermissionSetV2ResourceType.ALERT_CONFIG: + return alert_config() + if self is PermissionSetV2ResourceType.ALERT_RULE: + return alert_rule() + if self is PermissionSetV2ResourceType.GATEWAY_CONFIG: + return gateway_config() + if self is PermissionSetV2ResourceType.GATEWAY_CONTROLS: + return gateway_controls() + if self is PermissionSetV2ResourceType.GATEWAY_BUDGET: + return gateway_budget() + if self is PermissionSetV2ResourceType.GATEWAY_POLICY: + return gateway_policy() + if self is PermissionSetV2ResourceType.GATEWAY_APPROVAL_REQUEST: + return gateway_approval_request() + if self is PermissionSetV2ResourceType.TRACING_PROJECT: + return tracing_project() + if self is PermissionSetV2ResourceType.TRACING_APPLICATION: + return tracing_application() + if self is PermissionSetV2ResourceType.AGENT: + return agent() + if self is PermissionSetV2ResourceType.AGENT_APP: + return agent_app() + if self is PermissionSetV2ResourceType.AGENT_CHANNEL: + return agent_channel() + if self is PermissionSetV2ResourceType.GATEWAY_INSTALLATION: + return gateway_installation() + if self is PermissionSetV2ResourceType.VIRTUAL_ACCOUNT: + return virtual_account() + if self is PermissionSetV2ResourceType.SSO_BASED_IDENTITY: + return sso_based_identity() + if self is PermissionSetV2ResourceType.EXTERNAL_IDENTITY: + return external_identity() + if self is PermissionSetV2ResourceType.MCP_SERVER: + return mcp_server() + if self is PermissionSetV2ResourceType.EXTERNAL_IDENTITY_PROVIDER: + return external_identity_provider() + if self is PermissionSetV2ResourceType.AGENT_IDENTITY: + return agent_identity() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/perplexity_ai_provider_account.py b/src/truefoundry_sdk/types/perplexity_ai_provider_account.py index bccd1f60..3e3ae93c 100644 --- a/src/truefoundry_sdk/types/perplexity_ai_provider_account.py +++ b/src/truefoundry_sdk/types/perplexity_ai_provider_account.py @@ -14,7 +14,7 @@ class PerplexityAiProviderAccount(UniversalBaseModel): """ - Perplexity AI Provider Account + Perplexity AI Model Account """ type: typing.Literal["provider-account/perplexity-ai"] = pydantic.Field(default="provider-account/perplexity-ai") @@ -24,18 +24,18 @@ class PerplexityAiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Perplexity AI provider account + The name of the Perplexity AI model account """ auth_data: PerplexityAiKeyAuth integrations: typing.List[PerplexityIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Perplexity AI provider account + List of integrations that are associated with the Perplexity AI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class PerplexityAiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/policy.py b/src/truefoundry_sdk/types/policy.py new file mode 100644 index 00000000..57db5b5f --- /dev/null +++ b/src/truefoundry_sdk/types/policy.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .policy_version import PolicyVersion +from .subject import Subject + + +class Policy(UniversalBaseModel): + id: typing.Optional[str] = None + name: str + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + active_version: typing_extensions.Annotated[ + float, FieldMetadata(alias="activeVersion"), pydantic.Field(alias="activeVersion") + ] + active_policy_version: typing_extensions.Annotated[ + typing.Optional[PolicyVersion], + FieldMetadata(alias="activePolicyVersion"), + pydantic.Field(alias="activePolicyVersion"), + ] = None + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/policy_version.py b/src/truefoundry_sdk/types/policy_version.py new file mode 100644 index 00000000..c1265ef9 --- /dev/null +++ b/src/truefoundry_sdk/types/policy_version.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class PolicyVersion(UniversalBaseModel): + id: typing.Optional[str] = None + policy_id: typing_extensions.Annotated[str, FieldMetadata(alias="policyId"), pydantic.Field(alias="policyId")] + manifest: typing.Dict[str, typing.Any] + version: float + created_by_subject: typing_extensions.Annotated[ + typing.Optional[Subject], FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/provider_account.py b/src/truefoundry_sdk/types/provider_account.py new file mode 100644 index 00000000..a621e523 --- /dev/null +++ b/src/truefoundry_sdk/types/provider_account.py @@ -0,0 +1,59 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs +from ..core.serialization import FieldMetadata +from .provider_account_provider import ProviderAccountProvider +from .subject import Subject + + +class ProviderAccount(UniversalBaseModel): + id: typing.Optional[str] = pydantic.Field(default=None) + """ + System-generated provider account ID. + """ + + fqn: str = pydantic.Field() + """ + Human-readable Fully Qualified Name of the provider account. + """ + + provider: ProviderAccountProvider + manifest: typing.Dict[str, typing.Any] + integrations: typing.Optional[typing.List["ProviderIntegration"]] = pydantic.Field(default=None) + """ + List of Provider Integrations + """ + + created_by_subject: typing_extensions.Annotated[ + typing.Optional[Subject], FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] = None + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow + + +from .provider_integration import ProviderIntegration # noqa: E402, I001 + +update_forward_refs(ProviderAccount, ProviderIntegration=ProviderIntegration) diff --git a/src/truefoundry_sdk/types/provider_account_provider.py b/src/truefoundry_sdk/types/provider_account_provider.py new file mode 100644 index 00000000..1f8686a2 --- /dev/null +++ b/src/truefoundry_sdk/types/provider_account_provider.py @@ -0,0 +1,254 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class ProviderAccountProvider(enum.StrEnum): + AWS = "aws" + GCP = "gcp" + AZURE = "azure" + DOCKERHUB = "dockerhub" + OPENAI = "openai" + DATABRICKS = "databricks" + TRUEFOUNDRY = "truefoundry" + JFROG = "jfrog" + TTL = "ttl" + CUSTOM = "custom" + QUAY = "quay" + GITHUB = "github" + GITLAB = "gitlab" + BITBUCKET = "bitbucket" + BITBUCKET_DATA_CENTER = "bitbucket_data_center" + AI21 = "ai21" + COHERE = "cohere" + ANTHROPIC = "anthropic" + ANYSCALE = "anyscale" + DEEPINFRA = "deepinfra" + GROQ = "groq" + MISTRAL_AI = "mistral-ai" + NOMIC = "nomic" + PALM = "palm" + PERPLEXITY_AI = "perplexity-ai" + TOGETHER_AI = "together-ai" + OLLAMA = "ollama" + SLACK = "slack" + AWS_BEDROCK = "aws-bedrock" + GOOGLE_VERTEX = "google-vertex" + GOOGLE_GEMINI = "google-gemini" + AZURE_OPENAI = "azure-openai" + AZURE_FOUNDRY = "azure-foundry" + SELF_HOSTED_MODEL = "self-hosted-model" + MCP_SERVER_GROUP = "mcp-server-group" + PAGERDUTY = "pagerduty" + MS_TEAMS = "ms-teams" + MODEL_PROVIDER_ACCOUNTS = "model-provider-accounts" + GUARDRAIL_CONFIG_GROUP = "guardrail-config-group" + OPENROUTER = "openrouter" + SAMBANOVA = "sambanova" + AWS_SAGEMAKER = "aws-sagemaker" + CEREBRAS = "cerebras" + WAFER = "wafer" + HASHICORP = "hashicorp" + SNOWFLAKE_CORTEX = "snowflake-cortex" + CLOUDERA = "cloudera" + XAI = "xai" + BASETEN = "baseten" + VIRTUAL_MODEL = "virtual-model" + ELEVENLABS = "elevenlabs" + DEEPGRAM = "deepgram" + CARTESIA = "cartesia" + CUSTOM_ENDPOINT = "custom-endpoint" + SMALLEST_AI = "smallest-ai" + AWS_CLAUDE_PLATFORM = "aws-claude-platform" + AWS_BEDROCK_MANTLE = "aws-bedrock-mantle" + _UNKNOWN = "__PROVIDERACCOUNTPROVIDER_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "ProviderAccountProvider": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + aws: typing.Callable[[], T_Result], + gcp: typing.Callable[[], T_Result], + azure: typing.Callable[[], T_Result], + dockerhub: typing.Callable[[], T_Result], + openai: typing.Callable[[], T_Result], + databricks: typing.Callable[[], T_Result], + truefoundry: typing.Callable[[], T_Result], + jfrog: typing.Callable[[], T_Result], + ttl: typing.Callable[[], T_Result], + custom: typing.Callable[[], T_Result], + quay: typing.Callable[[], T_Result], + github: typing.Callable[[], T_Result], + gitlab: typing.Callable[[], T_Result], + bitbucket: typing.Callable[[], T_Result], + bitbucket_data_center: typing.Callable[[], T_Result], + ai21: typing.Callable[[], T_Result], + cohere: typing.Callable[[], T_Result], + anthropic: typing.Callable[[], T_Result], + anyscale: typing.Callable[[], T_Result], + deepinfra: typing.Callable[[], T_Result], + groq: typing.Callable[[], T_Result], + mistral_ai: typing.Callable[[], T_Result], + nomic: typing.Callable[[], T_Result], + palm: typing.Callable[[], T_Result], + perplexity_ai: typing.Callable[[], T_Result], + together_ai: typing.Callable[[], T_Result], + ollama: typing.Callable[[], T_Result], + slack: typing.Callable[[], T_Result], + aws_bedrock: typing.Callable[[], T_Result], + google_vertex: typing.Callable[[], T_Result], + google_gemini: typing.Callable[[], T_Result], + azure_openai: typing.Callable[[], T_Result], + azure_foundry: typing.Callable[[], T_Result], + self_hosted_model: typing.Callable[[], T_Result], + mcp_server_group: typing.Callable[[], T_Result], + pagerduty: typing.Callable[[], T_Result], + ms_teams: typing.Callable[[], T_Result], + model_provider_accounts: typing.Callable[[], T_Result], + guardrail_config_group: typing.Callable[[], T_Result], + openrouter: typing.Callable[[], T_Result], + sambanova: typing.Callable[[], T_Result], + aws_sagemaker: typing.Callable[[], T_Result], + cerebras: typing.Callable[[], T_Result], + wafer: typing.Callable[[], T_Result], + hashicorp: typing.Callable[[], T_Result], + snowflake_cortex: typing.Callable[[], T_Result], + cloudera: typing.Callable[[], T_Result], + xai: typing.Callable[[], T_Result], + baseten: typing.Callable[[], T_Result], + virtual_model: typing.Callable[[], T_Result], + elevenlabs: typing.Callable[[], T_Result], + deepgram: typing.Callable[[], T_Result], + cartesia: typing.Callable[[], T_Result], + custom_endpoint: typing.Callable[[], T_Result], + smallest_ai: typing.Callable[[], T_Result], + aws_claude_platform: typing.Callable[[], T_Result], + aws_bedrock_mantle: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is ProviderAccountProvider.AWS: + return aws() + if self is ProviderAccountProvider.GCP: + return gcp() + if self is ProviderAccountProvider.AZURE: + return azure() + if self is ProviderAccountProvider.DOCKERHUB: + return dockerhub() + if self is ProviderAccountProvider.OPENAI: + return openai() + if self is ProviderAccountProvider.DATABRICKS: + return databricks() + if self is ProviderAccountProvider.TRUEFOUNDRY: + return truefoundry() + if self is ProviderAccountProvider.JFROG: + return jfrog() + if self is ProviderAccountProvider.TTL: + return ttl() + if self is ProviderAccountProvider.CUSTOM: + return custom() + if self is ProviderAccountProvider.QUAY: + return quay() + if self is ProviderAccountProvider.GITHUB: + return github() + if self is ProviderAccountProvider.GITLAB: + return gitlab() + if self is ProviderAccountProvider.BITBUCKET: + return bitbucket() + if self is ProviderAccountProvider.BITBUCKET_DATA_CENTER: + return bitbucket_data_center() + if self is ProviderAccountProvider.AI21: + return ai21() + if self is ProviderAccountProvider.COHERE: + return cohere() + if self is ProviderAccountProvider.ANTHROPIC: + return anthropic() + if self is ProviderAccountProvider.ANYSCALE: + return anyscale() + if self is ProviderAccountProvider.DEEPINFRA: + return deepinfra() + if self is ProviderAccountProvider.GROQ: + return groq() + if self is ProviderAccountProvider.MISTRAL_AI: + return mistral_ai() + if self is ProviderAccountProvider.NOMIC: + return nomic() + if self is ProviderAccountProvider.PALM: + return palm() + if self is ProviderAccountProvider.PERPLEXITY_AI: + return perplexity_ai() + if self is ProviderAccountProvider.TOGETHER_AI: + return together_ai() + if self is ProviderAccountProvider.OLLAMA: + return ollama() + if self is ProviderAccountProvider.SLACK: + return slack() + if self is ProviderAccountProvider.AWS_BEDROCK: + return aws_bedrock() + if self is ProviderAccountProvider.GOOGLE_VERTEX: + return google_vertex() + if self is ProviderAccountProvider.GOOGLE_GEMINI: + return google_gemini() + if self is ProviderAccountProvider.AZURE_OPENAI: + return azure_openai() + if self is ProviderAccountProvider.AZURE_FOUNDRY: + return azure_foundry() + if self is ProviderAccountProvider.SELF_HOSTED_MODEL: + return self_hosted_model() + if self is ProviderAccountProvider.MCP_SERVER_GROUP: + return mcp_server_group() + if self is ProviderAccountProvider.PAGERDUTY: + return pagerduty() + if self is ProviderAccountProvider.MS_TEAMS: + return ms_teams() + if self is ProviderAccountProvider.MODEL_PROVIDER_ACCOUNTS: + return model_provider_accounts() + if self is ProviderAccountProvider.GUARDRAIL_CONFIG_GROUP: + return guardrail_config_group() + if self is ProviderAccountProvider.OPENROUTER: + return openrouter() + if self is ProviderAccountProvider.SAMBANOVA: + return sambanova() + if self is ProviderAccountProvider.AWS_SAGEMAKER: + return aws_sagemaker() + if self is ProviderAccountProvider.CEREBRAS: + return cerebras() + if self is ProviderAccountProvider.WAFER: + return wafer() + if self is ProviderAccountProvider.HASHICORP: + return hashicorp() + if self is ProviderAccountProvider.SNOWFLAKE_CORTEX: + return snowflake_cortex() + if self is ProviderAccountProvider.CLOUDERA: + return cloudera() + if self is ProviderAccountProvider.XAI: + return xai() + if self is ProviderAccountProvider.BASETEN: + return baseten() + if self is ProviderAccountProvider.VIRTUAL_MODEL: + return virtual_model() + if self is ProviderAccountProvider.ELEVENLABS: + return elevenlabs() + if self is ProviderAccountProvider.DEEPGRAM: + return deepgram() + if self is ProviderAccountProvider.CARTESIA: + return cartesia() + if self is ProviderAccountProvider.CUSTOM_ENDPOINT: + return custom_endpoint() + if self is ProviderAccountProvider.SMALLEST_AI: + return smallest_ai() + if self is ProviderAccountProvider.AWS_CLAUDE_PLATFORM: + return aws_claude_platform() + if self is ProviderAccountProvider.AWS_BEDROCK_MANTLE: + return aws_bedrock_mantle() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/provider_integration.py b/src/truefoundry_sdk/types/provider_integration.py new file mode 100644 index 00000000..739979cb --- /dev/null +++ b/src/truefoundry_sdk/types/provider_integration.py @@ -0,0 +1,63 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs +from ..core.serialization import FieldMetadata +from .provider_integration_type import ProviderIntegrationType +from .subject import Subject + + +class ProviderIntegration(UniversalBaseModel): + id: str = pydantic.Field() + """ + System-generated provider integration ID. + """ + + name: str + fqn: str = pydantic.Field() + """ + Human-readable Fully Qualified Name of the provider integration. + """ + + type: ProviderIntegrationType + manifest: typing.Optional[typing.Dict[str, typing.Any]] = None + metadata: typing.Optional[typing.Dict[str, typing.Any]] = None + provider_account_fqn: typing_extensions.Annotated[ + str, FieldMetadata(alias="providerAccountFqn"), pydantic.Field(alias="providerAccountFqn") + ] + provider_account: typing_extensions.Annotated[ + typing.Optional["ProviderAccount"], + FieldMetadata(alias="providerAccount"), + pydantic.Field(alias="providerAccount"), + ] = None + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow + + +from .provider_account import ProviderAccount # noqa: E402, I001 + +update_forward_refs(ProviderIntegration, ProviderAccount=ProviderAccount) diff --git a/src/truefoundry_sdk/types/provider_integration_type.py b/src/truefoundry_sdk/types/provider_integration_type.py new file mode 100644 index 00000000..c6ee863b --- /dev/null +++ b/src/truefoundry_sdk/types/provider_integration_type.py @@ -0,0 +1,70 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class ProviderIntegrationType(enum.StrEnum): + BLOB_STORAGE = "blob-storage" + SECRET_STORE = "secret-store" + DOCKER_REGISTRY = "docker-registry" + MODEL = "model" + VCS = "vcs" + CLUSTER = "cluster" + NOTIFICATION_CHANNEL = "notification-channel" + HELM_REPO = "helm-repo" + JWT_AUTH = "jwt-auth" + MCP_SERVER = "mcp-server" + GUARDRAIL_CONFIG = "guardrail-config" + _UNKNOWN = "__PROVIDERINTEGRATIONTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "ProviderIntegrationType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + blob_storage: typing.Callable[[], T_Result], + secret_store: typing.Callable[[], T_Result], + docker_registry: typing.Callable[[], T_Result], + model: typing.Callable[[], T_Result], + vcs: typing.Callable[[], T_Result], + cluster: typing.Callable[[], T_Result], + notification_channel: typing.Callable[[], T_Result], + helm_repo: typing.Callable[[], T_Result], + jwt_auth: typing.Callable[[], T_Result], + mcp_server: typing.Callable[[], T_Result], + guardrail_config: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is ProviderIntegrationType.BLOB_STORAGE: + return blob_storage() + if self is ProviderIntegrationType.SECRET_STORE: + return secret_store() + if self is ProviderIntegrationType.DOCKER_REGISTRY: + return docker_registry() + if self is ProviderIntegrationType.MODEL: + return model() + if self is ProviderIntegrationType.VCS: + return vcs() + if self is ProviderIntegrationType.CLUSTER: + return cluster() + if self is ProviderIntegrationType.NOTIFICATION_CHANNEL: + return notification_channel() + if self is ProviderIntegrationType.HELM_REPO: + return helm_repo() + if self is ProviderIntegrationType.JWT_AUTH: + return jwt_auth() + if self is ProviderIntegrationType.MCP_SERVER: + return mcp_server() + if self is ProviderIntegrationType.GUARDRAIL_CONFIG: + return guardrail_config() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/redaction.py b/src/truefoundry_sdk/types/redaction.py new file mode 100644 index 00000000..a51bcad1 --- /dev/null +++ b/src/truefoundry_sdk/types/redaction.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .custom_regex_pattern import CustomRegexPattern +from .preset_regex_pattern_enum import PresetRegexPatternEnum + + +class Redaction(UniversalBaseModel): + """ + Redaction + """ + + presets: typing.Optional[typing.List[PresetRegexPatternEnum]] = pydantic.Field(default=None) + """ + Predefined patterns to redact from the logged copy. + """ + + custom_patterns: typing.Optional[typing.List[CustomRegexPattern]] = pydantic.Field(default=None) + """ + Custom patterns to redact from the logged copy. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/role.py b/src/truefoundry_sdk/types/role.py new file mode 100644 index 00000000..8cefbae2 --- /dev/null +++ b/src/truefoundry_sdk/types/role.py @@ -0,0 +1,108 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .permission_set_v2 import PermissionSetV2 +from .role_manifest import RoleManifest +from .role_resource_type import RoleResourceType + + +class Role(UniversalBaseModel): + id: str = pydantic.Field() + """ + System-generated role ID. + """ + + tenant_name: typing_extensions.Annotated[ + str, + FieldMetadata(alias="tenantName"), + pydantic.Field(alias="tenantName", description="Tenant the role belongs to."), + ] + """ + Tenant the role belongs to. + """ + + account_id: typing_extensions.Annotated[ + str, + FieldMetadata(alias="accountId"), + pydantic.Field(alias="accountId", description="System-generated ID of the account that owns the role."), + ] + """ + System-generated ID of the account that owns the role. + """ + + resource_type: typing_extensions.Annotated[ + RoleResourceType, + FieldMetadata(alias="resourceType"), + pydantic.Field(alias="resourceType", description="Resource type this role applies to (e.g. account, team)."), + ] + """ + Resource type this role applies to (e.g. account, team). + """ + + manifest: RoleManifest = pydantic.Field() + """ + The role manifest defining name, permissions, and metadata. + """ + + created_by_subject: typing_extensions.Annotated[ + typing.Dict[str, typing.Any], + FieldMetadata(alias="createdBySubject"), + pydantic.Field( + alias="createdBySubject", description="The subject (user or service account) that created this role." + ), + ] + """ + The subject (user or service account) that created this role. + """ + + permission_sets_v2: typing_extensions.Annotated[ + typing.Optional[typing.List[PermissionSetV2]], + FieldMetadata(alias="permissionSetsV2"), + pydantic.Field(alias="permissionSetsV2", description="Permission sets defining the actions this role grants."), + ] = None + """ + Permission sets defining the actions this role grants. + """ + + is_editable: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="isEditable"), + pydantic.Field( + alias="isEditable", + description="Whether this role can be edited. Default and system roles are non-editable.", + ), + ] + """ + Whether this role can be edited. Default and system roles are non-editable. + """ + + is_default: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="isDefault"), + pydantic.Field(alias="isDefault", description="Whether this is a built-in default role."), + ] + """ + Whether this is a built-in default role. + """ + + is_reserved: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="isReserved"), + pydantic.Field(alias="isReserved", description="Whether this role name is reserved for internal use."), + ] + """ + Whether this role name is reserved for internal use. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/role_binding.py b/src/truefoundry_sdk/types/role_binding.py new file mode 100644 index 00000000..2edb8602 --- /dev/null +++ b/src/truefoundry_sdk/types/role_binding.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .role_binding_manifest import RoleBindingManifest +from .subject import Subject + + +class RoleBinding(UniversalBaseModel): + id: typing.Optional[str] = None + name: str + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + manifest: RoleBindingManifest = pydantic.Field() + """ + Stored role binding manifest + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = None + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/role_binding_subject.py b/src/truefoundry_sdk/types/role_binding_subject.py index 46c1827e..4939ef3b 100644 --- a/src/truefoundry_sdk/types/role_binding_subject.py +++ b/src/truefoundry_sdk/types/role_binding_subject.py @@ -15,12 +15,12 @@ class RoleBindingSubject(UniversalBaseModel): type: RoleBindingSubjectType = pydantic.Field() """ - Whether this row identifies a user (email), a team (name), a virtual account (name), or an external identity (name). + Whether this row identifies a user (email), a team (name), or a virtual account (name). """ name: str = pydantic.Field() """ - User email when type is user; team or virtual account name when type is team or virtualaccount; external identity name when type is external-identity. + User email when type is user; team or virtual account name when type is team or virtualaccount. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/role_binding_subject_type.py b/src/truefoundry_sdk/types/role_binding_subject_type.py index 66561e9a..8893dd46 100644 --- a/src/truefoundry_sdk/types/role_binding_subject_type.py +++ b/src/truefoundry_sdk/types/role_binding_subject_type.py @@ -9,13 +9,12 @@ class RoleBindingSubjectType(enum.StrEnum): """ - Whether this row identifies a user (email), a team (name), a virtual account (name), or an external identity (name). + Whether this row identifies a user (email), a team (name), or a virtual account (name). """ USER = "user" TEAM = "team" VIRTUALACCOUNT = "virtualaccount" - EXTERNAL_IDENTITY = "external-identity" _UNKNOWN = "__ROLEBINDINGSUBJECTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -32,7 +31,6 @@ def visit( user: typing.Callable[[], T_Result], team: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is RoleBindingSubjectType.USER: @@ -41,6 +39,4 @@ def visit( return team() if self is RoleBindingSubjectType.VIRTUALACCOUNT: return virtualaccount() - if self is RoleBindingSubjectType.EXTERNAL_IDENTITY: - return external_identity() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/resource_type.py b/src/truefoundry_sdk/types/role_resource_type.py similarity index 65% rename from src/truefoundry_sdk/types/resource_type.py rename to src/truefoundry_sdk/types/role_resource_type.py index 85991524..dfe365e3 100644 --- a/src/truefoundry_sdk/types/resource_type.py +++ b/src/truefoundry_sdk/types/role_resource_type.py @@ -7,9 +7,9 @@ T_Result = typing.TypeVar("T_Result") -class ResourceType(enum.StrEnum): +class RoleResourceType(enum.StrEnum): """ - Resource type scope for the role assignment. + Resource type this role applies to (e.g. account, team). """ ROLE = "role" @@ -40,10 +40,13 @@ class ResourceType(enum.StrEnum): GATEWAY_CONFIG = "gateway-config" GATEWAY_CONTROLS = "gateway-controls" GATEWAY_BUDGET = "gateway-budget" + GATEWAY_POLICY = "gateway-policy" + GATEWAY_APPROVAL_REQUEST = "gateway-approval-request" TRACING_PROJECT = "tracing-project" TRACING_APPLICATION = "tracing-application" AGENT = "agent" AGENT_APP = "agent-app" + AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" SSO_BASED_IDENTITY = "sso-based-identity" @@ -51,13 +54,13 @@ class ResourceType(enum.StrEnum): MCP_SERVER = "mcp-server" EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" AGENT_IDENTITY = "agent-identity" - _UNKNOWN = "__RESOURCETYPE_UNKNOWN__" + _UNKNOWN = "__ROLERESOURCETYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "ResourceType": + def _missing_(cls, value: typing.Any) -> "RoleResourceType": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -92,10 +95,13 @@ def visit( gateway_config: typing.Callable[[], T_Result], gateway_controls: typing.Callable[[], T_Result], gateway_budget: typing.Callable[[], T_Result], + gateway_policy: typing.Callable[[], T_Result], + gateway_approval_request: typing.Callable[[], T_Result], tracing_project: typing.Callable[[], T_Result], tracing_application: typing.Callable[[], T_Result], agent: typing.Callable[[], T_Result], agent_app: typing.Callable[[], T_Result], + agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], sso_based_identity: typing.Callable[[], T_Result], @@ -105,82 +111,88 @@ def visit( agent_identity: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is ResourceType.ROLE: + if self is RoleResourceType.ROLE: return role() - if self is ResourceType.ACCOUNT: + if self is RoleResourceType.ACCOUNT: return account() - if self is ResourceType.CLUSTER: + if self is RoleResourceType.CLUSTER: return cluster() - if self is ResourceType.WORKSPACE: + if self is RoleResourceType.WORKSPACE: return workspace() - if self is ResourceType.ENVIRONMENT: + if self is RoleResourceType.ENVIRONMENT: return environment() - if self is ResourceType.SECRET_GROUP: + if self is RoleResourceType.SECRET_GROUP: return secret_group() - if self is ResourceType.DEPLOYMENT: + if self is RoleResourceType.DEPLOYMENT: return deployment() - if self is ResourceType.APPLICATION: + if self is RoleResourceType.APPLICATION: return application() - if self is ResourceType.SECRET: + if self is RoleResourceType.SECRET: return secret() - if self is ResourceType.DOCKER_REGISTRY: + if self is RoleResourceType.DOCKER_REGISTRY: return docker_registry() - if self is ResourceType.TENANT: + if self is RoleResourceType.TENANT: return tenant() - if self is ResourceType.VCS_INTEGRATION: + if self is RoleResourceType.VCS_INTEGRATION: return vcs_integration() - if self is ResourceType.MLF_PROJECT: + if self is RoleResourceType.MLF_PROJECT: return mlf_project() - if self is ResourceType.REPOSITORY: + if self is RoleResourceType.REPOSITORY: return repository() - if self is ResourceType.PROVIDER_INTEGRATION: + if self is RoleResourceType.PROVIDER_INTEGRATION: return provider_integration() - if self is ResourceType.TEAM: + if self is RoleResourceType.TEAM: return team() - if self is ResourceType.SERVICE_ACCOUNT: + if self is RoleResourceType.SERVICE_ACCOUNT: return service_account() - if self is ResourceType.LLM_GATEWAY: + if self is RoleResourceType.LLM_GATEWAY: return llm_gateway() - if self is ResourceType.POLICY: + if self is RoleResourceType.POLICY: return policy() - if self is ResourceType.ROLE_BINDING: + if self is RoleResourceType.ROLE_BINDING: return role_binding() - if self is ResourceType.SETTINGS: + if self is RoleResourceType.SETTINGS: return settings() - if self is ResourceType.PROVIDER_ACCOUNT: + if self is RoleResourceType.PROVIDER_ACCOUNT: return provider_account() - if self is ResourceType.USER: + if self is RoleResourceType.USER: return user() - if self is ResourceType.ALERT_CONFIG: + if self is RoleResourceType.ALERT_CONFIG: return alert_config() - if self is ResourceType.ALERT_RULE: + if self is RoleResourceType.ALERT_RULE: return alert_rule() - if self is ResourceType.GATEWAY_CONFIG: + if self is RoleResourceType.GATEWAY_CONFIG: return gateway_config() - if self is ResourceType.GATEWAY_CONTROLS: + if self is RoleResourceType.GATEWAY_CONTROLS: return gateway_controls() - if self is ResourceType.GATEWAY_BUDGET: + if self is RoleResourceType.GATEWAY_BUDGET: return gateway_budget() - if self is ResourceType.TRACING_PROJECT: + if self is RoleResourceType.GATEWAY_POLICY: + return gateway_policy() + if self is RoleResourceType.GATEWAY_APPROVAL_REQUEST: + return gateway_approval_request() + if self is RoleResourceType.TRACING_PROJECT: return tracing_project() - if self is ResourceType.TRACING_APPLICATION: + if self is RoleResourceType.TRACING_APPLICATION: return tracing_application() - if self is ResourceType.AGENT: + if self is RoleResourceType.AGENT: return agent() - if self is ResourceType.AGENT_APP: + if self is RoleResourceType.AGENT_APP: return agent_app() - if self is ResourceType.GATEWAY_INSTALLATION: + if self is RoleResourceType.AGENT_CHANNEL: + return agent_channel() + if self is RoleResourceType.GATEWAY_INSTALLATION: return gateway_installation() - if self is ResourceType.VIRTUAL_ACCOUNT: + if self is RoleResourceType.VIRTUAL_ACCOUNT: return virtual_account() - if self is ResourceType.SSO_BASED_IDENTITY: + if self is RoleResourceType.SSO_BASED_IDENTITY: return sso_based_identity() - if self is ResourceType.EXTERNAL_IDENTITY: + if self is RoleResourceType.EXTERNAL_IDENTITY: return external_identity() - if self is ResourceType.MCP_SERVER: + if self is RoleResourceType.MCP_SERVER: return mcp_server() - if self is ResourceType.EXTERNAL_IDENTITY_PROVIDER: + if self is RoleResourceType.EXTERNAL_IDENTITY_PROVIDER: return external_identity_provider() - if self is ResourceType.AGENT_IDENTITY: + if self is RoleResourceType.AGENT_IDENTITY: return agent_identity() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/role_with_resource_resource_type.py b/src/truefoundry_sdk/types/role_with_resource_resource_type.py index efcd3e8f..876ff3de 100644 --- a/src/truefoundry_sdk/types/role_with_resource_resource_type.py +++ b/src/truefoundry_sdk/types/role_with_resource_resource_type.py @@ -36,10 +36,13 @@ class RoleWithResourceResourceType(enum.StrEnum): GATEWAY_CONFIG = "gateway-config" GATEWAY_CONTROLS = "gateway-controls" GATEWAY_BUDGET = "gateway-budget" + GATEWAY_POLICY = "gateway-policy" + GATEWAY_APPROVAL_REQUEST = "gateway-approval-request" TRACING_PROJECT = "tracing-project" TRACING_APPLICATION = "tracing-application" AGENT = "agent" AGENT_APP = "agent-app" + AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" SSO_BASED_IDENTITY = "sso-based-identity" @@ -88,10 +91,13 @@ def visit( gateway_config: typing.Callable[[], T_Result], gateway_controls: typing.Callable[[], T_Result], gateway_budget: typing.Callable[[], T_Result], + gateway_policy: typing.Callable[[], T_Result], + gateway_approval_request: typing.Callable[[], T_Result], tracing_project: typing.Callable[[], T_Result], tracing_application: typing.Callable[[], T_Result], agent: typing.Callable[[], T_Result], agent_app: typing.Callable[[], T_Result], + agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], sso_based_identity: typing.Callable[[], T_Result], @@ -157,6 +163,10 @@ def visit( return gateway_controls() if self is RoleWithResourceResourceType.GATEWAY_BUDGET: return gateway_budget() + if self is RoleWithResourceResourceType.GATEWAY_POLICY: + return gateway_policy() + if self is RoleWithResourceResourceType.GATEWAY_APPROVAL_REQUEST: + return gateway_approval_request() if self is RoleWithResourceResourceType.TRACING_PROJECT: return tracing_project() if self is RoleWithResourceResourceType.TRACING_APPLICATION: @@ -165,6 +175,8 @@ def visit( return agent() if self is RoleWithResourceResourceType.AGENT_APP: return agent_app() + if self is RoleWithResourceResourceType.AGENT_CHANNEL: + return agent_channel() if self is RoleWithResourceResourceType.GATEWAY_INSTALLATION: return gateway_installation() if self is RoleWithResourceResourceType.VIRTUAL_ACCOUNT: diff --git a/src/truefoundry_sdk/types/samba_nova_provider_account.py b/src/truefoundry_sdk/types/samba_nova_provider_account.py index 715859c3..77029d93 100644 --- a/src/truefoundry_sdk/types/samba_nova_provider_account.py +++ b/src/truefoundry_sdk/types/samba_nova_provider_account.py @@ -14,7 +14,7 @@ class SambaNovaProviderAccount(UniversalBaseModel): """ - SambaNova Provider Account + SambaNova Model Account """ type: typing.Literal["provider-account/sambanova"] = pydantic.Field(default="provider-account/sambanova") @@ -24,18 +24,18 @@ class SambaNovaProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the SambaNova provider account + The name of the SambaNova model account """ auth_data: SambaNovaKeyAuth integrations: typing.List[SambaNovaIntegrations] = pydantic.Field() """ - List of integrations that are associated with the SambaNova provider account + List of integrations that are associated with the SambaNova model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class SambaNovaProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/self_hosted_model_provider_account.py b/src/truefoundry_sdk/types/self_hosted_model_provider_account.py index 036487a4..8e575062 100644 --- a/src/truefoundry_sdk/types/self_hosted_model_provider_account.py +++ b/src/truefoundry_sdk/types/self_hosted_model_provider_account.py @@ -25,12 +25,12 @@ class SelfHostedModelProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the provider account. + The name of the model account. """ integrations: typing.List[SelfHostedModelIntegrations] = pydantic.Field() """ - List of integrations that are associated with the provider account. + List of integrations that are associated with the model account. """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) @@ -43,7 +43,7 @@ class SelfHostedModelProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/settings.py b/src/truefoundry_sdk/types/settings.py new file mode 100644 index 00000000..47c99a40 --- /dev/null +++ b/src/truefoundry_sdk/types/settings.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class Settings(UniversalBaseModel): + id: typing.Optional[str] = None + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + type: str + manifest: typing.Dict[str, typing.Any] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + metadata: typing.Optional[typing.Dict[str, typing.Any]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/smallest_ai_provider_account.py b/src/truefoundry_sdk/types/smallest_ai_provider_account.py index d390dc03..77d82365 100644 --- a/src/truefoundry_sdk/types/smallest_ai_provider_account.py +++ b/src/truefoundry_sdk/types/smallest_ai_provider_account.py @@ -14,7 +14,7 @@ class SmallestAiProviderAccount(UniversalBaseModel): """ - Smallest AI Provider Account + Smallest AI Model Account """ type: typing.Literal["provider-account/smallest-ai"] = pydantic.Field(default="provider-account/smallest-ai") @@ -24,7 +24,7 @@ class SmallestAiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Smallest AI provider account + The name of the Smallest AI model account """ auth_data: SmallestAiApiKeyAuth @@ -35,12 +35,12 @@ class SmallestAiProviderAccount(UniversalBaseModel): integrations: typing.List[SmallestAiModel] = pydantic.Field() """ - List of integrations that are associated with the Smallest AI provider account + List of integrations that are associated with the Smallest AI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -48,7 +48,7 @@ class SmallestAiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py b/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py index f9f84564..10a1852f 100644 --- a/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py +++ b/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py @@ -14,7 +14,7 @@ class SnowflakeCortexProviderAccount(UniversalBaseModel): """ - Snowflake Cortex Provider Account + Snowflake Cortex Model Account """ type: typing.Literal["provider-account/snowflake-cortex"] = pydantic.Field( @@ -26,7 +26,7 @@ class SnowflakeCortexProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Snowflake Cortex provider account + The name of the Snowflake Cortex model account """ auth_data: SnowflakeCortexPatTokenAuth @@ -37,12 +37,12 @@ class SnowflakeCortexProviderAccount(UniversalBaseModel): integrations: typing.List[SnowflakeCortexIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Snowflake Cortex provider account + List of integrations that are associated with the Snowflake Cortex model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -50,7 +50,7 @@ class SnowflakeCortexProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/spark_job.py b/src/truefoundry_sdk/types/spark_job.py index b20ab8df..0710a91b 100644 --- a/src/truefoundry_sdk/types/spark_job.py +++ b/src/truefoundry_sdk/types/spark_job.py @@ -8,6 +8,7 @@ from .spark_executor_config import SparkExecutorConfig from .spark_job_entrypoint import SparkJobEntrypoint from .spark_job_image import SparkJobImage +from .spark_job_trigger import SparkJobTrigger from .volume_mount import VolumeMount @@ -33,6 +34,11 @@ class SparkJob(UniversalBaseModel): Entrypoint """ + trigger: typing.Optional[SparkJobTrigger] = pydantic.Field(default=None) + """ + Specify the trigger + """ + driver_config: SparkDriverConfig executor_config: SparkExecutorConfig env: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) diff --git a/src/truefoundry_sdk/types/spark_job_trigger.py b/src/truefoundry_sdk/types/spark_job_trigger.py new file mode 100644 index 00000000..20e5c188 --- /dev/null +++ b/src/truefoundry_sdk/types/spark_job_trigger.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .manual import Manual +from .schedule import Schedule + +SparkJobTrigger = typing.Union[Manual, Schedule] diff --git a/src/truefoundry_sdk/types/static_fallback_strategy.py b/src/truefoundry_sdk/types/static_fallback_strategy.py new file mode 100644 index 00000000..47855acd --- /dev/null +++ b/src/truefoundry_sdk/types/static_fallback_strategy.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .static_fallback_strategy_default_tier import StaticFallbackStrategyDefaultTier + + +class StaticFallbackStrategy(UniversalBaseModel): + """ + On classifier timeout or error, route to a fixed default tier. + """ + + type: typing.Literal["static"] = pydantic.Field(default="static") + """ + Fallback Type + """ + + default_tier: StaticFallbackStrategyDefaultTier = pydantic.Field() + """ + Tier applied when the classifier fails or when a request has no prompt text to classify (e.g. an empty prompt). + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/static_fallback_strategy_default_tier.py b/src/truefoundry_sdk/types/static_fallback_strategy_default_tier.py new file mode 100644 index 00000000..4b148a88 --- /dev/null +++ b/src/truefoundry_sdk/types/static_fallback_strategy_default_tier.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class StaticFallbackStrategyDefaultTier(enum.StrEnum): + """ + Tier applied when the classifier fails or when a request has no prompt text to classify (e.g. an empty prompt). + """ + + MEDIUM = "medium" + SIMPLE = "simple" + COMPLEX = "complex" + _UNKNOWN = "__STATICFALLBACKSTRATEGYDEFAULTTIER_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "StaticFallbackStrategyDefaultTier": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + medium: typing.Callable[[], T_Result], + simple: typing.Callable[[], T_Result], + complex_: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is StaticFallbackStrategyDefaultTier.MEDIUM: + return medium() + if self is StaticFallbackStrategyDefaultTier.SIMPLE: + return simple() + if self is StaticFallbackStrategyDefaultTier.COMPLEX: + return complex_() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/subject.py b/src/truefoundry_sdk/types/subject.py index ae8fb8f8..1b869fb5 100644 --- a/src/truefoundry_sdk/types/subject.py +++ b/src/truefoundry_sdk/types/subject.py @@ -6,7 +6,7 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata -from .subject_type import SubjectType +from .subject_subject_type import SubjectSubjectType class Subject(UniversalBaseModel): @@ -18,7 +18,9 @@ class Subject(UniversalBaseModel): """ subject_type: typing_extensions.Annotated[ - SubjectType, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType", description="Subject type") + SubjectSubjectType, + FieldMetadata(alias="subjectType"), + pydantic.Field(alias="subjectType", description="Subject type"), ] """ Subject type diff --git a/src/truefoundry_sdk/types/subject_subject_type.py b/src/truefoundry_sdk/types/subject_subject_type.py new file mode 100644 index 00000000..d3819d13 --- /dev/null +++ b/src/truefoundry_sdk/types/subject_subject_type.py @@ -0,0 +1,54 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class SubjectSubjectType(enum.StrEnum): + """ + Subject type + """ + + USER = "user" + TEAM = "team" + SERVICEACCOUNT = "serviceaccount" + VIRTUALACCOUNT = "virtualaccount" + AGENT_IDENTITY = "agent-identity" + ROLE = "role" + _UNKNOWN = "__SUBJECTSUBJECTTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "SubjectSubjectType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + user: typing.Callable[[], T_Result], + team: typing.Callable[[], T_Result], + serviceaccount: typing.Callable[[], T_Result], + virtualaccount: typing.Callable[[], T_Result], + agent_identity: typing.Callable[[], T_Result], + role: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is SubjectSubjectType.USER: + return user() + if self is SubjectSubjectType.TEAM: + return team() + if self is SubjectSubjectType.SERVICEACCOUNT: + return serviceaccount() + if self is SubjectSubjectType.VIRTUALACCOUNT: + return virtualaccount() + if self is SubjectSubjectType.AGENT_IDENTITY: + return agent_identity() + if self is SubjectSubjectType.ROLE: + return role() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/subject_type.py b/src/truefoundry_sdk/types/subject_type.py index 9592f423..0ab22e45 100644 --- a/src/truefoundry_sdk/types/subject_type.py +++ b/src/truefoundry_sdk/types/subject_type.py @@ -16,7 +16,6 @@ class SubjectType(enum.StrEnum): TEAM = "team" SERVICEACCOUNT = "serviceaccount" VIRTUALACCOUNT = "virtualaccount" - EXTERNAL_IDENTITY = "external-identity" AGENT_IDENTITY = "agent-identity" ROLE = "role" _UNKNOWN = "__SUBJECTTYPE_UNKNOWN__" @@ -36,7 +35,6 @@ def visit( team: typing.Callable[[], T_Result], serviceaccount: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], role: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], @@ -49,8 +47,6 @@ def visit( return serviceaccount() if self is SubjectType.VIRTUALACCOUNT: return virtualaccount() - if self is SubjectType.EXTERNAL_IDENTITY: - return external_identity() if self is SubjectType.AGENT_IDENTITY: return agent_identity() if self is SubjectType.ROLE: diff --git a/src/truefoundry_sdk/types/team_budget_config.py b/src/truefoundry_sdk/types/team_budget_config.py index af169d6e..8aa131b7 100644 --- a/src/truefoundry_sdk/types/team_budget_config.py +++ b/src/truefoundry_sdk/types/team_budget_config.py @@ -32,12 +32,12 @@ class TeamBudgetConfig(UniversalBaseModel): Unique name for this budget """ - when: BudgetV2WhenTeamScoped + when: typing.Optional[BudgetV2WhenTeamScoped] = None limits: BudgetV2Limits applies_to: BudgetV2AppliesTo mode: TeamBudgetConfigMode = pydantic.Field() """ - `enforce` blocks breaching requests, `audit` only tracks them. + `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. """ alerts: typing.Optional[BudgetV2Alert] = None diff --git a/src/truefoundry_sdk/types/team_budget_config_mode.py b/src/truefoundry_sdk/types/team_budget_config_mode.py index 66a6abba..cfb5b141 100644 --- a/src/truefoundry_sdk/types/team_budget_config_mode.py +++ b/src/truefoundry_sdk/types/team_budget_config_mode.py @@ -9,11 +9,12 @@ class TeamBudgetConfigMode(enum.StrEnum): """ - `enforce` blocks breaching requests, `audit` only tracks them. + `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. """ ENFORCE = "enforce" AUDIT = "audit" + ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" _UNKNOWN = "__TEAMBUDGETCONFIGMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -29,10 +30,13 @@ def visit( self, enforce: typing.Callable[[], T_Result], audit: typing.Callable[[], T_Result], + enforce_with_low_priority: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is TeamBudgetConfigMode.ENFORCE: return enforce() if self is TeamBudgetConfigMode.AUDIT: return audit() + if self is TeamBudgetConfigMode.ENFORCE_WITH_LOW_PRIORITY: + return enforce_with_low_priority() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/tenant_budget_config.py b/src/truefoundry_sdk/types/tenant_budget_config.py index 009f4987..ed392152 100644 --- a/src/truefoundry_sdk/types/tenant_budget_config.py +++ b/src/truefoundry_sdk/types/tenant_budget_config.py @@ -27,12 +27,12 @@ class TenantBudgetConfig(UniversalBaseModel): Unique name for this budget """ - when: BudgetV2WhenTenantScoped + when: typing.Optional[BudgetV2WhenTenantScoped] = None limits: BudgetV2Limits applies_to: BudgetV2AppliesTo mode: TenantBudgetConfigMode = pydantic.Field() """ - `enforce` blocks breaching requests, `audit` only tracks them. + `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. """ alerts: typing.Optional[BudgetV2Alert] = None diff --git a/src/truefoundry_sdk/types/tenant_budget_config_mode.py b/src/truefoundry_sdk/types/tenant_budget_config_mode.py index 6cfbc015..ca0d98fe 100644 --- a/src/truefoundry_sdk/types/tenant_budget_config_mode.py +++ b/src/truefoundry_sdk/types/tenant_budget_config_mode.py @@ -9,11 +9,12 @@ class TenantBudgetConfigMode(enum.StrEnum): """ - `enforce` blocks breaching requests, `audit` only tracks them. + `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. """ ENFORCE = "enforce" AUDIT = "audit" + ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" _UNKNOWN = "__TENANTBUDGETCONFIGMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -29,10 +30,13 @@ def visit( self, enforce: typing.Callable[[], T_Result], audit: typing.Callable[[], T_Result], + enforce_with_low_priority: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is TenantBudgetConfigMode.ENFORCE: return enforce() if self is TenantBudgetConfigMode.AUDIT: return audit() + if self is TenantBudgetConfigMode.ENFORCE_WITH_LOW_PRIORITY: + return enforce_with_low_priority() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/together_ai_provider_account.py b/src/truefoundry_sdk/types/together_ai_provider_account.py index e0b1d96f..9a7aff1b 100644 --- a/src/truefoundry_sdk/types/together_ai_provider_account.py +++ b/src/truefoundry_sdk/types/together_ai_provider_account.py @@ -14,7 +14,7 @@ class TogetherAiProviderAccount(UniversalBaseModel): """ - Together AI Provider Account + Together AI Model Account """ type: typing.Literal["provider-account/together-ai"] = pydantic.Field(default="provider-account/together-ai") @@ -24,18 +24,18 @@ class TogetherAiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Together AI provider account + The name of the Together AI model account """ auth_data: TogetherAiKeyAuth integrations: typing.List[TogetherAiIntegrations] = pydantic.Field() """ - List of integrations that are associated with the Together AI provider account + List of integrations that are associated with the Together AI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class TogetherAiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/tracing_project.py b/src/truefoundry_sdk/types/tracing_project.py new file mode 100644 index 00000000..8cfbaabf --- /dev/null +++ b/src/truefoundry_sdk/types/tracing_project.py @@ -0,0 +1,44 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .subject import Subject + + +class TracingProject(UniversalBaseModel): + id: typing.Optional[str] = None + fqn: str + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + manifest: typing.Dict[str, typing.Any] + created_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None + updated_at: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + storage_type: typing_extensions.Annotated[ + str, FieldMetadata(alias="storageType"), pydantic.Field(alias="storageType") + ] + storage_root: typing_extensions.Annotated[ + str, FieldMetadata(alias="storageRoot"), pydantic.Field(alias="storageRoot") + ] + storage_integration_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="storageIntegrationId"), pydantic.Field(alias="storageIntegrationId") + ] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_git_source_skill.py b/src/truefoundry_sdk/types/true_foundry_agent_git_source_skill.py new file mode 100644 index 00000000..c4095b5d --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_git_source_skill.py @@ -0,0 +1,45 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentGitSourceSkill(UniversalBaseModel): + """ + Skill from a public Git repository. + """ + + type: typing.Literal["git"] = pydantic.Field(default="git") + """ + Type + """ + + url: str = pydantic.Field() + """ + Full HTTPS URL of a GitHub or GitLab repository. + """ + + path: typing.Optional[str] = pydantic.Field(default=None) + """ + Path to the skill directory within the repository (e.g. skills/durable-objects). Omit to use the repository root. + """ + + name: str = pydantic.Field() + """ + Name for the skill, used as the directory name in the sandbox. + """ + + ref: str = pydantic.Field() + """ + Git ref — branch name, tag, or commit SHA. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py index 6588a4c5..604d187a 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py @@ -2,50 +2,7 @@ import typing -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .true_foundry_agent_mcp_server_inline import TrueFoundryAgentMcpServerInline +from .true_foundry_agent_mcp_server_registry import TrueFoundryAgentMcpServerRegistry - -class TrueFoundryAgentMcpServer(UniversalBaseModel): - """ - A tool selector is either a literal tool name or one of the special tags: - @all, @read-only, @write, @destructive. - """ - - name: str = pydantic.Field() - """ - MCP server name - """ - - preload: typing.Optional[bool] = pydantic.Field(default=False) - """ - When true, this server's tools are preloaded into context. When false (default), tools are discovered lazily and only preload_tools stay eager. - """ - - enable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) - """ - Tools to enable. Supports tags @all, @read-only, @write, @destructive or literal tool names. - """ - - disable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) - """ - Tools to disable (subtracted from enable_tools). - """ - - preload_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) - """ - When preload is false, tools to still preload into context. - """ - - require_approval_for_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) - """ - Tools that require human approval before execution. Supports tags and literal tool names. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 - else: - - class Config: - smart_union = True - extra = pydantic.Extra.allow +TrueFoundryAgentMcpServer = typing.Union[TrueFoundryAgentMcpServerRegistry, TrueFoundryAgentMcpServerInline] diff --git a/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_inline.py b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_inline.py new file mode 100644 index 00000000..a317ec56 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_inline.py @@ -0,0 +1,60 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentMcpServerInline(UniversalBaseModel): + """ + An MCP server connected directly by its url, defined inline in the agent (not registered on the TrueFoundry platform). + """ + + type: typing.Literal["inline"] = pydantic.Field(default="inline") + """ + Type + """ + + name: str = pydantic.Field() + """ + A name you choose to identify this inline server. + """ + + url: str = pydantic.Field() + """ + The inline MCP server endpoint (streamable-http or SSE). Must be an http(s) URL. + """ + + preload: typing.Optional[bool] = pydantic.Field(default=False) + """ + When true, this server's tools are preloaded into context. When false (default), tools are discovered lazily and only preload_tools stay eager. + """ + + enable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools to enable. Supports tags @all, @read-only, @write, @destructive or literal tool names. + """ + + disable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools to disable (subtracted from enable_tools). + """ + + preload_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + When preload is false, tools to still preload into context. + """ + + require_approval_for_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools that require human approval before execution. Supports tags and literal tool names. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_registry.py b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_registry.py new file mode 100644 index 00000000..159701cb --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server_registry.py @@ -0,0 +1,55 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentMcpServerRegistry(UniversalBaseModel): + """ + An MCP server registered on the TrueFoundry platform, referenced by its registered name. + """ + + type: typing.Literal["truefoundry-mcp-registry"] = pydantic.Field(default="truefoundry-mcp-registry") + """ + Type + """ + + name: str = pydantic.Field() + """ + The registered name of the MCP server to connect. + """ + + preload: typing.Optional[bool] = pydantic.Field(default=False) + """ + When true, this server's tools are preloaded into context. When false (default), tools are discovered lazily and only preload_tools stay eager. + """ + + enable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools to enable. Supports tags @all, @read-only, @write, @destructive or literal tool names. + """ + + disable_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools to disable (subtracted from enable_tools). + """ + + preload_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + When preload is false, tools to still preload into context. + """ + + require_approval_for_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tools that require human approval before execution. Supports tags and literal tool names. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_data.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_data.py new file mode 100644 index 00000000..5333f23f --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_data.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .true_foundry_agent_sandbox_basic_auth_data import TrueFoundryAgentSandboxBasicAuthData + +TrueFoundryAgentSandboxAuthData = TrueFoundryAgentSandboxBasicAuthData diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject.py new file mode 100644 index 00000000..37ac5e44 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .true_foundry_agent_sandbox_git_auth_inject import TrueFoundryAgentSandboxGitAuthInject + +TrueFoundryAgentSandboxAuthInject = TrueFoundryAgentSandboxGitAuthInject diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject_match.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject_match.py new file mode 100644 index 00000000..14f5bd42 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_auth_inject_match.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentSandboxAuthInjectMatch(UniversalBaseModel): + hosts: typing.List[str] = pydantic.Field() + """ + Exact hostnames that this auth injection rule applies to (e.g. api.github.com). Wildcards are not allowed. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_basic_auth_data.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_basic_auth_data.py new file mode 100644 index 00000000..2e733d3d --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_basic_auth_data.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentSandboxBasicAuthData(UniversalBaseModel): + """ + Basic Auth + """ + + type: typing.Literal["basic"] = pydantic.Field(default="basic") + """ + +value=basic + """ + + username: str = pydantic.Field() + """ + Username for basic authentication. + """ + + password: str = pydantic.Field() + """ + Password or token for basic authentication. Stored as a secret reference (tfy-secret://…). + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_config.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_config.py index 76ee231e..41b29742 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_config.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_config.py @@ -4,11 +4,13 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .true_foundry_agent_sandbox_network_policy import TrueFoundryAgentSandboxNetworkPolicy class TrueFoundryAgentSandboxConfig(UniversalBaseModel): enabled: bool = True file_downloads: typing.Optional[bool] = True + network_policy: typing.Optional[TrueFoundryAgentSandboxNetworkPolicy] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_git_auth_inject.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_git_auth_inject.py new file mode 100644 index 00000000..95e4ca0d --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_git_auth_inject.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .true_foundry_agent_sandbox_auth_data import TrueFoundryAgentSandboxAuthData +from .true_foundry_agent_sandbox_auth_inject_match import TrueFoundryAgentSandboxAuthInjectMatch + + +class TrueFoundryAgentSandboxGitAuthInject(UniversalBaseModel): + """ + Git Auth Inject + """ + + type: typing.Literal["git"] = pydantic.Field(default="git") + """ + +value=git + """ + + match: TrueFoundryAgentSandboxAuthInjectMatch + auth_data: TrueFoundryAgentSandboxAuthData + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_sandbox_network_policy.py b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_network_policy.py new file mode 100644 index 00000000..f20f6f04 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_sandbox_network_policy.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .true_foundry_agent_sandbox_auth_inject import TrueFoundryAgentSandboxAuthInject + + +class TrueFoundryAgentSandboxNetworkPolicy(UniversalBaseModel): + auth_inject: typing.Optional[typing.List[TrueFoundryAgentSandboxAuthInject]] = pydantic.Field(default=None) + """ + Rules for injecting authentication into outbound network requests from the sandbox. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_skill.py b/src/truefoundry_sdk/types/true_foundry_agent_skill.py index 5c940046..8d27afcf 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_skill.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_skill.py @@ -2,25 +2,7 @@ import typing -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .true_foundry_agent_git_source_skill import TrueFoundryAgentGitSourceSkill +from .true_foundry_agent_true_foundry_skill import TrueFoundryAgentTrueFoundrySkill - -class TrueFoundryAgentSkill(UniversalBaseModel): - fqn: str = pydantic.Field() - """ - Fully qualified name of the agent skill - """ - - preload: bool = pydantic.Field(default=False) - """ - If true, the SKILL.md content is injected into the agent context. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 - else: - - class Config: - smart_union = True - extra = pydantic.Extra.allow +TrueFoundryAgentSkill = typing.Union[TrueFoundryAgentTrueFoundrySkill, TrueFoundryAgentGitSourceSkill] diff --git a/src/truefoundry_sdk/types/true_foundry_agent_true_foundry_skill.py b/src/truefoundry_sdk/types/true_foundry_agent_true_foundry_skill.py new file mode 100644 index 00000000..91c5e017 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_true_foundry_skill.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TrueFoundryAgentTrueFoundrySkill(UniversalBaseModel): + """ + Skill from the TrueFoundry skill registry, referenced by FQN. + """ + + type: typing.Literal["truefoundry-skills-registry"] = pydantic.Field(default="truefoundry-skills-registry") + """ + Type + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the agent skill + """ + + preload: bool = pydantic.Field(default=False) + """ + If true, the SKILL.md content is injected into the agent context. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_user_message.py b/src/truefoundry_sdk/types/true_foundry_agent_user_message.py index f97a130d..c2775355 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_user_message.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_user_message.py @@ -7,9 +7,9 @@ class TrueFoundryAgentUserMessage(UniversalBaseModel): - role: typing.Literal["user"] = pydantic.Field(default="user") + type: typing.Literal["user.message"] = pydantic.Field(default="user.message") """ - Role of the message sender. + Message type discriminator. """ content: str = pydantic.Field() diff --git a/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py b/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py index ca25c87a..21639ecb 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py @@ -2,6 +2,7 @@ import typing +from .agent_channel_manifest import AgentChannelManifest from .agent_identity_manifest import AgentIdentityManifest from .agent_manifest import AgentManifest from .ai_features_settings import AiFeaturesSettings @@ -72,4 +73,5 @@ McpServerManifest, RoleBindingManifest, AgentIdentityManifest, + AgentChannelManifest, ] diff --git a/src/truefoundry_sdk/types/true_foundry_apply_response.py b/src/truefoundry_sdk/types/true_foundry_apply_response.py index 56faabe4..6a9b6ca4 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_response.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_response.py @@ -1,12 +1,15 @@ # This file was auto-generated by Fern from our API Definition. +from __future__ import annotations + import typing import pydantic import typing_extensions -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata from .true_foundry_apply_response_action import TrueFoundryApplyResponseAction +from .true_foundry_apply_response_data import TrueFoundryApplyResponseData from .true_foundry_apply_response_existing_manifest import TrueFoundryApplyResponseExistingManifest @@ -25,7 +28,7 @@ class TrueFoundryApplyResponse(UniversalBaseModel): The action performed: CREATE or UPDATE """ - data: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + data: typing.Optional[TrueFoundryApplyResponseData] = pydantic.Field(default=None) """ The created or updated resource """ @@ -37,3 +40,6 @@ class TrueFoundryApplyResponse(UniversalBaseModel): class Config: smart_union = True extra = pydantic.Extra.allow + + +update_forward_refs(TrueFoundryApplyResponse) diff --git a/src/truefoundry_sdk/types/true_foundry_apply_response_data.py b/src/truefoundry_sdk/types/true_foundry_apply_response_data.py new file mode 100644 index 00000000..b94a62a6 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_apply_response_data.py @@ -0,0 +1,63 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .agent import Agent +from .agent_channel import AgentChannel +from .agent_identity import AgentIdentity +from .agent_skill_version import AgentSkillVersion +from .alert_config_entity import AlertConfigEntity +from .artifact_version import ArtifactVersion +from .cluster import Cluster +from .data_directory import DataDirectory +from .deployment import Deployment +from .environment import Environment +from .external_identity_provider import ExternalIdentityProvider +from .gateway_budget import GatewayBudget +from .gateway_configuration import GatewayConfiguration +from .gateway_installation import GatewayInstallation +from .mcp_server import McpServer +from .ml_repo import MlRepo +from .model_version import ModelVersion +from .policy import Policy +from .prompt_version import PromptVersion +from .provider_account import ProviderAccount +from .role import Role +from .role_binding import RoleBinding +from .secret_group import SecretGroup +from .settings import Settings +from .team import Team +from .tracing_project import TracingProject +from .virtual_account import VirtualAccount +from .workspace import Workspace + +TrueFoundryApplyResponseData = typing.Union[ + ProviderAccount, + Cluster, + Workspace, + MlRepo, + Deployment, + GatewayConfiguration, + Team, + Policy, + Role, + Settings, + AlertConfigEntity, + VirtualAccount, + Agent, + Environment, + TracingProject, + McpServer, + RoleBinding, + SecretGroup, + AgentIdentity, + ExternalIdentityProvider, + GatewayInstallation, + GatewayBudget, + ArtifactVersion, + ModelVersion, + PromptVersion, + AgentSkillVersion, + DataDirectory, + AgentChannel, +] diff --git a/src/truefoundry_sdk/types/true_foundry_apply_response_existing_manifest.py b/src/truefoundry_sdk/types/true_foundry_apply_response_existing_manifest.py index c9cf70ef..f101ade4 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_response_existing_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_response_existing_manifest.py @@ -2,6 +2,7 @@ import typing +from .agent_channel_manifest import AgentChannelManifest from .agent_identity_manifest import AgentIdentityManifest from .agent_manifest import AgentManifest from .ai_features_settings import AiFeaturesSettings @@ -72,4 +73,5 @@ McpServerManifest, RoleBindingManifest, AgentIdentityManifest, + AgentChannelManifest, ] diff --git a/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py b/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py index de31af91..9403ab46 100644 --- a/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py @@ -2,6 +2,7 @@ import typing +from .agent_channel_manifest import AgentChannelManifest from .agent_identity_manifest import AgentIdentityManifest from .agent_manifest import AgentManifest from .ai_features_settings import AiFeaturesSettings @@ -72,4 +73,5 @@ McpServerManifest, RoleBindingManifest, AgentIdentityManifest, + AgentChannelManifest, ] diff --git a/src/truefoundry_sdk/types/vertex_region.py b/src/truefoundry_sdk/types/vertex_region.py index 869c3678..ee224f4b 100644 --- a/src/truefoundry_sdk/types/vertex_region.py +++ b/src/truefoundry_sdk/types/vertex_region.py @@ -9,18 +9,7 @@ class VertexRegion(enum.StrEnum): GLOBAL = "global" - NORTHAMERICA_NORTHEAST1 = "northamerica-northeast1" - NORTHAMERICA_NORTHEAST2 = "northamerica-northeast2" - SOUTHAMERICA_EAST1 = "southamerica-east1" - US_CENTRAL1 = "us-central1" - US_EAST1 = "us-east1" - US_EAST4 = "us-east4" - US_EAST5 = "us-east5" - US_SOUTH1 = "us-south1" - US_WEST1 = "us-west1" - US_WEST2 = "us-west2" - US_WEST3 = "us-west3" - US_WEST4 = "us-west4" + AFRICA_SOUTH1 = "africa-south1" ASIA_EAST1 = "asia-east1" ASIA_EAST2 = "asia-east2" ASIA_NORTHEAST1 = "asia-northeast1" @@ -30,10 +19,12 @@ class VertexRegion(enum.StrEnum): ASIA_SOUTH2 = "asia-south2" ASIA_SOUTHEAST1 = "asia-southeast1" ASIA_SOUTHEAST2 = "asia-southeast2" + ASIA_SOUTHEAST3 = "asia-southeast3" AUSTRALIA_SOUTHEAST1 = "australia-southeast1" AUSTRALIA_SOUTHEAST2 = "australia-southeast2" EUROPE_CENTRAL2 = "europe-central2" EUROPE_NORTH1 = "europe-north1" + EUROPE_NORTH2 = "europe-north2" EUROPE_SOUTHWEST1 = "europe-southwest1" EUROPE_WEST1 = "europe-west1" EUROPE_WEST2 = "europe-west2" @@ -42,9 +33,25 @@ class VertexRegion(enum.StrEnum): EUROPE_WEST6 = "europe-west6" EUROPE_WEST8 = "europe-west8" EUROPE_WEST9 = "europe-west9" + EUROPE_WEST10 = "europe-west10" + EUROPE_WEST12 = "europe-west12" ME_CENTRAL1 = "me-central1" ME_CENTRAL2 = "me-central2" ME_WEST1 = "me-west1" + NORTHAMERICA_NORTHEAST1 = "northamerica-northeast1" + NORTHAMERICA_NORTHEAST2 = "northamerica-northeast2" + NORTHAMERICA_SOUTH1 = "northamerica-south1" + SOUTHAMERICA_EAST1 = "southamerica-east1" + SOUTHAMERICA_WEST1 = "southamerica-west1" + US_CENTRAL1 = "us-central1" + US_EAST1 = "us-east1" + US_EAST4 = "us-east4" + US_EAST5 = "us-east5" + US_SOUTH1 = "us-south1" + US_WEST1 = "us-west1" + US_WEST2 = "us-west2" + US_WEST3 = "us-west3" + US_WEST4 = "us-west4" EU = "eu" US = "us" _UNKNOWN = "__VERTEXREGION_UNKNOWN__" @@ -61,18 +68,7 @@ def _missing_(cls, value: typing.Any) -> "VertexRegion": def visit( self, global_: typing.Callable[[], T_Result], - northamerica_northeast1: typing.Callable[[], T_Result], - northamerica_northeast2: typing.Callable[[], T_Result], - southamerica_east1: typing.Callable[[], T_Result], - us_central1: typing.Callable[[], T_Result], - us_east1: typing.Callable[[], T_Result], - us_east4: typing.Callable[[], T_Result], - us_east5: typing.Callable[[], T_Result], - us_south1: typing.Callable[[], T_Result], - us_west1: typing.Callable[[], T_Result], - us_west2: typing.Callable[[], T_Result], - us_west3: typing.Callable[[], T_Result], - us_west4: typing.Callable[[], T_Result], + africa_south1: typing.Callable[[], T_Result], asia_east1: typing.Callable[[], T_Result], asia_east2: typing.Callable[[], T_Result], asia_northeast1: typing.Callable[[], T_Result], @@ -82,10 +78,12 @@ def visit( asia_south2: typing.Callable[[], T_Result], asia_southeast1: typing.Callable[[], T_Result], asia_southeast2: typing.Callable[[], T_Result], + asia_southeast3: typing.Callable[[], T_Result], australia_southeast1: typing.Callable[[], T_Result], australia_southeast2: typing.Callable[[], T_Result], europe_central2: typing.Callable[[], T_Result], europe_north1: typing.Callable[[], T_Result], + europe_north2: typing.Callable[[], T_Result], europe_southwest1: typing.Callable[[], T_Result], europe_west1: typing.Callable[[], T_Result], europe_west2: typing.Callable[[], T_Result], @@ -94,39 +92,33 @@ def visit( europe_west6: typing.Callable[[], T_Result], europe_west8: typing.Callable[[], T_Result], europe_west9: typing.Callable[[], T_Result], + europe_west10: typing.Callable[[], T_Result], + europe_west12: typing.Callable[[], T_Result], me_central1: typing.Callable[[], T_Result], me_central2: typing.Callable[[], T_Result], me_west1: typing.Callable[[], T_Result], + northamerica_northeast1: typing.Callable[[], T_Result], + northamerica_northeast2: typing.Callable[[], T_Result], + northamerica_south1: typing.Callable[[], T_Result], + southamerica_east1: typing.Callable[[], T_Result], + southamerica_west1: typing.Callable[[], T_Result], + us_central1: typing.Callable[[], T_Result], + us_east1: typing.Callable[[], T_Result], + us_east4: typing.Callable[[], T_Result], + us_east5: typing.Callable[[], T_Result], + us_south1: typing.Callable[[], T_Result], + us_west1: typing.Callable[[], T_Result], + us_west2: typing.Callable[[], T_Result], + us_west3: typing.Callable[[], T_Result], + us_west4: typing.Callable[[], T_Result], eu: typing.Callable[[], T_Result], us: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is VertexRegion.GLOBAL: return global_() - if self is VertexRegion.NORTHAMERICA_NORTHEAST1: - return northamerica_northeast1() - if self is VertexRegion.NORTHAMERICA_NORTHEAST2: - return northamerica_northeast2() - if self is VertexRegion.SOUTHAMERICA_EAST1: - return southamerica_east1() - if self is VertexRegion.US_CENTRAL1: - return us_central1() - if self is VertexRegion.US_EAST1: - return us_east1() - if self is VertexRegion.US_EAST4: - return us_east4() - if self is VertexRegion.US_EAST5: - return us_east5() - if self is VertexRegion.US_SOUTH1: - return us_south1() - if self is VertexRegion.US_WEST1: - return us_west1() - if self is VertexRegion.US_WEST2: - return us_west2() - if self is VertexRegion.US_WEST3: - return us_west3() - if self is VertexRegion.US_WEST4: - return us_west4() + if self is VertexRegion.AFRICA_SOUTH1: + return africa_south1() if self is VertexRegion.ASIA_EAST1: return asia_east1() if self is VertexRegion.ASIA_EAST2: @@ -145,6 +137,8 @@ def visit( return asia_southeast1() if self is VertexRegion.ASIA_SOUTHEAST2: return asia_southeast2() + if self is VertexRegion.ASIA_SOUTHEAST3: + return asia_southeast3() if self is VertexRegion.AUSTRALIA_SOUTHEAST1: return australia_southeast1() if self is VertexRegion.AUSTRALIA_SOUTHEAST2: @@ -153,6 +147,8 @@ def visit( return europe_central2() if self is VertexRegion.EUROPE_NORTH1: return europe_north1() + if self is VertexRegion.EUROPE_NORTH2: + return europe_north2() if self is VertexRegion.EUROPE_SOUTHWEST1: return europe_southwest1() if self is VertexRegion.EUROPE_WEST1: @@ -169,12 +165,44 @@ def visit( return europe_west8() if self is VertexRegion.EUROPE_WEST9: return europe_west9() + if self is VertexRegion.EUROPE_WEST10: + return europe_west10() + if self is VertexRegion.EUROPE_WEST12: + return europe_west12() if self is VertexRegion.ME_CENTRAL1: return me_central1() if self is VertexRegion.ME_CENTRAL2: return me_central2() if self is VertexRegion.ME_WEST1: return me_west1() + if self is VertexRegion.NORTHAMERICA_NORTHEAST1: + return northamerica_northeast1() + if self is VertexRegion.NORTHAMERICA_NORTHEAST2: + return northamerica_northeast2() + if self is VertexRegion.NORTHAMERICA_SOUTH1: + return northamerica_south1() + if self is VertexRegion.SOUTHAMERICA_EAST1: + return southamerica_east1() + if self is VertexRegion.SOUTHAMERICA_WEST1: + return southamerica_west1() + if self is VertexRegion.US_CENTRAL1: + return us_central1() + if self is VertexRegion.US_EAST1: + return us_east1() + if self is VertexRegion.US_EAST4: + return us_east4() + if self is VertexRegion.US_EAST5: + return us_east5() + if self is VertexRegion.US_SOUTH1: + return us_south1() + if self is VertexRegion.US_WEST1: + return us_west1() + if self is VertexRegion.US_WEST2: + return us_west2() + if self is VertexRegion.US_WEST3: + return us_west3() + if self is VertexRegion.US_WEST4: + return us_west4() if self is VertexRegion.EU: return eu() if self is VertexRegion.US: diff --git a/src/truefoundry_sdk/types/virtual_model_model_type.py b/src/truefoundry_sdk/types/virtual_model_model_type.py index 4595404e..853207be 100644 --- a/src/truefoundry_sdk/types/virtual_model_model_type.py +++ b/src/truefoundry_sdk/types/virtual_model_model_type.py @@ -17,6 +17,7 @@ class VirtualModelModelType(enum.StrEnum): AUDIO_TRANSLATION = "audio_translation" TEXT_TO_SPEECH = "text_to_speech" IMAGE = "image" + RESPONSES = "responses" _UNKNOWN = "__VIRTUALMODELMODELTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -39,6 +40,7 @@ def visit( audio_translation: typing.Callable[[], T_Result], text_to_speech: typing.Callable[[], T_Result], image: typing.Callable[[], T_Result], + responses: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is VirtualModelModelType.CHAT: @@ -59,4 +61,6 @@ def visit( return text_to_speech() if self is VirtualModelModelType.IMAGE: return image() + if self is VirtualModelModelType.RESPONSES: + return responses() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/wafer_provider_account.py b/src/truefoundry_sdk/types/wafer_provider_account.py index a053cad5..5b56bf49 100644 --- a/src/truefoundry_sdk/types/wafer_provider_account.py +++ b/src/truefoundry_sdk/types/wafer_provider_account.py @@ -14,7 +14,7 @@ class WaferProviderAccount(UniversalBaseModel): """ - Wafer Provider Account + Wafer Model Account """ type: typing.Literal["provider-account/wafer"] = pydantic.Field(default="provider-account/wafer") @@ -24,7 +24,7 @@ class WaferProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the Wafer provider account + The name of the Wafer model account """ auth_data: WaferApiKeyAuth @@ -40,12 +40,12 @@ class WaferProviderAccount(UniversalBaseModel): integrations: typing.Optional[typing.List[WaferIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the Wafer provider account + List of integrations that are associated with the Wafer model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -53,7 +53,7 @@ class WaferProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/xai_provider_account.py b/src/truefoundry_sdk/types/xai_provider_account.py index b5cc7be2..f1d94767 100644 --- a/src/truefoundry_sdk/types/xai_provider_account.py +++ b/src/truefoundry_sdk/types/xai_provider_account.py @@ -24,18 +24,18 @@ class XaiProviderAccount(UniversalBaseModel): name: str = pydantic.Field() """ - The name of the xAI provider account + The name of the xAI model account """ auth_data: XaiKeyAuth integrations: typing.Optional[typing.List[XaiIntegrations]] = pydantic.Field(default=None) """ - List of integrations that are associated with the xAI provider account + List of integrations that are associated with the xAI model account """ collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ - List of users who have access to this provider account + List of users who have access to this model account """ owned_by: typing_extensions.Annotated[ @@ -43,7 +43,7 @@ class XaiProviderAccount(UniversalBaseModel): ] = None discount_percent: typing.Optional[float] = pydantic.Field(default=None) """ - Discount % applied to upstream list price for this provider account. + Discount % applied to upstream list price for this model account. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/users/__init__.py b/src/truefoundry_sdk/users/__init__.py index 5cde0202..a4e2c185 100644 --- a/src/truefoundry_sdk/users/__init__.py +++ b/src/truefoundry_sdk/users/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import UpdateUserRolesRequestResourceType +_dynamic_imports: typing.Dict[str, str] = {"UpdateUserRolesRequestResourceType": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UpdateUserRolesRequestResourceType"] diff --git a/src/truefoundry_sdk/users/client.py b/src/truefoundry_sdk/users/client.py index ef1faa3f..abc99e53 100644 --- a/src/truefoundry_sdk/users/client.py +++ b/src/truefoundry_sdk/users/client.py @@ -16,10 +16,10 @@ from ..types.invite_user_response import InviteUserResponse from ..types.list_users_response import ListUsersResponse from ..types.register_users_response import RegisterUsersResponse -from ..types.resource_type import ResourceType from ..types.update_user_roles_response import UpdateUserRolesResponse from ..types.user import User from .raw_client import AsyncRawUsersClient, RawUsersClient +from .types.update_user_roles_request_resource_type import UpdateUserRolesRequestResourceType # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -166,7 +166,7 @@ def update_roles( *, email: str, roles: typing.Sequence[str], - resource_type: typing.Optional[ResourceType] = OMIT, + resource_type: typing.Optional[UpdateUserRolesRequestResourceType] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> UpdateUserRolesResponse: """ @@ -180,7 +180,7 @@ def update_roles( roles : typing.Sequence[str] Role names to assign to the user. - resource_type : typing.Optional[ResourceType] + resource_type : typing.Optional[UpdateUserRolesRequestResourceType] Resource type scope for the role assignment. request_options : typing.Optional[RequestOptions] @@ -246,6 +246,7 @@ def delete( id: str, *, tenant_name: typing.Optional[str] = None, + force_delete: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> DeleteUserResponse: """ @@ -259,6 +260,9 @@ def delete( tenant_name : typing.Optional[str] Tenant name override. Defaults to the caller's tenant when omitted. + force_delete : typing.Optional[bool] + When true, force-deletes the user by automatically removing all resource collaborations and team memberships. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -279,7 +283,9 @@ def delete( id="jqfwg345gi25n5ju2yz5iz6m", ) """ - _response = self._raw_client.delete(id, tenant_name=tenant_name, request_options=request_options) + _response = self._raw_client.delete( + id, tenant_name=tenant_name, force_delete=force_delete, request_options=request_options + ) return _response.data def invite_user( @@ -712,7 +718,7 @@ async def update_roles( *, email: str, roles: typing.Sequence[str], - resource_type: typing.Optional[ResourceType] = OMIT, + resource_type: typing.Optional[UpdateUserRolesRequestResourceType] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> UpdateUserRolesResponse: """ @@ -726,7 +732,7 @@ async def update_roles( roles : typing.Sequence[str] Role names to assign to the user. - resource_type : typing.Optional[ResourceType] + resource_type : typing.Optional[UpdateUserRolesRequestResourceType] Resource type scope for the role assignment. request_options : typing.Optional[RequestOptions] @@ -808,6 +814,7 @@ async def delete( id: str, *, tenant_name: typing.Optional[str] = None, + force_delete: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> DeleteUserResponse: """ @@ -821,6 +828,9 @@ async def delete( tenant_name : typing.Optional[str] Tenant name override. Defaults to the caller's tenant when omitted. + force_delete : typing.Optional[bool] + When true, force-deletes the user by automatically removing all resource collaborations and team memberships. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -849,7 +859,9 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.delete(id, tenant_name=tenant_name, request_options=request_options) + _response = await self._raw_client.delete( + id, tenant_name=tenant_name, force_delete=force_delete, request_options=request_options + ) return _response.data async def invite_user( diff --git a/src/truefoundry_sdk/users/raw_client.py b/src/truefoundry_sdk/users/raw_client.py index 72fa1de8..e1944c71 100644 --- a/src/truefoundry_sdk/users/raw_client.py +++ b/src/truefoundry_sdk/users/raw_client.py @@ -29,9 +29,9 @@ from ..types.invite_user_response import InviteUserResponse from ..types.list_users_response import ListUsersResponse from ..types.register_users_response import RegisterUsersResponse -from ..types.resource_type import ResourceType from ..types.update_user_roles_response import UpdateUserRolesResponse from ..types.user import User +from .types.update_user_roles_request_resource_type import UpdateUserRolesRequestResourceType from pydantic import ValidationError # this is used as the default value for optional parameters @@ -228,7 +228,7 @@ def update_roles( *, email: str, roles: typing.Sequence[str], - resource_type: typing.Optional[ResourceType] = OMIT, + resource_type: typing.Optional[UpdateUserRolesRequestResourceType] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[UpdateUserRolesResponse]: """ @@ -242,7 +242,7 @@ def update_roles( roles : typing.Sequence[str] Role names to assign to the user. - resource_type : typing.Optional[ResourceType] + resource_type : typing.Optional[UpdateUserRolesRequestResourceType] Resource type scope for the role assignment. request_options : typing.Optional[RequestOptions] @@ -376,6 +376,7 @@ def delete( id: str, *, tenant_name: typing.Optional[str] = None, + force_delete: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[DeleteUserResponse]: """ @@ -389,6 +390,9 @@ def delete( tenant_name : typing.Optional[str] Tenant name override. Defaults to the caller's tenant when omitted. + force_delete : typing.Optional[bool] + When true, force-deletes the user by automatically removing all resource collaborations and team memberships. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -402,6 +406,7 @@ def delete( method="DELETE", params={ "tenantName": tenant_name, + "forceDelete": force_delete, }, request_options=request_options, ) @@ -1156,7 +1161,7 @@ async def update_roles( *, email: str, roles: typing.Sequence[str], - resource_type: typing.Optional[ResourceType] = OMIT, + resource_type: typing.Optional[UpdateUserRolesRequestResourceType] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[UpdateUserRolesResponse]: """ @@ -1170,7 +1175,7 @@ async def update_roles( roles : typing.Sequence[str] Role names to assign to the user. - resource_type : typing.Optional[ResourceType] + resource_type : typing.Optional[UpdateUserRolesRequestResourceType] Resource type scope for the role assignment. request_options : typing.Optional[RequestOptions] @@ -1306,6 +1311,7 @@ async def delete( id: str, *, tenant_name: typing.Optional[str] = None, + force_delete: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[DeleteUserResponse]: """ @@ -1319,6 +1325,9 @@ async def delete( tenant_name : typing.Optional[str] Tenant name override. Defaults to the caller's tenant when omitted. + force_delete : typing.Optional[bool] + When true, force-deletes the user by automatically removing all resource collaborations and team memberships. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1332,6 +1341,7 @@ async def delete( method="DELETE", params={ "tenantName": tenant_name, + "forceDelete": force_delete, }, request_options=request_options, ) diff --git a/src/truefoundry_sdk/users/types/__init__.py b/src/truefoundry_sdk/users/types/__init__.py new file mode 100644 index 00000000..26a3367c --- /dev/null +++ b/src/truefoundry_sdk/users/types/__init__.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .update_user_roles_request_resource_type import UpdateUserRolesRequestResourceType +_dynamic_imports: typing.Dict[str, str] = { + "UpdateUserRolesRequestResourceType": ".update_user_roles_request_resource_type" +} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["UpdateUserRolesRequestResourceType"] diff --git a/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py b/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py new file mode 100644 index 00000000..53293dd6 --- /dev/null +++ b/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py @@ -0,0 +1,198 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core import enum + +T_Result = typing.TypeVar("T_Result") + + +class UpdateUserRolesRequestResourceType(enum.StrEnum): + """ + Resource type scope for the role assignment. + """ + + ROLE = "role" + ACCOUNT = "account" + CLUSTER = "cluster" + WORKSPACE = "workspace" + ENVIRONMENT = "environment" + SECRET_GROUP = "secret-group" + DEPLOYMENT = "deployment" + APPLICATION = "application" + SECRET = "secret" + DOCKER_REGISTRY = "docker-registry" + TENANT = "tenant" + VCS_INTEGRATION = "vcs-integration" + MLF_PROJECT = "mlf-project" + REPOSITORY = "repository" + PROVIDER_INTEGRATION = "provider-integration" + TEAM = "team" + SERVICE_ACCOUNT = "service-account" + LLM_GATEWAY = "llm-gateway" + POLICY = "policy" + ROLE_BINDING = "role-binding" + SETTINGS = "settings" + PROVIDER_ACCOUNT = "provider-account" + USER = "user" + ALERT_CONFIG = "alert-config" + ALERT_RULE = "alert-rule" + GATEWAY_CONFIG = "gateway-config" + GATEWAY_CONTROLS = "gateway-controls" + GATEWAY_BUDGET = "gateway-budget" + GATEWAY_POLICY = "gateway-policy" + GATEWAY_APPROVAL_REQUEST = "gateway-approval-request" + TRACING_PROJECT = "tracing-project" + TRACING_APPLICATION = "tracing-application" + AGENT = "agent" + AGENT_APP = "agent-app" + AGENT_CHANNEL = "agent-channel" + GATEWAY_INSTALLATION = "gateway-installation" + VIRTUAL_ACCOUNT = "virtual-account" + SSO_BASED_IDENTITY = "sso-based-identity" + EXTERNAL_IDENTITY = "external-identity" + MCP_SERVER = "mcp-server" + EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" + AGENT_IDENTITY = "agent-identity" + _UNKNOWN = "__UPDATEUSERROLESREQUESTRESOURCETYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "UpdateUserRolesRequestResourceType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + role: typing.Callable[[], T_Result], + account: typing.Callable[[], T_Result], + cluster: typing.Callable[[], T_Result], + workspace: typing.Callable[[], T_Result], + environment: typing.Callable[[], T_Result], + secret_group: typing.Callable[[], T_Result], + deployment: typing.Callable[[], T_Result], + application: typing.Callable[[], T_Result], + secret: typing.Callable[[], T_Result], + docker_registry: typing.Callable[[], T_Result], + tenant: typing.Callable[[], T_Result], + vcs_integration: typing.Callable[[], T_Result], + mlf_project: typing.Callable[[], T_Result], + repository: typing.Callable[[], T_Result], + provider_integration: typing.Callable[[], T_Result], + team: typing.Callable[[], T_Result], + service_account: typing.Callable[[], T_Result], + llm_gateway: typing.Callable[[], T_Result], + policy: typing.Callable[[], T_Result], + role_binding: typing.Callable[[], T_Result], + settings: typing.Callable[[], T_Result], + provider_account: typing.Callable[[], T_Result], + user: typing.Callable[[], T_Result], + alert_config: typing.Callable[[], T_Result], + alert_rule: typing.Callable[[], T_Result], + gateway_config: typing.Callable[[], T_Result], + gateway_controls: typing.Callable[[], T_Result], + gateway_budget: typing.Callable[[], T_Result], + gateway_policy: typing.Callable[[], T_Result], + gateway_approval_request: typing.Callable[[], T_Result], + tracing_project: typing.Callable[[], T_Result], + tracing_application: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], + agent_app: typing.Callable[[], T_Result], + agent_channel: typing.Callable[[], T_Result], + gateway_installation: typing.Callable[[], T_Result], + virtual_account: typing.Callable[[], T_Result], + sso_based_identity: typing.Callable[[], T_Result], + external_identity: typing.Callable[[], T_Result], + mcp_server: typing.Callable[[], T_Result], + external_identity_provider: typing.Callable[[], T_Result], + agent_identity: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is UpdateUserRolesRequestResourceType.ROLE: + return role() + if self is UpdateUserRolesRequestResourceType.ACCOUNT: + return account() + if self is UpdateUserRolesRequestResourceType.CLUSTER: + return cluster() + if self is UpdateUserRolesRequestResourceType.WORKSPACE: + return workspace() + if self is UpdateUserRolesRequestResourceType.ENVIRONMENT: + return environment() + if self is UpdateUserRolesRequestResourceType.SECRET_GROUP: + return secret_group() + if self is UpdateUserRolesRequestResourceType.DEPLOYMENT: + return deployment() + if self is UpdateUserRolesRequestResourceType.APPLICATION: + return application() + if self is UpdateUserRolesRequestResourceType.SECRET: + return secret() + if self is UpdateUserRolesRequestResourceType.DOCKER_REGISTRY: + return docker_registry() + if self is UpdateUserRolesRequestResourceType.TENANT: + return tenant() + if self is UpdateUserRolesRequestResourceType.VCS_INTEGRATION: + return vcs_integration() + if self is UpdateUserRolesRequestResourceType.MLF_PROJECT: + return mlf_project() + if self is UpdateUserRolesRequestResourceType.REPOSITORY: + return repository() + if self is UpdateUserRolesRequestResourceType.PROVIDER_INTEGRATION: + return provider_integration() + if self is UpdateUserRolesRequestResourceType.TEAM: + return team() + if self is UpdateUserRolesRequestResourceType.SERVICE_ACCOUNT: + return service_account() + if self is UpdateUserRolesRequestResourceType.LLM_GATEWAY: + return llm_gateway() + if self is UpdateUserRolesRequestResourceType.POLICY: + return policy() + if self is UpdateUserRolesRequestResourceType.ROLE_BINDING: + return role_binding() + if self is UpdateUserRolesRequestResourceType.SETTINGS: + return settings() + if self is UpdateUserRolesRequestResourceType.PROVIDER_ACCOUNT: + return provider_account() + if self is UpdateUserRolesRequestResourceType.USER: + return user() + if self is UpdateUserRolesRequestResourceType.ALERT_CONFIG: + return alert_config() + if self is UpdateUserRolesRequestResourceType.ALERT_RULE: + return alert_rule() + if self is UpdateUserRolesRequestResourceType.GATEWAY_CONFIG: + return gateway_config() + if self is UpdateUserRolesRequestResourceType.GATEWAY_CONTROLS: + return gateway_controls() + if self is UpdateUserRolesRequestResourceType.GATEWAY_BUDGET: + return gateway_budget() + if self is UpdateUserRolesRequestResourceType.GATEWAY_POLICY: + return gateway_policy() + if self is UpdateUserRolesRequestResourceType.GATEWAY_APPROVAL_REQUEST: + return gateway_approval_request() + if self is UpdateUserRolesRequestResourceType.TRACING_PROJECT: + return tracing_project() + if self is UpdateUserRolesRequestResourceType.TRACING_APPLICATION: + return tracing_application() + if self is UpdateUserRolesRequestResourceType.AGENT: + return agent() + if self is UpdateUserRolesRequestResourceType.AGENT_APP: + return agent_app() + if self is UpdateUserRolesRequestResourceType.AGENT_CHANNEL: + return agent_channel() + if self is UpdateUserRolesRequestResourceType.GATEWAY_INSTALLATION: + return gateway_installation() + if self is UpdateUserRolesRequestResourceType.VIRTUAL_ACCOUNT: + return virtual_account() + if self is UpdateUserRolesRequestResourceType.SSO_BASED_IDENTITY: + return sso_based_identity() + if self is UpdateUserRolesRequestResourceType.EXTERNAL_IDENTITY: + return external_identity() + if self is UpdateUserRolesRequestResourceType.MCP_SERVER: + return mcp_server() + if self is UpdateUserRolesRequestResourceType.EXTERNAL_IDENTITY_PROVIDER: + return external_identity_provider() + if self is UpdateUserRolesRequestResourceType.AGENT_IDENTITY: + return agent_identity() + return _unknown_member(self._value_) From edc6e38ba1f5033c0a7735f53ba41d6046d637ff Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 16:44:08 +0000 Subject: [PATCH 4/9] SDK regeneration --- .fern/metadata.json | 2 +- reference.md | 8 +-- src/truefoundry_sdk/__init__.py | 60 +++++++++++------ .../gateway_budgets/__init__.py | 6 +- src/truefoundry_sdk/gateway_budgets/client.py | 36 +++++------ .../gateway_budgets/raw_client.py | 64 +++++++++---------- .../gateway_budgets/types/__init__.py | 6 +- ...eate_or_update_budget_request_manifest.py} | 2 +- src/truefoundry_sdk/types/__init__.py | 54 ++++++++++------ ...ty_usage_dto.py => budget_entity_usage.py} | 6 +- ...age_entry_dto.py => budget_usage_entry.py} | 14 ++-- ...dto_mode.py => budget_usage_entry_mode.py} | 12 ++-- ...dto_type.py => budget_usage_entry_type.py} | 10 +-- ...sponse_dto.py => budget_usage_response.py} | 6 +- .../cisco_ai_defense_guardrail_config.py | 56 ++++++++++++++++ ...isco_ai_defense_guardrail_config_config.py | 32 ++++++++++ ..._defense_guardrail_config_config_region.py | 42 ++++++++++++ .../types/cisco_ai_defense_key_auth.py | 26 ++++++++ .../types/guardrail_config_integrations.py | 2 + .../{period_usage_dto.py => period_usage.py} | 2 +- .../types/py_spark_task_config.py | 9 ++- .../types/py_spark_task_config_image.py | 8 +++ src/truefoundry_sdk/types/task_spark_image.py | 48 ++++++++++++++ 23 files changed, 383 insertions(+), 128 deletions(-) rename src/truefoundry_sdk/gateway_budgets/types/{create_or_update_budget_dto_manifest.py => create_or_update_budget_request_manifest.py} (69%) rename src/truefoundry_sdk/types/{budget_entity_usage_dto.py => budget_entity_usage.py} (80%) rename src/truefoundry_sdk/types/{budget_usage_entry_dto.py => budget_usage_entry.py} (71%) rename src/truefoundry_sdk/types/{budget_usage_entry_dto_mode.py => budget_usage_entry_mode.py} (74%) rename src/truefoundry_sdk/types/{budget_usage_entry_dto_type.py => budget_usage_entry_type.py} (75%) rename src/truefoundry_sdk/types/{budget_usage_response_dto.py => budget_usage_response.py} (73%) create mode 100644 src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config.py create mode 100644 src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config.py create mode 100644 src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config_region.py create mode 100644 src/truefoundry_sdk/types/cisco_ai_defense_key_auth.py rename src/truefoundry_sdk/types/{period_usage_dto.py => period_usage.py} (95%) create mode 100644 src/truefoundry_sdk/types/py_spark_task_config_image.py create mode 100644 src/truefoundry_sdk/types/task_spark_image.py diff --git a/.fern/metadata.json b/.fern/metadata.json index be583736..dbfc45c9 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "60bec551303af343ab2a767a3ce1e8aa67328b1a", + "originGitCommit": "9af00380b1f1ccfcd9dc2d0272197dac286c4c6e", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/reference.md b/reference.md index add83836..5705175d 100644 --- a/reference.md +++ b/reference.md @@ -1991,7 +1991,7 @@ client.gateway_budgets.create_or_update(
-**manifest:** `CreateOrUpdateBudgetDtoManifest` — The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. +**manifest:** `CreateOrUpdateBudgetRequestManifest` — The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema.
@@ -2019,7 +2019,7 @@ client.gateway_budgets.create_or_update(
-
client.gateway_budgets.get_my_usage() -> BudgetUsageResponseDto +
client.gateway_budgets.get_my_usage() -> BudgetUsageResponse
@@ -2081,7 +2081,7 @@ client.gateway_budgets.get_my_usage()
-
client.gateway_budgets.simulate(...) -> BudgetUsageResponseDto +
client.gateway_budgets.simulate(...) -> BudgetUsageResponse
@@ -2335,7 +2335,7 @@ client.gateway_budgets.delete(
-
client.gateway_budgets.get_leaderboard(...) -> BudgetUsageResponseDto +
client.gateway_budgets.get_leaderboard(...) -> BudgetUsageResponse
diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 0b4b0d2f..9f593ecc 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -196,13 +196,13 @@ BlueGreen, BudgetAlert, BudgetConfig, - BudgetEntityUsageDto, + BudgetEntityUsage, BudgetLimitUnit, BudgetRule, - BudgetUsageEntryDto, - BudgetUsageEntryDtoMode, - BudgetUsageEntryDtoType, - BudgetUsageResponseDto, + BudgetUsageEntry, + BudgetUsageEntryMode, + BudgetUsageEntryType, + BudgetUsageResponse, BudgetV2Alert, BudgetV2AppliesTo, BudgetV2AppliesToAggregate, @@ -246,6 +246,10 @@ ChatPromptManifestMcpServersItem, ChatPromptManifestResponseFormat, ChatPromptManifestRoutingConfig, + CiscoAiDefenseGuardrailConfig, + CiscoAiDefenseGuardrailConfigConfig, + CiscoAiDefenseGuardrailConfigConfigRegion, + CiscoAiDefenseKeyAuth, ClouderaIntegrations, ClouderaModel, ClouderaProviderAccount, @@ -830,7 +834,7 @@ PerMinuteOfAudioCostMetricValue, PerThousandEmbeddingTokensCostMetric, PerThousandTokensCostMetric, - PeriodUsageDto, + PeriodUsage, PermissionSetV2, PermissionSetV2ResourceType, Permissions, @@ -874,6 +878,7 @@ ProviderIntegrationType, PublicCostMetric, PySparkTaskConfig, + PySparkTaskConfigImage, PyTorchFramework, PythonBuild, PythonBuildCommand, @@ -1057,6 +1062,7 @@ TaskDockerFileBuild, TaskPySparkBuild, TaskPythonBuild, + TaskSparkImage, Team, TeamBudgetConfig, TeamBudgetConfigMode, @@ -1269,7 +1275,7 @@ ) from .artifact_versions import StageArtifactRequestManifest from .client import AsyncTrueFoundry, TrueFoundry - from .gateway_budgets import CreateOrUpdateBudgetDtoManifest, ListGatewayBudgetsRequestType + from .gateway_budgets import CreateOrUpdateBudgetRequestManifest, ListGatewayBudgetsRequestType from .jobs import TriggerJobRequestInput from .personal_access_tokens import CreatePersonalAccessTokenRequestTokenType from .traces import QuerySpansRequestFiltersItem @@ -1467,13 +1473,13 @@ "BlueGreen": ".types", "BudgetAlert": ".types", "BudgetConfig": ".types", - "BudgetEntityUsageDto": ".types", + "BudgetEntityUsage": ".types", "BudgetLimitUnit": ".types", "BudgetRule": ".types", - "BudgetUsageEntryDto": ".types", - "BudgetUsageEntryDtoMode": ".types", - "BudgetUsageEntryDtoType": ".types", - "BudgetUsageResponseDto": ".types", + "BudgetUsageEntry": ".types", + "BudgetUsageEntryMode": ".types", + "BudgetUsageEntryType": ".types", + "BudgetUsageResponse": ".types", "BudgetV2Alert": ".types", "BudgetV2AppliesTo": ".types", "BudgetV2AppliesToAggregate": ".types", @@ -1518,6 +1524,10 @@ "ChatPromptManifestMcpServersItem": ".types", "ChatPromptManifestResponseFormat": ".types", "ChatPromptManifestRoutingConfig": ".types", + "CiscoAiDefenseGuardrailConfig": ".types", + "CiscoAiDefenseGuardrailConfigConfig": ".types", + "CiscoAiDefenseGuardrailConfigConfigRegion": ".types", + "CiscoAiDefenseKeyAuth": ".types", "ClouderaIntegrations": ".types", "ClouderaModel": ".types", "ClouderaProviderAccount": ".types", @@ -1554,7 +1564,7 @@ "CpuUtilizationMetric": ".types", "CreateDockerRepositoryResponse": ".types", "CreateMultiPartUploadRequest": ".types", - "CreateOrUpdateBudgetDtoManifest": ".gateway_budgets", + "CreateOrUpdateBudgetRequestManifest": ".gateway_budgets", "CreatePersonalAccessTokenRequestTokenType": ".personal_access_tokens", "CreatePersonalAccessTokenResponse": ".types", "CreateRunResponse": ".types", @@ -2118,7 +2128,7 @@ "PerMinuteOfAudioCostMetricValue": ".types", "PerThousandEmbeddingTokensCostMetric": ".types", "PerThousandTokensCostMetric": ".types", - "PeriodUsageDto": ".types", + "PeriodUsage": ".types", "PermissionSetV2": ".types", "PermissionSetV2ResourceType": ".types", "Permissions": ".types", @@ -2162,6 +2172,7 @@ "ProviderIntegrationType": ".types", "PublicCostMetric": ".types", "PySparkTaskConfig": ".types", + "PySparkTaskConfigImage": ".types", "PyTorchFramework": ".types", "PythonBuild": ".types", "PythonBuildCommand": ".types", @@ -2347,6 +2358,7 @@ "TaskDockerFileBuild": ".types", "TaskPySparkBuild": ".types", "TaskPythonBuild": ".types", + "TaskSparkImage": ".types", "Team": ".types", "TeamBudgetConfig": ".types", "TeamBudgetConfigMode": ".types", @@ -2756,13 +2768,13 @@ def __dir__(): "BlueGreen", "BudgetAlert", "BudgetConfig", - "BudgetEntityUsageDto", + "BudgetEntityUsage", "BudgetLimitUnit", "BudgetRule", - "BudgetUsageEntryDto", - "BudgetUsageEntryDtoMode", - "BudgetUsageEntryDtoType", - "BudgetUsageResponseDto", + "BudgetUsageEntry", + "BudgetUsageEntryMode", + "BudgetUsageEntryType", + "BudgetUsageResponse", "BudgetV2Alert", "BudgetV2AppliesTo", "BudgetV2AppliesToAggregate", @@ -2807,6 +2819,10 @@ def __dir__(): "ChatPromptManifestMcpServersItem", "ChatPromptManifestResponseFormat", "ChatPromptManifestRoutingConfig", + "CiscoAiDefenseGuardrailConfig", + "CiscoAiDefenseGuardrailConfigConfig", + "CiscoAiDefenseGuardrailConfigConfigRegion", + "CiscoAiDefenseKeyAuth", "ClouderaIntegrations", "ClouderaModel", "ClouderaProviderAccount", @@ -2843,7 +2859,7 @@ def __dir__(): "CpuUtilizationMetric", "CreateDockerRepositoryResponse", "CreateMultiPartUploadRequest", - "CreateOrUpdateBudgetDtoManifest", + "CreateOrUpdateBudgetRequestManifest", "CreatePersonalAccessTokenRequestTokenType", "CreatePersonalAccessTokenResponse", "CreateRunResponse", @@ -3407,7 +3423,7 @@ def __dir__(): "PerMinuteOfAudioCostMetricValue", "PerThousandEmbeddingTokensCostMetric", "PerThousandTokensCostMetric", - "PeriodUsageDto", + "PeriodUsage", "PermissionSetV2", "PermissionSetV2ResourceType", "Permissions", @@ -3451,6 +3467,7 @@ def __dir__(): "ProviderIntegrationType", "PublicCostMetric", "PySparkTaskConfig", + "PySparkTaskConfigImage", "PyTorchFramework", "PythonBuild", "PythonBuildCommand", @@ -3636,6 +3653,7 @@ def __dir__(): "TaskDockerFileBuild", "TaskPySparkBuild", "TaskPythonBuild", + "TaskSparkImage", "Team", "TeamBudgetConfig", "TeamBudgetConfigMode", diff --git a/src/truefoundry_sdk/gateway_budgets/__init__.py b/src/truefoundry_sdk/gateway_budgets/__init__.py index da962d04..8fce2a29 100644 --- a/src/truefoundry_sdk/gateway_budgets/__init__.py +++ b/src/truefoundry_sdk/gateway_budgets/__init__.py @@ -6,9 +6,9 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .types import CreateOrUpdateBudgetDtoManifest, ListGatewayBudgetsRequestType + from .types import CreateOrUpdateBudgetRequestManifest, ListGatewayBudgetsRequestType _dynamic_imports: typing.Dict[str, str] = { - "CreateOrUpdateBudgetDtoManifest": ".types", + "CreateOrUpdateBudgetRequestManifest": ".types", "ListGatewayBudgetsRequestType": ".types", } @@ -34,4 +34,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["CreateOrUpdateBudgetDtoManifest", "ListGatewayBudgetsRequestType"] +__all__ = ["CreateOrUpdateBudgetRequestManifest", "ListGatewayBudgetsRequestType"] diff --git a/src/truefoundry_sdk/gateway_budgets/client.py b/src/truefoundry_sdk/gateway_budgets/client.py index 25ede7a4..aaee2cce 100644 --- a/src/truefoundry_sdk/gateway_budgets/client.py +++ b/src/truefoundry_sdk/gateway_budgets/client.py @@ -4,10 +4,10 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions -from ..types.budget_usage_response_dto import BudgetUsageResponseDto +from ..types.budget_usage_response import BudgetUsageResponse from ..types.gateway_budget import GatewayBudget from .raw_client import AsyncRawGatewayBudgetsClient, RawGatewayBudgetsClient -from .types.create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest +from .types.create_or_update_budget_request_manifest import CreateOrUpdateBudgetRequestManifest from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType # this is used as the default value for optional parameters @@ -71,7 +71,7 @@ def list( def create_or_update( self, *, - manifest: CreateOrUpdateBudgetDtoManifest, + manifest: CreateOrUpdateBudgetRequestManifest, dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GatewayBudget: @@ -80,7 +80,7 @@ def create_or_update( Parameters ---------- - manifest : CreateOrUpdateBudgetDtoManifest + manifest : CreateOrUpdateBudgetRequestManifest The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. dry_run : typing.Optional[bool] @@ -122,7 +122,7 @@ def create_or_update( ) return _response.data - def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponseDto: + def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponse: """ Returns every per-user budget that currently applies to the caller, with current usage per period. @@ -133,7 +133,7 @@ def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The caller-scoped budget usage. Examples @@ -159,7 +159,7 @@ def simulate( model: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, str]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> BudgetUsageResponseDto: + ) -> BudgetUsageResponse: """ Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. @@ -188,7 +188,7 @@ def simulate( Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The budgets matching the selection. Examples @@ -277,7 +277,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = def get_leaderboard( self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None - ) -> BudgetUsageResponseDto: + ) -> BudgetUsageResponse: """ Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). @@ -294,7 +294,7 @@ def get_leaderboard( Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The budget leaderboard. Examples @@ -379,7 +379,7 @@ async def main() -> None: async def create_or_update( self, *, - manifest: CreateOrUpdateBudgetDtoManifest, + manifest: CreateOrUpdateBudgetRequestManifest, dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GatewayBudget: @@ -388,7 +388,7 @@ async def create_or_update( Parameters ---------- - manifest : CreateOrUpdateBudgetDtoManifest + manifest : CreateOrUpdateBudgetRequestManifest The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. dry_run : typing.Optional[bool] @@ -438,7 +438,7 @@ async def main() -> None: ) return _response.data - async def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponseDto: + async def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] = None) -> BudgetUsageResponse: """ Returns every per-user budget that currently applies to the caller, with current usage per period. @@ -449,7 +449,7 @@ async def get_my_usage(self, *, request_options: typing.Optional[RequestOptions] Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The caller-scoped budget usage. Examples @@ -483,7 +483,7 @@ async def simulate( model: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, str]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> BudgetUsageResponseDto: + ) -> BudgetUsageResponse: """ Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. @@ -512,7 +512,7 @@ async def simulate( Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The budgets matching the selection. Examples @@ -625,7 +625,7 @@ async def main() -> None: async def get_leaderboard( self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None - ) -> BudgetUsageResponseDto: + ) -> BudgetUsageResponse: """ Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). @@ -642,7 +642,7 @@ async def get_leaderboard( Returns ------- - BudgetUsageResponseDto + BudgetUsageResponse The budget leaderboard. Examples diff --git a/src/truefoundry_sdk/gateway_budgets/raw_client.py b/src/truefoundry_sdk/gateway_budgets/raw_client.py index 573fe84a..77c586d8 100644 --- a/src/truefoundry_sdk/gateway_budgets/raw_client.py +++ b/src/truefoundry_sdk/gateway_budgets/raw_client.py @@ -13,9 +13,9 @@ from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError -from ..types.budget_usage_response_dto import BudgetUsageResponseDto +from ..types.budget_usage_response import BudgetUsageResponse from ..types.gateway_budget import GatewayBudget -from .types.create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest +from .types.create_or_update_budget_request_manifest import CreateOrUpdateBudgetRequestManifest from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType from pydantic import ValidationError @@ -84,7 +84,7 @@ def list( def create_or_update( self, *, - manifest: CreateOrUpdateBudgetDtoManifest, + manifest: CreateOrUpdateBudgetRequestManifest, dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GatewayBudget]: @@ -93,7 +93,7 @@ def create_or_update( Parameters ---------- - manifest : CreateOrUpdateBudgetDtoManifest + manifest : CreateOrUpdateBudgetRequestManifest The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. dry_run : typing.Optional[bool] @@ -112,7 +112,7 @@ def create_or_update( method="PUT", json={ "manifest": convert_and_respect_annotation_metadata( - object_=manifest, annotation=CreateOrUpdateBudgetDtoManifest, direction="write" + object_=manifest, annotation=CreateOrUpdateBudgetRequestManifest, direction="write" ), "dryRun": dry_run, }, @@ -154,7 +154,7 @@ def create_or_update( def get_my_usage( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[BudgetUsageResponseDto]: + ) -> HttpResponse[BudgetUsageResponse]: """ Returns every per-user budget that currently applies to the caller, with current usage per period. @@ -165,7 +165,7 @@ def get_my_usage( Returns ------- - HttpResponse[BudgetUsageResponseDto] + HttpResponse[BudgetUsageResponse] The caller-scoped budget usage. """ _response = self._client_wrapper.httpx_client.request( @@ -176,9 +176,9 @@ def get_my_usage( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) @@ -202,7 +202,7 @@ def simulate( model: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, str]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[BudgetUsageResponseDto]: + ) -> HttpResponse[BudgetUsageResponse]: """ Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. @@ -231,7 +231,7 @@ def simulate( Returns ------- - HttpResponse[BudgetUsageResponseDto] + HttpResponse[BudgetUsageResponse] The budgets matching the selection. """ _response = self._client_wrapper.httpx_client.request( @@ -254,9 +254,9 @@ def simulate( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) @@ -368,7 +368,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = def get_leaderboard( self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[BudgetUsageResponseDto]: + ) -> HttpResponse[BudgetUsageResponse]: """ Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). @@ -385,7 +385,7 @@ def get_leaderboard( Returns ------- - HttpResponse[BudgetUsageResponseDto] + HttpResponse[BudgetUsageResponse] The budget leaderboard. """ _response = self._client_wrapper.httpx_client.request( @@ -399,9 +399,9 @@ def get_leaderboard( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) @@ -488,7 +488,7 @@ async def list( async def create_or_update( self, *, - manifest: CreateOrUpdateBudgetDtoManifest, + manifest: CreateOrUpdateBudgetRequestManifest, dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GatewayBudget]: @@ -497,7 +497,7 @@ async def create_or_update( Parameters ---------- - manifest : CreateOrUpdateBudgetDtoManifest + manifest : CreateOrUpdateBudgetRequestManifest The budget manifest. Must match either the TenantBudgetConfig or TeamBudgetConfig schema. dry_run : typing.Optional[bool] @@ -516,7 +516,7 @@ async def create_or_update( method="PUT", json={ "manifest": convert_and_respect_annotation_metadata( - object_=manifest, annotation=CreateOrUpdateBudgetDtoManifest, direction="write" + object_=manifest, annotation=CreateOrUpdateBudgetRequestManifest, direction="write" ), "dryRun": dry_run, }, @@ -558,7 +558,7 @@ async def create_or_update( async def get_my_usage( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + ) -> AsyncHttpResponse[BudgetUsageResponse]: """ Returns every per-user budget that currently applies to the caller, with current usage per period. @@ -569,7 +569,7 @@ async def get_my_usage( Returns ------- - AsyncHttpResponse[BudgetUsageResponseDto] + AsyncHttpResponse[BudgetUsageResponse] The caller-scoped budget usage. """ _response = await self._client_wrapper.httpx_client.request( @@ -580,9 +580,9 @@ async def get_my_usage( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) @@ -606,7 +606,7 @@ async def simulate( model: typing.Optional[str] = OMIT, metadata: typing.Optional[typing.Dict[str, str]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + ) -> AsyncHttpResponse[BudgetUsageResponse]: """ Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. @@ -635,7 +635,7 @@ async def simulate( Returns ------- - AsyncHttpResponse[BudgetUsageResponseDto] + AsyncHttpResponse[BudgetUsageResponse] The budgets matching the selection. """ _response = await self._client_wrapper.httpx_client.request( @@ -658,9 +658,9 @@ async def simulate( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) @@ -776,7 +776,7 @@ async def delete( async def get_leaderboard( self, id: str, *, limit: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[BudgetUsageResponseDto]: + ) -> AsyncHttpResponse[BudgetUsageResponse]: """ Returns the top spenders for a budget in its applies_to dimension, for the configured period. Aggregate budgets return a single whole-budget entity (entity: null). @@ -793,7 +793,7 @@ async def get_leaderboard( Returns ------- - AsyncHttpResponse[BudgetUsageResponseDto] + AsyncHttpResponse[BudgetUsageResponse] The budget leaderboard. """ _response = await self._client_wrapper.httpx_client.request( @@ -807,9 +807,9 @@ async def get_leaderboard( try: if 200 <= _response.status_code < 300: _data = typing.cast( - BudgetUsageResponseDto, + BudgetUsageResponse, parse_obj_as( - type_=BudgetUsageResponseDto, # type: ignore + type_=BudgetUsageResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/truefoundry_sdk/gateway_budgets/types/__init__.py b/src/truefoundry_sdk/gateway_budgets/types/__init__.py index 530f6ec5..e9eac7f4 100644 --- a/src/truefoundry_sdk/gateway_budgets/types/__init__.py +++ b/src/truefoundry_sdk/gateway_budgets/types/__init__.py @@ -6,10 +6,10 @@ from importlib import import_module if typing.TYPE_CHECKING: - from .create_or_update_budget_dto_manifest import CreateOrUpdateBudgetDtoManifest + from .create_or_update_budget_request_manifest import CreateOrUpdateBudgetRequestManifest from .list_gateway_budgets_request_type import ListGatewayBudgetsRequestType _dynamic_imports: typing.Dict[str, str] = { - "CreateOrUpdateBudgetDtoManifest": ".create_or_update_budget_dto_manifest", + "CreateOrUpdateBudgetRequestManifest": ".create_or_update_budget_request_manifest", "ListGatewayBudgetsRequestType": ".list_gateway_budgets_request_type", } @@ -35,4 +35,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["CreateOrUpdateBudgetDtoManifest", "ListGatewayBudgetsRequestType"] +__all__ = ["CreateOrUpdateBudgetRequestManifest", "ListGatewayBudgetsRequestType"] diff --git a/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py b/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_request_manifest.py similarity index 69% rename from src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py rename to src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_request_manifest.py index d8da804d..e4e15de6 100644 --- a/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_dto_manifest.py +++ b/src/truefoundry_sdk/gateway_budgets/types/create_or_update_budget_request_manifest.py @@ -5,4 +5,4 @@ from ...types.team_budget_config import TeamBudgetConfig from ...types.tenant_budget_config import TenantBudgetConfig -CreateOrUpdateBudgetDtoManifest = typing.Union[TenantBudgetConfig, TeamBudgetConfig] +CreateOrUpdateBudgetRequestManifest = typing.Union[TenantBudgetConfig, TeamBudgetConfig] diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index 6da2cb02..add73802 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -198,13 +198,13 @@ from .blue_green import BlueGreen from .budget_alert import BudgetAlert from .budget_config import BudgetConfig - from .budget_entity_usage_dto import BudgetEntityUsageDto + from .budget_entity_usage import BudgetEntityUsage from .budget_limit_unit import BudgetLimitUnit from .budget_rule import BudgetRule - from .budget_usage_entry_dto import BudgetUsageEntryDto - from .budget_usage_entry_dto_mode import BudgetUsageEntryDtoMode - from .budget_usage_entry_dto_type import BudgetUsageEntryDtoType - from .budget_usage_response_dto import BudgetUsageResponseDto + from .budget_usage_entry import BudgetUsageEntry + from .budget_usage_entry_mode import BudgetUsageEntryMode + from .budget_usage_entry_type import BudgetUsageEntryType + from .budget_usage_response import BudgetUsageResponse from .budget_v2alert import BudgetV2Alert from .budget_v2applies_to import BudgetV2AppliesTo from .budget_v2applies_to_aggregate import BudgetV2AppliesToAggregate @@ -248,6 +248,10 @@ from .chat_prompt_manifest_mcp_servers_item import ChatPromptManifestMcpServersItem from .chat_prompt_manifest_response_format import ChatPromptManifestResponseFormat from .chat_prompt_manifest_routing_config import ChatPromptManifestRoutingConfig + from .cisco_ai_defense_guardrail_config import CiscoAiDefenseGuardrailConfig + from .cisco_ai_defense_guardrail_config_config import CiscoAiDefenseGuardrailConfigConfig + from .cisco_ai_defense_guardrail_config_config_region import CiscoAiDefenseGuardrailConfigConfigRegion + from .cisco_ai_defense_key_auth import CiscoAiDefenseKeyAuth from .cloudera_integrations import ClouderaIntegrations from .cloudera_model import ClouderaModel from .cloudera_provider_account import ClouderaProviderAccount @@ -848,7 +852,7 @@ from .per_minute_of_audio_cost_metric_value import PerMinuteOfAudioCostMetricValue from .per_thousand_embedding_tokens_cost_metric import PerThousandEmbeddingTokensCostMetric from .per_thousand_tokens_cost_metric import PerThousandTokensCostMetric - from .period_usage_dto import PeriodUsageDto + from .period_usage import PeriodUsage from .permission_set_v2 import PermissionSetV2 from .permission_set_v2resource_type import PermissionSetV2ResourceType from .permissions import Permissions @@ -892,6 +896,7 @@ from .provider_integration_type import ProviderIntegrationType from .public_cost_metric import PublicCostMetric from .py_spark_task_config import PySparkTaskConfig + from .py_spark_task_config_image import PySparkTaskConfigImage from .py_torch_framework import PyTorchFramework from .python_build import PythonBuild from .python_build_command import PythonBuildCommand @@ -1072,6 +1077,7 @@ from .task_docker_file_build import TaskDockerFileBuild from .task_py_spark_build import TaskPySparkBuild from .task_python_build import TaskPythonBuild + from .task_spark_image import TaskSparkImage from .team import Team from .team_budget_config import TeamBudgetConfig from .team_budget_config_mode import TeamBudgetConfigMode @@ -1418,13 +1424,13 @@ "BlueGreen": ".blue_green", "BudgetAlert": ".budget_alert", "BudgetConfig": ".budget_config", - "BudgetEntityUsageDto": ".budget_entity_usage_dto", + "BudgetEntityUsage": ".budget_entity_usage", "BudgetLimitUnit": ".budget_limit_unit", "BudgetRule": ".budget_rule", - "BudgetUsageEntryDto": ".budget_usage_entry_dto", - "BudgetUsageEntryDtoMode": ".budget_usage_entry_dto_mode", - "BudgetUsageEntryDtoType": ".budget_usage_entry_dto_type", - "BudgetUsageResponseDto": ".budget_usage_response_dto", + "BudgetUsageEntry": ".budget_usage_entry", + "BudgetUsageEntryMode": ".budget_usage_entry_mode", + "BudgetUsageEntryType": ".budget_usage_entry_type", + "BudgetUsageResponse": ".budget_usage_response", "BudgetV2Alert": ".budget_v2alert", "BudgetV2AppliesTo": ".budget_v2applies_to", "BudgetV2AppliesToAggregate": ".budget_v2applies_to_aggregate", @@ -1468,6 +1474,10 @@ "ChatPromptManifestMcpServersItem": ".chat_prompt_manifest_mcp_servers_item", "ChatPromptManifestResponseFormat": ".chat_prompt_manifest_response_format", "ChatPromptManifestRoutingConfig": ".chat_prompt_manifest_routing_config", + "CiscoAiDefenseGuardrailConfig": ".cisco_ai_defense_guardrail_config", + "CiscoAiDefenseGuardrailConfigConfig": ".cisco_ai_defense_guardrail_config_config", + "CiscoAiDefenseGuardrailConfigConfigRegion": ".cisco_ai_defense_guardrail_config_config_region", + "CiscoAiDefenseKeyAuth": ".cisco_ai_defense_key_auth", "ClouderaIntegrations": ".cloudera_integrations", "ClouderaModel": ".cloudera_model", "ClouderaProviderAccount": ".cloudera_provider_account", @@ -2052,7 +2062,7 @@ "PerMinuteOfAudioCostMetricValue": ".per_minute_of_audio_cost_metric_value", "PerThousandEmbeddingTokensCostMetric": ".per_thousand_embedding_tokens_cost_metric", "PerThousandTokensCostMetric": ".per_thousand_tokens_cost_metric", - "PeriodUsageDto": ".period_usage_dto", + "PeriodUsage": ".period_usage", "PermissionSetV2": ".permission_set_v2", "PermissionSetV2ResourceType": ".permission_set_v2resource_type", "Permissions": ".permissions", @@ -2096,6 +2106,7 @@ "ProviderIntegrationType": ".provider_integration_type", "PublicCostMetric": ".public_cost_metric", "PySparkTaskConfig": ".py_spark_task_config", + "PySparkTaskConfigImage": ".py_spark_task_config_image", "PyTorchFramework": ".py_torch_framework", "PythonBuild": ".python_build", "PythonBuildCommand": ".python_build_command", @@ -2279,6 +2290,7 @@ "TaskDockerFileBuild": ".task_docker_file_build", "TaskPySparkBuild": ".task_py_spark_build", "TaskPythonBuild": ".task_python_build", + "TaskSparkImage": ".task_spark_image", "Team": ".team", "TeamBudgetConfig": ".team_budget_config", "TeamBudgetConfigMode": ".team_budget_config_mode", @@ -2649,13 +2661,13 @@ def __dir__(): "BlueGreen", "BudgetAlert", "BudgetConfig", - "BudgetEntityUsageDto", + "BudgetEntityUsage", "BudgetLimitUnit", "BudgetRule", - "BudgetUsageEntryDto", - "BudgetUsageEntryDtoMode", - "BudgetUsageEntryDtoType", - "BudgetUsageResponseDto", + "BudgetUsageEntry", + "BudgetUsageEntryMode", + "BudgetUsageEntryType", + "BudgetUsageResponse", "BudgetV2Alert", "BudgetV2AppliesTo", "BudgetV2AppliesToAggregate", @@ -2699,6 +2711,10 @@ def __dir__(): "ChatPromptManifestMcpServersItem", "ChatPromptManifestResponseFormat", "ChatPromptManifestRoutingConfig", + "CiscoAiDefenseGuardrailConfig", + "CiscoAiDefenseGuardrailConfigConfig", + "CiscoAiDefenseGuardrailConfigConfigRegion", + "CiscoAiDefenseKeyAuth", "ClouderaIntegrations", "ClouderaModel", "ClouderaProviderAccount", @@ -3283,7 +3299,7 @@ def __dir__(): "PerMinuteOfAudioCostMetricValue", "PerThousandEmbeddingTokensCostMetric", "PerThousandTokensCostMetric", - "PeriodUsageDto", + "PeriodUsage", "PermissionSetV2", "PermissionSetV2ResourceType", "Permissions", @@ -3327,6 +3343,7 @@ def __dir__(): "ProviderIntegrationType", "PublicCostMetric", "PySparkTaskConfig", + "PySparkTaskConfigImage", "PyTorchFramework", "PythonBuild", "PythonBuildCommand", @@ -3510,6 +3527,7 @@ def __dir__(): "TaskDockerFileBuild", "TaskPySparkBuild", "TaskPythonBuild", + "TaskSparkImage", "Team", "TeamBudgetConfig", "TeamBudgetConfigMode", diff --git a/src/truefoundry_sdk/types/budget_entity_usage_dto.py b/src/truefoundry_sdk/types/budget_entity_usage.py similarity index 80% rename from src/truefoundry_sdk/types/budget_entity_usage_dto.py rename to src/truefoundry_sdk/types/budget_entity_usage.py index b4a932cd..729f35f1 100644 --- a/src/truefoundry_sdk/types/budget_entity_usage_dto.py +++ b/src/truefoundry_sdk/types/budget_entity_usage.py @@ -4,16 +4,16 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .period_usage_dto import PeriodUsageDto +from .period_usage import PeriodUsage -class BudgetEntityUsageDto(UniversalBaseModel): +class BudgetEntityUsage(UniversalBaseModel): entity: typing.Optional[str] = pydantic.Field(default=None) """ Entity counter this usage maps to; null for aggregate budgets. """ - periods: typing.Dict[str, PeriodUsageDto] = pydantic.Field() + periods: typing.Dict[str, PeriodUsage] = pydantic.Field() """ Per-period usage keyed by period (cost_per_day, cost_per_month, ...). """ diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto.py b/src/truefoundry_sdk/types/budget_usage_entry.py similarity index 71% rename from src/truefoundry_sdk/types/budget_usage_entry_dto.py rename to src/truefoundry_sdk/types/budget_usage_entry.py index 640ad1bc..976d8160 100644 --- a/src/truefoundry_sdk/types/budget_usage_entry_dto.py +++ b/src/truefoundry_sdk/types/budget_usage_entry.py @@ -4,18 +4,18 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .budget_entity_usage_dto import BudgetEntityUsageDto -from .budget_usage_entry_dto_mode import BudgetUsageEntryDtoMode -from .budget_usage_entry_dto_type import BudgetUsageEntryDtoType +from .budget_entity_usage import BudgetEntityUsage +from .budget_usage_entry_mode import BudgetUsageEntryMode +from .budget_usage_entry_type import BudgetUsageEntryType -class BudgetUsageEntryDto(UniversalBaseModel): +class BudgetUsageEntry(UniversalBaseModel): name: str = pydantic.Field() """ Human-readable name of the budget. """ - type: BudgetUsageEntryDtoType = pydantic.Field() + type: BudgetUsageEntryType = pydantic.Field() """ Budget type. """ @@ -30,12 +30,12 @@ class BudgetUsageEntryDto(UniversalBaseModel): How counters are partitioned (per-user, per-model, per-virtual-account, aggregate, or metadata:). """ - mode: BudgetUsageEntryDtoMode = pydantic.Field() + mode: BudgetUsageEntryMode = pydantic.Field() """ Budget mode. """ - entities: typing.List[BudgetEntityUsageDto] = pydantic.Field() + entities: typing.List[BudgetEntityUsage] = pydantic.Field() """ Per-entity usage for this budget. For my-usage and simulate this contains a single entity; leaderboard-style endpoints may return many. """ diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py b/src/truefoundry_sdk/types/budget_usage_entry_mode.py similarity index 74% rename from src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py rename to src/truefoundry_sdk/types/budget_usage_entry_mode.py index a8cc75dd..67dd492b 100644 --- a/src/truefoundry_sdk/types/budget_usage_entry_dto_mode.py +++ b/src/truefoundry_sdk/types/budget_usage_entry_mode.py @@ -7,7 +7,7 @@ T_Result = typing.TypeVar("T_Result") -class BudgetUsageEntryDtoMode(enum.StrEnum): +class BudgetUsageEntryMode(enum.StrEnum): """ Budget mode. """ @@ -15,13 +15,13 @@ class BudgetUsageEntryDtoMode(enum.StrEnum): ENFORCE = "enforce" AUDIT = "audit" ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" - _UNKNOWN = "__BUDGETUSAGEENTRYDTOMODE_UNKNOWN__" + _UNKNOWN = "__BUDGETUSAGEENTRYMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryDtoMode": + def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryMode": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -33,10 +33,10 @@ def visit( enforce_with_low_priority: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is BudgetUsageEntryDtoMode.ENFORCE: + if self is BudgetUsageEntryMode.ENFORCE: return enforce() - if self is BudgetUsageEntryDtoMode.AUDIT: + if self is BudgetUsageEntryMode.AUDIT: return audit() - if self is BudgetUsageEntryDtoMode.ENFORCE_WITH_LOW_PRIORITY: + if self is BudgetUsageEntryMode.ENFORCE_WITH_LOW_PRIORITY: return enforce_with_low_priority() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/budget_usage_entry_dto_type.py b/src/truefoundry_sdk/types/budget_usage_entry_type.py similarity index 75% rename from src/truefoundry_sdk/types/budget_usage_entry_dto_type.py rename to src/truefoundry_sdk/types/budget_usage_entry_type.py index 1078aeb6..0ecd2332 100644 --- a/src/truefoundry_sdk/types/budget_usage_entry_dto_type.py +++ b/src/truefoundry_sdk/types/budget_usage_entry_type.py @@ -7,20 +7,20 @@ T_Result = typing.TypeVar("T_Result") -class BudgetUsageEntryDtoType(enum.StrEnum): +class BudgetUsageEntryType(enum.StrEnum): """ Budget type. """ TENANT_BUDGET_CONFIG = "tenant-budget-config" TEAM_BUDGET_CONFIG = "team-budget-config" - _UNKNOWN = "__BUDGETUSAGEENTRYDTOTYPE_UNKNOWN__" + _UNKNOWN = "__BUDGETUSAGEENTRYTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. """ @classmethod - def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryDtoType": + def _missing_(cls, value: typing.Any) -> "BudgetUsageEntryType": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -31,8 +31,8 @@ def visit( team_budget_config: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is BudgetUsageEntryDtoType.TENANT_BUDGET_CONFIG: + if self is BudgetUsageEntryType.TENANT_BUDGET_CONFIG: return tenant_budget_config() - if self is BudgetUsageEntryDtoType.TEAM_BUDGET_CONFIG: + if self is BudgetUsageEntryType.TEAM_BUDGET_CONFIG: return team_budget_config() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/budget_usage_response_dto.py b/src/truefoundry_sdk/types/budget_usage_response.py similarity index 73% rename from src/truefoundry_sdk/types/budget_usage_response_dto.py rename to src/truefoundry_sdk/types/budget_usage_response.py index ccc7c699..fa95c0e1 100644 --- a/src/truefoundry_sdk/types/budget_usage_response_dto.py +++ b/src/truefoundry_sdk/types/budget_usage_response.py @@ -4,11 +4,11 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .budget_usage_entry_dto import BudgetUsageEntryDto +from .budget_usage_entry import BudgetUsageEntry -class BudgetUsageResponseDto(UniversalBaseModel): - matched: typing.List[BudgetUsageEntryDto] = pydantic.Field() +class BudgetUsageResponse(UniversalBaseModel): + matched: typing.List[BudgetUsageEntry] = pydantic.Field() """ Budgets that apply, with current usage. """ diff --git a/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config.py b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config.py new file mode 100644 index 00000000..4ccbd30c --- /dev/null +++ b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config.py @@ -0,0 +1,56 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .cisco_ai_defense_guardrail_config_config import CiscoAiDefenseGuardrailConfigConfig +from .cisco_ai_defense_key_auth import CiscoAiDefenseKeyAuth +from .enforcing_strategy import EnforcingStrategy + + +class CiscoAiDefenseGuardrailConfig(UniversalBaseModel): + """ + Cisco AI Defense + """ + + name: str = pydantic.Field() + """ + The name of the Guardrail Config. + """ + + description: typing.Optional[str] = pydantic.Field( + default="Cisco AI Defense for security, safety, privacy, and relevance inspection" + ) + """ + Optional description for this Guardrail Config. + """ + + type: typing.Literal["integration/guardrail-config/cisco-ai-defense"] = pydantic.Field( + default="integration/guardrail-config/cisco-ai-defense" + ) + """ + +uiType=Hidden + +value=integration/guardrail-config/cisco-ai-defense + """ + + auth_data: CiscoAiDefenseKeyAuth + operation: typing.Literal["validate"] = pydantic.Field(default="validate") + """ + Cisco AI Defense inspects and validates content without modifying it. + """ + + enforcing_strategy: EnforcingStrategy + config: CiscoAiDefenseGuardrailConfigConfig = pydantic.Field() + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config.py b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config.py new file mode 100644 index 00000000..cc240477 --- /dev/null +++ b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .cisco_ai_defense_guardrail_config_config_region import CiscoAiDefenseGuardrailConfigConfigRegion + + +class CiscoAiDefenseGuardrailConfigConfig(UniversalBaseModel): + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + region: CiscoAiDefenseGuardrailConfigConfigRegion = pydantic.Field() + """ + Cisco AI Defense regional API endpoint. + """ + + metadata: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Additional metadata forwarded to Cisco AI Defense. The authenticated TrueFoundry user is added automatically. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config_region.py b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config_region.py new file mode 100644 index 00000000..4c993546 --- /dev/null +++ b/src/truefoundry_sdk/types/cisco_ai_defense_guardrail_config_config_region.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class CiscoAiDefenseGuardrailConfigConfigRegion(enum.StrEnum): + """ + Cisco AI Defense regional API endpoint. + """ + + US = "us" + EU = "eu" + AP = "ap" + _UNKNOWN = "__CISCOAIDEFENSEGUARDRAILCONFIGCONFIGREGION_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "CiscoAiDefenseGuardrailConfigConfigRegion": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + us: typing.Callable[[], T_Result], + eu: typing.Callable[[], T_Result], + ap: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is CiscoAiDefenseGuardrailConfigConfigRegion.US: + return us() + if self is CiscoAiDefenseGuardrailConfigConfigRegion.EU: + return eu() + if self is CiscoAiDefenseGuardrailConfigConfigRegion.AP: + return ap() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/cisco_ai_defense_key_auth.py b/src/truefoundry_sdk/types/cisco_ai_defense_key_auth.py new file mode 100644 index 00000000..78f09f21 --- /dev/null +++ b/src/truefoundry_sdk/types/cisco_ai_defense_key_auth.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CiscoAiDefenseKeyAuth(UniversalBaseModel): + type: typing.Literal["api-key"] = pydantic.Field(default="api-key") + """ + +value=api-key + """ + + api_key: str = pydantic.Field() + """ + API key generated from the Cisco AI Defense UI + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/guardrail_config_integrations.py b/src/truefoundry_sdk/types/guardrail_config_integrations.py index 11d9e179..14338b9c 100644 --- a/src/truefoundry_sdk/types/guardrail_config_integrations.py +++ b/src/truefoundry_sdk/types/guardrail_config_integrations.py @@ -8,6 +8,7 @@ from .azure_pii_guardrail_config import AzurePiiGuardrailConfig from .azure_prompt_shield_guardrail_config import AzurePromptShieldGuardrailConfig from .cedar_guardrail_config import CedarGuardrailConfig +from .cisco_ai_defense_guardrail_config import CiscoAiDefenseGuardrailConfig from .code_safety_linter_guardrail_config import CodeSafetyLinterGuardrailConfig from .crowd_strike_aidr_guardrail_config import CrowdStrikeAidrGuardrailConfig from .custom_guardrail_config import CustomGuardrailConfig @@ -39,6 +40,7 @@ EnkryptAiGuardrailConfig, PaloAltoPrismaAirsGuardrailConfig, FiddlerGuardrailConfig, + CiscoAiDefenseGuardrailConfig, CrowdStrikeAidrGuardrailConfig, PatronusGuardrailConfig, SecretDetectionGuardrailConfig, diff --git a/src/truefoundry_sdk/types/period_usage_dto.py b/src/truefoundry_sdk/types/period_usage.py similarity index 95% rename from src/truefoundry_sdk/types/period_usage_dto.py rename to src/truefoundry_sdk/types/period_usage.py index 38aa65ff..a269f96f 100644 --- a/src/truefoundry_sdk/types/period_usage_dto.py +++ b/src/truefoundry_sdk/types/period_usage.py @@ -6,7 +6,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class PeriodUsageDto(UniversalBaseModel): +class PeriodUsage(UniversalBaseModel): limit: float = pydantic.Field() """ Resolved (override-aware) cost limit for the period. diff --git a/src/truefoundry_sdk/types/py_spark_task_config.py b/src/truefoundry_sdk/types/py_spark_task_config.py index d38e3344..48e5e315 100644 --- a/src/truefoundry_sdk/types/py_spark_task_config.py +++ b/src/truefoundry_sdk/types/py_spark_task_config.py @@ -4,9 +4,9 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .py_spark_task_config_image import PySparkTaskConfigImage from .spark_driver_config import SparkDriverConfig from .spark_executor_config import SparkExecutorConfig -from .task_py_spark_build import TaskPySparkBuild from .volume_mount import VolumeMount @@ -16,7 +16,12 @@ class PySparkTaskConfig(UniversalBaseModel): +value=pyspark-task-config """ - image: TaskPySparkBuild + image: PySparkTaskConfigImage = pydantic.Field() + """ + Specification for the image to be used for the task. Use TaskPySparkBuild to build an image, + or TaskSparkImage to use a pre-built image that already contains all code and dependencies. + """ + driver_config: SparkDriverConfig executor_config: SparkExecutorConfig spark_conf: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) diff --git a/src/truefoundry_sdk/types/py_spark_task_config_image.py b/src/truefoundry_sdk/types/py_spark_task_config_image.py new file mode 100644 index 00000000..c052538a --- /dev/null +++ b/src/truefoundry_sdk/types/py_spark_task_config_image.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .task_py_spark_build import TaskPySparkBuild +from .task_spark_image import TaskSparkImage + +PySparkTaskConfigImage = typing.Union[TaskPySparkBuild, TaskSparkImage] diff --git a/src/truefoundry_sdk/types/task_spark_image.py b/src/truefoundry_sdk/types/task_spark_image.py new file mode 100644 index 00000000..a354da2d --- /dev/null +++ b/src/truefoundry_sdk/types/task_spark_image.py @@ -0,0 +1,48 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TaskSparkImage(UniversalBaseModel): + """ + Describes a pre-built Spark image for a task. Use this when your image already contains + all workflow code, dependencies (including truefoundry[workflow,spark]), and required JARs. + This skips the Docker build phase entirely. + """ + + type: typing.Literal["task-spark-image"] = pydantic.Field(default="task-spark-image") + """ + +uiType=Hidden + +value=task-spark-image + """ + + spark_version: str = pydantic.Field(default="3.5.2") + """ + Spark version should match the spark version installed in the image. + """ + + container_image: str = pydantic.Field() + """ + The container image URI of the pre-built Spark image. The image must contain: + 1. All workflow source code at /app (or appropriate PYTHONPATH) + 2. truefoundry[workflow,spark] package installed + 3. PySpark matching the spark_version + 4. Hadoop AWS/GCS/Azure JARs if using cloud storage + """ + + docker_registry: typing.Optional[str] = pydantic.Field(default=None) + """ + FQN of the container registry. If you can't find your registry here, + add it through the [Integrations](/integrations?tab=docker-registry) page + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow From db5f727972e63f50471855b4b17ddd79b89da476 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:31:10 +0000 Subject: [PATCH 5/9] SDK regeneration --- .fern/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.fern/metadata.json b/.fern/metadata.json index dbfc45c9..f6ee8e06 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "9af00380b1f1ccfcd9dc2d0272197dac286c4c6e", + "originGitCommit": "3d4ff551c7cdba5d3ffe71f0b16583924f916302", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", From e2836b583fee3f1afbf22eb1f3636077551474a8 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:48:48 +0000 Subject: [PATCH 6/9] SDK regeneration --- .fern/metadata.json | 2 +- reference.md | 8 ++-- src/truefoundry_sdk/__init__.py | 9 +++++ src/truefoundry_sdk/gateway_budgets/client.py | 21 +++++----- .../gateway_budgets/raw_client.py | 29 +++++++------- src/truefoundry_sdk/types/__init__.py | 9 +++++ .../types/gateway_data_created_by_filter.py | 3 +- ...gateway_data_created_by_filter_operator.py | 38 +++++++++++++++++++ .../types/gateway_data_metadata_filter.py | 3 +- .../gateway_data_metadata_filter_operator.py | 38 +++++++++++++++++++ .../types/list_budgets_response.py | 22 +++++++++++ 11 files changed, 151 insertions(+), 31 deletions(-) create mode 100644 src/truefoundry_sdk/types/gateway_data_created_by_filter_operator.py create mode 100644 src/truefoundry_sdk/types/gateway_data_metadata_filter_operator.py create mode 100644 src/truefoundry_sdk/types/list_budgets_response.py diff --git a/.fern/metadata.json b/.fern/metadata.json index f6ee8e06..d966da4d 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "3d4ff551c7cdba5d3ffe71f0b16583924f916302", + "originGitCommit": "37506419fb22bb29b74d5d9178400b8f96c7e594", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/reference.md b/reference.md index 5705175d..163ce0f5 100644 --- a/reference.md +++ b/reference.md @@ -1853,7 +1853,7 @@ client.teams.get_permissions(
## GatewayBudgets -
client.gateway_budgets.list(...) -> typing.List[GatewayBudget] +
client.gateway_budgets.list(...) -> ListBudgetsResponse
@@ -1865,7 +1865,7 @@ client.teams.get_permissions(
-Returns all budgets for the tenant. Supports filtering by type and team_name. +List the gateway budgets the caller can read within the tenant.
@@ -1903,7 +1903,7 @@ client.gateway_budgets.list()
-**type:** `typing.Optional[ListGatewayBudgetsRequestType]` — Filter by budget type. One of tenant-budget-config | team-budget-config. +**type:** `typing.Optional[ListGatewayBudgetsRequestType]` — Filter by budget type.
@@ -1911,7 +1911,7 @@ client.gateway_budgets.list()
-**team_name:** `typing.Optional[str]` — Filter by team_name (only meaningful for team-budget-config). +**team_name:** `typing.Optional[str]` — Human-readable name of the team owning the budget. Only matches team budgets.
diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 9f593ecc..b2d2b599 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -413,7 +413,9 @@ GatewayConfiguration, GatewayDataAccessConfig, GatewayDataCreatedByFilter, + GatewayDataCreatedByFilterOperator, GatewayDataMetadataFilter, + GatewayDataMetadataFilterOperator, GatewayDataRoutingConfig, GatewayDataRoutingConfigDestination, GatewayDataRoutingConfigDestinationCondition, @@ -622,6 +624,7 @@ ListApplicationsResponse, ListArtifactVersionsResponse, ListArtifactsResponse, + ListBudgetsResponse, ListClusterAddonsResponse, ListClustersResponse, ListDataDirectoriesResponse, @@ -1699,7 +1702,9 @@ "GatewayConfiguration": ".types", "GatewayDataAccessConfig": ".types", "GatewayDataCreatedByFilter": ".types", + "GatewayDataCreatedByFilterOperator": ".types", "GatewayDataMetadataFilter": ".types", + "GatewayDataMetadataFilterOperator": ".types", "GatewayDataRoutingConfig": ".types", "GatewayDataRoutingConfigDestination": ".types", "GatewayDataRoutingConfigDestinationCondition": ".types", @@ -1912,6 +1917,7 @@ "ListApplicationsResponse": ".types", "ListArtifactVersionsResponse": ".types", "ListArtifactsResponse": ".types", + "ListBudgetsResponse": ".types", "ListClusterAddonsResponse": ".types", "ListClustersResponse": ".types", "ListDataDirectoriesResponse": ".types", @@ -2994,7 +3000,9 @@ def __dir__(): "GatewayConfiguration", "GatewayDataAccessConfig", "GatewayDataCreatedByFilter", + "GatewayDataCreatedByFilterOperator", "GatewayDataMetadataFilter", + "GatewayDataMetadataFilterOperator", "GatewayDataRoutingConfig", "GatewayDataRoutingConfigDestination", "GatewayDataRoutingConfigDestinationCondition", @@ -3207,6 +3215,7 @@ def __dir__(): "ListApplicationsResponse", "ListArtifactVersionsResponse", "ListArtifactsResponse", + "ListBudgetsResponse", "ListClusterAddonsResponse", "ListClustersResponse", "ListDataDirectoriesResponse", diff --git a/src/truefoundry_sdk/gateway_budgets/client.py b/src/truefoundry_sdk/gateway_budgets/client.py index aaee2cce..144a4915 100644 --- a/src/truefoundry_sdk/gateway_budgets/client.py +++ b/src/truefoundry_sdk/gateway_budgets/client.py @@ -6,6 +6,7 @@ from ..core.request_options import RequestOptions from ..types.budget_usage_response import BudgetUsageResponse from ..types.gateway_budget import GatewayBudget +from ..types.list_budgets_response import ListBudgetsResponse from .raw_client import AsyncRawGatewayBudgetsClient, RawGatewayBudgetsClient from .types.create_or_update_budget_request_manifest import CreateOrUpdateBudgetRequestManifest from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType @@ -35,24 +36,24 @@ def list( type: typing.Optional[ListGatewayBudgetsRequestType] = None, team_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[GatewayBudget]: + ) -> ListBudgetsResponse: """ - Returns all budgets for the tenant. Supports filtering by type and team_name. + List the gateway budgets the caller can read within the tenant. Parameters ---------- type : typing.Optional[ListGatewayBudgetsRequestType] - Filter by budget type. One of tenant-budget-config | team-budget-config. + Filter by budget type. team_name : typing.Optional[str] - Filter by team_name (only meaningful for team-budget-config). + Human-readable name of the team owning the budget. Only matches team budgets. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[GatewayBudget] + ListBudgetsResponse List of budgets. Examples @@ -335,24 +336,24 @@ async def list( type: typing.Optional[ListGatewayBudgetsRequestType] = None, team_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[GatewayBudget]: + ) -> ListBudgetsResponse: """ - Returns all budgets for the tenant. Supports filtering by type and team_name. + List the gateway budgets the caller can read within the tenant. Parameters ---------- type : typing.Optional[ListGatewayBudgetsRequestType] - Filter by budget type. One of tenant-budget-config | team-budget-config. + Filter by budget type. team_name : typing.Optional[str] - Filter by team_name (only meaningful for team-budget-config). + Human-readable name of the team owning the budget. Only matches team budgets. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - typing.List[GatewayBudget] + ListBudgetsResponse List of budgets. Examples diff --git a/src/truefoundry_sdk/gateway_budgets/raw_client.py b/src/truefoundry_sdk/gateway_budgets/raw_client.py index 77c586d8..4b130cc0 100644 --- a/src/truefoundry_sdk/gateway_budgets/raw_client.py +++ b/src/truefoundry_sdk/gateway_budgets/raw_client.py @@ -15,6 +15,7 @@ from ..errors.not_found_error import NotFoundError from ..types.budget_usage_response import BudgetUsageResponse from ..types.gateway_budget import GatewayBudget +from ..types.list_budgets_response import ListBudgetsResponse from .types.create_or_update_budget_request_manifest import CreateOrUpdateBudgetRequestManifest from .types.list_gateway_budgets_request_type import ListGatewayBudgetsRequestType from pydantic import ValidationError @@ -33,24 +34,24 @@ def list( type: typing.Optional[ListGatewayBudgetsRequestType] = None, team_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[typing.List[GatewayBudget]]: + ) -> HttpResponse[ListBudgetsResponse]: """ - Returns all budgets for the tenant. Supports filtering by type and team_name. + List the gateway budgets the caller can read within the tenant. Parameters ---------- type : typing.Optional[ListGatewayBudgetsRequestType] - Filter by budget type. One of tenant-budget-config | team-budget-config. + Filter by budget type. team_name : typing.Optional[str] - Filter by team_name (only meaningful for team-budget-config). + Human-readable name of the team owning the budget. Only matches team budgets. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[typing.List[GatewayBudget]] + HttpResponse[ListBudgetsResponse] List of budgets. """ _response = self._client_wrapper.httpx_client.request( @@ -65,9 +66,9 @@ def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - typing.List[GatewayBudget], + ListBudgetsResponse, parse_obj_as( - type_=typing.List[GatewayBudget], # type: ignore + type_=ListBudgetsResponse, # type: ignore object_=_response.json(), ), ) @@ -437,24 +438,24 @@ async def list( type: typing.Optional[ListGatewayBudgetsRequestType] = None, team_name: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[typing.List[GatewayBudget]]: + ) -> AsyncHttpResponse[ListBudgetsResponse]: """ - Returns all budgets for the tenant. Supports filtering by type and team_name. + List the gateway budgets the caller can read within the tenant. Parameters ---------- type : typing.Optional[ListGatewayBudgetsRequestType] - Filter by budget type. One of tenant-budget-config | team-budget-config. + Filter by budget type. team_name : typing.Optional[str] - Filter by team_name (only meaningful for team-budget-config). + Human-readable name of the team owning the budget. Only matches team budgets. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[typing.List[GatewayBudget]] + AsyncHttpResponse[ListBudgetsResponse] List of budgets. """ _response = await self._client_wrapper.httpx_client.request( @@ -469,9 +470,9 @@ async def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - typing.List[GatewayBudget], + ListBudgetsResponse, parse_obj_as( - type_=typing.List[GatewayBudget], # type: ignore + type_=ListBudgetsResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index add73802..52b723e9 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -417,7 +417,9 @@ from .gateway_configuration import GatewayConfiguration from .gateway_data_access_config import GatewayDataAccessConfig from .gateway_data_created_by_filter import GatewayDataCreatedByFilter + from .gateway_data_created_by_filter_operator import GatewayDataCreatedByFilterOperator from .gateway_data_metadata_filter import GatewayDataMetadataFilter + from .gateway_data_metadata_filter_operator import GatewayDataMetadataFilterOperator from .gateway_data_routing_config import GatewayDataRoutingConfig from .gateway_data_routing_config_destination import GatewayDataRoutingConfigDestination from .gateway_data_routing_config_destination_condition import GatewayDataRoutingConfigDestinationCondition @@ -640,6 +642,7 @@ from .list_applications_response import ListApplicationsResponse from .list_artifact_versions_response import ListArtifactVersionsResponse from .list_artifacts_response import ListArtifactsResponse + from .list_budgets_response import ListBudgetsResponse from .list_cluster_addons_response import ListClusterAddonsResponse from .list_clusters_response import ListClustersResponse from .list_data_directories_response import ListDataDirectoriesResponse @@ -1641,7 +1644,9 @@ "GatewayConfiguration": ".gateway_configuration", "GatewayDataAccessConfig": ".gateway_data_access_config", "GatewayDataCreatedByFilter": ".gateway_data_created_by_filter", + "GatewayDataCreatedByFilterOperator": ".gateway_data_created_by_filter_operator", "GatewayDataMetadataFilter": ".gateway_data_metadata_filter", + "GatewayDataMetadataFilterOperator": ".gateway_data_metadata_filter_operator", "GatewayDataRoutingConfig": ".gateway_data_routing_config", "GatewayDataRoutingConfigDestination": ".gateway_data_routing_config_destination", "GatewayDataRoutingConfigDestinationCondition": ".gateway_data_routing_config_destination_condition", @@ -1850,6 +1855,7 @@ "ListApplicationsResponse": ".list_applications_response", "ListArtifactVersionsResponse": ".list_artifact_versions_response", "ListArtifactsResponse": ".list_artifacts_response", + "ListBudgetsResponse": ".list_budgets_response", "ListClusterAddonsResponse": ".list_cluster_addons_response", "ListClustersResponse": ".list_clusters_response", "ListDataDirectoriesResponse": ".list_data_directories_response", @@ -2878,7 +2884,9 @@ def __dir__(): "GatewayConfiguration", "GatewayDataAccessConfig", "GatewayDataCreatedByFilter", + "GatewayDataCreatedByFilterOperator", "GatewayDataMetadataFilter", + "GatewayDataMetadataFilterOperator", "GatewayDataRoutingConfig", "GatewayDataRoutingConfigDestination", "GatewayDataRoutingConfigDestinationCondition", @@ -3087,6 +3095,7 @@ def __dir__(): "ListApplicationsResponse", "ListArtifactVersionsResponse", "ListArtifactsResponse", + "ListBudgetsResponse", "ListClusterAddonsResponse", "ListClustersResponse", "ListDataDirectoriesResponse", diff --git a/src/truefoundry_sdk/types/gateway_data_created_by_filter.py b/src/truefoundry_sdk/types/gateway_data_created_by_filter.py index 7ecb78db..4c765668 100644 --- a/src/truefoundry_sdk/types/gateway_data_created_by_filter.py +++ b/src/truefoundry_sdk/types/gateway_data_created_by_filter.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .gateway_data_created_by_filter_operator import GatewayDataCreatedByFilterOperator class GatewayDataCreatedByFilter(UniversalBaseModel): @@ -16,7 +17,7 @@ class GatewayDataCreatedByFilter(UniversalBaseModel): Filter type """ - operator: typing.Literal["IN"] = pydantic.Field(default="IN") + operator: GatewayDataCreatedByFilterOperator = pydantic.Field() """ Comparison operator """ diff --git a/src/truefoundry_sdk/types/gateway_data_created_by_filter_operator.py b/src/truefoundry_sdk/types/gateway_data_created_by_filter_operator.py new file mode 100644 index 00000000..e9998597 --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_data_created_by_filter_operator.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class GatewayDataCreatedByFilterOperator(enum.StrEnum): + """ + Comparison operator + """ + + IN = "IN" + NOT_IN = "NOT_IN" + _UNKNOWN = "__GATEWAYDATACREATEDBYFILTEROPERATOR_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "GatewayDataCreatedByFilterOperator": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + in_: typing.Callable[[], T_Result], + not_in: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is GatewayDataCreatedByFilterOperator.IN: + return in_() + if self is GatewayDataCreatedByFilterOperator.NOT_IN: + return not_in() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/gateway_data_metadata_filter.py b/src/truefoundry_sdk/types/gateway_data_metadata_filter.py index 3ae54651..658a7fbc 100644 --- a/src/truefoundry_sdk/types/gateway_data_metadata_filter.py +++ b/src/truefoundry_sdk/types/gateway_data_metadata_filter.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .gateway_data_metadata_filter_operator import GatewayDataMetadataFilterOperator class GatewayDataMetadataFilter(UniversalBaseModel): @@ -21,7 +22,7 @@ class GatewayDataMetadataFilter(UniversalBaseModel): Metadata key to filter on """ - operator: typing.Literal["IN"] = pydantic.Field(default="IN") + operator: GatewayDataMetadataFilterOperator = pydantic.Field() """ Comparison operator """ diff --git a/src/truefoundry_sdk/types/gateway_data_metadata_filter_operator.py b/src/truefoundry_sdk/types/gateway_data_metadata_filter_operator.py new file mode 100644 index 00000000..89500c4a --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_data_metadata_filter_operator.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class GatewayDataMetadataFilterOperator(enum.StrEnum): + """ + Comparison operator + """ + + IN = "IN" + NOT_IN = "NOT_IN" + _UNKNOWN = "__GATEWAYDATAMETADATAFILTEROPERATOR_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "GatewayDataMetadataFilterOperator": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + in_: typing.Callable[[], T_Result], + not_in: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is GatewayDataMetadataFilterOperator.IN: + return in_() + if self is GatewayDataMetadataFilterOperator.NOT_IN: + return not_in() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/list_budgets_response.py b/src/truefoundry_sdk/types/list_budgets_response.py new file mode 100644 index 00000000..1fa23584 --- /dev/null +++ b/src/truefoundry_sdk/types/list_budgets_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .gateway_budget import GatewayBudget + + +class ListBudgetsResponse(UniversalBaseModel): + data: typing.List[GatewayBudget] = pydantic.Field() + """ + Budgets matching the requested filters. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow From 29089a8d5e56864c36d1b86a4c52ea4afe0de511 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 20:15:04 +0000 Subject: [PATCH 7/9] SDK regeneration --- .fern/metadata.json | 6 +- poetry.lock | 10 +-- reference.md | 24 ++++-- src/truefoundry_sdk/__init__.py | 15 ++++ src/truefoundry_sdk/agents/client.py | 4 +- src/truefoundry_sdk/agents/raw_client.py | 26 ++++++- src/truefoundry_sdk/core/jsonable_encoder.py | 13 ++++ src/truefoundry_sdk/teams/client.py | 74 ++++++++++++------- src/truefoundry_sdk/teams/raw_client.py | 64 +++++++++------- src/truefoundry_sdk/types/__init__.py | 15 ++++ .../types/budget_usage_entry_mode.py | 8 +- .../types/calypso_ai_api_key_auth.py | 30 ++++++++ .../types/calypso_ai_guardrail_config.py | 63 ++++++++++++++++ .../calypso_ai_guardrail_config_config.py | 31 ++++++++ .../calypso_ai_guardrail_config_operation.py | 39 ++++++++++ .../types/custom_server_header_auth.py | 5 +- .../types/google_vertex_provider_account.py | 5 ++ .../types/guardrail_config_integrations.py | 2 + .../types/noma_security_api_key_auth.py | 2 +- .../types/noma_security_guardrail_config.py | 13 +++- .../noma_security_guardrail_config_config.py | 6 +- ...oma_security_guardrail_config_operation.py | 39 ++++++++++ .../types/open_apimcp_server_manifest.py | 5 ++ .../types/provider_integration.py | 1 + .../types/remote_mcp_server_manifest.py | 5 ++ .../types/stdio_mcp_server_manifest.py | 5 ++ .../types/subject_subject_type.py | 8 ++ src/truefoundry_sdk/types/subject_type.py | 8 ++ .../types/team_budget_config.py | 2 +- .../types/team_budget_config_mode.py | 10 +-- .../types/tenant_budget_config.py | 2 +- .../types/tenant_budget_config_mode.py | 10 +-- .../types/tfy_managed_mcp_server_manifest.py | 5 ++ .../types/virtual_mcp_server_manifest.py | 5 ++ 34 files changed, 462 insertions(+), 98 deletions(-) create mode 100644 src/truefoundry_sdk/types/calypso_ai_api_key_auth.py create mode 100644 src/truefoundry_sdk/types/calypso_ai_guardrail_config.py create mode 100644 src/truefoundry_sdk/types/calypso_ai_guardrail_config_config.py create mode 100644 src/truefoundry_sdk/types/calypso_ai_guardrail_config_operation.py create mode 100644 src/truefoundry_sdk/types/noma_security_guardrail_config_operation.py diff --git a/.fern/metadata.json b/.fern/metadata.json index d966da4d..7607b885 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "5.82.0", + "cliVersion": "5.89.4", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "5.24.0", + "generatorVersion": "5.26.0", "generatorConfig": { "package_name": "truefoundry_sdk", "use_request_defaults": "all", @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "37506419fb22bb29b74d5d9178400b8f96c7e594", + "originGitCommit": "ee220d57a9ea7d75b0042756f2870909b45115ab", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/poetry.lock b/poetry.lock index aa93f6eb..afd06166 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1956,19 +1956,19 @@ files = [ [[package]] name = "traitlets" -version = "5.15.1" +version = "5.16.1" description = "Traitlets Python configuration system" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "traitlets-5.15.1-py3-none-any.whl", hash = "sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92"}, - {file = "traitlets-5.15.1.tar.gz", hash = "sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722"}, + {file = "traitlets-5.16.1-py3-none-any.whl", hash = "sha256:f775618166caa0396c8e337099240f2bd3e5e917d203b2e6fbe21a58d3cb1f6b"}, + {file = "traitlets-5.16.1.tar.gz", hash = "sha256:ed900c2b631aa3a112811139fa97b8d2c3bad5e989656bba4b7e52c7852c18c1"}, ] [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.17.0,<1.19)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] +test = ["argcomplete (>=3.0.3) ; python_version < \"3.12\"", "argcomplete (>=3.5.2) ; python_version >= \"3.12\"", "mypy (>=2.0) ; implementation_name != \"pypy\"", "pre-commit", "pytest (>=7.0,<10.0)", "pytest-mock", "pytest-mypy-testing ; implementation_name != \"pypy\""] [[package]] name = "types-python-dateutil" diff --git a/reference.md b/reference.md index 163ce0f5..f1284b2c 100644 --- a/reference.md +++ b/reference.md @@ -1267,7 +1267,7 @@ client.users.get_teams(
-List teams accessible to the current user. +List teams accessible to the current user. Set includeMembership=false to omit full member and manager lists and return cached membership summaries instead.
@@ -1340,6 +1340,14 @@ client.teams.list(
+**include_membership:** `typing.Optional[bool]` — Whether to include full member and manager lists. Set to false for a metadata-only response with cached membership summaries. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1474,8 +1482,8 @@ client = TrueFoundry( client.teams.list_members( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", ) @@ -1501,7 +1509,7 @@ client.teams.list_members(
-**limit:** `typing.Optional[int]` — Number of items per page +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -1509,7 +1517,7 @@ client.teams.list_members(
-**offset:** `typing.Optional[int]` — Number of items to skip +**limit:** `typing.Optional[int]` — Number of items per page
@@ -1573,8 +1581,8 @@ client = TrueFoundry( client.teams.list_managers( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter="{\"type\":\"AND\",\"children\":[{\"column\":\"email\",\"op\":\"STRING_CONTAINS\",\"value\":\"@example.com\"}]}", ) @@ -1600,7 +1608,7 @@ client.teams.list_managers(
-**limit:** `typing.Optional[int]` — Number of items per page +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -1608,7 +1616,7 @@ client.teams.list_managers(
-**offset:** `typing.Optional[int]` — Number of items to skip +**limit:** `typing.Optional[int]` — Number of items per page
@@ -7557,7 +7565,7 @@ client.agents.delete(
-Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. +Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity.
diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index b2d2b599..8a082c89 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -227,6 +227,10 @@ BuildBuildSpec, BuildInfo, BuildSecret, + CalypsoAiApiKeyAuth, + CalypsoAiGuardrailConfig, + CalypsoAiGuardrailConfigConfig, + CalypsoAiGuardrailConfigOperation, Canary, CanaryStep, CartesiaApiKeyAuth, @@ -742,6 +746,7 @@ NomaSecurityApiKeyAuth, NomaSecurityGuardrailConfig, NomaSecurityGuardrailConfigConfig, + NomaSecurityGuardrailConfigOperation, NomicIntegrations, NomicKeyAuth, NomicModel, @@ -1507,6 +1512,10 @@ "BuildBuildSpec": ".types", "BuildInfo": ".types", "BuildSecret": ".types", + "CalypsoAiApiKeyAuth": ".types", + "CalypsoAiGuardrailConfig": ".types", + "CalypsoAiGuardrailConfigConfig": ".types", + "CalypsoAiGuardrailConfigOperation": ".types", "Canary": ".types", "CanaryStep": ".types", "CancelDeploymentApplicationsResponse": ".applications", @@ -2037,6 +2046,7 @@ "NomaSecurityApiKeyAuth": ".types", "NomaSecurityGuardrailConfig": ".types", "NomaSecurityGuardrailConfigConfig": ".types", + "NomaSecurityGuardrailConfigOperation": ".types", "NomicIntegrations": ".types", "NomicKeyAuth": ".types", "NomicModel": ".types", @@ -2805,6 +2815,10 @@ def __dir__(): "BuildBuildSpec", "BuildInfo", "BuildSecret", + "CalypsoAiApiKeyAuth", + "CalypsoAiGuardrailConfig", + "CalypsoAiGuardrailConfigConfig", + "CalypsoAiGuardrailConfigOperation", "Canary", "CanaryStep", "CancelDeploymentApplicationsResponse", @@ -3335,6 +3349,7 @@ def __dir__(): "NomaSecurityApiKeyAuth", "NomaSecurityGuardrailConfig", "NomaSecurityGuardrailConfigConfig", + "NomaSecurityGuardrailConfigOperation", "NomicIntegrations", "NomicKeyAuth", "NomicModel", diff --git a/src/truefoundry_sdk/agents/client.py b/src/truefoundry_sdk/agents/client.py index 2d1bf459..94780936 100644 --- a/src/truefoundry_sdk/agents/client.py +++ b/src/truefoundry_sdk/agents/client.py @@ -230,7 +230,7 @@ def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetAgentIdentityTokenResponse: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. Parameters ---------- @@ -506,7 +506,7 @@ async def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetAgentIdentityTokenResponse: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. Parameters ---------- diff --git a/src/truefoundry_sdk/agents/raw_client.py b/src/truefoundry_sdk/agents/raw_client.py index 706dd887..a5b671df 100644 --- a/src/truefoundry_sdk/agents/raw_client.py +++ b/src/truefoundry_sdk/agents/raw_client.py @@ -395,7 +395,7 @@ def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetAgentIdentityTokenResponse]: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. Parameters ---------- @@ -436,6 +436,17 @@ def get_token( ), ), ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 404: raise NotFoundError( headers=dict(_response.headers), @@ -836,7 +847,7 @@ async def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetAgentIdentityTokenResponse]: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. 404s if the agent has no linked identity. + Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. Parameters ---------- @@ -877,6 +888,17 @@ async def get_token( ), ), ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 404: raise NotFoundError( headers=dict(_response.headers), diff --git a/src/truefoundry_sdk/core/jsonable_encoder.py b/src/truefoundry_sdk/core/jsonable_encoder.py index 5b0902eb..f638cc9a 100644 --- a/src/truefoundry_sdk/core/jsonable_encoder.py +++ b/src/truefoundry_sdk/core/jsonable_encoder.py @@ -15,6 +15,7 @@ from pathlib import PurePath from types import GeneratorType from typing import Any, Callable, Dict, List, Optional, Set, Union +from urllib.parse import quote import pydantic from .datetime_utils import serialize_datetime @@ -118,3 +119,15 @@ def encode_path_param(obj: Any) -> str: if isinstance(obj, bool): return "true" if obj else "false" return str(jsonable_encoder(obj)) + + +def quote_path_param(obj: Any) -> str: + """Encode a value for use in a URL path segment, percent-encoding it. + + Same as encode_path_param, except the result is percent-encoded so + that a value containing "/" or ".." cannot change which endpoint + the request resolves to. + """ + if isinstance(obj, bool): + return "true" if obj else "false" + return quote(str(jsonable_encoder(obj)), safe="") diff --git a/src/truefoundry_sdk/teams/client.py b/src/truefoundry_sdk/teams/client.py index 5bc224a9..48e35f2d 100644 --- a/src/truefoundry_sdk/teams/client.py +++ b/src/truefoundry_sdk/teams/client.py @@ -42,10 +42,11 @@ def list( offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, attributes: typing.Optional[typing.Sequence[str]] = None, + include_membership: typing.Optional[bool] = True, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Team, ListTeamsResponse]: """ - List teams accessible to the current user. + List teams accessible to the current user. Set includeMembership=false to omit full member and manager lists and return cached membership summaries instead. Parameters ---------- @@ -61,6 +62,9 @@ def list( attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. + include_membership : typing.Optional[bool] + Whether to include full member and manager lists. Set to false for a metadata-only response with cached membership summaries. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -88,7 +92,12 @@ def list( yield page """ return self._raw_client.list( - limit=limit, offset=offset, role=role, attributes=attributes, request_options=request_options + limit=limit, + offset=offset, + role=role, + attributes=attributes, + include_membership=include_membership, + request_options=request_options, ) def create_or_update( @@ -141,8 +150,8 @@ def list_members( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TeamSubjectRow, ListTeamMembersResponse]: @@ -154,12 +163,12 @@ def list_members( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -181,8 +190,8 @@ def list_members( ) response = client.teams.list_members( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter='{"type":"AND","children":[{"column":"email","op":"STRING_CONTAINS","value":"@example.com"}]}', ) for item in response: @@ -192,15 +201,15 @@ def list_members( yield page """ return self._raw_client.list_members( - id, limit=limit, offset=offset, filter=filter, request_options=request_options + id, offset=offset, limit=limit, filter=filter, request_options=request_options ) def list_managers( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TeamSubjectRow, ListTeamManagersResponse]: @@ -212,12 +221,12 @@ def list_managers( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -239,8 +248,8 @@ def list_managers( ) response = client.teams.list_managers( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter='{"type":"AND","children":[{"column":"email","op":"STRING_CONTAINS","value":"@example.com"}]}', ) for item in response: @@ -250,7 +259,7 @@ def list_managers( yield page """ return self._raw_client.list_managers( - id, limit=limit, offset=offset, filter=filter, request_options=request_options + id, offset=offset, limit=limit, filter=filter, request_options=request_options ) def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetTeamResponse: @@ -374,10 +383,11 @@ async def list( offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, attributes: typing.Optional[typing.Sequence[str]] = None, + include_membership: typing.Optional[bool] = True, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Team, ListTeamsResponse]: """ - List teams accessible to the current user. + List teams accessible to the current user. Set includeMembership=false to omit full member and manager lists and return cached membership summaries instead. Parameters ---------- @@ -393,6 +403,9 @@ async def list( attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. + include_membership : typing.Optional[bool] + Whether to include full member and manager lists. Set to false for a metadata-only response with cached membership summaries. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -429,7 +442,12 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - limit=limit, offset=offset, role=role, attributes=attributes, request_options=request_options + limit=limit, + offset=offset, + role=role, + attributes=attributes, + include_membership=include_membership, + request_options=request_options, ) async def create_or_update( @@ -490,8 +508,8 @@ async def list_members( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TeamSubjectRow, ListTeamMembersResponse]: @@ -503,12 +521,12 @@ async def list_members( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -535,8 +553,8 @@ async def list_members( async def main() -> None: response = await client.teams.list_members( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter='{"type":"AND","children":[{"column":"email","op":"STRING_CONTAINS","value":"@example.com"}]}', ) async for item in response: @@ -550,15 +568,15 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_members( - id, limit=limit, offset=offset, filter=filter, request_options=request_options + id, offset=offset, limit=limit, filter=filter, request_options=request_options ) async def list_managers( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TeamSubjectRow, ListTeamManagersResponse]: @@ -570,12 +588,12 @@ async def list_managers( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -602,8 +620,8 @@ async def list_managers( async def main() -> None: response = await client.teams.list_managers( id="jqfwg345gi25n5ju2yz5iz6m", - limit=10, offset=0, + limit=10, filter='{"type":"AND","children":[{"column":"email","op":"STRING_CONTAINS","value":"@example.com"}]}', ) async for item in response: @@ -617,7 +635,7 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list_managers( - id, limit=limit, offset=offset, filter=filter, request_options=request_options + id, offset=offset, limit=limit, filter=filter, request_options=request_options ) async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetTeamResponse: diff --git a/src/truefoundry_sdk/teams/raw_client.py b/src/truefoundry_sdk/teams/raw_client.py index e4ed4446..945e4a6b 100644 --- a/src/truefoundry_sdk/teams/raw_client.py +++ b/src/truefoundry_sdk/teams/raw_client.py @@ -43,10 +43,11 @@ def list( offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, attributes: typing.Optional[typing.Sequence[str]] = None, + include_membership: typing.Optional[bool] = True, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Team, ListTeamsResponse]: """ - List teams accessible to the current user. + List teams accessible to the current user. Set includeMembership=false to omit full member and manager lists and return cached membership summaries instead. Parameters ---------- @@ -62,6 +63,9 @@ def list( attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. + include_membership : typing.Optional[bool] + Whether to include full member and manager lists. Set to false for a metadata-only response with cached membership summaries. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -80,6 +84,7 @@ def list( "offset": offset, "role": role, "attributes": attributes, + "includeMembership": include_membership, }, request_options=request_options, ) @@ -99,6 +104,7 @@ def list( offset=offset + len(_items or []), role=role, attributes=attributes, + include_membership=include_membership, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) @@ -197,8 +203,8 @@ def list_members( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TeamSubjectRow, ListTeamMembersResponse]: @@ -210,12 +216,12 @@ def list_members( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -233,8 +239,8 @@ def list_members( f"api/svc/v1/teams/{encode_path_param(id)}/members", method="GET", params={ - "limit": limit, "offset": offset, + "limit": limit, "filter": filter, }, request_options=request_options, @@ -252,8 +258,8 @@ def list_members( _has_next = len(_items or []) > 0 _get_next = lambda: self.list_members( id, - limit=limit, offset=offset + len(_items or []), + limit=limit, filter=filter, request_options=request_options, ) @@ -293,8 +299,8 @@ def list_managers( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TeamSubjectRow, ListTeamManagersResponse]: @@ -306,12 +312,12 @@ def list_managers( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -329,8 +335,8 @@ def list_managers( f"api/svc/v1/teams/{encode_path_param(id)}/managers", method="GET", params={ - "limit": limit, "offset": offset, + "limit": limit, "filter": filter, }, request_options=request_options, @@ -348,8 +354,8 @@ def list_managers( _has_next = len(_items or []) > 0 _get_next = lambda: self.list_managers( id, - limit=limit, offset=offset + len(_items or []), + limit=limit, filter=filter, request_options=request_options, ) @@ -579,10 +585,11 @@ async def list( offset: typing.Optional[int] = 0, role: typing.Optional[typing.Literal["manager"]] = None, attributes: typing.Optional[typing.Sequence[str]] = None, + include_membership: typing.Optional[bool] = True, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Team, ListTeamsResponse]: """ - List teams accessible to the current user. + List teams accessible to the current user. Set includeMembership=false to omit full member and manager lists and return cached membership summaries instead. Parameters ---------- @@ -598,6 +605,9 @@ async def list( attributes : typing.Optional[typing.Sequence[str]] Comma-separated list of attributes to return (e.g. `id,teamName`). When provided, only the specified fields are fetched. `id` is always included. + include_membership : typing.Optional[bool] + Whether to include full member and manager lists. Set to false for a metadata-only response with cached membership summaries. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -616,6 +626,7 @@ async def list( "offset": offset, "role": role, "attributes": attributes, + "includeMembership": include_membership, }, request_options=request_options, ) @@ -637,6 +648,7 @@ async def _get_next(): offset=offset + len(_items or []), role=role, attributes=attributes, + include_membership=include_membership, request_options=request_options, ) @@ -736,8 +748,8 @@ async def list_members( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TeamSubjectRow, ListTeamMembersResponse]: @@ -749,12 +761,12 @@ async def list_members( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -772,8 +784,8 @@ async def list_members( f"api/svc/v1/teams/{encode_path_param(id)}/members", method="GET", params={ - "limit": limit, "offset": offset, + "limit": limit, "filter": filter, }, request_options=request_options, @@ -793,8 +805,8 @@ async def list_members( async def _get_next(): return await self.list_members( id, - limit=limit, offset=offset + len(_items or []), + limit=limit, filter=filter, request_options=request_options, ) @@ -835,8 +847,8 @@ async def list_managers( self, id: str, *, - limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = None, filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TeamSubjectRow, ListTeamManagersResponse]: @@ -848,12 +860,12 @@ async def list_managers( id : str System-generated team ID. - limit : typing.Optional[int] - Number of items per page - offset : typing.Optional[int] Number of items to skip + limit : typing.Optional[int] + Number of items per page + filter : typing.Optional[str] JSON string: structured filter tree (AND/OR groups, column leaves on `email` and `userId`). @@ -871,8 +883,8 @@ async def list_managers( f"api/svc/v1/teams/{encode_path_param(id)}/managers", method="GET", params={ - "limit": limit, "offset": offset, + "limit": limit, "filter": filter, }, request_options=request_options, @@ -892,8 +904,8 @@ async def list_managers( async def _get_next(): return await self.list_managers( id, - limit=limit, offset=offset + len(_items or []), + limit=limit, filter=filter, request_options=request_options, ) diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index 52b723e9..46bb4de6 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -229,6 +229,10 @@ from .build_build_spec import BuildBuildSpec from .build_info import BuildInfo from .build_secret import BuildSecret + from .calypso_ai_api_key_auth import CalypsoAiApiKeyAuth + from .calypso_ai_guardrail_config import CalypsoAiGuardrailConfig + from .calypso_ai_guardrail_config_config import CalypsoAiGuardrailConfigConfig + from .calypso_ai_guardrail_config_operation import CalypsoAiGuardrailConfigOperation from .canary import Canary from .canary_step import CanaryStep from .cartesia_api_key_auth import CartesiaApiKeyAuth @@ -760,6 +764,7 @@ from .noma_security_api_key_auth import NomaSecurityApiKeyAuth from .noma_security_guardrail_config import NomaSecurityGuardrailConfig from .noma_security_guardrail_config_config import NomaSecurityGuardrailConfigConfig + from .noma_security_guardrail_config_operation import NomaSecurityGuardrailConfigOperation from .nomic_integrations import NomicIntegrations from .nomic_key_auth import NomicKeyAuth from .nomic_model import NomicModel @@ -1458,6 +1463,10 @@ "BuildBuildSpec": ".build_build_spec", "BuildInfo": ".build_info", "BuildSecret": ".build_secret", + "CalypsoAiApiKeyAuth": ".calypso_ai_api_key_auth", + "CalypsoAiGuardrailConfig": ".calypso_ai_guardrail_config", + "CalypsoAiGuardrailConfigConfig": ".calypso_ai_guardrail_config_config", + "CalypsoAiGuardrailConfigOperation": ".calypso_ai_guardrail_config_operation", "Canary": ".canary", "CanaryStep": ".canary_step", "CartesiaApiKeyAuth": ".cartesia_api_key_auth", @@ -1973,6 +1982,7 @@ "NomaSecurityApiKeyAuth": ".noma_security_api_key_auth", "NomaSecurityGuardrailConfig": ".noma_security_guardrail_config", "NomaSecurityGuardrailConfigConfig": ".noma_security_guardrail_config_config", + "NomaSecurityGuardrailConfigOperation": ".noma_security_guardrail_config_operation", "NomicIntegrations": ".nomic_integrations", "NomicKeyAuth": ".nomic_key_auth", "NomicModel": ".nomic_model", @@ -2698,6 +2708,10 @@ def __dir__(): "BuildBuildSpec", "BuildInfo", "BuildSecret", + "CalypsoAiApiKeyAuth", + "CalypsoAiGuardrailConfig", + "CalypsoAiGuardrailConfigConfig", + "CalypsoAiGuardrailConfigOperation", "Canary", "CanaryStep", "CartesiaApiKeyAuth", @@ -3213,6 +3227,7 @@ def __dir__(): "NomaSecurityApiKeyAuth", "NomaSecurityGuardrailConfig", "NomaSecurityGuardrailConfigConfig", + "NomaSecurityGuardrailConfigOperation", "NomicIntegrations", "NomicKeyAuth", "NomicModel", diff --git a/src/truefoundry_sdk/types/budget_usage_entry_mode.py b/src/truefoundry_sdk/types/budget_usage_entry_mode.py index 67dd492b..c9dc1223 100644 --- a/src/truefoundry_sdk/types/budget_usage_entry_mode.py +++ b/src/truefoundry_sdk/types/budget_usage_entry_mode.py @@ -14,7 +14,7 @@ class BudgetUsageEntryMode(enum.StrEnum): ENFORCE = "enforce" AUDIT = "audit" - ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" + SOFT_ENFORCE = "soft_enforce" _UNKNOWN = "__BUDGETUSAGEENTRYMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -30,13 +30,13 @@ def visit( self, enforce: typing.Callable[[], T_Result], audit: typing.Callable[[], T_Result], - enforce_with_low_priority: typing.Callable[[], T_Result], + soft_enforce: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is BudgetUsageEntryMode.ENFORCE: return enforce() if self is BudgetUsageEntryMode.AUDIT: return audit() - if self is BudgetUsageEntryMode.ENFORCE_WITH_LOW_PRIORITY: - return enforce_with_low_priority() + if self is BudgetUsageEntryMode.SOFT_ENFORCE: + return soft_enforce() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/calypso_ai_api_key_auth.py b/src/truefoundry_sdk/types/calypso_ai_api_key_auth.py new file mode 100644 index 00000000..3ae88b36 --- /dev/null +++ b/src/truefoundry_sdk/types/calypso_ai_api_key_auth.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CalypsoAiApiKeyAuth(UniversalBaseModel): + """ + CalypsoAI API Key Auth + """ + + type: typing.Literal["api-key"] = pydantic.Field(default="api-key") + """ + +value=api-key + """ + + api_key: str = pydantic.Field() + """ + CalypsoAI API token from Configuration → API tokens + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/calypso_ai_guardrail_config.py b/src/truefoundry_sdk/types/calypso_ai_guardrail_config.py new file mode 100644 index 00000000..2a043056 --- /dev/null +++ b/src/truefoundry_sdk/types/calypso_ai_guardrail_config.py @@ -0,0 +1,63 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .calypso_ai_api_key_auth import CalypsoAiApiKeyAuth +from .calypso_ai_guardrail_config_config import CalypsoAiGuardrailConfigConfig +from .calypso_ai_guardrail_config_operation import CalypsoAiGuardrailConfigOperation +from .enforcing_strategy import EnforcingStrategy + + +class CalypsoAiGuardrailConfig(UniversalBaseModel): + """ + CalypsoAI (F5 AI Security) + """ + + name: str = pydantic.Field() + """ + The name of the Guardrail Config. + """ + + description: typing.Optional[str] = pydantic.Field( + default="F5 AI Security (CalypsoAI) for prompt injection, jailbreak, PII, and policy-violation scanning" + ) + """ + Optional description for this Guardrail Config. + """ + + type: typing.Literal["integration/guardrail-config/calypsoai"] = pydantic.Field( + default="integration/guardrail-config/calypsoai" + ) + """ + +uiType=Hidden + +value=integration/guardrail-config/calypsoai + """ + + auth_data: CalypsoAiApiKeyAuth + operation: CalypsoAiGuardrailConfigOperation = pydantic.Field() + """ + The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests (forward redactedInput). + Validate guardrails are run in parallel while mutate guardrails are run sequentially. + """ + + priority: typing.Optional[int] = pydantic.Field(default=1) + """ + Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. + """ + + enforcing_strategy: EnforcingStrategy + config: CalypsoAiGuardrailConfigConfig = pydantic.Field() + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/calypso_ai_guardrail_config_config.py b/src/truefoundry_sdk/types/calypso_ai_guardrail_config_config.py new file mode 100644 index 00000000..e8486659 --- /dev/null +++ b/src/truefoundry_sdk/types/calypso_ai_guardrail_config_config.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CalypsoAiGuardrailConfigConfig(UniversalBaseModel): + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional override for the CalypsoAI base URL. Defaults to https://www.us1.calypsoai.app if not provided. Set this if your tenant is provisioned in another region (e.g. https://www.eu1.calypsoai.app). + """ + + project: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional CalypsoAI project ID or friendly ID. Omit to use the tenant's global default scanner configuration. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/calypso_ai_guardrail_config_operation.py b/src/truefoundry_sdk/types/calypso_ai_guardrail_config_operation.py new file mode 100644 index 00000000..1ddc0823 --- /dev/null +++ b/src/truefoundry_sdk/types/calypso_ai_guardrail_config_operation.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class CalypsoAiGuardrailConfigOperation(enum.StrEnum): + """ + The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests (forward redactedInput). + Validate guardrails are run in parallel while mutate guardrails are run sequentially. + """ + + VALIDATE = "validate" + MUTATE = "mutate" + _UNKNOWN = "__CALYPSOAIGUARDRAILCONFIGOPERATION_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "CalypsoAiGuardrailConfigOperation": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + validate: typing.Callable[[], T_Result], + mutate: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is CalypsoAiGuardrailConfigOperation.VALIDATE: + return validate() + if self is CalypsoAiGuardrailConfigOperation.MUTATE: + return mutate() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/custom_server_header_auth.py b/src/truefoundry_sdk/types/custom_server_header_auth.py index 1a17e868..5392d755 100644 --- a/src/truefoundry_sdk/types/custom_server_header_auth.py +++ b/src/truefoundry_sdk/types/custom_server_header_auth.py @@ -16,7 +16,10 @@ class CustomServerHeaderAuth(UniversalBaseModel): +value=header """ - headers: typing.Dict[str, str] + headers: typing.Dict[str, str] = pydantic.Field() + """ + Map each header name to its value. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/google_vertex_provider_account.py b/src/truefoundry_sdk/types/google_vertex_provider_account.py index d96508dc..576bfd00 100644 --- a/src/truefoundry_sdk/types/google_vertex_provider_account.py +++ b/src/truefoundry_sdk/types/google_vertex_provider_account.py @@ -39,6 +39,11 @@ class GoogleVertexProviderAccount(UniversalBaseModel): Service account key JSON, or Workload Identity Federation file (workload-identity-federation-file) with external_account JSON (e.g. create-cred-config). https://docs.truefoundry.com/gateway/google-vertex """ + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional custom base URL for the Vertex AI inference endpoint (e.g. a Private Service Connect / PSC endpoint for private connectivity). When set, chat/generate requests are routed here instead of the region-derived public host (-aiplatform.googleapis.com). Leave empty to use the public Vertex AI API. + """ + integrations: typing.List[VertexModel] = pydantic.Field() """ List of integrations that are associated with the Google Vertex model account diff --git a/src/truefoundry_sdk/types/guardrail_config_integrations.py b/src/truefoundry_sdk/types/guardrail_config_integrations.py index 14338b9c..fe2085fd 100644 --- a/src/truefoundry_sdk/types/guardrail_config_integrations.py +++ b/src/truefoundry_sdk/types/guardrail_config_integrations.py @@ -7,6 +7,7 @@ from .azure_content_safety_guardrail_config import AzureContentSafetyGuardrailConfig from .azure_pii_guardrail_config import AzurePiiGuardrailConfig from .azure_prompt_shield_guardrail_config import AzurePromptShieldGuardrailConfig +from .calypso_ai_guardrail_config import CalypsoAiGuardrailConfig from .cedar_guardrail_config import CedarGuardrailConfig from .cisco_ai_defense_guardrail_config import CiscoAiDefenseGuardrailConfig from .code_safety_linter_guardrail_config import CodeSafetyLinterGuardrailConfig @@ -56,6 +57,7 @@ GoogleModelArmorGuardrailConfig, GraySwanCygnalGuardrailConfig, NomaSecurityGuardrailConfig, + CalypsoAiGuardrailConfig, AktoGuardrailConfig, TrojAiGuardrailConfig, ] diff --git a/src/truefoundry_sdk/types/noma_security_api_key_auth.py b/src/truefoundry_sdk/types/noma_security_api_key_auth.py index 0f403acf..7f0101c5 100644 --- a/src/truefoundry_sdk/types/noma_security_api_key_auth.py +++ b/src/truefoundry_sdk/types/noma_security_api_key_auth.py @@ -18,7 +18,7 @@ class NomaSecurityApiKeyAuth(UniversalBaseModel): api_key: str = pydantic.Field() """ - Noma API key for AI-DR scan access + Noma scoped access token with truefoundry_guardrail scope (sent as Bearer) """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config.py b/src/truefoundry_sdk/types/noma_security_guardrail_config.py index e9952e1d..f2f43d1c 100644 --- a/src/truefoundry_sdk/types/noma_security_guardrail_config.py +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config.py @@ -7,6 +7,7 @@ from .enforcing_strategy import EnforcingStrategy from .noma_security_api_key_auth import NomaSecurityApiKeyAuth from .noma_security_guardrail_config_config import NomaSecurityGuardrailConfigConfig +from .noma_security_guardrail_config_operation import NomaSecurityGuardrailConfigOperation class NomaSecurityGuardrailConfig(UniversalBaseModel): @@ -20,7 +21,7 @@ class NomaSecurityGuardrailConfig(UniversalBaseModel): """ description: typing.Optional[str] = pydantic.Field( - default="Noma AI-DR for prompt, response, and tool content safety scanning" + default="Noma TrueFoundry Guardrail for prompt, response, and tool content safety" ) """ Optional description for this Guardrail Config. @@ -35,9 +36,15 @@ class NomaSecurityGuardrailConfig(UniversalBaseModel): """ auth_data: NomaSecurityApiKeyAuth - operation: typing.Literal["validate"] = pydantic.Field(default="validate") + operation: NomaSecurityGuardrailConfigOperation = pydantic.Field() """ - The operation type for this guardrail. Noma Security guardrails can only be used for validation. + Validate blocks policy denials. Mutate also applies complete masked request or response payloads returned by Noma. + Validate guardrails are run in parallel while mutate guardrails are run sequentially. + """ + + priority: typing.Optional[int] = pydantic.Field(default=1) + """ + Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ enforcing_strategy: EnforcingStrategy diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py index 8629ae1e..3ad3df9e 100644 --- a/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py @@ -14,17 +14,17 @@ class NomaSecurityGuardrailConfigConfig(UniversalBaseModel): base_url: typing.Optional[str] = pydantic.Field(default=None) """ - Optional override for the Noma AI-DR base URL. Defaults to https://api.noma.security if not provided. Use https://app.sandbox.noma.security for sandbox testing. + Optional override for the Noma API base URL. Defaults to https://api.noma.security if not provided. """ application_id: typing.Optional[str] = pydantic.Field(default=None) """ - Value sent in x-noma-context.applicationId for traceability. Defaults to truefoundry if not provided. + Literal applicationId sent as config.config.applicationId and used to select the Noma Runtime Protection profile. Defaults to truefoundry. """ user_id_metadata_key: typing.Optional[str] = pydantic.Field(default=None) """ - Optional request metadata key used to populate x-noma-context.userId. Defaults to gateway when not set. + Fallback subjectId sent in context.user when no authenticated runtime subject is available. Defaults to gateway. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config_operation.py b/src/truefoundry_sdk/types/noma_security_guardrail_config_operation.py new file mode 100644 index 00000000..a6a1c402 --- /dev/null +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config_operation.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class NomaSecurityGuardrailConfigOperation(enum.StrEnum): + """ + Validate blocks policy denials. Mutate also applies complete masked request or response payloads returned by Noma. + Validate guardrails are run in parallel while mutate guardrails are run sequentially. + """ + + VALIDATE = "validate" + MUTATE = "mutate" + _UNKNOWN = "__NOMASECURITYGUARDRAILCONFIGOPERATION_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "NomaSecurityGuardrailConfigOperation": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + validate: typing.Callable[[], T_Result], + mutate: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is NomaSecurityGuardrailConfigOperation.VALIDATE: + return validate() + if self is NomaSecurityGuardrailConfigOperation.MUTATE: + return mutate() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py index f06eab7d..ecc7228d 100644 --- a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py +++ b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py @@ -29,6 +29,11 @@ class OpenApimcpServerManifest(UniversalBaseModel): The name of the OpenAPI MCP Server. """ + display_name: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable label for the OpenAPI MCP Server in the UI. If omitted, the server name is shown. + """ + description: str = pydantic.Field() """ Provide a brief description of the purpose of this OpenAPI MCP Server. diff --git a/src/truefoundry_sdk/types/provider_integration.py b/src/truefoundry_sdk/types/provider_integration.py index 739979cb..77e98a6e 100644 --- a/src/truefoundry_sdk/types/provider_integration.py +++ b/src/truefoundry_sdk/types/provider_integration.py @@ -31,6 +31,7 @@ class ProviderIntegration(UniversalBaseModel): provider_account_fqn: typing_extensions.Annotated[ str, FieldMetadata(alias="providerAccountFqn"), pydantic.Field(alias="providerAccountFqn") ] + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] provider_account: typing_extensions.Annotated[ typing.Optional["ProviderAccount"], FieldMetadata(alias="providerAccount"), diff --git a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py index 175509b8..01a5f3eb 100644 --- a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py @@ -28,6 +28,11 @@ class RemoteMcpServerManifest(UniversalBaseModel): The name of the MCP Server. """ + display_name: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable label for the MCP Server in the UI. If omitted, the server name is shown. + """ + description: str = pydantic.Field() """ Provide a brief description of the purpose of this MCP Server. diff --git a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py index 056dd7ad..73422f1f 100644 --- a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py @@ -22,6 +22,11 @@ class StdioMcpServerManifest(UniversalBaseModel): The name of the MCP Server. """ + display_name: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable label for the MCP Server in the UI. If omitted, the server name is shown. + """ + description: str = pydantic.Field() """ Provide a brief description of the purpose of this MCP Server. diff --git a/src/truefoundry_sdk/types/subject_subject_type.py b/src/truefoundry_sdk/types/subject_subject_type.py index d3819d13..ab7eb6c3 100644 --- a/src/truefoundry_sdk/types/subject_subject_type.py +++ b/src/truefoundry_sdk/types/subject_subject_type.py @@ -17,6 +17,8 @@ class SubjectSubjectType(enum.StrEnum): SERVICEACCOUNT = "serviceaccount" VIRTUALACCOUNT = "virtualaccount" AGENT_IDENTITY = "agent-identity" + AGENT = "agent" + AGENT_CHANNEL_IDENTITY = "agent-channel-identity" ROLE = "role" _UNKNOWN = "__SUBJECTSUBJECTTYPE_UNKNOWN__" """ @@ -36,6 +38,8 @@ def visit( serviceaccount: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], + agent_channel_identity: typing.Callable[[], T_Result], role: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: @@ -49,6 +53,10 @@ def visit( return virtualaccount() if self is SubjectSubjectType.AGENT_IDENTITY: return agent_identity() + if self is SubjectSubjectType.AGENT: + return agent() + if self is SubjectSubjectType.AGENT_CHANNEL_IDENTITY: + return agent_channel_identity() if self is SubjectSubjectType.ROLE: return role() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/subject_type.py b/src/truefoundry_sdk/types/subject_type.py index 0ab22e45..859cd7ee 100644 --- a/src/truefoundry_sdk/types/subject_type.py +++ b/src/truefoundry_sdk/types/subject_type.py @@ -17,6 +17,8 @@ class SubjectType(enum.StrEnum): SERVICEACCOUNT = "serviceaccount" VIRTUALACCOUNT = "virtualaccount" AGENT_IDENTITY = "agent-identity" + AGENT = "agent" + AGENT_CHANNEL_IDENTITY = "agent-channel-identity" ROLE = "role" _UNKNOWN = "__SUBJECTTYPE_UNKNOWN__" """ @@ -36,6 +38,8 @@ def visit( serviceaccount: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], + agent_channel_identity: typing.Callable[[], T_Result], role: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: @@ -49,6 +53,10 @@ def visit( return virtualaccount() if self is SubjectType.AGENT_IDENTITY: return agent_identity() + if self is SubjectType.AGENT: + return agent() + if self is SubjectType.AGENT_CHANNEL_IDENTITY: + return agent_channel_identity() if self is SubjectType.ROLE: return role() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/team_budget_config.py b/src/truefoundry_sdk/types/team_budget_config.py index 8aa131b7..75ac9fda 100644 --- a/src/truefoundry_sdk/types/team_budget_config.py +++ b/src/truefoundry_sdk/types/team_budget_config.py @@ -37,7 +37,7 @@ class TeamBudgetConfig(UniversalBaseModel): applies_to: BudgetV2AppliesTo mode: TeamBudgetConfigMode = pydantic.Field() """ - `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. + `enforce` blocks breaching requests, `audit` only tracks them, `soft_enforce` blocks only when no other matching budget allows the request. """ alerts: typing.Optional[BudgetV2Alert] = None diff --git a/src/truefoundry_sdk/types/team_budget_config_mode.py b/src/truefoundry_sdk/types/team_budget_config_mode.py index cfb5b141..b9ff9019 100644 --- a/src/truefoundry_sdk/types/team_budget_config_mode.py +++ b/src/truefoundry_sdk/types/team_budget_config_mode.py @@ -9,12 +9,12 @@ class TeamBudgetConfigMode(enum.StrEnum): """ - `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. + `enforce` blocks breaching requests, `audit` only tracks them, `soft_enforce` blocks only when no other matching budget allows the request. """ ENFORCE = "enforce" AUDIT = "audit" - ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" + SOFT_ENFORCE = "soft_enforce" _UNKNOWN = "__TEAMBUDGETCONFIGMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -30,13 +30,13 @@ def visit( self, enforce: typing.Callable[[], T_Result], audit: typing.Callable[[], T_Result], - enforce_with_low_priority: typing.Callable[[], T_Result], + soft_enforce: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is TeamBudgetConfigMode.ENFORCE: return enforce() if self is TeamBudgetConfigMode.AUDIT: return audit() - if self is TeamBudgetConfigMode.ENFORCE_WITH_LOW_PRIORITY: - return enforce_with_low_priority() + if self is TeamBudgetConfigMode.SOFT_ENFORCE: + return soft_enforce() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/tenant_budget_config.py b/src/truefoundry_sdk/types/tenant_budget_config.py index ed392152..a5311ddc 100644 --- a/src/truefoundry_sdk/types/tenant_budget_config.py +++ b/src/truefoundry_sdk/types/tenant_budget_config.py @@ -32,7 +32,7 @@ class TenantBudgetConfig(UniversalBaseModel): applies_to: BudgetV2AppliesTo mode: TenantBudgetConfigMode = pydantic.Field() """ - `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. + `enforce` blocks breaching requests, `audit` only tracks them, `soft_enforce` blocks only when no other matching budget allows the request. """ alerts: typing.Optional[BudgetV2Alert] = None diff --git a/src/truefoundry_sdk/types/tenant_budget_config_mode.py b/src/truefoundry_sdk/types/tenant_budget_config_mode.py index ca0d98fe..6877b87f 100644 --- a/src/truefoundry_sdk/types/tenant_budget_config_mode.py +++ b/src/truefoundry_sdk/types/tenant_budget_config_mode.py @@ -9,12 +9,12 @@ class TenantBudgetConfigMode(enum.StrEnum): """ - `enforce` blocks breaching requests, `audit` only tracks them, `enforce_with_low_priority` blocks only when no other matching budget allows the request. + `enforce` blocks breaching requests, `audit` only tracks them, `soft_enforce` blocks only when no other matching budget allows the request. """ ENFORCE = "enforce" AUDIT = "audit" - ENFORCE_WITH_LOW_PRIORITY = "enforce_with_low_priority" + SOFT_ENFORCE = "soft_enforce" _UNKNOWN = "__TENANTBUDGETCONFIGMODE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -30,13 +30,13 @@ def visit( self, enforce: typing.Callable[[], T_Result], audit: typing.Callable[[], T_Result], - enforce_with_low_priority: typing.Callable[[], T_Result], + soft_enforce: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is TenantBudgetConfigMode.ENFORCE: return enforce() if self is TenantBudgetConfigMode.AUDIT: return audit() - if self is TenantBudgetConfigMode.ENFORCE_WITH_LOW_PRIORITY: - return enforce_with_low_priority() + if self is TenantBudgetConfigMode.SOFT_ENFORCE: + return soft_enforce() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py b/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py index f27bee2b..8b62644d 100644 --- a/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py @@ -27,6 +27,11 @@ class TfyManagedMcpServerManifest(UniversalBaseModel): The name of the MCP Server. """ + display_name: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable label for the MCP Server in the UI. If omitted, the server name is shown. + """ + description: str = pydantic.Field() """ Provide a brief description of the purpose of this MCP Server. diff --git a/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py index a0c2c3e8..bf268add 100644 --- a/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py @@ -26,6 +26,11 @@ class VirtualMcpServerManifest(UniversalBaseModel): The name of the Virtual MCP Server. """ + display_name: typing.Optional[str] = pydantic.Field(default=None) + """ + A human-readable label for the Virtual MCP Server in the UI. If omitted, the server name is shown. + """ + description: str = pydantic.Field() """ Provide a brief description of the purpose of this Virtual MCP Server. From 35e0a64d6d5f22dfc812792e7b66493fd320d061 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 16:17:50 +0000 Subject: [PATCH 8/9] SDK regeneration --- .fern/metadata.json | 6 +- poetry.lock | 571 ++++++++++-------- reference.md | 365 +++++++++-- src/truefoundry_sdk/__init__.py | 75 ++- src/truefoundry_sdk/agents/client.py | 220 ++++++- src/truefoundry_sdk/agents/raw_client.py | 463 +++++++++++++- .../application_versions/client.py | 4 +- .../application_versions/raw_client.py | 4 +- src/truefoundry_sdk/base_client.py | 48 +- src/truefoundry_sdk/clusters/client.py | 14 - src/truefoundry_sdk/core/http_client.py | 67 +- src/truefoundry_sdk/core/http_response.py | 4 + src/truefoundry_sdk/gateway_budgets/client.py | 8 +- .../gateway_budgets/raw_client.py | 8 +- .../internal/build_logs/client.py | 21 +- .../internal/build_logs/raw_client.py | 21 +- src/truefoundry_sdk/ml_repos/client.py | 16 +- .../personal_access_tokens/client.py | 128 +++- .../personal_access_tokens/raw_client.py | 233 ++++++- src/truefoundry_sdk/raw_base_client.py | 10 + src/truefoundry_sdk/secret_groups/client.py | 16 +- src/truefoundry_sdk/types/__init__.py | 75 ++- src/truefoundry_sdk/types/agent.py | 5 + src/truefoundry_sdk/types/agent_identity.py | 23 + .../types/aws_assumed_role_based_auth.py | 5 + .../aws_bedrock_assumed_role_based_auth.py | 15 +- .../aws_bedrock_mantle_provider_account.py | 5 + ...claude_platform_assumed_role_based_auth.py | 15 +- .../types/aws_parameter_store.py | 5 + .../types/aws_secrets_manager.py | 5 + .../types/azure_open_ai_provider_account.py | 2 +- .../types/base_remote_agent.py | 2 +- .../types/bedrock_mantle_model.py | 5 + src/truefoundry_sdk/types/cluster_manifest.py | 2 +- .../types/complexity_based_load_balancing.py | 5 +- .../types/complexity_sticky_routing.py | 31 - .../types/custom_agent_server_auth.py | 6 +- .../custom_server_aws_access_key_auth.py | 35 ++ .../custom_server_aws_assume_role_auth.py | 30 + .../types/custom_server_aws_sig_v4.py | 33 + .../types/custom_server_aws_sig_v4auth.py | 8 + .../types/custom_server_o_auth2marker.py | 31 + .../custom_server_o_auth2marker_grant_type.py | 38 ++ src/truefoundry_sdk/types/data_access_rule.py | 5 +- src/truefoundry_sdk/types/deployment.py | 11 +- src/truefoundry_sdk/types/deployment_build.py | 112 +++- .../types/deployment_build_status.py | 4 + .../types/fiddler_guardrail_config_config.py | 5 + .../heuristic_classification_strategy.py | 2 +- .../types/legacy_agent_manifest.py | 2 +- .../types/llm_classification_strategy.py | 6 +- src/truefoundry_sdk/types/mcp_server_auth.py | 3 +- .../types/mcp_server_aws_access_key_auth.py | 35 ++ .../types/mcp_server_aws_assume_role_auth.py | 30 + .../types/mcp_server_aws_sig_v4auth.py | 33 + .../types/mcp_server_aws_sig_v4auth_auth.py | 8 + .../types/mcp_server_env_auth.py | 2 +- .../types/mcp_server_o_auth2.py | 16 + ...mcp_server_o_auth2client_authentication.py | 38 ++ .../types/mcp_server_o_auth2grant_type.py | 4 + .../types/mcp_server_o_auth2provider.py | 4 + .../types/mcp_server_provider_account.py | 2 +- .../types/mcp_tool_metadata.py | 28 + src/truefoundry_sdk/types/mcp_tool_policy.py | 35 ++ .../types/microsoft_foundry_model.py | 72 +++ ...microsoft_foundry_model_deployment_type.py | 46 ++ .../microsoft_foundry_model_publisher.py | 38 ++ .../microsoft_foundry_provider_account.py | 71 +++ ...soft_foundry_provider_account_auth_data.py | 12 + src/truefoundry_sdk/types/ml_repo_manifest.py | 2 +- .../types/model_provider_account.py | 2 + .../noma_security_guardrail_config_config.py | 6 +- .../types/open_apimcp_server_manifest.py | 2 +- .../otel_metrics_exporter_common_config.py | 25 + .../otel_metrics_exporter_grpc_config.py | 3 +- .../otel_metrics_exporter_http_config.py | 3 +- .../types/permission_set_v2resource_type.py | 8 - .../types/policy_entity_types.py | 4 + .../types/preset_regex_pattern_enum.py | 8 + .../types/provider_account_provider.py | 4 + .../types/remote_mcp_server_manifest.py | 10 +- .../types/role_binding_manifest.py | 2 +- .../types/role_binding_subject.py | 4 +- .../types/role_binding_subject_type.py | 6 +- .../types/role_resource_type.py | 8 - .../types/role_with_resource_resource_type.py | 8 - .../types/secret_group_manifest.py | 2 +- .../types/secret_store_config.py | 28 +- .../types/secret_store_integration_config.py | 35 ++ src/truefoundry_sdk/types/spark_job.py | 8 +- .../types/spark_job_driver_config.py | 26 + .../types/spark_job_executor_config.py | 26 + .../types/stdio_mcp_server_manifest.py | 10 +- .../types/sync_token_in_secret_store_info.py | 11 + .../types/team_data_access_rule.py | 2 +- .../team_virtual_account_data_access_rule.py | 26 + .../types/tfy_managed_mcp_server_manifest.py | 10 +- .../types/tfy_secrets_config.py | 35 ++ .../types/tracing_project_manifest.py | 2 +- .../types/true_foundry_agent_manifest.py | 2 +- .../types/virtual_account_manifest.py | 2 +- .../types/virtual_mcp_server_manifest.py | 7 +- src/truefoundry_sdk/types/virtual_model.py | 5 + ...update_user_roles_request_resource_type.py | 8 - .../virtual_accounts/client.py | 68 +-- .../virtual_accounts/raw_client.py | 66 +- tests/utils/test_http_client.py | 92 +++ 107 files changed, 3220 insertions(+), 663 deletions(-) delete mode 100644 src/truefoundry_sdk/types/complexity_sticky_routing.py create mode 100644 src/truefoundry_sdk/types/custom_server_aws_access_key_auth.py create mode 100644 src/truefoundry_sdk/types/custom_server_aws_assume_role_auth.py create mode 100644 src/truefoundry_sdk/types/custom_server_aws_sig_v4.py create mode 100644 src/truefoundry_sdk/types/custom_server_aws_sig_v4auth.py create mode 100644 src/truefoundry_sdk/types/custom_server_o_auth2marker.py create mode 100644 src/truefoundry_sdk/types/custom_server_o_auth2marker_grant_type.py create mode 100644 src/truefoundry_sdk/types/mcp_server_aws_access_key_auth.py create mode 100644 src/truefoundry_sdk/types/mcp_server_aws_assume_role_auth.py create mode 100644 src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth.py create mode 100644 src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth_auth.py create mode 100644 src/truefoundry_sdk/types/mcp_server_o_auth2client_authentication.py create mode 100644 src/truefoundry_sdk/types/mcp_tool_metadata.py create mode 100644 src/truefoundry_sdk/types/mcp_tool_policy.py create mode 100644 src/truefoundry_sdk/types/microsoft_foundry_model.py create mode 100644 src/truefoundry_sdk/types/microsoft_foundry_model_deployment_type.py create mode 100644 src/truefoundry_sdk/types/microsoft_foundry_model_publisher.py create mode 100644 src/truefoundry_sdk/types/microsoft_foundry_provider_account.py create mode 100644 src/truefoundry_sdk/types/microsoft_foundry_provider_account_auth_data.py create mode 100644 src/truefoundry_sdk/types/otel_metrics_exporter_common_config.py create mode 100644 src/truefoundry_sdk/types/secret_store_integration_config.py create mode 100644 src/truefoundry_sdk/types/spark_job_driver_config.py create mode 100644 src/truefoundry_sdk/types/spark_job_executor_config.py create mode 100644 src/truefoundry_sdk/types/team_virtual_account_data_access_rule.py create mode 100644 src/truefoundry_sdk/types/tfy_secrets_config.py diff --git a/.fern/metadata.json b/.fern/metadata.json index 7607b885..ac819985 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "5.89.4", + "cliVersion": "5.109.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "5.26.0", + "generatorVersion": "5.29.2", "generatorConfig": { "package_name": "truefoundry_sdk", "use_request_defaults": "all", @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "ee220d57a9ea7d75b0042756f2870909b45115ab", + "originGitCommit": "82be7d4013faa5a458fe5d6ac1e5a48b69113417", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0", diff --git a/poetry.lock b/poetry.lock index afd06166..c8b04a68 100644 --- a/poetry.lock +++ b/poetry.lock @@ -302,105 +302,184 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.9" +version = "3.5.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-win32.whl", hash = "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee"}, - {file = "charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-win32.whl", hash = "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1"}, - {file = "charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-win32.whl", hash = "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0"}, - {file = "charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115"}, - {file = "charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b"}, - {file = "charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177"}, - {file = "charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-win32.whl", hash = "sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-win_amd64.whl", hash = "sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b"}, - {file = "charset_normalizer-3.4.9-cp39-cp39-win_arm64.whl", hash = "sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe"}, - {file = "charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5"}, - {file = "charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-win32.whl", hash = "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d"}, + {file = "charset_normalizer-3.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-win32.whl", hash = "sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9"}, + {file = "charset_normalizer-3.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-win32.whl", hash = "sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2"}, + {file = "charset_normalizer-3.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-win32.whl", hash = "sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6"}, + {file = "charset_normalizer-3.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-win32.whl", hash = "sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b"}, + {file = "charset_normalizer-3.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-win32.whl", hash = "sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00"}, + {file = "charset_normalizer-3.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-win32.whl", hash = "sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712"}, + {file = "charset_normalizer-3.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-win32.whl", hash = "sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb"}, + {file = "charset_normalizer-3.5.1-cp315-cp315t-win_arm64.whl", hash = "sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-win32.whl", hash = "sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-win_amd64.whl", hash = "sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959"}, + {file = "charset_normalizer-3.5.1-cp37-abi3-win_arm64.whl", hash = "sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:85de3134b5379856e323ba37c19c9256d39425f7b76a63af52b09fb4664c2e8f"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e5e1224c0a6a90e05843e07adfec669edebec17801c67072f51e59561d63c0b"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5e2d0e146dcb57034f8b97dc58d2d512cb90aba253960ce449f695fec6a82c6f"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e06efa066f7dbadbc84ebc126a97c452a6451dfcf589d89d788484949e1cf795"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:994e883d17c559cdfd38c84003c8b27d25424a1077272a17e7cd27bfe0bf57b2"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:789b8982559ae28dad2356519f841655756cdcd96616410590ae0b17454ee64f"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a951ad59cad9145664a730d3036b40b844e74d2d3683da40111463cd3a83845d"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:55261ac0d2941c42f196dd576f543d87a8ee03cd6f5e30dfb4d807b2e3b9121a"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5ca0555312ae2fe82715cada7fac375530c2f3349e1eaa1bcb33d0283ac79a18"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2e9cf9253119d8e5d111f05d71626786fd3d6193817316eab1ca088cdb8593cf"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:433c5a81eade63b47e522303bad236f59dba55ea6951746f5558355eeed8c75d"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:13e3afe97712e8887cd516e960c63f0b93122971e5b5e4b2622fe7701771e838"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb12fb2ba69ffa05f8695f61c69e591dc4b4a12ac3757ac8af8adb259bf56d17"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-win32.whl", hash = "sha256:56490c595a28b1bb27dfc583e816152a9767721ef58b2c03b13f954d2f707420"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:012a22b88a77ca2e59b98ac5889b0deb604147666032f45e6d6e217634d2550d"}, + {file = "charset_normalizer-3.5.1-cp39-cp39-win_arm64.whl", hash = "sha256:29880d17a8eb0b5cfdfd8944b468322928059aa35f1f5fa8ff22b149ec0b42f8"}, + {file = "charset_normalizer-3.5.1-py3-none-any.whl", hash = "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6"}, + {file = "charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3"}, ] [[package]] @@ -708,29 +787,29 @@ httpx = ">=0.27.0" [[package]] name = "idna" -version = "3.18" +version = "3.19" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"}, - {file = "idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848"}, + {file = "idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4"}, + {file = "idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15"}, ] [package.extras] -all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +all = ["coverage (>=7.10.0)", "hypothesis (>=6.141.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.16.0)", "ty (>=0.0.37)"] [[package]] name = "imagesize" -version = "1.5.0" -description = "Getting image size from png/jpeg/jpeg2000/gif file" +version = "2.0.1" +description = "Get image size from headers (BMP/PNG/JPEG/JPEG2000/GIF/TIFF/SVG/Netpbm/WebP/AVIF/HEIC/HEIF)" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "imagesize-1.5.0-py2.py3-none-any.whl", hash = "sha256:32677681b3f434c2cb496f00e89c5a291247b35b1f527589909e008057da5899"}, - {file = "imagesize-1.5.0.tar.gz", hash = "sha256:8bfc5363a7f2133a89f0098451e0bcb1cd71aba4dc02bbcecb39d99d40e1b94f"}, + {file = "imagesize-2.0.1-py3-none-any.whl", hash = "sha256:ea0c9a0384df69ed86a943a15cde37d0360b82491b3910dc2215e202e62b5b02"}, + {file = "imagesize-2.0.1.tar.gz", hash = "sha256:b2ba6a4dea487a7ebcd53248d3476aca449d30db12a2dde5e0c5ca9624fd77e5"}, ] [[package]] @@ -1182,14 +1261,14 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [[package]] name = "packaging" -version = "26.2" +version = "26.3" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"}, - {file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"}, + {file = "packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c"}, + {file = "packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79"}, ] [[package]] @@ -1417,19 +1496,19 @@ tests = ["pytest"] [[package]] name = "pydantic" -version = "2.13.4" +version = "2.13.5" description = "Data validation using Python type hints" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba"}, - {file = "pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6"}, + {file = "pydantic-2.13.5-py3-none-any.whl", hash = "sha256:346a034f080da3755d8e9cb5e00e8b07de1d39e4f6e2c87d8ab7cafa0b269a73"}, + {file = "pydantic-2.13.5.tar.gz", hash = "sha256:51a9c5f7b2f8e636f04c6cada605d9b6a3bf1348fdf945a3d8869b19bba0ee08"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.46.4" +pydantic-core = "2.46.5" typing-extensions = ">=4.14.1" typing-inspection = ">=0.4.2" @@ -1439,132 +1518,132 @@ timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows [[package]] name = "pydantic-core" -version = "2.46.4" +version = "2.46.5" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4"}, - {file = "pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01"}, - {file = "pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d"}, - {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4"}, - {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f"}, - {file = "pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39"}, - {file = "pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d"}, - {file = "pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf"}, - {file = "pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594"}, - {file = "pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398"}, - {file = "pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3"}, - {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848"}, - {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3"}, - {file = "pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109"}, - {file = "pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda"}, - {file = "pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33"}, - {file = "pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d"}, - {file = "pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2"}, - {file = "pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987"}, - {file = "pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b"}, - {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458"}, - {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b"}, - {file = "pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c"}, - {file = "pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894"}, - {file = "pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89"}, - {file = "pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a"}, - {file = "pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008"}, - {file = "pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262"}, - {file = "pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e"}, - {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd"}, - {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be"}, - {file = "pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d"}, - {file = "pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb"}, - {file = "pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292"}, - {file = "pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d"}, - {file = "pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb"}, - {file = "pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c"}, - {file = "pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb"}, - {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898"}, - {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e"}, - {file = "pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519"}, - {file = "pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4"}, - {file = "pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac"}, - {file = "pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5"}, - {file = "pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596"}, - {file = "pydantic_core-2.46.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:fd8b3d9fd264be37976686c7f65cd52a83f5e84f4bfd2adf9c1d469676bbb6ae"}, - {file = "pydantic_core-2.46.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9f444c499b3eefd3a92e348059471ea0c3a6e303d9c1cec09fa748fd9f895201"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3447661d99f75a3683a4cf5c87da72f2161964611864dbbeac7fbb118bb4bfc0"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b9bab013d1c7a79d3501ff86d0bc9c31bf587db4551677b96bec07df78c6b15"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d995260fdf4e1db774581b4900e0f832abe3c7c84996726bbc161b19c8f29e76"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13a646d65d09fbf1bc6b3a9635d30095c8e7e5cc419ff35ecc563c5fd04cd49"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432c179df7874eeb73307aad2df0755e1ae0efa61ff0ea89b93e194411ae3928"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:e68b7a074f65a2fd746c52a7ce6142ab7006074ac269ace0c25cd8ba171f8066"}, - {file = "pydantic_core-2.46.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4a05d69cba51d852c5c3e92758653245a50c0b646ced0cf05bd793ed592839d6"}, - {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:228ee9bae8bef5b1e97ec58302f80357c37199e0d0a99174e138d28e6957b9d9"}, - {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:10e17cbb10a330363733efc4d7c4d0dd827ac0909b8f6a6542298fed1ea62f29"}, - {file = "pydantic_core-2.46.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:91a06d2e259ecfbd8c901d70c3c507900458498142b3026a296b7de4d1322cc9"}, - {file = "pydantic_core-2.46.4-cp39-cp39-win32.whl", hash = "sha256:d80ee3d731373b24cebbc10d689ca4ee1875caf0d5703a245db18efd4dd37fc1"}, - {file = "pydantic_core-2.46.4-cp39-cp39-win_amd64.whl", hash = "sha256:3be77f45df024d789a672ae34f8b06fb346c4f9f46ea714956660ea4862e89ac"}, - {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c"}, - {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b"}, - {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b"}, - {file = "pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea"}, - {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7"}, - {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df"}, - {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526"}, - {file = "pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc"}, - {file = "pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983"}, - {file = "pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1"}, + {file = "pydantic_core-2.46.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:657b40d6240c0a7b6a64b30f22d1e3aa631c7e846c621b0c0f6d1d75e2e15ea6"}, + {file = "pydantic_core-2.46.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ecb42011e12ee19cafbc312887cbf3546959fe02fbad44f272d4be5baa997615"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dedce55295becb61921e386b99d4f2706045306e7fa52249a33004c837379fb"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9f47b8a949e60f027f0aa0a6f6c7b7e9c55cbf4380d10b344e282fa4e7ab1e1b"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:200aa3dc9f8d54f0754f43247c0bad0999fdcfbfd2488384dd44f37279271fe6"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d30e1a4f138b8951063e9a394752a9179b51da288ffa507b1e659222f4c1793"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:850a08d167dde16db8702c274f320c7be9d7da6f6dff2b58b18f9e815bd94f5b"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:c3471e5c4a949c26ec00a77f01df59096aa9495877de76fd60a980f8ee6be461"}, + {file = "pydantic_core-2.46.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a3e26b6a8274211bddee2d0e4d0d42778f17a34510f49d2ec44b58abfc41736"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc5d783bd4a2387e97b8a2d5ec781cfb92b3d893bf82370548e99db5915935d3"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:356c8368cbc321050b169595683a2e1d63413b1e0e2868b330af9fc14c616d3f"}, + {file = "pydantic_core-2.46.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eb7d8d0e5886a89a55d2eef490e272fa965a9d57c6b29a5b5088a7997ec2cad1"}, + {file = "pydantic_core-2.46.5-cp310-cp310-win32.whl", hash = "sha256:4d44cf99ddebf875f9b68cc267aa684c99b7b44fe63ee1cac4ec163807290069"}, + {file = "pydantic_core-2.46.5-cp310-cp310-win_amd64.whl", hash = "sha256:1e5aad1220a1192c42341c8fd4a8686657e73ab2a920c970bdc4de334fe3193d"}, + {file = "pydantic_core-2.46.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a1dee1b804ff4d11c663636cf15d2ea47e9f79cd56c033fb1cbf08924842a48f"}, + {file = "pydantic_core-2.46.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d625a186a65201c23a9e3b8ed9c47e90a026e03256608cc91851c6709096844f"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8507560a9284e1370bb048ed4282012fbef4e8d109875b95e884d228552061"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f93c5fe914d75fbec9a49209b00da5f08e9e467d69da2b1510c81940cfd10be"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c767f552b21b10f774aeac128e828eafb796adfa1b666a18bf6321453c3a"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:701b2e04b560eeb4bddf7a25ab8ca476176e34fdbd9a0e18196f0d12d4685f0b"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49776eab08766a08dfff7012f8b422dcd7e25e43b316eedf0477c24fcfa84b7c"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:a2468d93d181667a7abd66e1b64bb9f76f361b0fef8faddf687456453576f5ee"}, + {file = "pydantic_core-2.46.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53feb344243bb9510a9dec7bf3cf1b64d88a98af5dc7872a5160465f8b198c8e"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cd5214352ae68f3b5e9af7768bdc5253695ee069675db3480518420b3be881f2"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:9432f3598db432cb51c5b37fdbf29a60fcccc79e30d37a05022776a6bc4ab689"}, + {file = "pydantic_core-2.46.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8feeac04b5794e513e710af2f9c87d49f31a6dc47967bb264a1fed61a8989bec"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win32.whl", hash = "sha256:892a881d5f68c2b9ea304b7a6c2c60d9343df578a311b0f86b94bc8f1ffe8129"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win_amd64.whl", hash = "sha256:40375c2d05acec10323e45dfe2077ac44bc74659008614af5069034e2cfc781c"}, + {file = "pydantic_core-2.46.5-cp311-cp311-win_arm64.whl", hash = "sha256:28a6a556cd3b6066bea827857f9d9cce027c96f776e512f544a581f9e42161f8"}, + {file = "pydantic_core-2.46.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b9fe6fb92520e3fd61f2e49000b6911b188824f089b75973ea06d6267f0b476d"}, + {file = "pydantic_core-2.46.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a39ac25a9a2fa4072efdb429833c4a4c8009a51ff9eea3eeae131713cd27991e"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fdc8b93a41521988916eeaa271173fcca7fa0803d62f87675aac8dcec1c8e29"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b98134087d9de723658d17a42c7d0da8d6e2ef08015dee7dc93889047315f5e4"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e652ab17569c94bff5475520f907b7148b8c24036a8ebbe5cf7cf7493d28579a"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d925f3d9afd05a8c0fb3a1031463a8d59ebe5e2afad297e29c78be19e13b4e62"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fc5be0abd4a407e200d844b404e33639a554e7bd0d448e7b9ae181be4789ac2"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:816ff0a6550ffc06c098ccd2e0698600f9aa7da192a79eaa6f9af504a35db869"}, + {file = "pydantic_core-2.46.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7ea57fc63aa7da93a1bd2d644e6577befae10c52c4e36377635eea1056a74f5"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:efd62a42486f1bda5d24cb4f63d15a3c7768375fe83d36f9417b4ad7a2fb20b3"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2bc9419666990c06d7397831f2126a1ecc3594aaa3ff7de5bf2d066802f4e07b"}, + {file = "pydantic_core-2.46.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:18a09e1e1011b462f2e32774f25859ef1223d5c2b0546a633cf56654710721e0"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win32.whl", hash = "sha256:5cb482e9e84c851f4e623fe4acc1ced89168cf1fe18f7089db4548c8f5bbb65b"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win_amd64.whl", hash = "sha256:5e81740c09e310f5aa5cbd3e434a01c154d4bef93241c7877b39f211d2b78ba8"}, + {file = "pydantic_core-2.46.5-cp312-cp312-win_arm64.whl", hash = "sha256:f7b0ec93a2893de856652154d73b7ba622f26fa97726487dcac373de5f4c6084"}, + {file = "pydantic_core-2.46.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b7ca9034437b6022f941f4857459562ee00a560b97e7cce8a0ec5a74fc6766e0"}, + {file = "pydantic_core-2.46.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f332f0e72a5a0400141f830744e141bf9f97917878dbe968669e8a7fefea78ff"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193375f3548919d3f0b60936ca113ada3e38f264f91b9b8e0508efaad57be931"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:79bdfa52f843137045b2d081cc05c120ba6665d29b7559c2c47690906f39279f"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24922243639cbdac66c75fcb6fd6495a9cb52b213d62f9a0d16f0310b1ff8038"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76fe65e607be28c7fd4d56fc3c42b1583aa058ce3408b7ad0fd540171d31f9f"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f7b393a8b3da82f5c1fc0751e6d01ac6c55b93c18226a60bdfba4a724efafd1"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:7ac031912d54f3d83ef3b3eb98dfabc1608802e2202263d25957eeed40b94761"}, + {file = "pydantic_core-2.46.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:837b396ca3d7b74091ca623f6cbd8351bd42d670a79c2683e79fb089f06a2de5"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5ee239d575f80b08eca11f6e20f90c4c695de7825c67eefe6091fbf20dda648e"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e80675d75ae2cd14372cb65cad5400d9347a3d3f6c13000183f22dfd027283ed"}, + {file = "pydantic_core-2.46.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c4b71f10dd532fb7a5cbc8f58707779e64f03a258c2bf8bfbaecfcd9970b519"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win32.whl", hash = "sha256:97bf8de4d541598c94a59344eeb988a94c08ff76b5723c41f6567ec18c7892ea"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win_amd64.whl", hash = "sha256:15f4a94963c95accac15b7b657bb177d3ad82bb90b0d0526d9a9b85079925db5"}, + {file = "pydantic_core-2.46.5-cp313-cp313-win_arm64.whl", hash = "sha256:d22a945598fb91236b4dd793a6e42e4f3dd7740bb5aace5ebd7d4c08d13bb575"}, + {file = "pydantic_core-2.46.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c1c43ad4339643d70ebb8124e1305a7dab423001eff58bb41a0f731adbc98355"}, + {file = "pydantic_core-2.46.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1a353f84de772f423b5ffb11d7ae352fbbef0f446f3c0b0af0f8236d7233606e"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5086029a57366b8cf81b130a43908738095c270c21a8d7f0e8bdfdb89718e2f3"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46c25dda9d092a06c08db76ffe0a197107904d0dfac653f7d5306bbcd6d6119c"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37ea7b83c935e5b0d68c9449b82651accf78a10828b2c02b2f2d9e9496446c21"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e64e88d5585bea9ce95861079de72006c7fa6d3df4e3a3b65ba31eb979c15c9f"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d510bac3ee52247af28ed4bb18a1e799f040ac60fd2bf5ccd4c92f1fbe786f"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a2a5e1d0ff29adddc9f6d6821a66302e4493f8ca898b715b6b1182c2c201ea0a"}, + {file = "pydantic_core-2.46.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03b9666e41e35d8909852ba191a0607520f81b74eaf12ccf8737005dbb313821"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:a91c17edf6eea2402cb5457b4c89e99bc5ed1004aa34c4adf1d4258c1a5c22c2"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b49924c73a235e969511bf2aabdff3beebf9820931f646c80274d5d780010c47"}, + {file = "pydantic_core-2.46.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:2cbd9a5eff05e51c447c34dfa4632145b26b09120cf04bd0c871e44c1a5e1c9a"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win32.whl", hash = "sha256:2d5d76654becf5efd62c9e51c3756c67b49498b0c9a40884934c40807adbd074"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win_amd64.whl", hash = "sha256:fa10ef4112775900e7a0661068635eb67b2ab824fbde764de6e0e21982a93db0"}, + {file = "pydantic_core-2.46.5-cp314-cp314-win_arm64.whl", hash = "sha256:045ab3b6d308439e32b81cc173bba5b9018bc6ed896afd0c65b3b009b1699af5"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8816f3d218beb4b787de5c9759c259b8fa61f9dec42dc7811f320a33771778b7"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:bce57638e08ac148e5778cce7feb968307a727d66f8e2274a543d0cf0c9ad6a3"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976e1128455aa595ea04c79ccfedff1aaeab96ee013fcc916bed120c4f0ad94f"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b891faeedeafba41b2983e5001a81b6a915b69544c7e7570d1989ce1c36ac7"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f194189415698233dd1114a093a9b56e61e2c57e11b469be3b0506f46f0771c"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82a36973cf8a2ef5406f4fe2edbf8ed0c99629535d959e0b100c76a32535a111"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdbb78909f52b981d3b2d56b97328d71eb0b974c36bd77c920123a7ebb192829"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:52e24eacdb536cade636aa90fb851835222becff8484b7001fdc78cb0290f2aa"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:37ae34309d7bd8c0d61ab839668058f2a7962ea1fc51d105d2db228fe0618034"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:0cdbada856a1c69a7624a64d3d9aefe79300bd6ef827b43a4f265010b9b55184"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:545f26c504b27c3758439a5e6d9349931f0a04f855668d5fe323c89e82300a38"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:ff218293c9c806138dca139765e3b067621be52bcd93cdc14c7711be7ddc90a9"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win32.whl", hash = "sha256:97cf3eb53a8cccacf9d46686a0926186c9bfb5574f2ed66d3639d5fe117cd3a9"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win_amd64.whl", hash = "sha256:d2f9fc07a8042a8f95925b35c4f04f469707c981fc33245b6ca187cf5d2dd290"}, + {file = "pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f"}, + {file = "pydantic_core-2.46.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c583b927a8838dab890706a6fa7573fbb8b70e24000ef9f7238e2d6f6435a5ed"}, + {file = "pydantic_core-2.46.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdc8b74ecc48c0cb1e9607a05ec4e9e88db60a19ffcc9a1d5f9088ede40c8dc0"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b10e3e8fd7ddc2bd915848a2768e44c15b22936f1cc54c462ad1164deb02655"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f077d0b97ab11fa7dcc633fca53515f290bca8a8a633e966d5b6d1879d9ed01a"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b0fc826b16c55e561e5d2a0c5c77b051ba1d92808118c4e4b5390f5e0cf191d"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef3fbbf161dc9351a2fe0422e51b129f9e97e42385bd0320b309c15f7d287dd8"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978e7b97d4824b5be09c69fb70507cbde3b0323fc147332ca40a94d9a6a0ebbf"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:9b68938dd5b0c783d88ff8e2dcc69451b5eb936fe212d516b21b9d5567f6d464"}, + {file = "pydantic_core-2.46.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:771cf63ae0b1b50dd22e5f3e3549fab5f3f4ff1635d352a9e1a97fe01c7b2e64"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c6be839a5a8312626b32029a415644a0846b420bc8b52b95b28cd92da162168"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:895395f8918627b04efb1ad2a4cf605387143300ba03304cd1dfa6d03f5e095e"}, + {file = "pydantic_core-2.46.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fc8515076c11f3cfdf4fb142dcca0fe384b1230a3b5415458ac84f3e0903ec13"}, + {file = "pydantic_core-2.46.5-cp39-cp39-win32.whl", hash = "sha256:3d2652072b2d774947ba5cf78a9e59644ac62ee572daf6dd2e1dfe905e15b2b7"}, + {file = "pydantic_core-2.46.5-cp39-cp39-win_amd64.whl", hash = "sha256:3aa166e99c4f2985407fb8714aebede877ecb5455cf321b606adca926d30d5a0"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:c14ad3bdc85ee7f318742c457ca3968a92126d144b15721c759033bfb06296c2"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0bddb4020d8f04175865ccd17eff3040874fc11fb593f424edb452653b4b947c"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2471fd51c61c610e1dcf7de44d7299283661654d11264ab4802b303368d69c47"}, + {file = "pydantic_core-2.46.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b10ec717381bdbfafef34607824db4c91de69ff085e4fca3b2af91b4fa17e68a"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:013d6f3483d81e02e7c328831808f336c8596ee33b4bd4026b9ffb1e960b8942"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:e9c134bb666dd54b778b9fc0d2b50cbb7f979b9e3716f26a88c9ab3b6fc1dd0f"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:347ec774390c87326a2e4929d58d3f7e8763a104d5d35f4cd595a4c952366433"}, + {file = "pydantic_core-2.46.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e24d8f05fa2d28513d94e877e9c75ad66175376209b3977f916e240e623193c"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ab4b66edffb32d9e951efb3814bd104b8367a7501b81b955cacb5726d897389f"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:337639ba62a11acde6ef3aeb08c8ea755f8ef1fe5e513356c0f36a2b0d7568b0"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:413a717a410d0c817ef5b786a059415550b3794e1d0c2abffd9efb93a3d9f7b4"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e449def1945a462c464331254e5a44fca7c3b4f9aedf59ec2f50f8066dd8e25"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a445486499897b88a7d6c310c88ed64dd37b1b59bfd7ae9107490bbb362f47d6"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:2d330aaba8621b1edcec8ae2c4050f63b84ccf6d98723a8f212e9684713abf0e"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b6acfb46a814762367fb7ba0828b0a17d441b92ce249a0e007474c9072662dda"}, + {file = "pydantic_core-2.46.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d0a24b40877af2de4950252be9d21eaf7fb07660f3c2cae1f56c6b599ada5266"}, + {file = "pydantic_core-2.46.5.tar.gz", hash = "sha256:10416c15b8839ecc4ef4d0885da76da6fd0f67333a0eb8aff6d93c4b8f2910fc"}, ] [package.dependencies] @@ -1572,14 +1651,14 @@ typing-extensions = ">=4.14.1" [[package]] name = "pygments" -version = "2.20.0" +version = "2.21.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"}, - {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"}, + {file = "pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9"}, + {file = "pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c"}, ] [package.extras] @@ -1972,14 +2051,14 @@ test = ["argcomplete (>=3.0.3) ; python_version < \"3.12\"", "argcomplete (>=3.5 [[package]] name = "types-python-dateutil" -version = "2.9.0.20260716" +version = "2.9.0.20260807" description = "Typing stubs for python-dateutil" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "types_python_dateutil-2.9.0.20260716-py3-none-any.whl", hash = "sha256:1ae41d51a5c5f6bbeeb7f1f34df7086d55ff1605cf88d2ed71a7a276e1a7794e"}, - {file = "types_python_dateutil-2.9.0.20260716.tar.gz", hash = "sha256:1d55d1c3024bdb4861bb6a6622c9ec800c433d87bdc5b16fb84cdd0eed4ef2cb"}, + {file = "types_python_dateutil-2.9.0.20260807-py3-none-any.whl", hash = "sha256:54aa3707350ed7a9cc0776fd2f6739679d6967d11b40150985e81edcb86df4db"}, + {file = "types_python_dateutil-2.9.0.20260807.tar.gz", hash = "sha256:e0b8a90d464c8684c66b7b8e4556d9074afdddcc56ca45323f0987134f9e7034"}, ] [[package]] @@ -1996,18 +2075,18 @@ files = [ [[package]] name = "typing-inspection" -version = "0.4.2" +version = "0.4.4" description = "Runtime typing introspection tools" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"}, - {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"}, + {file = "typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147"}, + {file = "typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47"}, ] [package.dependencies] -typing-extensions = ">=4.12.0" +typing-extensions = ">=4.15.0" [[package]] name = "urllib3" @@ -2029,14 +2108,14 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [[package]] name = "wcwidth" -version = "0.8.2" +version = "0.8.3" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85"}, - {file = "wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda"}, + {file = "wcwidth-0.8.3-py3-none-any.whl", hash = "sha256:d5b73dba6158a595ec9370350e7f2637bcac8d6c5e4fde34f30fcffb6103a5e4"}, + {file = "wcwidth-0.8.3.tar.gz", hash = "sha256:d128512515fbf4612e0ff21fd6380399210318b7b54a9af59dff8454cf9730eb"}, ] [[package]] diff --git a/reference.md b/reference.md index f1284b2c..c0518598 100644 --- a/reference.md +++ b/reference.md @@ -26,7 +26,7 @@ Apply a manifest to create or update a resource.
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import TrueFoundry, MlRepoManifest client = TrueFoundry( api_key="", @@ -38,12 +38,6 @@ client.apply( type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -77,6 +71,14 @@ client.apply(
+**force:** `typing.Optional[bool]` — When `true`, acknowledges that updating this manifest may delete existing per-subject auth records. Currently used for MCP server apply. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -116,7 +118,7 @@ Delete a resource identified by the provided manifest.
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import TrueFoundry, MlRepoManifest client = TrueFoundry( api_key="", @@ -128,12 +130,6 @@ client.delete( type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -2101,7 +2097,7 @@ client.gateway_budgets.get_my_usage()
-Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. +Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. Pass a virtual model id in `model` to preview virtual-model traffic.
@@ -2171,7 +2167,7 @@ client.gateway_budgets.simulate()
-**model:** `typing.Optional[str]` — Model to simulate. +**model:** `typing.Optional[str]` — Model id to simulate (`account/model`). Use the virtual model id when previewing virtual-model traffic.
@@ -2527,7 +2523,7 @@ client.personal_access_tokens.list(
-Create a new personal access token for the current user. +Create a new personal access token for the current user. Cannot be called while authenticated with a personal access token.
@@ -2615,6 +2611,103 @@ client.personal_access_tokens.create(
+ +
+
+ +
client.personal_access_tokens.create_for_user(...) -> CreatePersonalAccessTokenResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create a personal access token owned by another user in the current tenant. Requires tenant admin. Cannot be called while authenticated with a personal access token. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.personal_access_tokens.create_for_user( + name="my-ci-token", + user_email="alice@example.com", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**name:** `str` — Name for the personal access token. Must be 3-36 characters, start with a lowercase letter, end with a lowercase alphanumeric character, and contain only lowercase letters, numbers, and hyphens. + +
+
+ +
+
+ +**user_email:** `str` — Email of the user in the current tenant who will own the personal access token. + +
+
+ +
+
+ +**expiration_date:** `typing.Optional[str]` — Expiration date in ISO format. The token becomes invalid after this date. + +
+
+ +
+
+ +**team_name:** `typing.Optional[str]` — Team to attribute this token cost to. The token owner must be a member of this team. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -2775,7 +2868,7 @@ client.personal_access_tokens.delete(
-Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. +Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. Creating a new token cannot be done while authenticated with a personal access token.
@@ -2971,7 +3064,7 @@ client.virtual_accounts.list(
-Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. +Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. Omitting `permissions` leaves the existing access untouched; an empty list is rejected.
@@ -2986,7 +3079,7 @@ Create a new virtual account or update an existing one using the provided Virtua
```python -from truefoundry_sdk import TrueFoundry, VirtualAccountManifest, Permissions +from truefoundry_sdk import TrueFoundry, VirtualAccountManifest client = TrueFoundry( api_key="", @@ -2997,13 +3090,6 @@ client.virtual_accounts.create_or_update( manifest=VirtualAccountManifest( name="name", type="virtual-account", - permissions=[ - Permissions( - resource_fqn="resource_fqn", - resource_type="resource_type", - role_id="role_id", - ) - ], ), ) @@ -3277,7 +3363,7 @@ client.virtual_accounts.get_token(
-Sync the virtual account token to the configured secret store. Returns the sync metadata including timestamp and error (if any). +Sync the virtual account token to the configured secret store. By default the write is skipped when the active jwt already matches the last successful sync (used by the rotation cron). Pass force=true to rewrite unconditionally. Returns the sync metadata including timestamp and error (if any).
@@ -3325,6 +3411,14 @@ client.virtual_accounts.sync_to_secret_store(
+**force:** `typing.Optional[bool]` — When true, rewrite the token to the secret store even if the active jwt was already synced. Defaults to false so periodic syncs stay idempotent. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3349,7 +3443,7 @@ client.virtual_accounts.sync_to_secret_store(
-Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. +Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. Not allowed when the virtual account has identity provider mapping configured.
@@ -3373,7 +3467,7 @@ client = TrueFoundry( client.virtual_accounts.regenerate_token( id="jqfwg345gi25n5ju2yz5iz6m", - grace_period_in_days=30, + grace_period_in_minutes=30, ) ``` @@ -3398,7 +3492,7 @@ client.virtual_accounts.regenerate_token(
-**grace_period_in_days:** `float` — Grace period in days for which the old token will remain valid after regeneration +**grace_period_in_minutes:** `float` — Grace period in minutes for which the old token will remain valid after regeneration
@@ -3616,7 +3710,7 @@ Create a new cluster or update an existing one using the provided `ClusterManife
```python -from truefoundry_sdk import TrueFoundry, ClusterManifest, ClusterManifestClusterType, Collaborator +from truefoundry_sdk import TrueFoundry, ClusterManifest, ClusterManifestClusterType client = TrueFoundry( api_key="", @@ -3631,12 +3725,6 @@ client.clusters.create_or_update( environment_names=[ "environment_names" ], - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -4899,7 +4987,7 @@ client.application_versions.list(
-Get a single deployment by application ID and deployment ID. +Get a single deployment by application ID and deployment ID, with its status history and builds. A status of DEPLOY_SUCCESS means the rollout was accepted, not that the workload is healthy: a pod that is crashlooping, out of memory or unable to pull its image still reports DEPLOY_SUCCESS. Confirm health with list_k8s_pods or get_application_state before reporting success. Read currentStatus.state.isTerminalState first — currentStatus.state.type says `success` while a deployment is still in progress, so it is only meaningful once the state is terminal.
@@ -6688,7 +6776,7 @@ Create a new secret group or update an existing one using the provided manifest.
```python -from truefoundry_sdk import TrueFoundry, SecretGroupManifest, Collaborator +from truefoundry_sdk import TrueFoundry, SecretGroupManifest client = TrueFoundry( api_key="", @@ -6700,12 +6788,6 @@ client.secret_groups.create_or_update( type="secret-group", name="name", integration_fqn="integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -7343,7 +7425,7 @@ Create or Update an Agent.
```python -from truefoundry_sdk import TrueFoundry, TrueFoundryAgentManifest, TrueFoundryAgentModel, Collaborator +from truefoundry_sdk import TrueFoundry, TrueFoundryAgentManifest, TrueFoundryAgentModel client = TrueFoundry( api_key="", @@ -7358,12 +7440,6 @@ client.agents.create_or_update( model=TrueFoundryAgentModel( name="name", ), - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -7565,7 +7641,7 @@ client.agents.delete(
-Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. +Returns the stored TrueFoundry-backed token for the agent's linked identity. Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. Use the create-token endpoint to issue one.
@@ -7621,6 +7697,175 @@ client.agents.get_token(
+ + +
+ +
client.agents.create_token(...) -> GetAgentIdentityTokenResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Issues a new TrueFoundry-backed token for the agent's linked identity. Fails with 409 when a valid token already exists — use the get-token endpoint to retrieve it. An expired token is replaced by a new one. An optional expirationDate (yyyy-mm-dd) sets the token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.agents.create_token( + id="jqfwg345gi25n5ju2yz5iz6m", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated agent ID. + +
+
+ +
+
+ +**expiration_date:** `typing.Optional[str]` — Token expiry as yyyy-mm-dd, applied to the issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.agents.regenerate_token(...) -> GetAgentIdentityTokenResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Regenerates the TrueFoundry-backed token for the agent's linked identity. The old token remains valid for the specified grace period. Fails when a previous token is still in its grace window. An optional expirationDate (yyyy-mm-dd) sets the new token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.agents.regenerate_token( + id="jqfwg345gi25n5ju2yz5iz6m", + grace_period_in_minutes=60, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — System-generated agent ID. + +
+
+ +
+
+ +**grace_period_in_minutes:** `float` — Grace period in minutes for which the old token will remain valid after regeneration + +
+
+ +
+
+ +**expiration_date:** `typing.Optional[str]` — Token expiry as yyyy-mm-dd, applied to the newly issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -9801,7 +10046,7 @@ Creates or updates an MLRepo entity based on the provided manifest.
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import TrueFoundry, MlRepoManifest client = TrueFoundry( api_key="", @@ -9813,12 +10058,6 @@ client.ml_repos.create_or_update( type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -14880,7 +15119,7 @@ client.internal.build_logs.get(
-**start_ts:** `typing.Optional[str]` — Start timestamp for querying logs, in nanoseconds from the Unix epoch. +**start_ts:** `typing.Optional[str]` — Start timestamp for querying logs, in nanoseconds from the Unix epoch. Supply the `logsStartTs` of the build; omitting it searches from the epoch and matches nothing.
@@ -14904,7 +15143,7 @@ client.internal.build_logs.get(
-**direction:** `typing.Optional[str]` — Direction of sorting logs. Can be `asc` or `desc` +**direction:** `typing.Optional[LogsSortingDirection]` — Direction of sorting logs by timestamp.
diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 8a082c89..0948da2d 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -280,7 +280,6 @@ ComplexityBasedLoadBalanceTargetTier, ComplexityBasedLoadBalancing, ComplexityBasedLoadBalancingClassificationStrategy, - ComplexityStickyRouting, Config, ContainerTaskConfig, ContainerTaskConfigImage, @@ -318,7 +317,13 @@ CustomJwtAuthIntegration, CustomProviderAccount, CustomRegexPattern, + CustomServerAwsAccessKeyAuth, + CustomServerAwsAssumeRoleAuth, + CustomServerAwsSigV4, + CustomServerAwsSigV4Auth, CustomServerHeaderAuth, + CustomServerOAuth2Marker, + CustomServerOAuth2MarkerGrantType, CustomServerPassthrough, CustomTlsSettings, CustomUsernamePasswordArtifactsRegistry, @@ -677,6 +682,10 @@ McpServerAuthStatusInfo, McpServerAuthStatusInfoMethod, McpServerAuthStatusInfoStatus, + McpServerAwsAccessKeyAuth, + McpServerAwsAssumeRoleAuth, + McpServerAwsSigV4Auth, + McpServerAwsSigV4AuthAuth, McpServerEnvAuth, McpServerEnvAuthAuthLevel, McpServerHeaderAuth, @@ -687,6 +696,7 @@ McpServerIntegrations, McpServerManifest, McpServerOAuth2, + McpServerOAuth2ClientAuthentication, McpServerOAuth2GrantType, McpServerOAuth2JwtSource, McpServerOAuth2Provider, @@ -701,6 +711,8 @@ McpServerWithUrl, McpTool, McpToolAnnotations, + McpToolMetadata, + McpToolPolicy, McpToolSetting, McpToolTarget, McpToolsOperator, @@ -708,6 +720,11 @@ Metadata, Metric, MetricCollection, + MicrosoftFoundryModel, + MicrosoftFoundryModelDeploymentType, + MicrosoftFoundryModelPublisher, + MicrosoftFoundryProviderAccount, + MicrosoftFoundryProviderAccountAuthData, MimeType, MirrorAction, MistralAiIntegrations, @@ -792,6 +809,7 @@ OtelExporterGrpcConfigBase, OtelExporterHttpConfigBase, OtelExporterHttpConfigBaseEncoding, + OtelMetricsExporterCommonConfig, OtelMetricsExporterGrpcConfig, OtelMetricsExporterHttpConfig, OtelTracesExporterCommonConfig, @@ -962,6 +980,7 @@ SecretInput, SecretMount, SecretStoreConfig, + SecretStoreIntegrationConfig, SecretVersion, SelfHostedAgent, SelfHostedModel, @@ -1025,7 +1044,9 @@ SparkImageBuild, SparkImageBuildBuildSource, SparkJob, + SparkJobDriverConfig, SparkJobEntrypoint, + SparkJobExecutorConfig, SparkJobImage, SparkJobJavaEntrypoint, SparkJobPythonEntrypoint, @@ -1079,6 +1100,7 @@ TeamMetadata, TeamOwnedBy, TeamSubjectRow, + TeamVirtualAccountDataAccessRule, TenantBudgetConfig, TenantBudgetConfigMode, TensorFlowFramework, @@ -1095,6 +1117,7 @@ TfyPiiGuardrailConfigConfig, TfyPiiGuardrailConfigOperation, TfyPromptInjectionGuardrailConfig, + TfySecretsConfig, TogetherAiIntegrations, TogetherAiKeyAuth, TogetherAiModel, @@ -1566,7 +1589,6 @@ "ComplexityBasedLoadBalanceTargetTier": ".types", "ComplexityBasedLoadBalancing": ".types", "ComplexityBasedLoadBalancingClassificationStrategy": ".types", - "ComplexityStickyRouting": ".types", "Config": ".types", "ConflictError": ".errors", "ContainerTaskConfig": ".types", @@ -1607,7 +1629,13 @@ "CustomJwtAuthIntegration": ".types", "CustomProviderAccount": ".types", "CustomRegexPattern": ".types", + "CustomServerAwsAccessKeyAuth": ".types", + "CustomServerAwsAssumeRoleAuth": ".types", + "CustomServerAwsSigV4": ".types", + "CustomServerAwsSigV4Auth": ".types", "CustomServerHeaderAuth": ".types", + "CustomServerOAuth2Marker": ".types", + "CustomServerOAuth2MarkerGrantType": ".types", "CustomServerPassthrough": ".types", "CustomTlsSettings": ".types", "CustomUsernamePasswordArtifactsRegistry": ".types", @@ -1976,6 +2004,10 @@ "McpServerAuthStatusInfo": ".types", "McpServerAuthStatusInfoMethod": ".types", "McpServerAuthStatusInfoStatus": ".types", + "McpServerAwsAccessKeyAuth": ".types", + "McpServerAwsAssumeRoleAuth": ".types", + "McpServerAwsSigV4Auth": ".types", + "McpServerAwsSigV4AuthAuth": ".types", "McpServerEnvAuth": ".types", "McpServerEnvAuthAuthLevel": ".types", "McpServerHeaderAuth": ".types", @@ -1986,6 +2018,7 @@ "McpServerIntegrations": ".types", "McpServerManifest": ".types", "McpServerOAuth2": ".types", + "McpServerOAuth2ClientAuthentication": ".types", "McpServerOAuth2GrantType": ".types", "McpServerOAuth2JwtSource": ".types", "McpServerOAuth2Provider": ".types", @@ -2000,6 +2033,8 @@ "McpServerWithUrl": ".types", "McpTool": ".types", "McpToolAnnotations": ".types", + "McpToolMetadata": ".types", + "McpToolPolicy": ".types", "McpToolSetting": ".types", "McpToolTarget": ".types", "McpToolsOperator": ".types", @@ -2008,6 +2043,11 @@ "MethodNotAllowedError": ".errors", "Metric": ".types", "MetricCollection": ".types", + "MicrosoftFoundryModel": ".types", + "MicrosoftFoundryModelDeploymentType": ".types", + "MicrosoftFoundryModelPublisher": ".types", + "MicrosoftFoundryProviderAccount": ".types", + "MicrosoftFoundryProviderAccountAuthData": ".types", "MimeType": ".types", "MirrorAction": ".types", "MistralAiIntegrations": ".types", @@ -2094,6 +2134,7 @@ "OtelExporterGrpcConfigBase": ".types", "OtelExporterHttpConfigBase": ".types", "OtelExporterHttpConfigBaseEncoding": ".types", + "OtelMetricsExporterCommonConfig": ".types", "OtelMetricsExporterGrpcConfig": ".types", "OtelMetricsExporterHttpConfig": ".types", "OtelTracesExporterCommonConfig": ".types", @@ -2265,6 +2306,7 @@ "SecretInput": ".types", "SecretMount": ".types", "SecretStoreConfig": ".types", + "SecretStoreIntegrationConfig": ".types", "SecretVersion": ".types", "SelfHostedAgent": ".types", "SelfHostedModel": ".types", @@ -2328,7 +2370,9 @@ "SparkImageBuild": ".types", "SparkImageBuildBuildSource": ".types", "SparkJob": ".types", + "SparkJobDriverConfig": ".types", "SparkJobEntrypoint": ".types", + "SparkJobExecutorConfig": ".types", "SparkJobImage": ".types", "SparkJobJavaEntrypoint": ".types", "SparkJobPythonEntrypoint": ".types", @@ -2383,6 +2427,7 @@ "TeamMetadata": ".types", "TeamOwnedBy": ".types", "TeamSubjectRow": ".types", + "TeamVirtualAccountDataAccessRule": ".types", "TenantBudgetConfig": ".types", "TenantBudgetConfigMode": ".types", "TensorFlowFramework": ".types", @@ -2399,6 +2444,7 @@ "TfyPiiGuardrailConfigConfig": ".types", "TfyPiiGuardrailConfigOperation": ".types", "TfyPromptInjectionGuardrailConfig": ".types", + "TfySecretsConfig": ".types", "TogetherAiIntegrations": ".types", "TogetherAiKeyAuth": ".types", "TogetherAiModel": ".types", @@ -2869,7 +2915,6 @@ def __dir__(): "ComplexityBasedLoadBalanceTargetTier", "ComplexityBasedLoadBalancing", "ComplexityBasedLoadBalancingClassificationStrategy", - "ComplexityStickyRouting", "Config", "ConflictError", "ContainerTaskConfig", @@ -2910,7 +2955,13 @@ def __dir__(): "CustomJwtAuthIntegration", "CustomProviderAccount", "CustomRegexPattern", + "CustomServerAwsAccessKeyAuth", + "CustomServerAwsAssumeRoleAuth", + "CustomServerAwsSigV4", + "CustomServerAwsSigV4Auth", "CustomServerHeaderAuth", + "CustomServerOAuth2Marker", + "CustomServerOAuth2MarkerGrantType", "CustomServerPassthrough", "CustomTlsSettings", "CustomUsernamePasswordArtifactsRegistry", @@ -3279,6 +3330,10 @@ def __dir__(): "McpServerAuthStatusInfo", "McpServerAuthStatusInfoMethod", "McpServerAuthStatusInfoStatus", + "McpServerAwsAccessKeyAuth", + "McpServerAwsAssumeRoleAuth", + "McpServerAwsSigV4Auth", + "McpServerAwsSigV4AuthAuth", "McpServerEnvAuth", "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", @@ -3289,6 +3344,7 @@ def __dir__(): "McpServerIntegrations", "McpServerManifest", "McpServerOAuth2", + "McpServerOAuth2ClientAuthentication", "McpServerOAuth2GrantType", "McpServerOAuth2JwtSource", "McpServerOAuth2Provider", @@ -3303,6 +3359,8 @@ def __dir__(): "McpServerWithUrl", "McpTool", "McpToolAnnotations", + "McpToolMetadata", + "McpToolPolicy", "McpToolSetting", "McpToolTarget", "McpToolsOperator", @@ -3311,6 +3369,11 @@ def __dir__(): "MethodNotAllowedError", "Metric", "MetricCollection", + "MicrosoftFoundryModel", + "MicrosoftFoundryModelDeploymentType", + "MicrosoftFoundryModelPublisher", + "MicrosoftFoundryProviderAccount", + "MicrosoftFoundryProviderAccountAuthData", "MimeType", "MirrorAction", "MistralAiIntegrations", @@ -3397,6 +3460,7 @@ def __dir__(): "OtelExporterGrpcConfigBase", "OtelExporterHttpConfigBase", "OtelExporterHttpConfigBaseEncoding", + "OtelMetricsExporterCommonConfig", "OtelMetricsExporterGrpcConfig", "OtelMetricsExporterHttpConfig", "OtelTracesExporterCommonConfig", @@ -3568,6 +3632,7 @@ def __dir__(): "SecretInput", "SecretMount", "SecretStoreConfig", + "SecretStoreIntegrationConfig", "SecretVersion", "SelfHostedAgent", "SelfHostedModel", @@ -3631,7 +3696,9 @@ def __dir__(): "SparkImageBuild", "SparkImageBuildBuildSource", "SparkJob", + "SparkJobDriverConfig", "SparkJobEntrypoint", + "SparkJobExecutorConfig", "SparkJobImage", "SparkJobJavaEntrypoint", "SparkJobPythonEntrypoint", @@ -3686,6 +3753,7 @@ def __dir__(): "TeamMetadata", "TeamOwnedBy", "TeamSubjectRow", + "TeamVirtualAccountDataAccessRule", "TenantBudgetConfig", "TenantBudgetConfigMode", "TensorFlowFramework", @@ -3702,6 +3770,7 @@ def __dir__(): "TfyPiiGuardrailConfigConfig", "TfyPiiGuardrailConfigOperation", "TfyPromptInjectionGuardrailConfig", + "TfySecretsConfig", "TogetherAiIntegrations", "TogetherAiKeyAuth", "TogetherAiModel", diff --git a/src/truefoundry_sdk/agents/client.py b/src/truefoundry_sdk/agents/client.py index 94780936..02432c4a 100644 --- a/src/truefoundry_sdk/agents/client.py +++ b/src/truefoundry_sdk/agents/client.py @@ -132,7 +132,6 @@ def create_or_update( Examples -------- from truefoundry_sdk import ( - Collaborator, TrueFoundry, TrueFoundryAgentManifest, TrueFoundryAgentModel, @@ -149,12 +148,6 @@ def create_or_update( model=TrueFoundryAgentModel( name="name", ), - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ @@ -230,7 +223,7 @@ def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetAgentIdentityTokenResponse: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. + Returns the stored TrueFoundry-backed token for the agent's linked identity. Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. Use the create-token endpoint to issue one. Parameters ---------- @@ -260,6 +253,98 @@ def get_token( _response = self._raw_client.get_token(id, request_options=request_options) return _response.data + def create_token( + self, + id: str, + *, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetAgentIdentityTokenResponse: + """ + Issues a new TrueFoundry-backed token for the agent's linked identity. Fails with 409 when a valid token already exists — use the get-token endpoint to retrieve it. An expired token is replaced by a new one. An optional expirationDate (yyyy-mm-dd) sets the token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The newly issued TrueFoundry-backed token for the agent's identity. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agents.create_token( + id="jqfwg345gi25n5ju2yz5iz6m", + ) + """ + _response = self._raw_client.create_token(id, expiration_date=expiration_date, request_options=request_options) + return _response.data + + def regenerate_token( + self, + id: str, + *, + grace_period_in_minutes: float, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetAgentIdentityTokenResponse: + """ + Regenerates the TrueFoundry-backed token for the agent's linked identity. The old token remains valid for the specified grace period. Fails when a previous token is still in its grace window. An optional expirationDate (yyyy-mm-dd) sets the new token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the newly issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The newly issued TrueFoundry-backed token for the agent's identity. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agents.regenerate_token( + id="jqfwg345gi25n5ju2yz5iz6m", + grace_period_in_minutes=60.0, + ) + """ + _response = self._raw_client.regenerate_token( + id, + grace_period_in_minutes=grace_period_in_minutes, + expiration_date=expiration_date, + request_options=request_options, + ) + return _response.data + class AsyncAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -387,7 +472,6 @@ async def create_or_update( from truefoundry_sdk import ( AsyncTrueFoundry, - Collaborator, TrueFoundryAgentManifest, TrueFoundryAgentModel, ) @@ -406,12 +490,6 @@ async def main() -> None: model=TrueFoundryAgentModel( name="name", ), - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) @@ -506,7 +584,7 @@ async def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetAgentIdentityTokenResponse: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. + Returns the stored TrueFoundry-backed token for the agent's linked identity. Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. Use the create-token endpoint to issue one. Parameters ---------- @@ -543,3 +621,113 @@ async def main() -> None: """ _response = await self._raw_client.get_token(id, request_options=request_options) return _response.data + + async def create_token( + self, + id: str, + *, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetAgentIdentityTokenResponse: + """ + Issues a new TrueFoundry-backed token for the agent's linked identity. Fails with 409 when a valid token already exists — use the get-token endpoint to retrieve it. An expired token is replaced by a new one. An optional expirationDate (yyyy-mm-dd) sets the token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The newly issued TrueFoundry-backed token for the agent's identity. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.agents.create_token( + id="jqfwg345gi25n5ju2yz5iz6m", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_token( + id, expiration_date=expiration_date, request_options=request_options + ) + return _response.data + + async def regenerate_token( + self, + id: str, + *, + grace_period_in_minutes: float, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> GetAgentIdentityTokenResponse: + """ + Regenerates the TrueFoundry-backed token for the agent's linked identity. The old token remains valid for the specified grace period. Fails when a previous token is still in its grace window. An optional expirationDate (yyyy-mm-dd) sets the new token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the newly issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentIdentityTokenResponse + The newly issued TrueFoundry-backed token for the agent's identity. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.agents.regenerate_token( + id="jqfwg345gi25n5ju2yz5iz6m", + grace_period_in_minutes=60.0, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.regenerate_token( + id, + grace_period_in_minutes=grace_period_in_minutes, + expiration_date=expiration_date, + request_options=request_options, + ) + return _response.data diff --git a/src/truefoundry_sdk/agents/raw_client.py b/src/truefoundry_sdk/agents/raw_client.py index a5b671df..f1427468 100644 --- a/src/truefoundry_sdk/agents/raw_client.py +++ b/src/truefoundry_sdk/agents/raw_client.py @@ -13,6 +13,7 @@ from ..core.request_options import RequestOptions from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.bad_request_error import BadRequestError +from ..errors.conflict_error import ConflictError from ..errors.forbidden_error import ForbiddenError from ..errors.internal_server_error import InternalServerError from ..errors.not_found_error import NotFoundError @@ -395,7 +396,7 @@ def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetAgentIdentityTokenResponse]: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. + Returns the stored TrueFoundry-backed token for the agent's linked identity. Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. Use the create-token endpoint to issue one. Parameters ---------- @@ -478,6 +479,235 @@ def get_token( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def create_token( + self, + id: str, + *, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[GetAgentIdentityTokenResponse]: + """ + Issues a new TrueFoundry-backed token for the agent's linked identity. Fails with 409 when a valid token already exists — use the get-token endpoint to retrieve it. An expired token is replaced by a new one. An optional expirationDate (yyyy-mm-dd) sets the token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentIdentityTokenResponse] + The newly issued TrueFoundry-backed token for the agent's identity. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/token", + method="POST", + json={ + "expirationDate": expiration_date, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def regenerate_token( + self, + id: str, + *, + grace_period_in_minutes: float, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[GetAgentIdentityTokenResponse]: + """ + Regenerates the TrueFoundry-backed token for the agent's linked identity. The old token remains valid for the specified grace period. Fails when a previous token is still in its grace window. An optional expirationDate (yyyy-mm-dd) sets the new token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the newly issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentIdentityTokenResponse] + The newly issued TrueFoundry-backed token for the agent's identity. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/regenerate-token", + method="POST", + json={ + "gracePeriodInMinutes": grace_period_in_minutes, + "expirationDate": expiration_date, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + class AsyncRawAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -847,7 +1077,7 @@ async def get_token( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetAgentIdentityTokenResponse]: """ - Returns the TrueFoundry-backed token for the agent's linked identity, generating one on demand if none exists yet (or the stored one has expired). Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. 404s if the agent has no linked identity. + Returns the stored TrueFoundry-backed token for the agent's linked identity. Only valid for agents whose identity is TrueFoundry-backed. Requires manage access on the agent since the token authenticates as it. Use the create-token endpoint to issue one. Parameters ---------- @@ -929,3 +1159,232 @@ async def get_token( status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_token( + self, + id: str, + *, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[GetAgentIdentityTokenResponse]: + """ + Issues a new TrueFoundry-backed token for the agent's linked identity. Fails with 409 when a valid token already exists — use the get-token endpoint to retrieve it. An expired token is replaced by a new one. An optional expirationDate (yyyy-mm-dd) sets the token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentIdentityTokenResponse] + The newly issued TrueFoundry-backed token for the agent's identity. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/token", + method="POST", + json={ + "expirationDate": expiration_date, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def regenerate_token( + self, + id: str, + *, + grace_period_in_minutes: float, + expiration_date: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[GetAgentIdentityTokenResponse]: + """ + Regenerates the TrueFoundry-backed token for the agent's linked identity. The old token remains valid for the specified grace period. Fails when a previous token is still in its grace window. An optional expirationDate (yyyy-mm-dd) sets the new token's expiry; the identity manifest is not modified. Requires manage access on the agent since the token authenticates as it. + + Parameters + ---------- + id : str + System-generated agent ID. + + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration + + expiration_date : typing.Optional[str] + Token expiry as yyyy-mm-dd, applied to the newly issued token's own expiry only (the identity manifest is not modified). Defaults to a long-lived, effectively non-expiring token when omitted. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentIdentityTokenResponse] + The newly issued TrueFoundry-backed token for the agent's identity. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/agents/{encode_path_param(id)}/regenerate-token", + method="POST", + json={ + "gracePeriodInMinutes": grace_period_in_minutes, + "expirationDate": expiration_date, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentIdentityTokenResponse, + parse_obj_as( + type_=GetAgentIdentityTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/truefoundry_sdk/application_versions/client.py b/src/truefoundry_sdk/application_versions/client.py index ec885eb5..8ec112bb 100644 --- a/src/truefoundry_sdk/application_versions/client.py +++ b/src/truefoundry_sdk/application_versions/client.py @@ -98,7 +98,7 @@ def get( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetApplicationDeploymentResponse: """ - Get a single deployment by application ID and deployment ID. + Get a single deployment by application ID and deployment ID, with its status history and builds. A status of DEPLOY_SUCCESS means the rollout was accepted, not that the workload is healthy: a pod that is crashlooping, out of memory or unable to pull its image still reports DEPLOY_SUCCESS. Confirm health with list_k8s_pods or get_application_state before reporting success. Read currentStatus.state.isTerminalState first — currentStatus.state.type says `success` while a deployment is still in progress, so it is only meaningful once the state is terminal. Parameters ---------- @@ -229,7 +229,7 @@ async def get( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetApplicationDeploymentResponse: """ - Get a single deployment by application ID and deployment ID. + Get a single deployment by application ID and deployment ID, with its status history and builds. A status of DEPLOY_SUCCESS means the rollout was accepted, not that the workload is healthy: a pod that is crashlooping, out of memory or unable to pull its image still reports DEPLOY_SUCCESS. Confirm health with list_k8s_pods or get_application_state before reporting success. Read currentStatus.state.isTerminalState first — currentStatus.state.type says `success` while a deployment is still in progress, so it is only meaningful once the state is terminal. Parameters ---------- diff --git a/src/truefoundry_sdk/application_versions/raw_client.py b/src/truefoundry_sdk/application_versions/raw_client.py index 1e860e8c..b54a1e32 100644 --- a/src/truefoundry_sdk/application_versions/raw_client.py +++ b/src/truefoundry_sdk/application_versions/raw_client.py @@ -130,7 +130,7 @@ def get( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetApplicationDeploymentResponse]: """ - Get a single deployment by application ID and deployment ID. + Get a single deployment by application ID and deployment ID, with its status history and builds. A status of DEPLOY_SUCCESS means the rollout was accepted, not that the workload is healthy: a pod that is crashlooping, out of memory or unable to pull its image still reports DEPLOY_SUCCESS. Confirm health with list_k8s_pods or get_application_state before reporting success. Read currentStatus.state.isTerminalState first — currentStatus.state.type says `success` while a deployment is still in progress, so it is only meaningful once the state is terminal. Parameters ---------- @@ -308,7 +308,7 @@ async def get( self, id: str, deployment_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetApplicationDeploymentResponse]: """ - Get a single deployment by application ID and deployment ID. + Get a single deployment by application ID and deployment ID, with its status history and builds. A status of DEPLOY_SUCCESS means the rollout was accepted, not that the workload is healthy: a pod that is crashlooping, out of memory or unable to pull its image still reports DEPLOY_SUCCESS. Confirm health with list_k8s_pods or get_application_state before reporting success. Read currentStatus.state.isTerminalState first — currentStatus.state.type says `success` while a deployment is still in progress, so it is only meaningful once the state is terminal. Parameters ---------- diff --git a/src/truefoundry_sdk/base_client.py b/src/truefoundry_sdk/base_client.py index 5e7ee69e..b2aee2cf 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -178,6 +178,7 @@ def apply( *, manifest: TrueFoundryApplyRequestManifest, dry_run: typing.Optional[bool] = False, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ @@ -191,6 +192,9 @@ def apply( dry_run : typing.Optional[bool] Dry run the apply operation without actually applying + force : typing.Optional[bool] + When `true`, acknowledges that updating this manifest may delete existing per-subject auth records. Currently used for MCP server apply. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -201,7 +205,7 @@ def apply( Examples -------- - from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry + from truefoundry_sdk import MlRepoManifest, TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -211,16 +215,12 @@ def apply( manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ - _response = self._raw_client.apply(manifest=manifest, dry_run=dry_run, request_options=request_options) + _response = self._raw_client.apply( + manifest=manifest, dry_run=dry_run, force=force, request_options=request_options + ) return _response.data def delete( @@ -244,7 +244,7 @@ def delete( Examples -------- - from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry + from truefoundry_sdk import MlRepoManifest, TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -254,12 +254,6 @@ def delete( manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ @@ -662,6 +656,7 @@ async def apply( *, manifest: TrueFoundryApplyRequestManifest, dry_run: typing.Optional[bool] = False, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ @@ -675,6 +670,9 @@ async def apply( dry_run : typing.Optional[bool] Dry run the apply operation without actually applying + force : typing.Optional[bool] + When `true`, acknowledges that updating this manifest may delete existing per-subject auth records. Currently used for MCP server apply. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -687,7 +685,7 @@ async def apply( -------- import asyncio - from truefoundry_sdk import AsyncTrueFoundry, Collaborator, MlRepoManifest + from truefoundry_sdk import AsyncTrueFoundry, MlRepoManifest client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -700,19 +698,15 @@ async def main() -> None: manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) asyncio.run(main()) """ - _response = await self._raw_client.apply(manifest=manifest, dry_run=dry_run, request_options=request_options) + _response = await self._raw_client.apply( + manifest=manifest, dry_run=dry_run, force=force, request_options=request_options + ) return _response.data async def delete( @@ -738,7 +732,7 @@ async def delete( -------- import asyncio - from truefoundry_sdk import AsyncTrueFoundry, Collaborator, MlRepoManifest + from truefoundry_sdk import AsyncTrueFoundry, MlRepoManifest client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -751,12 +745,6 @@ async def main() -> None: manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) diff --git a/src/truefoundry_sdk/clusters/client.py b/src/truefoundry_sdk/clusters/client.py index 7a106371..87c2eda7 100644 --- a/src/truefoundry_sdk/clusters/client.py +++ b/src/truefoundry_sdk/clusters/client.py @@ -114,7 +114,6 @@ def create_or_update( from truefoundry_sdk import ( ClusterManifest, ClusterManifestClusterType, - Collaborator, TrueFoundry, ) @@ -127,12 +126,6 @@ def create_or_update( name="name", cluster_type=ClusterManifestClusterType.AWS_EKS, environment_names=["environment_names"], - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ @@ -403,7 +396,6 @@ async def create_or_update( AsyncTrueFoundry, ClusterManifest, ClusterManifestClusterType, - Collaborator, ) client = AsyncTrueFoundry( @@ -418,12 +410,6 @@ async def main() -> None: name="name", cluster_type=ClusterManifestClusterType.AWS_EKS, environment_names=["environment_names"], - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) diff --git a/src/truefoundry_sdk/core/http_client.py b/src/truefoundry_sdk/core/http_client.py index 409d2670..3e5a7865 100644 --- a/src/truefoundry_sdk/core/http_client.py +++ b/src/truefoundry_sdk/core/http_client.py @@ -272,7 +272,16 @@ def get_request_body( data: typing.Optional[typing.Any], request_options: typing.Optional[RequestOptions], omit: typing.Optional[typing.Any], + optional_body: bool = False, ) -> typing.Tuple[typing.Optional[typing.Any], typing.Optional[typing.Any]]: + # A whole body left at the sentinel was never passed by the caller, so it is absent + # rather than empty: the request carries no content and no `Content-Type`. + if omit is not None: + if json is omit: + json = None + if data is omit: + data = None + json_body = None data_body = None if data is not None: @@ -288,14 +297,36 @@ def get_request_body( # Only collapse empty dict to None when the body was not explicitly provided # and there are no additional body parameters. This preserves explicit empty # bodies (e.g., when an endpoint has a request body type but all fields are optional). - if json_body == {} and json is None and not has_additional_body_parameters: + # `optional_body` marks an endpoint whose body the API does not require, where a body + # that ends up empty means the caller passed none of its properties, so the request is + # sent with no content and no `Content-Type`. + if json_body == {} and (json is None or optional_body) and not has_additional_body_parameters: json_body = None - if data_body == {} and data is None and not has_additional_body_parameters: + if data_body == {} and (data is None or optional_body) and not has_additional_body_parameters: data_body = None return json_body, data_body +def drop_content_type_without_body( + headers: typing.Dict[str, typing.Any], + *, + json_body: typing.Optional[typing.Any], + data_body: typing.Optional[typing.Any], + optional_body: bool, +) -> typing.Dict[str, typing.Any]: + """Strip ``Content-Type`` from a request that carries no body. + + ``get_request_body`` drops the body of an ``optional_body`` endpoint when the caller + supplied none of it, but the endpoint still passes the content type it would have used. + A request that sends nothing must not advertise a media type, so a server that branches + on the header sees a bodyless call for what it is. + """ + if not optional_body or json_body is not None or data_body is not None: + return headers + return {key: value for key, value in headers.items() if key.lower() != "content-type"} + + class HttpClient: def __init__( self, @@ -343,6 +374,7 @@ def request( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) @@ -355,7 +387,9 @@ def request( ) timeout = _timeout if _timeout is not None else httpx.USE_CLIENT_DEFAULT - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) request_files: typing.Optional[RequestFiles] = ( convert_file_dict_to_httpx_tuples(remove_omit_from_dict(remove_none_from_dict(files), omit)) @@ -398,6 +432,9 @@ def request( } ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -506,6 +543,7 @@ def stream( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> typing.Iterator[httpx.Response]: base_url = self.get_base_url(base_url) @@ -527,7 +565,9 @@ def stream( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -561,6 +601,9 @@ def stream( } ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -638,6 +681,7 @@ async def request( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: base_url = self.get_base_url(base_url) @@ -659,7 +703,9 @@ async def request( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -696,6 +742,9 @@ async def request( } ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( @@ -804,6 +853,7 @@ async def stream( request_options: typing.Optional[RequestOptions] = None, retries: int = 0, omit: typing.Optional[typing.Any] = None, + optional_body: bool = False, force_multipart: typing.Optional[bool] = None, ) -> typing.AsyncIterator[httpx.Response]: base_url = self.get_base_url(base_url) @@ -825,7 +875,9 @@ async def stream( if (request_files is None or len(request_files) == 0) and force_multipart: request_files = FORCE_MULTIPART - json_body, data_body = get_request_body(json=json, data=data, request_options=request_options, omit=omit) + json_body, data_body = get_request_body( + json=json, data=data, request_options=request_options, omit=omit, optional_body=optional_body + ) data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) @@ -862,6 +914,9 @@ async def stream( } ) ) + _request_headers = drop_content_type_without_body( + _request_headers, json_body=json_body, data_body=data_body, optional_body=optional_body + ) if self.logger.is_debug(): self.logger.debug( diff --git a/src/truefoundry_sdk/core/http_response.py b/src/truefoundry_sdk/core/http_response.py index 00bb1096..9aa1e188 100644 --- a/src/truefoundry_sdk/core/http_response.py +++ b/src/truefoundry_sdk/core/http_response.py @@ -24,6 +24,10 @@ def headers(self) -> Dict[str, str]: def status_code(self) -> int: return self._response.status_code + @property + def response(self) -> httpx.Response: + return self._response + class HttpResponse(Generic[T], BaseHttpResponse): """HTTP response wrapper that exposes response headers and data.""" diff --git a/src/truefoundry_sdk/gateway_budgets/client.py b/src/truefoundry_sdk/gateway_budgets/client.py index 144a4915..7058795f 100644 --- a/src/truefoundry_sdk/gateway_budgets/client.py +++ b/src/truefoundry_sdk/gateway_budgets/client.py @@ -162,7 +162,7 @@ def simulate( request_options: typing.Optional[RequestOptions] = None, ) -> BudgetUsageResponse: """ - Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. Pass a virtual model id in `model` to preview virtual-model traffic. Parameters ---------- @@ -179,7 +179,7 @@ def simulate( All teams the simulated user belongs to. Merged with `team` when both are provided. model : typing.Optional[str] - Model to simulate. + Model id to simulate (`account/model`). Use the virtual model id when previewing virtual-model traffic. metadata : typing.Optional[typing.Dict[str, str]] Request metadata key/value pairs to simulate. @@ -486,7 +486,7 @@ async def simulate( request_options: typing.Optional[RequestOptions] = None, ) -> BudgetUsageResponse: """ - Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. Pass a virtual model id in `model` to preview virtual-model traffic. Parameters ---------- @@ -503,7 +503,7 @@ async def simulate( All teams the simulated user belongs to. Merged with `team` when both are provided. model : typing.Optional[str] - Model to simulate. + Model id to simulate (`account/model`). Use the virtual model id when previewing virtual-model traffic. metadata : typing.Optional[typing.Dict[str, str]] Request metadata key/value pairs to simulate. diff --git a/src/truefoundry_sdk/gateway_budgets/raw_client.py b/src/truefoundry_sdk/gateway_budgets/raw_client.py index 4b130cc0..74c7c9a8 100644 --- a/src/truefoundry_sdk/gateway_budgets/raw_client.py +++ b/src/truefoundry_sdk/gateway_budgets/raw_client.py @@ -205,7 +205,7 @@ def simulate( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[BudgetUsageResponse]: """ - Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. Pass a virtual model id in `model` to preview virtual-model traffic. Parameters ---------- @@ -222,7 +222,7 @@ def simulate( All teams the simulated user belongs to. Merged with `team` when both are provided. model : typing.Optional[str] - Model to simulate. + Model id to simulate (`account/model`). Use the virtual model id when previewing virtual-model traffic. metadata : typing.Optional[typing.Dict[str, str]] Request metadata key/value pairs to simulate. @@ -609,7 +609,7 @@ async def simulate( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[BudgetUsageResponse]: """ - Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. + Returns the budgets that would apply to a hypothetical user/team/model/metadata selection, with current usage. Pass a virtual model id in `model` to preview virtual-model traffic. Parameters ---------- @@ -626,7 +626,7 @@ async def simulate( All teams the simulated user belongs to. Merged with `team` when both are provided. model : typing.Optional[str] - Model to simulate. + Model id to simulate (`account/model`). Use the virtual model id when previewing virtual-model traffic. metadata : typing.Optional[typing.Dict[str, str]] Request metadata key/value pairs to simulate. diff --git a/src/truefoundry_sdk/internal/build_logs/client.py b/src/truefoundry_sdk/internal/build_logs/client.py index c081c150..b6ef5007 100644 --- a/src/truefoundry_sdk/internal/build_logs/client.py +++ b/src/truefoundry_sdk/internal/build_logs/client.py @@ -5,6 +5,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.request_options import RequestOptions from ...types.logs_response import LogsResponse +from ...types.logs_sorting_direction import LogsSortingDirection from .raw_client import AsyncRawBuildLogsClient, RawBuildLogsClient @@ -29,8 +30,8 @@ def get( *, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, - limit: typing.Optional[str] = None, - direction: typing.Optional[str] = None, + limit: typing.Optional[str] = "10000", + direction: typing.Optional[LogsSortingDirection] = None, filter_query: typing.Optional[str] = None, num_logs_to_ignore: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -44,7 +45,7 @@ def get( PipelineRun Name start_ts : typing.Optional[str] - Start timestamp for querying logs, in nanoseconds from the Unix epoch. + Start timestamp for querying logs, in nanoseconds from the Unix epoch. Supply the `logsStartTs` of the build; omitting it searches from the epoch and matches nothing. end_ts : typing.Optional[str] End timestamp for querying logs, in nanoseconds from the Unix epoch. @@ -52,8 +53,8 @@ def get( limit : typing.Optional[str] Max number of log lines to fetch - direction : typing.Optional[str] - Direction of sorting logs. Can be `asc` or `desc` + direction : typing.Optional[LogsSortingDirection] + Direction of sorting logs by timestamp. filter_query : typing.Optional[str] JSON-encoded filter object with shape `{ matchString, type, operator }`. `type` is `regex` or `substring`; `operator` is `equal` or `not_equal`. @@ -118,8 +119,8 @@ async def get( *, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, - limit: typing.Optional[str] = None, - direction: typing.Optional[str] = None, + limit: typing.Optional[str] = "10000", + direction: typing.Optional[LogsSortingDirection] = None, filter_query: typing.Optional[str] = None, num_logs_to_ignore: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -133,7 +134,7 @@ async def get( PipelineRun Name start_ts : typing.Optional[str] - Start timestamp for querying logs, in nanoseconds from the Unix epoch. + Start timestamp for querying logs, in nanoseconds from the Unix epoch. Supply the `logsStartTs` of the build; omitting it searches from the epoch and matches nothing. end_ts : typing.Optional[str] End timestamp for querying logs, in nanoseconds from the Unix epoch. @@ -141,8 +142,8 @@ async def get( limit : typing.Optional[str] Max number of log lines to fetch - direction : typing.Optional[str] - Direction of sorting logs. Can be `asc` or `desc` + direction : typing.Optional[LogsSortingDirection] + Direction of sorting logs by timestamp. filter_query : typing.Optional[str] JSON-encoded filter object with shape `{ matchString, type, operator }`. `type` is `regex` or `substring`; `operator` is `equal` or `not_equal`. diff --git a/src/truefoundry_sdk/internal/build_logs/raw_client.py b/src/truefoundry_sdk/internal/build_logs/raw_client.py index 75e3a2d8..fc46aed5 100644 --- a/src/truefoundry_sdk/internal/build_logs/raw_client.py +++ b/src/truefoundry_sdk/internal/build_logs/raw_client.py @@ -12,6 +12,7 @@ from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...types.logs_response import LogsResponse +from ...types.logs_sorting_direction import LogsSortingDirection from pydantic import ValidationError @@ -25,8 +26,8 @@ def get( *, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, - limit: typing.Optional[str] = None, - direction: typing.Optional[str] = None, + limit: typing.Optional[str] = "10000", + direction: typing.Optional[LogsSortingDirection] = None, filter_query: typing.Optional[str] = None, num_logs_to_ignore: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -40,7 +41,7 @@ def get( PipelineRun Name start_ts : typing.Optional[str] - Start timestamp for querying logs, in nanoseconds from the Unix epoch. + Start timestamp for querying logs, in nanoseconds from the Unix epoch. Supply the `logsStartTs` of the build; omitting it searches from the epoch and matches nothing. end_ts : typing.Optional[str] End timestamp for querying logs, in nanoseconds from the Unix epoch. @@ -48,8 +49,8 @@ def get( limit : typing.Optional[str] Max number of log lines to fetch - direction : typing.Optional[str] - Direction of sorting logs. Can be `asc` or `desc` + direction : typing.Optional[LogsSortingDirection] + Direction of sorting logs by timestamp. filter_query : typing.Optional[str] JSON-encoded filter object with shape `{ matchString, type, operator }`. `type` is `regex` or `substring`; `operator` is `equal` or `not_equal`. @@ -119,8 +120,8 @@ async def get( *, start_ts: typing.Optional[str] = None, end_ts: typing.Optional[str] = None, - limit: typing.Optional[str] = None, - direction: typing.Optional[str] = None, + limit: typing.Optional[str] = "10000", + direction: typing.Optional[LogsSortingDirection] = None, filter_query: typing.Optional[str] = None, num_logs_to_ignore: typing.Optional[float] = None, request_options: typing.Optional[RequestOptions] = None, @@ -134,7 +135,7 @@ async def get( PipelineRun Name start_ts : typing.Optional[str] - Start timestamp for querying logs, in nanoseconds from the Unix epoch. + Start timestamp for querying logs, in nanoseconds from the Unix epoch. Supply the `logsStartTs` of the build; omitting it searches from the epoch and matches nothing. end_ts : typing.Optional[str] End timestamp for querying logs, in nanoseconds from the Unix epoch. @@ -142,8 +143,8 @@ async def get( limit : typing.Optional[str] Max number of log lines to fetch - direction : typing.Optional[str] - Direction of sorting logs. Can be `asc` or `desc` + direction : typing.Optional[LogsSortingDirection] + Direction of sorting logs by timestamp. filter_query : typing.Optional[str] JSON-encoded filter object with shape `{ matchString, type, operator }`. `type` is `regex` or `substring`; `operator` is `equal` or `not_equal`. diff --git a/src/truefoundry_sdk/ml_repos/client.py b/src/truefoundry_sdk/ml_repos/client.py index 1ac6ae0b..e18db3ae 100644 --- a/src/truefoundry_sdk/ml_repos/client.py +++ b/src/truefoundry_sdk/ml_repos/client.py @@ -179,7 +179,7 @@ def create_or_update( Examples -------- - from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry + from truefoundry_sdk import MlRepoManifest, TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -189,12 +189,6 @@ def create_or_update( manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ @@ -394,7 +388,7 @@ async def create_or_update( -------- import asyncio - from truefoundry_sdk import AsyncTrueFoundry, Collaborator, MlRepoManifest + from truefoundry_sdk import AsyncTrueFoundry, MlRepoManifest client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -407,12 +401,6 @@ async def main() -> None: manifest=MlRepoManifest( name="name", storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) diff --git a/src/truefoundry_sdk/personal_access_tokens/client.py b/src/truefoundry_sdk/personal_access_tokens/client.py index 8d911ea1..a2dcb030 100644 --- a/src/truefoundry_sdk/personal_access_tokens/client.py +++ b/src/truefoundry_sdk/personal_access_tokens/client.py @@ -97,7 +97,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> CreatePersonalAccessTokenResponse: """ - Create a new personal access token for the current user. + Create a new personal access token for the current user. Cannot be called while authenticated with a personal access token. Parameters ---------- @@ -146,6 +146,62 @@ def create( ) return _response.data + def create_for_user( + self, + *, + name: str, + user_email: str, + expiration_date: typing.Optional[str] = OMIT, + team_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> CreatePersonalAccessTokenResponse: + """ + Create a personal access token owned by another user in the current tenant. Requires tenant admin. Cannot be called while authenticated with a personal access token. + + Parameters + ---------- + name : str + Name for the personal access token. Must be 3-36 characters, start with a lowercase letter, end with a lowercase alphanumeric character, and contain only lowercase letters, numbers, and hyphens. + + user_email : str + Email of the user in the current tenant who will own the personal access token. + + expiration_date : typing.Optional[str] + Expiration date in ISO format. The token becomes invalid after this date. + + team_name : typing.Optional[str] + Team to attribute this token cost to. The token owner must be a member of this team. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CreatePersonalAccessTokenResponse + The newly created personal access token owned by the target user. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.personal_access_tokens.create_for_user( + name="my-ci-token", + user_email="alice@example.com", + ) + """ + _response = self._raw_client.create_for_user( + name=name, + user_email=user_email, + expiration_date=expiration_date, + team_name=team_name, + request_options=request_options, + ) + return _response.data + def revoke_all( self, *, email: str, request_options: typing.Optional[RequestOptions] = None ) -> RevokeAllPersonalAccessTokenResponse: @@ -222,7 +278,7 @@ def get( request_options: typing.Optional[RequestOptions] = None, ) -> GetOrCreatePersonalAccessTokenResponse: """ - Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. + Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. Creating a new token cannot be done while authenticated with a personal access token. Parameters ---------- @@ -343,7 +399,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> CreatePersonalAccessTokenResponse: """ - Create a new personal access token for the current user. + Create a new personal access token for the current user. Cannot be called while authenticated with a personal access token. Parameters ---------- @@ -400,6 +456,70 @@ async def main() -> None: ) return _response.data + async def create_for_user( + self, + *, + name: str, + user_email: str, + expiration_date: typing.Optional[str] = OMIT, + team_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> CreatePersonalAccessTokenResponse: + """ + Create a personal access token owned by another user in the current tenant. Requires tenant admin. Cannot be called while authenticated with a personal access token. + + Parameters + ---------- + name : str + Name for the personal access token. Must be 3-36 characters, start with a lowercase letter, end with a lowercase alphanumeric character, and contain only lowercase letters, numbers, and hyphens. + + user_email : str + Email of the user in the current tenant who will own the personal access token. + + expiration_date : typing.Optional[str] + Expiration date in ISO format. The token becomes invalid after this date. + + team_name : typing.Optional[str] + Team to attribute this token cost to. The token owner must be a member of this team. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CreatePersonalAccessTokenResponse + The newly created personal access token owned by the target user. + + Examples + -------- + import asyncio + + from truefoundry_sdk import AsyncTrueFoundry + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.personal_access_tokens.create_for_user( + name="my-ci-token", + user_email="alice@example.com", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_for_user( + name=name, + user_email=user_email, + expiration_date=expiration_date, + team_name=team_name, + request_options=request_options, + ) + return _response.data + async def revoke_all( self, *, email: str, request_options: typing.Optional[RequestOptions] = None ) -> RevokeAllPersonalAccessTokenResponse: @@ -492,7 +612,7 @@ async def get( request_options: typing.Optional[RequestOptions] = None, ) -> GetOrCreatePersonalAccessTokenResponse: """ - Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. + Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. Creating a new token cannot be done while authenticated with a personal access token. Parameters ---------- diff --git a/src/truefoundry_sdk/personal_access_tokens/raw_client.py b/src/truefoundry_sdk/personal_access_tokens/raw_client.py index 09e46088..37eec654 100644 --- a/src/truefoundry_sdk/personal_access_tokens/raw_client.py +++ b/src/truefoundry_sdk/personal_access_tokens/raw_client.py @@ -13,6 +13,7 @@ from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError from ..errors.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..types.create_personal_access_token_response import CreatePersonalAccessTokenResponse from ..types.delete_personal_access_token_response import DeletePersonalAccessTokenResponse @@ -112,7 +113,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[CreatePersonalAccessTokenResponse]: """ - Create a new personal access token for the current user. + Create a new personal access token for the current user. Cannot be called while authenticated with a personal access token. Parameters ---------- @@ -196,6 +197,118 @@ def create( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def create_for_user( + self, + *, + name: str, + user_email: str, + expiration_date: typing.Optional[str] = OMIT, + team_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CreatePersonalAccessTokenResponse]: + """ + Create a personal access token owned by another user in the current tenant. Requires tenant admin. Cannot be called while authenticated with a personal access token. + + Parameters + ---------- + name : str + Name for the personal access token. Must be 3-36 characters, start with a lowercase letter, end with a lowercase alphanumeric character, and contain only lowercase letters, numbers, and hyphens. + + user_email : str + Email of the user in the current tenant who will own the personal access token. + + expiration_date : typing.Optional[str] + Expiration date in ISO format. The token becomes invalid after this date. + + team_name : typing.Optional[str] + Team to attribute this token cost to. The token owner must be a member of this team. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CreatePersonalAccessTokenResponse] + The newly created personal access token owned by the target user. + """ + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/personal-access-tokens/for-user", + method="POST", + json={ + "name": name, + "userEmail": user_email, + "expirationDate": expiration_date, + "teamName": team_name, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CreatePersonalAccessTokenResponse, + parse_obj_as( + type_=CreatePersonalAccessTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def revoke_all( self, *, email: str, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[RevokeAllPersonalAccessTokenResponse]: @@ -319,7 +432,7 @@ def get( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetOrCreatePersonalAccessTokenResponse]: """ - Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. + Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. Creating a new token cannot be done while authenticated with a personal access token. Parameters ---------- @@ -462,7 +575,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[CreatePersonalAccessTokenResponse]: """ - Create a new personal access token for the current user. + Create a new personal access token for the current user. Cannot be called while authenticated with a personal access token. Parameters ---------- @@ -546,6 +659,118 @@ async def create( ) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def create_for_user( + self, + *, + name: str, + user_email: str, + expiration_date: typing.Optional[str] = OMIT, + team_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CreatePersonalAccessTokenResponse]: + """ + Create a personal access token owned by another user in the current tenant. Requires tenant admin. Cannot be called while authenticated with a personal access token. + + Parameters + ---------- + name : str + Name for the personal access token. Must be 3-36 characters, start with a lowercase letter, end with a lowercase alphanumeric character, and contain only lowercase letters, numbers, and hyphens. + + user_email : str + Email of the user in the current tenant who will own the personal access token. + + expiration_date : typing.Optional[str] + Expiration date in ISO format. The token becomes invalid after this date. + + team_name : typing.Optional[str] + Team to attribute this token cost to. The token owner must be a member of this team. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CreatePersonalAccessTokenResponse] + The newly created personal access token owned by the target user. + """ + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/personal-access-tokens/for-user", + method="POST", + json={ + "name": name, + "userEmail": user_email, + "expirationDate": expiration_date, + "teamName": team_name, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CreatePersonalAccessTokenResponse, + parse_obj_as( + type_=CreatePersonalAccessTokenResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Any, + parse_obj_as( + type_=typing.Any, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def revoke_all( self, *, email: str, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[RevokeAllPersonalAccessTokenResponse]: @@ -669,7 +894,7 @@ async def get( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetOrCreatePersonalAccessTokenResponse]: """ - Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. + Get an existing personal access token by name. If none exists, a new one is created and returned with a fresh token. Creating a new token cannot be done while authenticated with a personal access token. Parameters ---------- diff --git a/src/truefoundry_sdk/raw_base_client.py b/src/truefoundry_sdk/raw_base_client.py index 200dfd99..c5f531da 100644 --- a/src/truefoundry_sdk/raw_base_client.py +++ b/src/truefoundry_sdk/raw_base_client.py @@ -29,6 +29,7 @@ def apply( *, manifest: TrueFoundryApplyRequestManifest, dry_run: typing.Optional[bool] = False, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TrueFoundryApplyResponse]: """ @@ -42,6 +43,9 @@ def apply( dry_run : typing.Optional[bool] Dry run the apply operation without actually applying + force : typing.Optional[bool] + When `true`, acknowledges that updating this manifest may delete existing per-subject auth records. Currently used for MCP server apply. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -58,6 +62,7 @@ def apply( object_=manifest, annotation=TrueFoundryApplyRequestManifest, direction="write" ), "dryRun": dry_run, + "force": force, }, headers={ "content-type": "application/json", @@ -146,6 +151,7 @@ async def apply( *, manifest: TrueFoundryApplyRequestManifest, dry_run: typing.Optional[bool] = False, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TrueFoundryApplyResponse]: """ @@ -159,6 +165,9 @@ async def apply( dry_run : typing.Optional[bool] Dry run the apply operation without actually applying + force : typing.Optional[bool] + When `true`, acknowledges that updating this manifest may delete existing per-subject auth records. Currently used for MCP server apply. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -175,6 +184,7 @@ async def apply( object_=manifest, annotation=TrueFoundryApplyRequestManifest, direction="write" ), "dryRun": dry_run, + "force": force, }, headers={ "content-type": "application/json", diff --git a/src/truefoundry_sdk/secret_groups/client.py b/src/truefoundry_sdk/secret_groups/client.py index 82dccb92..d666eaa0 100644 --- a/src/truefoundry_sdk/secret_groups/client.py +++ b/src/truefoundry_sdk/secret_groups/client.py @@ -175,7 +175,7 @@ def create_or_update( Examples -------- - from truefoundry_sdk import Collaborator, SecretGroupManifest, TrueFoundry + from truefoundry_sdk import SecretGroupManifest, TrueFoundry client = TrueFoundry( api_key="YOUR_API_KEY", @@ -185,12 +185,6 @@ def create_or_update( manifest=SecretGroupManifest( name="name", integration_fqn="integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) """ @@ -494,7 +488,7 @@ async def create_or_update( -------- import asyncio - from truefoundry_sdk import AsyncTrueFoundry, Collaborator, SecretGroupManifest + from truefoundry_sdk import AsyncTrueFoundry, SecretGroupManifest client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -507,12 +501,6 @@ async def main() -> None: manifest=SecretGroupManifest( name="name", integration_fqn="integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], ), ) diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index 46bb4de6..5177de20 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -284,7 +284,6 @@ from .complexity_based_load_balancing_classification_strategy import ( ComplexityBasedLoadBalancingClassificationStrategy, ) - from .complexity_sticky_routing import ComplexityStickyRouting from .config import Config from .container_task_config import ContainerTaskConfig from .container_task_config_image import ContainerTaskConfigImage @@ -322,7 +321,13 @@ from .custom_jwt_auth_integration import CustomJwtAuthIntegration from .custom_provider_account import CustomProviderAccount from .custom_regex_pattern import CustomRegexPattern + from .custom_server_aws_access_key_auth import CustomServerAwsAccessKeyAuth + from .custom_server_aws_assume_role_auth import CustomServerAwsAssumeRoleAuth + from .custom_server_aws_sig_v4 import CustomServerAwsSigV4 + from .custom_server_aws_sig_v4auth import CustomServerAwsSigV4Auth from .custom_server_header_auth import CustomServerHeaderAuth + from .custom_server_o_auth2marker import CustomServerOAuth2Marker + from .custom_server_o_auth2marker_grant_type import CustomServerOAuth2MarkerGrantType from .custom_server_passthrough import CustomServerPassthrough from .custom_tls_settings import CustomTlsSettings from .custom_username_password_artifacts_registry import CustomUsernamePasswordArtifactsRegistry @@ -695,6 +700,10 @@ from .mcp_server_auth_status_info import McpServerAuthStatusInfo from .mcp_server_auth_status_info_method import McpServerAuthStatusInfoMethod from .mcp_server_auth_status_info_status import McpServerAuthStatusInfoStatus + from .mcp_server_aws_access_key_auth import McpServerAwsAccessKeyAuth + from .mcp_server_aws_assume_role_auth import McpServerAwsAssumeRoleAuth + from .mcp_server_aws_sig_v4auth import McpServerAwsSigV4Auth + from .mcp_server_aws_sig_v4auth_auth import McpServerAwsSigV4AuthAuth from .mcp_server_env_auth import McpServerEnvAuth from .mcp_server_env_auth_auth_level import McpServerEnvAuthAuthLevel from .mcp_server_header_auth import McpServerHeaderAuth @@ -705,6 +714,7 @@ from .mcp_server_integrations import McpServerIntegrations from .mcp_server_manifest import McpServerManifest from .mcp_server_o_auth2 import McpServerOAuth2 + from .mcp_server_o_auth2client_authentication import McpServerOAuth2ClientAuthentication from .mcp_server_o_auth2grant_type import McpServerOAuth2GrantType from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource from .mcp_server_o_auth2provider import McpServerOAuth2Provider @@ -719,6 +729,8 @@ from .mcp_server_with_url import McpServerWithUrl from .mcp_tool import McpTool from .mcp_tool_annotations import McpToolAnnotations + from .mcp_tool_metadata import McpToolMetadata + from .mcp_tool_policy import McpToolPolicy from .mcp_tool_setting import McpToolSetting from .mcp_tool_target import McpToolTarget from .mcp_tools_operator import McpToolsOperator @@ -726,6 +738,11 @@ from .metadata import Metadata from .metric import Metric from .metric_collection import MetricCollection + from .microsoft_foundry_model import MicrosoftFoundryModel + from .microsoft_foundry_model_deployment_type import MicrosoftFoundryModelDeploymentType + from .microsoft_foundry_model_publisher import MicrosoftFoundryModelPublisher + from .microsoft_foundry_provider_account import MicrosoftFoundryProviderAccount + from .microsoft_foundry_provider_account_auth_data import MicrosoftFoundryProviderAccountAuthData from .mime_type import MimeType from .mirror_action import MirrorAction from .mistral_ai_integrations import MistralAiIntegrations @@ -810,6 +827,7 @@ from .otel_exporter_grpc_config_base import OtelExporterGrpcConfigBase from .otel_exporter_http_config_base import OtelExporterHttpConfigBase from .otel_exporter_http_config_base_encoding import OtelExporterHttpConfigBaseEncoding + from .otel_metrics_exporter_common_config import OtelMetricsExporterCommonConfig from .otel_metrics_exporter_grpc_config import OtelMetricsExporterGrpcConfig from .otel_metrics_exporter_http_config import OtelMetricsExporterHttpConfig from .otel_traces_exporter_common_config import OtelTracesExporterCommonConfig @@ -977,6 +995,7 @@ from .secret_input import SecretInput from .secret_mount import SecretMount from .secret_store_config import SecretStoreConfig + from .secret_store_integration_config import SecretStoreIntegrationConfig from .secret_version import SecretVersion from .self_hosted_agent import SelfHostedAgent from .self_hosted_model import SelfHostedModel @@ -1040,7 +1059,9 @@ from .spark_image_build import SparkImageBuild from .spark_image_build_build_source import SparkImageBuildBuildSource from .spark_job import SparkJob + from .spark_job_driver_config import SparkJobDriverConfig from .spark_job_entrypoint import SparkJobEntrypoint + from .spark_job_executor_config import SparkJobExecutorConfig from .spark_job_image import SparkJobImage from .spark_job_java_entrypoint import SparkJobJavaEntrypoint from .spark_job_python_entrypoint import SparkJobPythonEntrypoint @@ -1094,6 +1115,7 @@ from .team_metadata import TeamMetadata from .team_owned_by import TeamOwnedBy from .team_subject_row import TeamSubjectRow + from .team_virtual_account_data_access_rule import TeamVirtualAccountDataAccessRule from .tenant_budget_config import TenantBudgetConfig from .tenant_budget_config_mode import TenantBudgetConfigMode from .tensor_flow_framework import TensorFlowFramework @@ -1110,6 +1132,7 @@ from .tfy_pii_guardrail_config_config import TfyPiiGuardrailConfigConfig from .tfy_pii_guardrail_config_operation import TfyPiiGuardrailConfigOperation from .tfy_prompt_injection_guardrail_config import TfyPromptInjectionGuardrailConfig + from .tfy_secrets_config import TfySecretsConfig from .together_ai_integrations import TogetherAiIntegrations from .together_ai_key_auth import TogetherAiKeyAuth from .together_ai_model import TogetherAiModel @@ -1516,7 +1539,6 @@ "ComplexityBasedLoadBalanceTargetTier": ".complexity_based_load_balance_target_tier", "ComplexityBasedLoadBalancing": ".complexity_based_load_balancing", "ComplexityBasedLoadBalancingClassificationStrategy": ".complexity_based_load_balancing_classification_strategy", - "ComplexityStickyRouting": ".complexity_sticky_routing", "Config": ".config", "ContainerTaskConfig": ".container_task_config", "ContainerTaskConfigImage": ".container_task_config_image", @@ -1554,7 +1576,13 @@ "CustomJwtAuthIntegration": ".custom_jwt_auth_integration", "CustomProviderAccount": ".custom_provider_account", "CustomRegexPattern": ".custom_regex_pattern", + "CustomServerAwsAccessKeyAuth": ".custom_server_aws_access_key_auth", + "CustomServerAwsAssumeRoleAuth": ".custom_server_aws_assume_role_auth", + "CustomServerAwsSigV4": ".custom_server_aws_sig_v4", + "CustomServerAwsSigV4Auth": ".custom_server_aws_sig_v4auth", "CustomServerHeaderAuth": ".custom_server_header_auth", + "CustomServerOAuth2Marker": ".custom_server_o_auth2marker", + "CustomServerOAuth2MarkerGrantType": ".custom_server_o_auth2marker_grant_type", "CustomServerPassthrough": ".custom_server_passthrough", "CustomTlsSettings": ".custom_tls_settings", "CustomUsernamePasswordArtifactsRegistry": ".custom_username_password_artifacts_registry", @@ -1913,6 +1941,10 @@ "McpServerAuthStatusInfo": ".mcp_server_auth_status_info", "McpServerAuthStatusInfoMethod": ".mcp_server_auth_status_info_method", "McpServerAuthStatusInfoStatus": ".mcp_server_auth_status_info_status", + "McpServerAwsAccessKeyAuth": ".mcp_server_aws_access_key_auth", + "McpServerAwsAssumeRoleAuth": ".mcp_server_aws_assume_role_auth", + "McpServerAwsSigV4Auth": ".mcp_server_aws_sig_v4auth", + "McpServerAwsSigV4AuthAuth": ".mcp_server_aws_sig_v4auth_auth", "McpServerEnvAuth": ".mcp_server_env_auth", "McpServerEnvAuthAuthLevel": ".mcp_server_env_auth_auth_level", "McpServerHeaderAuth": ".mcp_server_header_auth", @@ -1923,6 +1955,7 @@ "McpServerIntegrations": ".mcp_server_integrations", "McpServerManifest": ".mcp_server_manifest", "McpServerOAuth2": ".mcp_server_o_auth2", + "McpServerOAuth2ClientAuthentication": ".mcp_server_o_auth2client_authentication", "McpServerOAuth2GrantType": ".mcp_server_o_auth2grant_type", "McpServerOAuth2JwtSource": ".mcp_server_o_auth2jwt_source", "McpServerOAuth2Provider": ".mcp_server_o_auth2provider", @@ -1937,6 +1970,8 @@ "McpServerWithUrl": ".mcp_server_with_url", "McpTool": ".mcp_tool", "McpToolAnnotations": ".mcp_tool_annotations", + "McpToolMetadata": ".mcp_tool_metadata", + "McpToolPolicy": ".mcp_tool_policy", "McpToolSetting": ".mcp_tool_setting", "McpToolTarget": ".mcp_tool_target", "McpToolsOperator": ".mcp_tools_operator", @@ -1944,6 +1979,11 @@ "Metadata": ".metadata", "Metric": ".metric", "MetricCollection": ".metric_collection", + "MicrosoftFoundryModel": ".microsoft_foundry_model", + "MicrosoftFoundryModelDeploymentType": ".microsoft_foundry_model_deployment_type", + "MicrosoftFoundryModelPublisher": ".microsoft_foundry_model_publisher", + "MicrosoftFoundryProviderAccount": ".microsoft_foundry_provider_account", + "MicrosoftFoundryProviderAccountAuthData": ".microsoft_foundry_provider_account_auth_data", "MimeType": ".mime_type", "MirrorAction": ".mirror_action", "MistralAiIntegrations": ".mistral_ai_integrations", @@ -2028,6 +2068,7 @@ "OtelExporterGrpcConfigBase": ".otel_exporter_grpc_config_base", "OtelExporterHttpConfigBase": ".otel_exporter_http_config_base", "OtelExporterHttpConfigBaseEncoding": ".otel_exporter_http_config_base_encoding", + "OtelMetricsExporterCommonConfig": ".otel_metrics_exporter_common_config", "OtelMetricsExporterGrpcConfig": ".otel_metrics_exporter_grpc_config", "OtelMetricsExporterHttpConfig": ".otel_metrics_exporter_http_config", "OtelTracesExporterCommonConfig": ".otel_traces_exporter_common_config", @@ -2198,6 +2239,7 @@ "SecretInput": ".secret_input", "SecretMount": ".secret_mount", "SecretStoreConfig": ".secret_store_config", + "SecretStoreIntegrationConfig": ".secret_store_integration_config", "SecretVersion": ".secret_version", "SelfHostedAgent": ".self_hosted_agent", "SelfHostedModel": ".self_hosted_model", @@ -2261,7 +2303,9 @@ "SparkImageBuild": ".spark_image_build", "SparkImageBuildBuildSource": ".spark_image_build_build_source", "SparkJob": ".spark_job", + "SparkJobDriverConfig": ".spark_job_driver_config", "SparkJobEntrypoint": ".spark_job_entrypoint", + "SparkJobExecutorConfig": ".spark_job_executor_config", "SparkJobImage": ".spark_job_image", "SparkJobJavaEntrypoint": ".spark_job_java_entrypoint", "SparkJobPythonEntrypoint": ".spark_job_python_entrypoint", @@ -2315,6 +2359,7 @@ "TeamMetadata": ".team_metadata", "TeamOwnedBy": ".team_owned_by", "TeamSubjectRow": ".team_subject_row", + "TeamVirtualAccountDataAccessRule": ".team_virtual_account_data_access_rule", "TenantBudgetConfig": ".tenant_budget_config", "TenantBudgetConfigMode": ".tenant_budget_config_mode", "TensorFlowFramework": ".tensor_flow_framework", @@ -2331,6 +2376,7 @@ "TfyPiiGuardrailConfigConfig": ".tfy_pii_guardrail_config_config", "TfyPiiGuardrailConfigOperation": ".tfy_pii_guardrail_config_operation", "TfyPromptInjectionGuardrailConfig": ".tfy_prompt_injection_guardrail_config", + "TfySecretsConfig": ".tfy_secrets_config", "TogetherAiIntegrations": ".together_ai_integrations", "TogetherAiKeyAuth": ".together_ai_key_auth", "TogetherAiModel": ".together_ai_model", @@ -2761,7 +2807,6 @@ def __dir__(): "ComplexityBasedLoadBalanceTargetTier", "ComplexityBasedLoadBalancing", "ComplexityBasedLoadBalancingClassificationStrategy", - "ComplexityStickyRouting", "Config", "ContainerTaskConfig", "ContainerTaskConfigImage", @@ -2799,7 +2844,13 @@ def __dir__(): "CustomJwtAuthIntegration", "CustomProviderAccount", "CustomRegexPattern", + "CustomServerAwsAccessKeyAuth", + "CustomServerAwsAssumeRoleAuth", + "CustomServerAwsSigV4", + "CustomServerAwsSigV4Auth", "CustomServerHeaderAuth", + "CustomServerOAuth2Marker", + "CustomServerOAuth2MarkerGrantType", "CustomServerPassthrough", "CustomTlsSettings", "CustomUsernamePasswordArtifactsRegistry", @@ -3158,6 +3209,10 @@ def __dir__(): "McpServerAuthStatusInfo", "McpServerAuthStatusInfoMethod", "McpServerAuthStatusInfoStatus", + "McpServerAwsAccessKeyAuth", + "McpServerAwsAssumeRoleAuth", + "McpServerAwsSigV4Auth", + "McpServerAwsSigV4AuthAuth", "McpServerEnvAuth", "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", @@ -3168,6 +3223,7 @@ def __dir__(): "McpServerIntegrations", "McpServerManifest", "McpServerOAuth2", + "McpServerOAuth2ClientAuthentication", "McpServerOAuth2GrantType", "McpServerOAuth2JwtSource", "McpServerOAuth2Provider", @@ -3182,6 +3238,8 @@ def __dir__(): "McpServerWithUrl", "McpTool", "McpToolAnnotations", + "McpToolMetadata", + "McpToolPolicy", "McpToolSetting", "McpToolTarget", "McpToolsOperator", @@ -3189,6 +3247,11 @@ def __dir__(): "Metadata", "Metric", "MetricCollection", + "MicrosoftFoundryModel", + "MicrosoftFoundryModelDeploymentType", + "MicrosoftFoundryModelPublisher", + "MicrosoftFoundryProviderAccount", + "MicrosoftFoundryProviderAccountAuthData", "MimeType", "MirrorAction", "MistralAiIntegrations", @@ -3273,6 +3336,7 @@ def __dir__(): "OtelExporterGrpcConfigBase", "OtelExporterHttpConfigBase", "OtelExporterHttpConfigBaseEncoding", + "OtelMetricsExporterCommonConfig", "OtelMetricsExporterGrpcConfig", "OtelMetricsExporterHttpConfig", "OtelTracesExporterCommonConfig", @@ -3443,6 +3507,7 @@ def __dir__(): "SecretInput", "SecretMount", "SecretStoreConfig", + "SecretStoreIntegrationConfig", "SecretVersion", "SelfHostedAgent", "SelfHostedModel", @@ -3506,7 +3571,9 @@ def __dir__(): "SparkImageBuild", "SparkImageBuildBuildSource", "SparkJob", + "SparkJobDriverConfig", "SparkJobEntrypoint", + "SparkJobExecutorConfig", "SparkJobImage", "SparkJobJavaEntrypoint", "SparkJobPythonEntrypoint", @@ -3560,6 +3627,7 @@ def __dir__(): "TeamMetadata", "TeamOwnedBy", "TeamSubjectRow", + "TeamVirtualAccountDataAccessRule", "TenantBudgetConfig", "TenantBudgetConfigMode", "TensorFlowFramework", @@ -3576,6 +3644,7 @@ def __dir__(): "TfyPiiGuardrailConfigConfig", "TfyPiiGuardrailConfigOperation", "TfyPromptInjectionGuardrailConfig", + "TfySecretsConfig", "TogetherAiIntegrations", "TogetherAiKeyAuth", "TogetherAiModel", diff --git a/src/truefoundry_sdk/types/agent.py b/src/truefoundry_sdk/types/agent.py index 338b3fda..eb3efc5c 100644 --- a/src/truefoundry_sdk/types/agent.py +++ b/src/truefoundry_sdk/types/agent.py @@ -41,6 +41,11 @@ class Agent(UniversalBaseModel): Copy of the agent manifest (v2). """ + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Server-owned bookkeeping, such as the outbound auth revision. + """ + agent_identity_id: typing_extensions.Annotated[ typing.Optional[str], FieldMetadata(alias="agentIdentityId"), diff --git a/src/truefoundry_sdk/types/agent_identity.py b/src/truefoundry_sdk/types/agent_identity.py index 51f5175b..da32e5c8 100644 --- a/src/truefoundry_sdk/types/agent_identity.py +++ b/src/truefoundry_sdk/types/agent_identity.py @@ -28,6 +28,29 @@ class AgentIdentity(UniversalBaseModel): updated_at: typing_extensions.Annotated[ dt.datetime, FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") ] + token_id: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="tokenId"), + pydantic.Field( + alias="tokenId", + description="Id of the active TrueFoundry-backed token. Absent when the identity has no token.", + ), + ] = None + """ + Id of the active TrueFoundry-backed token. Absent when the identity has no token. + """ + + token_expiry: typing_extensions.Annotated[ + typing.Optional[dt.datetime], + FieldMetadata(alias="tokenExpiry"), + pydantic.Field( + alias="tokenExpiry", + description="Expiry of the active TrueFoundry-backed token. Absent when the identity has no token.", + ), + ] = None + """ + Expiry of the active TrueFoundry-backed token. Absent when the identity has no token. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/aws_assumed_role_based_auth.py b/src/truefoundry_sdk/types/aws_assumed_role_based_auth.py index 63683a4e..5e3d738a 100644 --- a/src/truefoundry_sdk/types/aws_assumed_role_based_auth.py +++ b/src/truefoundry_sdk/types/aws_assumed_role_based_auth.py @@ -21,6 +21,11 @@ class AwsAssumedRoleBasedAuth(UniversalBaseModel): ARN of the role you want to assume. """ + external_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional external ID to use when assuming the role. This provides an added layer of security by ensuring only parties with the correct external ID can assume the role. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/aws_bedrock_assumed_role_based_auth.py b/src/truefoundry_sdk/types/aws_bedrock_assumed_role_based_auth.py index 255bb41c..906ada69 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_assumed_role_based_auth.py +++ b/src/truefoundry_sdk/types/aws_bedrock_assumed_role_based_auth.py @@ -3,11 +3,10 @@ import typing import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from .aws_assumed_role_based_auth import AwsAssumedRoleBasedAuth +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class AwsBedrockAssumedRoleBasedAuth(AwsAssumedRoleBasedAuth): +class AwsBedrockAssumedRoleBasedAuth(UniversalBaseModel): """ Assumed Role Based """ @@ -17,6 +16,16 @@ class AwsBedrockAssumedRoleBasedAuth(AwsAssumedRoleBasedAuth): Optional external ID to use when assuming the role. This provides an added layer of security by ensuring only parties with the correct external ID can assume the role. """ + type: typing.Literal["assumed-role-based"] = pydantic.Field(default="assumed-role-based") + """ + +value=assumed-role-based + """ + + assumed_role_arn: str = pydantic.Field() + """ + ARN of the role you want to assume. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py b/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py index 8b57f301..12d0b305 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py +++ b/src/truefoundry_sdk/types/aws_bedrock_mantle_provider_account.py @@ -31,6 +31,11 @@ class AwsBedrockMantleProviderAccount(UniversalBaseModel): """ region: AwsRegion + project: typing.Optional[str] = pydantic.Field(default=None) + """ + The default AWS Bedrock project that inference requests will be attributed to (e.g., proj_5d5ykleja6cwpirysbb7). Used for all models unless overridden at the model level. If not specified, the AWS account's default project is used. + """ + base_url: typing.Optional[str] = pydantic.Field(default=None) """ Optional custom base URL (e.g. a VPC/PrivateLink endpoint) for AWS Bedrock Mantle. When set, requests are sent here instead of the default bedrock-mantle.{region}.api.aws host. diff --git a/src/truefoundry_sdk/types/aws_claude_platform_assumed_role_based_auth.py b/src/truefoundry_sdk/types/aws_claude_platform_assumed_role_based_auth.py index 0ebf1079..017ab706 100644 --- a/src/truefoundry_sdk/types/aws_claude_platform_assumed_role_based_auth.py +++ b/src/truefoundry_sdk/types/aws_claude_platform_assumed_role_based_auth.py @@ -3,11 +3,10 @@ import typing import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from .aws_assumed_role_based_auth import AwsAssumedRoleBasedAuth +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class AwsClaudePlatformAssumedRoleBasedAuth(AwsAssumedRoleBasedAuth): +class AwsClaudePlatformAssumedRoleBasedAuth(UniversalBaseModel): """ Assumed Role Based """ @@ -17,6 +16,16 @@ class AwsClaudePlatformAssumedRoleBasedAuth(AwsAssumedRoleBasedAuth): Optional external ID to use when assuming the role. This provides an added layer of security by ensuring only parties with the correct external ID can assume the role. """ + type: typing.Literal["assumed-role-based"] = pydantic.Field(default="assumed-role-based") + """ + +value=assumed-role-based + """ + + assumed_role_arn: str = pydantic.Field() + """ + ARN of the role you want to assume. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/aws_parameter_store.py b/src/truefoundry_sdk/types/aws_parameter_store.py index 38f62d66..3729a448 100644 --- a/src/truefoundry_sdk/types/aws_parameter_store.py +++ b/src/truefoundry_sdk/types/aws_parameter_store.py @@ -41,6 +41,11 @@ class AwsParameterStore(UniversalBaseModel): The ARN of the KMS key to use for encryption. """ + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Key-value pairs attached as metadata to secrets created in this store + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/aws_secrets_manager.py b/src/truefoundry_sdk/types/aws_secrets_manager.py index aa9a4d61..3f3a7f71 100644 --- a/src/truefoundry_sdk/types/aws_secrets_manager.py +++ b/src/truefoundry_sdk/types/aws_secrets_manager.py @@ -41,6 +41,11 @@ class AwsSecretsManager(UniversalBaseModel): The ARN of the KMS key to use for encryption. """ + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Key-value pairs attached as metadata to secrets created in this store + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/azure_open_ai_provider_account.py b/src/truefoundry_sdk/types/azure_open_ai_provider_account.py index 6f3f8a46..94436ec8 100644 --- a/src/truefoundry_sdk/types/azure_open_ai_provider_account.py +++ b/src/truefoundry_sdk/types/azure_open_ai_provider_account.py @@ -29,7 +29,7 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): azure_endpoint: str = pydantic.Field() """ - The Azure OpenAI Service endpoint URL. Should look like https://{resource-name}.openai.azure.com + The Azure OpenAI Service endpoint URL. Should look like https://{resource-name}.openai.azure.com (a trailing /openai suffix is optional and stripped automatically) """ auth_data: AzureOpenAiProviderAccountAuthData = pydantic.Field() diff --git a/src/truefoundry_sdk/types/base_remote_agent.py b/src/truefoundry_sdk/types/base_remote_agent.py index bd34e068..39534057 100644 --- a/src/truefoundry_sdk/types/base_remote_agent.py +++ b/src/truefoundry_sdk/types/base_remote_agent.py @@ -26,7 +26,7 @@ class BaseRemoteAgent(UniversalBaseModel): Tags for the Agent """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ List of users who have access to this Agent """ diff --git a/src/truefoundry_sdk/types/bedrock_mantle_model.py b/src/truefoundry_sdk/types/bedrock_mantle_model.py index d13174f7..ae6b8de8 100644 --- a/src/truefoundry_sdk/types/bedrock_mantle_model.py +++ b/src/truefoundry_sdk/types/bedrock_mantle_model.py @@ -37,6 +37,11 @@ class BedrockMantleModel(UniversalBaseModel): """ region: typing.Optional[AwsRegion] = None + project: typing.Optional[str] = pydantic.Field(default=None) + """ + The AWS Bedrock project that inference requests for this model will be attributed to (e.g., proj_5d5ykleja6cwpirysbb7). If not specified, the project from the model account will be used, and if that is also unset the AWS account's default project is used. + """ + cost: typing.Optional[ModelCostMetric] = None authorized_subjects: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ diff --git a/src/truefoundry_sdk/types/cluster_manifest.py b/src/truefoundry_sdk/types/cluster_manifest.py index d396ed85..33b0bc71 100644 --- a/src/truefoundry_sdk/types/cluster_manifest.py +++ b/src/truefoundry_sdk/types/cluster_manifest.py @@ -84,7 +84,7 @@ class ClusterManifest(UniversalBaseModel): For more information, check out [this documentation](https://docs.truefoundry.com/docs/generic-control-plane#configuring-node-pools-for-truefoundry). """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Collaborators who can access this cluster """ diff --git a/src/truefoundry_sdk/types/complexity_based_load_balancing.py b/src/truefoundry_sdk/types/complexity_based_load_balancing.py index 08b4765a..f89c3b49 100644 --- a/src/truefoundry_sdk/types/complexity_based_load_balancing.py +++ b/src/truefoundry_sdk/types/complexity_based_load_balancing.py @@ -6,12 +6,11 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .complexity_based_load_balance_target import ComplexityBasedLoadBalanceTarget from .complexity_based_load_balancing_classification_strategy import ComplexityBasedLoadBalancingClassificationStrategy -from .complexity_sticky_routing import ComplexityStickyRouting class ComplexityBasedLoadBalancing(UniversalBaseModel): """ - Complexity-based Load Balancing + Auto Routing """ type: typing.Literal["complexity-based-routing"] = pydantic.Field(default="complexity-based-routing") @@ -31,8 +30,6 @@ class ComplexityBasedLoadBalancing(UniversalBaseModel): List of targets for complexity-based load balancing. Each target serves a single tier; a model must not appear under more than one tier. """ - sticky_routing: typing.Optional[ComplexityStickyRouting] = None - if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 else: diff --git a/src/truefoundry_sdk/types/complexity_sticky_routing.py b/src/truefoundry_sdk/types/complexity_sticky_routing.py deleted file mode 100644 index 11758dd8..00000000 --- a/src/truefoundry_sdk/types/complexity_sticky_routing.py +++ /dev/null @@ -1,31 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .sticky_session_identifier import StickySessionIdentifier - - -class ComplexityStickyRouting(UniversalBaseModel): - """ - Sticky routing for complexity-based routing. A session is pinned to the tier/target chosen on its first classified turn for up to ttl_seconds (5 minutes to 1 hour). - """ - - ttl_seconds: int = pydantic.Field() - """ - Sticky mapping TTL in seconds. Minimum 5 minutes, maximum 1 hour. - """ - - session_identifiers: typing.List[StickySessionIdentifier] = pydantic.Field() - """ - List of identifier selectors used to build sticky key - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 - else: - - class Config: - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_agent_server_auth.py b/src/truefoundry_sdk/types/custom_agent_server_auth.py index fd3dfcba..bed21f95 100644 --- a/src/truefoundry_sdk/types/custom_agent_server_auth.py +++ b/src/truefoundry_sdk/types/custom_agent_server_auth.py @@ -2,7 +2,11 @@ import typing +from .custom_server_aws_sig_v4 import CustomServerAwsSigV4 from .custom_server_header_auth import CustomServerHeaderAuth +from .custom_server_o_auth2marker import CustomServerOAuth2Marker from .custom_server_passthrough import CustomServerPassthrough -CustomAgentServerAuth = typing.Union[CustomServerHeaderAuth, CustomServerPassthrough] +CustomAgentServerAuth = typing.Union[ + CustomServerHeaderAuth, CustomServerPassthrough, CustomServerOAuth2Marker, CustomServerAwsSigV4 +] diff --git a/src/truefoundry_sdk/types/custom_server_aws_access_key_auth.py b/src/truefoundry_sdk/types/custom_server_aws_access_key_auth.py new file mode 100644 index 00000000..f6e46c18 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_aws_access_key_auth.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CustomServerAwsAccessKeyAuth(UniversalBaseModel): + """ + Authenticate with an AWS access key pair. + """ + + type: typing.Literal["aws-access-key"] = pydantic.Field(default="aws-access-key") + """ + +value=aws-access-key + """ + + access_key_id: str = pydantic.Field() + """ + AWS access key ID. Prefer a tfy-secret reference. + """ + + secret_access_key: str = pydantic.Field() + """ + AWS secret access key. Prefer a tfy-secret reference. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_server_aws_assume_role_auth.py b/src/truefoundry_sdk/types/custom_server_aws_assume_role_auth.py new file mode 100644 index 00000000..46a97711 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_aws_assume_role_auth.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CustomServerAwsAssumeRoleAuth(UniversalBaseModel): + """ + Authenticate by assuming an IAM role (SigV4). + """ + + type: typing.Literal["aws-assumed-role"] = pydantic.Field(default="aws-assumed-role") + """ + +value=aws-assumed-role + """ + + assumed_role_arn: str = pydantic.Field() + """ + ARN of the role you want to assume. Prefer a tfy-secret reference. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_server_aws_sig_v4.py b/src/truefoundry_sdk/types/custom_server_aws_sig_v4.py new file mode 100644 index 00000000..ab4a9248 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_aws_sig_v4.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .aws_region import AwsRegion +from .custom_server_aws_sig_v4auth import CustomServerAwsSigV4Auth + + +class CustomServerAwsSigV4(UniversalBaseModel): + """ + Sign requests to AWS Bedrock AgentCore with AWS credentials (SigV4). + """ + + type: typing.Literal["aws-sigv4"] = pydantic.Field(default="aws-sigv4") + """ + +value=aws-sigv4 + """ + + region: AwsRegion + auth: CustomServerAwsSigV4Auth = pydantic.Field() + """ + Credentials used to sign requests. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_server_aws_sig_v4auth.py b/src/truefoundry_sdk/types/custom_server_aws_sig_v4auth.py new file mode 100644 index 00000000..0e269664 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_aws_sig_v4auth.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .custom_server_aws_access_key_auth import CustomServerAwsAccessKeyAuth +from .custom_server_aws_assume_role_auth import CustomServerAwsAssumeRoleAuth + +CustomServerAwsSigV4Auth = typing.Union[CustomServerAwsAccessKeyAuth, CustomServerAwsAssumeRoleAuth] diff --git a/src/truefoundry_sdk/types/custom_server_o_auth2marker.py b/src/truefoundry_sdk/types/custom_server_o_auth2marker.py new file mode 100644 index 00000000..a344d917 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_o_auth2marker.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .custom_server_o_auth2marker_grant_type import CustomServerOAuth2MarkerGrantType + + +class CustomServerOAuth2Marker(UniversalBaseModel): + """ + The Gateway attaches an access token acquired from the agent's configured identity provider. The credentials live in the v2 manifest and are deliberately absent here, so this manifest can be synced to the Gateway without carrying a client secret. + """ + + type: typing.Literal["oauth2"] = pydantic.Field(default="oauth2") + """ + +value=oauth2 + """ + + grant_type: CustomServerOAuth2MarkerGrantType = pydantic.Field() + """ + The OAuth2 flow the Gateway uses to acquire the token. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_server_o_auth2marker_grant_type.py b/src/truefoundry_sdk/types/custom_server_o_auth2marker_grant_type.py new file mode 100644 index 00000000..8c68fc95 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_o_auth2marker_grant_type.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class CustomServerOAuth2MarkerGrantType(enum.StrEnum): + """ + The OAuth2 flow the Gateway uses to acquire the token. + """ + + CLIENT_CREDENTIALS = "client_credentials" + JWT_BEARER = "jwt_bearer" + _UNKNOWN = "__CUSTOMSERVEROAUTH2MARKERGRANTTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "CustomServerOAuth2MarkerGrantType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + client_credentials: typing.Callable[[], T_Result], + jwt_bearer: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is CustomServerOAuth2MarkerGrantType.CLIENT_CREDENTIALS: + return client_credentials() + if self is CustomServerOAuth2MarkerGrantType.JWT_BEARER: + return jwt_bearer() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/data_access_rule.py b/src/truefoundry_sdk/types/data_access_rule.py index 70af23e0..bd9b7592 100644 --- a/src/truefoundry_sdk/types/data_access_rule.py +++ b/src/truefoundry_sdk/types/data_access_rule.py @@ -5,5 +5,8 @@ from .all_data_access_rule import AllDataAccessRule from .own_data_access_rule import OwnDataAccessRule from .team_data_access_rule import TeamDataAccessRule +from .team_virtual_account_data_access_rule import TeamVirtualAccountDataAccessRule -DataAccessRule = typing.Union[OwnDataAccessRule, TeamDataAccessRule, AllDataAccessRule] +DataAccessRule = typing.Union[ + OwnDataAccessRule, TeamDataAccessRule, TeamVirtualAccountDataAccessRule, AllDataAccessRule +] diff --git a/src/truefoundry_sdk/types/deployment.py b/src/truefoundry_sdk/types/deployment.py index bfe5d39a..54114c2b 100644 --- a/src/truefoundry_sdk/types/deployment.py +++ b/src/truefoundry_sdk/types/deployment.py @@ -8,7 +8,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata from .application_summary import ApplicationSummary -from .build_info import BuildInfo +from .deployment_build import DeploymentBuild from .deployment_manifest import DeploymentManifest from .deployment_status import DeploymentStatus from .recommendation import Recommendation @@ -82,12 +82,15 @@ class Deployment(UniversalBaseModel): """ deployment_builds: typing_extensions.Annotated[ - typing.Optional[typing.List[BuildInfo]], + typing.Optional[typing.List[DeploymentBuild]], FieldMetadata(alias="deploymentBuilds"), - pydantic.Field(alias="deploymentBuilds", description="Build steps associated with this deployment"), + pydantic.Field( + alias="deploymentBuilds", + description="Builds associated with this deployment, one per component built from source", + ), ] = None """ - Build steps associated with this deployment + Builds associated with this deployment, one per component built from source """ deployment_statuses: typing_extensions.Annotated[ diff --git a/src/truefoundry_sdk/types/deployment_build.py b/src/truefoundry_sdk/types/deployment_build.py index 03f6b8b7..1c76a5c5 100644 --- a/src/truefoundry_sdk/types/deployment_build.py +++ b/src/truefoundry_sdk/types/deployment_build.py @@ -12,38 +12,122 @@ class DeploymentBuild(UniversalBaseModel): - id: typing.Optional[str] = None + id: typing.Optional[str] = pydantic.Field(default=None) + """ + System-generated unique identifier for the deployment build. + """ + deployment_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="deploymentId"), pydantic.Field(alias="deploymentId") + typing.Optional[str], + FieldMetadata(alias="deploymentId"), + pydantic.Field( + alias="deploymentId", + description="System-generated unique identifier for the deployment this build belongs to.", + ), ] = None + """ + System-generated unique identifier for the deployment this build belongs to. + """ + component_name: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="componentName"), pydantic.Field(alias="componentName") + typing.Optional[str], + FieldMetadata(alias="componentName"), + pydantic.Field( + alias="componentName", + description="Human-readable name of the application component this build produces an image for.", + ), ] = None - build: typing.Optional[BuildInfo] = None + """ + Human-readable name of the application component this build produces an image for. + """ + + build: typing.Optional[BuildInfo] = pydantic.Field(default=None) + """ + Underlying build record. + """ + build_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="buildId"), pydantic.Field(alias="buildId") + typing.Optional[str], + FieldMetadata(alias="buildId"), + pydantic.Field(alias="buildId", description="System-generated unique identifier for the build."), ] = None + """ + System-generated unique identifier for the build. + """ + image_uri: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="imageUri"), pydantic.Field(alias="imageUri") + typing.Optional[str], + FieldMetadata(alias="imageUri"), + pydantic.Field(alias="imageUri", description="Fully-qualified URI of the image produced by this build."), ] = None - name: typing.Optional[str] = None - status: typing.Optional[DeploymentBuildStatus] = None + """ + Fully-qualified URI of the image produced by this build. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Human-readable name of the build, accepted as the `pipelineRunName` by the build logs API. + """ + + status: typing.Optional[DeploymentBuildStatus] = pydantic.Field(default=None) + """ + Current status of the build. + """ + get_logs_url: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="getLogsUrl"), pydantic.Field(alias="getLogsUrl") + typing.Optional[str], + FieldMetadata(alias="getLogsUrl"), + pydantic.Field(alias="getLogsUrl", description="URL for fetching this build’s logs."), ] = None + """ + URL for fetching this build’s logs. + """ + tail_logs_url: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="tailLogsUrl"), pydantic.Field(alias="tailLogsUrl") + typing.Optional[str], + FieldMetadata(alias="tailLogsUrl"), + pydantic.Field( + alias="tailLogsUrl", description="JSON-encoded connection details for streaming this build’s logs." + ), ] = None + """ + JSON-encoded connection details for streaming this build’s logs. + """ + logs_start_ts: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="logsStartTs"), pydantic.Field(alias="logsStartTs") + typing.Optional[str], + FieldMetadata(alias="logsStartTs"), + pydantic.Field( + alias="logsStartTs", + description="Timestamp the build started, in nanoseconds. Pass as `startTs` when fetching build logs.", + ), ] = None - metadata: typing.Optional[typing.Dict[str, typing.Any]] = None + """ + Timestamp the build started, in nanoseconds. Pass as `startTs` when fetching build logs. + """ + + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Additional metadata recorded against the build. + """ + created_at: typing_extensions.Annotated[ - typing.Optional[dt.datetime], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + typing.Optional[dt.datetime], + FieldMetadata(alias="createdAt"), + pydantic.Field(alias="createdAt", description="Timestamp when the build was created."), ] = None + """ + Timestamp when the build was created. + """ + updated_at: typing_extensions.Annotated[ - typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + typing.Optional[dt.datetime], + FieldMetadata(alias="updatedAt"), + pydantic.Field(alias="updatedAt", description="Timestamp when the build was last updated."), ] = None + """ + Timestamp when the build was last updated. + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 diff --git a/src/truefoundry_sdk/types/deployment_build_status.py b/src/truefoundry_sdk/types/deployment_build_status.py index adf58664..55375561 100644 --- a/src/truefoundry_sdk/types/deployment_build_status.py +++ b/src/truefoundry_sdk/types/deployment_build_status.py @@ -8,6 +8,10 @@ class DeploymentBuildStatus(enum.StrEnum): + """ + Current status of the build. + """ + STARTED = "STARTED" SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" diff --git a/src/truefoundry_sdk/types/fiddler_guardrail_config_config.py b/src/truefoundry_sdk/types/fiddler_guardrail_config_config.py index a0ed3cca..ad642843 100644 --- a/src/truefoundry_sdk/types/fiddler_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/fiddler_guardrail_config_config.py @@ -14,6 +14,11 @@ class FiddlerGuardrailConfigConfig(UniversalBaseModel): """ guard_type: FiddlerGuardType + base_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional override for the Fiddler guardrails base URL. Defaults to https://guardrails.cloud.fiddler.ai if not provided. Set this if your tenant is provisioned on a different host (e.g. https://creditone-pov.cloud.fiddler.ai). + """ + threshold: typing.Optional[float] = pydantic.Field(default=None) """ Confidence threshold (0.0-1.0) for flagging content. Content scoring above the threshold will be flagged diff --git a/src/truefoundry_sdk/types/heuristic_classification_strategy.py b/src/truefoundry_sdk/types/heuristic_classification_strategy.py index 550377ff..712ff2a2 100644 --- a/src/truefoundry_sdk/types/heuristic_classification_strategy.py +++ b/src/truefoundry_sdk/types/heuristic_classification_strategy.py @@ -8,7 +8,7 @@ class HeuristicClassificationStrategy(UniversalBaseModel): """ - Fast, in-process heuristic classifier. Runs with zero added latency and no classifier model. This is the default strategy. + Fast built-in classifier, zero added latency """ type: typing.Literal["heuristic"] = pydantic.Field(default="heuristic") diff --git a/src/truefoundry_sdk/types/legacy_agent_manifest.py b/src/truefoundry_sdk/types/legacy_agent_manifest.py index 60f8ede5..be76c1e2 100644 --- a/src/truefoundry_sdk/types/legacy_agent_manifest.py +++ b/src/truefoundry_sdk/types/legacy_agent_manifest.py @@ -29,7 +29,7 @@ class LegacyAgentManifest(UniversalBaseModel): """ source: AgentSource - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ List of users who have access to this Agent """ diff --git a/src/truefoundry_sdk/types/llm_classification_strategy.py b/src/truefoundry_sdk/types/llm_classification_strategy.py index 79f8b7ce..2938733b 100644 --- a/src/truefoundry_sdk/types/llm_classification_strategy.py +++ b/src/truefoundry_sdk/types/llm_classification_strategy.py @@ -9,7 +9,7 @@ class LlmClassificationStrategy(UniversalBaseModel): """ - Classify each request by calling a fast chat model. On timeout or error the gateway applies the configured fallback strategy. + Classify request using chat model """ type: typing.Literal["llm-classifier"] = pydantic.Field(default="llm-classifier") @@ -27,9 +27,9 @@ class LlmClassificationStrategy(UniversalBaseModel): Maximum time to wait for the classifier response in milliseconds before applying the fallback strategy. """ - fallback_strategy: typing.Optional[LlmClassificationStrategyFallbackStrategy] = pydantic.Field(default=None) + fallback_strategy: LlmClassificationStrategyFallbackStrategy = pydantic.Field() """ - Fallback strategy applied when the classifier fails. Defaults to the heuristic classifier. + Fallback strategy applied when the classifier fails. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/mcp_server_auth.py b/src/truefoundry_sdk/types/mcp_server_auth.py index bea14493..69b48f1e 100644 --- a/src/truefoundry_sdk/types/mcp_server_auth.py +++ b/src/truefoundry_sdk/types/mcp_server_auth.py @@ -2,8 +2,9 @@ import typing +from .mcp_server_aws_sig_v4auth import McpServerAwsSigV4Auth from .mcp_server_header_auth import McpServerHeaderAuth from .mcp_server_o_auth2 import McpServerOAuth2 from .mcp_server_passthrough import McpServerPassthrough -McpServerAuth = typing.Union[McpServerHeaderAuth, McpServerOAuth2, McpServerPassthrough] +McpServerAuth = typing.Union[McpServerHeaderAuth, McpServerOAuth2, McpServerPassthrough, McpServerAwsSigV4Auth] diff --git a/src/truefoundry_sdk/types/mcp_server_aws_access_key_auth.py b/src/truefoundry_sdk/types/mcp_server_aws_access_key_auth.py new file mode 100644 index 00000000..45593ba7 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_aws_access_key_auth.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class McpServerAwsAccessKeyAuth(UniversalBaseModel): + """ + Authenticate with an AWS access key pair. + """ + + type: typing.Literal["aws-access-key"] = pydantic.Field(default="aws-access-key") + """ + +value=aws-access-key + """ + + access_key_id: str = pydantic.Field() + """ + AWS access key ID. Prefer a tfy-secret reference. + """ + + secret_access_key: str = pydantic.Field() + """ + AWS secret access key. Prefer a tfy-secret reference. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_aws_assume_role_auth.py b/src/truefoundry_sdk/types/mcp_server_aws_assume_role_auth.py new file mode 100644 index 00000000..56ec0c63 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_aws_assume_role_auth.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class McpServerAwsAssumeRoleAuth(UniversalBaseModel): + """ + Authenticate by assuming an IAM role (SigV4). + """ + + type: typing.Literal["aws-assumed-role"] = pydantic.Field(default="aws-assumed-role") + """ + +value=aws-assumed-role + """ + + assumed_role_arn: str = pydantic.Field() + """ + ARN of the role you want to assume. Prefer a tfy-secret reference. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth.py b/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth.py new file mode 100644 index 00000000..b7e6aaf8 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .aws_region import AwsRegion +from .mcp_server_aws_sig_v4auth_auth import McpServerAwsSigV4AuthAuth + + +class McpServerAwsSigV4Auth(UniversalBaseModel): + """ + Sign requests to AWS Bedrock AgentCore with AWS credentials (SigV4). + """ + + type: typing.Literal["aws-sigv4"] = pydantic.Field(default="aws-sigv4") + """ + +value=aws-sigv4 + """ + + region: AwsRegion + auth: McpServerAwsSigV4AuthAuth = pydantic.Field() + """ + Credentials used to sign requests. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth_auth.py b/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth_auth.py new file mode 100644 index 00000000..91415b50 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_aws_sig_v4auth_auth.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .mcp_server_aws_access_key_auth import McpServerAwsAccessKeyAuth +from .mcp_server_aws_assume_role_auth import McpServerAwsAssumeRoleAuth + +McpServerAwsSigV4AuthAuth = typing.Union[McpServerAwsAccessKeyAuth, McpServerAwsAssumeRoleAuth] diff --git a/src/truefoundry_sdk/types/mcp_server_env_auth.py b/src/truefoundry_sdk/types/mcp_server_env_auth.py index c19c0d63..8b2412a3 100644 --- a/src/truefoundry_sdk/types/mcp_server_env_auth.py +++ b/src/truefoundry_sdk/types/mcp_server_env_auth.py @@ -9,7 +9,7 @@ class McpServerEnvAuth(UniversalBaseModel): """ - Environment variable authentication for stdio MCP. For individual credentials, use a single {{placeholder}} name in values (same rules as header auth). + Environment variable authentication for stdio MCP. For individual credentials, use one or more {{placeholder}} names in values (same rules as header auth). """ type: typing.Literal["env"] = pydantic.Field(default="env") diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2.py b/src/truefoundry_sdk/types/mcp_server_o_auth2.py index 03a42fb3..301b8aba 100644 --- a/src/truefoundry_sdk/types/mcp_server_o_auth2.py +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from .mcp_server_o_auth2client_authentication import McpServerOAuth2ClientAuthentication from .mcp_server_o_auth2grant_type import McpServerOAuth2GrantType from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource from .mcp_server_o_auth2provider import McpServerOAuth2Provider @@ -44,11 +45,26 @@ class McpServerOAuth2( client ID for OAuth2 or the TrueFoundry secret FQN containing the client ID. """ + client_authentication: typing.Optional[McpServerOAuth2ClientAuthentication] = pydantic.Field(default=None) + """ + How the OAuth client authenticates to the token endpoint. Certificate auth is available for Microsoft Entra client_credentials and jwt_bearer (on-behalf-of). + """ + client_secret: typing.Optional[str] = pydantic.Field(default=None) """ Client secret or the TrueFoundry secret FQN containing the client secret for OAuth2. """ + certificate_thumbprint: typing.Optional[str] = pydantic.Field(default=None) + """ + Hex SHA-1 thumbprint from the Azure portal, or the TrueFoundry secret FQN containing it. + """ + + private_key: typing.Optional[str] = pydantic.Field(default=None) + """ + PEM private key for Microsoft Entra certificate-based client authentication, or the TrueFoundry secret FQN containing it. + """ + registration_url: typing.Optional[str] = pydantic.Field(default=None) """ URL for dynamic client registration (RFC 7591). If provided, client credentials will be obtained automatically using the Dynamic Client Registration (DCR) process. diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2client_authentication.py b/src/truefoundry_sdk/types/mcp_server_o_auth2client_authentication.py new file mode 100644 index 00000000..f82cb077 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2client_authentication.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class McpServerOAuth2ClientAuthentication(enum.StrEnum): + """ + How the OAuth client authenticates to the token endpoint. Certificate auth is available for Microsoft Entra client_credentials and jwt_bearer (on-behalf-of). + """ + + CLIENT_SECRET = "client_secret" + CERTIFICATE = "certificate" + _UNKNOWN = "__MCPSERVEROAUTH2CLIENTAUTHENTICATION_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "McpServerOAuth2ClientAuthentication": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + client_secret: typing.Callable[[], T_Result], + certificate: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is McpServerOAuth2ClientAuthentication.CLIENT_SECRET: + return client_secret() + if self is McpServerOAuth2ClientAuthentication.CERTIFICATE: + return certificate() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py index fcdf4bf5..12796448 100644 --- a/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py @@ -16,6 +16,7 @@ class McpServerOAuth2GrantType(enum.StrEnum): CLIENT_CREDENTIALS = "client_credentials" TOKEN_EXCHANGE = "token_exchange" ID_JAG = "id_jag" + JWT_BEARER = "jwt_bearer" _UNKNOWN = "__MCPSERVEROAUTH2GRANTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -33,6 +34,7 @@ def visit( client_credentials: typing.Callable[[], T_Result], token_exchange: typing.Callable[[], T_Result], id_jag: typing.Callable[[], T_Result], + jwt_bearer: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is McpServerOAuth2GrantType.AUTHORIZATION_CODE: @@ -43,4 +45,6 @@ def visit( return token_exchange() if self is McpServerOAuth2GrantType.ID_JAG: return id_jag() + if self is McpServerOAuth2GrantType.JWT_BEARER: + return jwt_bearer() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2provider.py b/src/truefoundry_sdk/types/mcp_server_o_auth2provider.py index 2763eb31..83f350d4 100644 --- a/src/truefoundry_sdk/types/mcp_server_o_auth2provider.py +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2provider.py @@ -15,6 +15,7 @@ class McpServerOAuth2Provider(enum.StrEnum): CUSTOM = "custom" AUTH0 = "auth0" OKTA = "okta" + MICROSOFT_ENTRA = "microsoft-entra" _UNKNOWN = "__MCPSERVEROAUTH2PROVIDER_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -31,6 +32,7 @@ def visit( custom: typing.Callable[[], T_Result], auth0: typing.Callable[[], T_Result], okta: typing.Callable[[], T_Result], + microsoft_entra: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is McpServerOAuth2Provider.CUSTOM: @@ -39,4 +41,6 @@ def visit( return auth0() if self is McpServerOAuth2Provider.OKTA: return okta() + if self is McpServerOAuth2Provider.MICROSOFT_ENTRA: + return microsoft_entra() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_provider_account.py b/src/truefoundry_sdk/types/mcp_server_provider_account.py index 38283a98..90389481 100644 --- a/src/truefoundry_sdk/types/mcp_server_provider_account.py +++ b/src/truefoundry_sdk/types/mcp_server_provider_account.py @@ -28,7 +28,7 @@ class McpServerProviderAccount(UniversalBaseModel): The name of the MCP Server Group. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ List of teams/users who can manage this MCP Server Group. These subjects can add new MCP server integrations, can edit existing ones and can also use the MCP server. """ diff --git a/src/truefoundry_sdk/types/mcp_tool_metadata.py b/src/truefoundry_sdk/types/mcp_tool_metadata.py new file mode 100644 index 00000000..24b6d6a7 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_tool_metadata.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .mcp_tool_annotations import McpToolAnnotations + + +class McpToolMetadata(UniversalBaseModel): + """ + Description and annotation overrides for a single MCP tool. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Describe what this tool does. This helps AI models understand when to use it. + """ + + annotations: typing.Optional[McpToolAnnotations] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/mcp_tool_policy.py b/src/truefoundry_sdk/types/mcp_tool_policy.py new file mode 100644 index 00000000..71e5a3c3 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_tool_policy.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class McpToolPolicy(UniversalBaseModel): + """ + Enable/disable policy for MCP tools. + """ + + enable_tools_by_default: bool = pydantic.Field(default=True) + """ + When true, all tools are exposed except those in disabled_tools. When false, only tools listed in enabled_tools are exposed. + """ + + disabled_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tool names to disable when enable_tools_by_default is true. + """ + + enabled_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Tool names to enable when enable_tools_by_default is false. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/microsoft_foundry_model.py b/src/truefoundry_sdk/types/microsoft_foundry_model.py new file mode 100644 index 00000000..c82688a4 --- /dev/null +++ b/src/truefoundry_sdk/types/microsoft_foundry_model.py @@ -0,0 +1,72 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .microsoft_foundry_model_deployment_type import MicrosoftFoundryModelDeploymentType +from .microsoft_foundry_model_publisher import MicrosoftFoundryModelPublisher +from .model_cost_metric import ModelCostMetric +from .model_type import ModelType + + +class MicrosoftFoundryModel(UniversalBaseModel): + """ + Microsoft Foundry Model + """ + + type: typing.Literal["integration/model/microsoft-foundry"] = pydantic.Field( + default="integration/model/microsoft-foundry" + ) + """ + +value=integration/model/microsoft-foundry + """ + + name: str = pydantic.Field() + """ + A descriptive name to identify this model integration in the UI. Once discovered, this becomes part of the stable client-facing model identifier and should not be changed lightly. + """ + + model_id: str = pydantic.Field() + """ + The model deployment name created in your Azure resource (e.g., gpt-4o-deployment). This is NOT the base model name but the deployment name you configured in Azure. + """ + + api_version: typing.Optional[str] = pydantic.Field(default=None) + """ + Only needed if this deployment does not support Azure's OpenAI-compatible v1 API. When set, requests to this deployment use the legacy deployment-scoped API with this api-version instead of /openai/v1/. + """ + + foundation_model: typing.Optional[str] = pydantic.Field(default=None) + """ + The foundation model identifier (e.g., gpt-4o-2024-11-20). Drives pricing lookups. Editable, since Azure's reported model string may not always match an entry in TrueFoundry's model catalogue. + """ + + deployment_type: typing.Optional[MicrosoftFoundryModelDeploymentType] = pydantic.Field(default=None) + """ + Global: worldwide processing; Data zone (US): US data zone processing; Data zone (EU): EU data zone processing; Standard: single-region processing + """ + + model_types: typing.List[ModelType] = pydantic.Field() + """ + Specify the type of the Azure model + """ + + publisher: MicrosoftFoundryModelPublisher = pydantic.Field() + """ + The model publisher. Deployments published by anyone other than OpenAI are not yet routable through this provider's OpenAI-compatible endpoint. + """ + + cost: typing.Optional[ModelCostMetric] = None + authorized_subjects: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of subjects that are authorized to access this integration. List of user fqn in format :. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/microsoft_foundry_model_deployment_type.py b/src/truefoundry_sdk/types/microsoft_foundry_model_deployment_type.py new file mode 100644 index 00000000..4c75af96 --- /dev/null +++ b/src/truefoundry_sdk/types/microsoft_foundry_model_deployment_type.py @@ -0,0 +1,46 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class MicrosoftFoundryModelDeploymentType(enum.StrEnum): + """ + Global: worldwide processing; Data zone (US): US data zone processing; Data zone (EU): EU data zone processing; Standard: single-region processing + """ + + STANDARD = "standard" + DATAZONE_US = "datazone_us" + DATAZONE_EU = "datazone_eu" + GLOBAL = "global" + _UNKNOWN = "__MICROSOFTFOUNDRYMODELDEPLOYMENTTYPE_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "MicrosoftFoundryModelDeploymentType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + standard: typing.Callable[[], T_Result], + datazone_us: typing.Callable[[], T_Result], + datazone_eu: typing.Callable[[], T_Result], + global_: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is MicrosoftFoundryModelDeploymentType.STANDARD: + return standard() + if self is MicrosoftFoundryModelDeploymentType.DATAZONE_US: + return datazone_us() + if self is MicrosoftFoundryModelDeploymentType.DATAZONE_EU: + return datazone_eu() + if self is MicrosoftFoundryModelDeploymentType.GLOBAL: + return global_() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/microsoft_foundry_model_publisher.py b/src/truefoundry_sdk/types/microsoft_foundry_model_publisher.py new file mode 100644 index 00000000..9044e1d8 --- /dev/null +++ b/src/truefoundry_sdk/types/microsoft_foundry_model_publisher.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class MicrosoftFoundryModelPublisher(enum.StrEnum): + """ + The model publisher. Deployments published by anyone other than OpenAI are not yet routable through this provider's OpenAI-compatible endpoint. + """ + + OPEN_AI = "OpenAI" + OTHER = "Other" + _UNKNOWN = "__MICROSOFTFOUNDRYMODELPUBLISHER_UNKNOWN__" + """ + This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "MicrosoftFoundryModelPublisher": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + open_ai: typing.Callable[[], T_Result], + other: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is MicrosoftFoundryModelPublisher.OPEN_AI: + return open_ai() + if self is MicrosoftFoundryModelPublisher.OTHER: + return other() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/microsoft_foundry_provider_account.py b/src/truefoundry_sdk/types/microsoft_foundry_provider_account.py new file mode 100644 index 00000000..14ea21c3 --- /dev/null +++ b/src/truefoundry_sdk/types/microsoft_foundry_provider_account.py @@ -0,0 +1,71 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata +from .collaborator import Collaborator +from .microsoft_foundry_model import MicrosoftFoundryModel +from .microsoft_foundry_provider_account_auth_data import MicrosoftFoundryProviderAccountAuthData +from .owned_by import OwnedBy + + +class MicrosoftFoundryProviderAccount(UniversalBaseModel): + """ + Microsoft Foundry Model Account + """ + + type: typing.Literal["provider-account/microsoft-foundry"] = pydantic.Field( + default="provider-account/microsoft-foundry" + ) + """ + +value=provider-account/microsoft-foundry + """ + + name: str = pydantic.Field() + """ + The name of the Microsoft Foundry model account + """ + + openai_endpoint: typing.Optional[str] = pydantic.Field(default=None) + """ + The classic Azure OpenAI endpoint, e.g. https://{resource-name}.openai.azure.com (the /openai or /openai/v1 suffix is optional and stripped automatically). Provide this, the project endpoint below, or both. + """ + + project_endpoint: typing.Optional[str] = pydantic.Field(default=None) + """ + The Microsoft Foundry project endpoint, e.g. https://{resource-name}.services.ai.azure.com/api/projects/{project-name}. Provide this, the Azure OpenAI endpoint above, or both. + """ + + auth_data: MicrosoftFoundryProviderAccountAuthData = pydantic.Field() + """ + Azure authentication credentials + """ + + integrations: typing.List[MicrosoftFoundryModel] = pydantic.Field() + """ + List of integrations that are associated with this model account. Populate by fetching deployed models from Azure, then reviewing and selecting which ones to add. + """ + + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) + """ + List of users who have access to this model account + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None + discount_percent: typing.Optional[float] = pydantic.Field(default=None) + """ + Discount % applied to upstream list price for this model account. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/microsoft_foundry_provider_account_auth_data.py b/src/truefoundry_sdk/types/microsoft_foundry_provider_account_auth_data.py new file mode 100644 index 00000000..ac0de568 --- /dev/null +++ b/src/truefoundry_sdk/types/microsoft_foundry_provider_account_auth_data.py @@ -0,0 +1,12 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .azure_certificate_auth import AzureCertificateAuth +from .azure_client_secret_auth import AzureClientSecretAuth +from .azure_key_auth import AzureKeyAuth +from .azure_workload_identity_auth import AzureWorkloadIdentityAuth + +MicrosoftFoundryProviderAccountAuthData = typing.Union[ + AzureKeyAuth, AzureCertificateAuth, AzureClientSecretAuth, AzureWorkloadIdentityAuth +] diff --git a/src/truefoundry_sdk/types/ml_repo_manifest.py b/src/truefoundry_sdk/types/ml_repo_manifest.py index a97fb48c..6b4c577b 100644 --- a/src/truefoundry_sdk/types/ml_repo_manifest.py +++ b/src/truefoundry_sdk/types/ml_repo_manifest.py @@ -35,7 +35,7 @@ class MlRepoManifest(UniversalBaseModel): Storage Integration to store artifacts and models. A storage integration represents a connected blob storage like AWS S3 / Azure Blob Storage / Google Cloud Storage. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to MLRepo """ diff --git a/src/truefoundry_sdk/types/model_provider_account.py b/src/truefoundry_sdk/types/model_provider_account.py index a0c97129..3d8f1f36 100644 --- a/src/truefoundry_sdk/types/model_provider_account.py +++ b/src/truefoundry_sdk/types/model_provider_account.py @@ -23,6 +23,7 @@ from .google_gemini_provider_account import GoogleGeminiProviderAccount from .google_vertex_provider_account import GoogleVertexProviderAccount from .groq_provider_account import GroqProviderAccount +from .microsoft_foundry_provider_account import MicrosoftFoundryProviderAccount from .mistral_ai_provider_account import MistralAiProviderAccount from .nomic_provider_account import NomicProviderAccount from .ollama_provider_account import OllamaProviderAccount @@ -45,6 +46,7 @@ GoogleGeminiProviderAccount, AzureOpenAiProviderAccount, AzureFoundryProviderAccount, + MicrosoftFoundryProviderAccount, CohereProviderAccount, Ai21ProviderAccount, AnthropicProviderAccount, diff --git a/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py index 3ad3df9e..41522e28 100644 --- a/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/noma_security_guardrail_config_config.py @@ -19,12 +19,12 @@ class NomaSecurityGuardrailConfigConfig(UniversalBaseModel): application_id: typing.Optional[str] = pydantic.Field(default=None) """ - Literal applicationId sent as config.config.applicationId and used to select the Noma Runtime Protection profile. Defaults to truefoundry. + Literal applicationId sent in the x-noma-context header and used to select the Noma Runtime Protection profile. Defaults to truefoundry. """ - user_id_metadata_key: typing.Optional[str] = pydantic.Field(default=None) + session_id: typing.Optional[str] = pydantic.Field(default=None) """ - Fallback subjectId sent in context.user when no authenticated runtime subject is available. Defaults to gateway. + Literal sessionId sent in the x-noma-context header for session attribution in Noma. Optional. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py index ecc7228d..022a3853 100644 --- a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py +++ b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py @@ -57,7 +57,7 @@ class OpenApimcpServerManifest(UniversalBaseModel): """ auth_data: typing.Optional[McpServerAuth] = None - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to this OpenAPI Server """ diff --git a/src/truefoundry_sdk/types/otel_metrics_exporter_common_config.py b/src/truefoundry_sdk/types/otel_metrics_exporter_common_config.py new file mode 100644 index 00000000..a126df27 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_metrics_exporter_common_config.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class OtelMetricsExporterCommonConfig(UniversalBaseModel): + """ + Common fields shared by HTTP and gRPC metrics exporter configs + """ + + export_delta_metrics: typing.Optional[bool] = pydantic.Field(default=None) + """ + Export counters and histograms with delta temporality instead of cumulative. Enable this for backends such as Datadog that expect delta-encoded metrics. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py b/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py index b6278902..54eda3ab 100644 --- a/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py +++ b/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py @@ -5,9 +5,10 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from .otel_exporter_grpc_config_base import OtelExporterGrpcConfigBase +from .otel_metrics_exporter_common_config import OtelMetricsExporterCommonConfig -class OtelMetricsExporterGrpcConfig(OtelExporterGrpcConfigBase): +class OtelMetricsExporterGrpcConfig(OtelExporterGrpcConfigBase, OtelMetricsExporterCommonConfig): """ gRPC Configuration """ diff --git a/src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py b/src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py index a1660a10..cb47fdf9 100644 --- a/src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py +++ b/src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py @@ -5,9 +5,10 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from .otel_exporter_http_config_base import OtelExporterHttpConfigBase +from .otel_metrics_exporter_common_config import OtelMetricsExporterCommonConfig -class OtelMetricsExporterHttpConfig(OtelExporterHttpConfigBase): +class OtelMetricsExporterHttpConfig(OtelExporterHttpConfigBase, OtelMetricsExporterCommonConfig): """ HTTP Configuration """ diff --git a/src/truefoundry_sdk/types/permission_set_v2resource_type.py b/src/truefoundry_sdk/types/permission_set_v2resource_type.py index a71c7163..67733a59 100644 --- a/src/truefoundry_sdk/types/permission_set_v2resource_type.py +++ b/src/truefoundry_sdk/types/permission_set_v2resource_type.py @@ -45,8 +45,6 @@ class PermissionSetV2ResourceType(enum.StrEnum): AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" - SSO_BASED_IDENTITY = "sso-based-identity" - EXTERNAL_IDENTITY = "external-identity" MCP_SERVER = "mcp-server" EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" AGENT_IDENTITY = "agent-identity" @@ -100,8 +98,6 @@ def visit( agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], - sso_based_identity: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], mcp_server: typing.Callable[[], T_Result], external_identity_provider: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], @@ -181,10 +177,6 @@ def visit( return gateway_installation() if self is PermissionSetV2ResourceType.VIRTUAL_ACCOUNT: return virtual_account() - if self is PermissionSetV2ResourceType.SSO_BASED_IDENTITY: - return sso_based_identity() - if self is PermissionSetV2ResourceType.EXTERNAL_IDENTITY: - return external_identity() if self is PermissionSetV2ResourceType.MCP_SERVER: return mcp_server() if self is PermissionSetV2ResourceType.EXTERNAL_IDENTITY_PROVIDER: diff --git a/src/truefoundry_sdk/types/policy_entity_types.py b/src/truefoundry_sdk/types/policy_entity_types.py index 9c7f7607..b8b92797 100644 --- a/src/truefoundry_sdk/types/policy_entity_types.py +++ b/src/truefoundry_sdk/types/policy_entity_types.py @@ -16,6 +16,7 @@ class PolicyEntityTypes(enum.StrEnum): WORKFLOW = "workflow" HELM = "helm" VOLUME = "volume" + SPARK_JOB = "spark-job" _UNKNOWN = "__POLICYENTITYTYPES_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -37,6 +38,7 @@ def visit( workflow: typing.Callable[[], T_Result], helm: typing.Callable[[], T_Result], volume: typing.Callable[[], T_Result], + spark_job: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is PolicyEntityTypes.SERVICE: @@ -55,4 +57,6 @@ def visit( return helm() if self is PolicyEntityTypes.VOLUME: return volume() + if self is PolicyEntityTypes.SPARK_JOB: + return spark_job() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/preset_regex_pattern_enum.py b/src/truefoundry_sdk/types/preset_regex_pattern_enum.py index 669df98a..c10d0395 100644 --- a/src/truefoundry_sdk/types/preset_regex_pattern_enum.py +++ b/src/truefoundry_sdk/types/preset_regex_pattern_enum.py @@ -12,6 +12,8 @@ class PresetRegexPatternEnum(enum.StrEnum): US_SSN_NO_DASH = "us_ssn_no_dash" EMAIL = "email" US_PHONE = "us_phone" + INDIA_AADHAAR = "india_aadhaar" + INDIA_PAN = "india_pan" VISA = "visa" MASTERCARD = "mastercard" AMEX = "amex" @@ -68,6 +70,8 @@ def visit( us_ssn_no_dash: typing.Callable[[], T_Result], email: typing.Callable[[], T_Result], us_phone: typing.Callable[[], T_Result], + india_aadhaar: typing.Callable[[], T_Result], + india_pan: typing.Callable[[], T_Result], visa: typing.Callable[[], T_Result], mastercard: typing.Callable[[], T_Result], amex: typing.Callable[[], T_Result], @@ -117,6 +121,10 @@ def visit( return email() if self is PresetRegexPatternEnum.US_PHONE: return us_phone() + if self is PresetRegexPatternEnum.INDIA_AADHAAR: + return india_aadhaar() + if self is PresetRegexPatternEnum.INDIA_PAN: + return india_pan() if self is PresetRegexPatternEnum.VISA: return visa() if self is PresetRegexPatternEnum.MASTERCARD: diff --git a/src/truefoundry_sdk/types/provider_account_provider.py b/src/truefoundry_sdk/types/provider_account_provider.py index 1f8686a2..4d8f86b3 100644 --- a/src/truefoundry_sdk/types/provider_account_provider.py +++ b/src/truefoundry_sdk/types/provider_account_provider.py @@ -41,6 +41,7 @@ class ProviderAccountProvider(enum.StrEnum): GOOGLE_GEMINI = "google-gemini" AZURE_OPENAI = "azure-openai" AZURE_FOUNDRY = "azure-foundry" + MICROSOFT_FOUNDRY = "microsoft-foundry" SELF_HOSTED_MODEL = "self-hosted-model" MCP_SERVER_GROUP = "mcp-server-group" PAGERDUTY = "pagerduty" @@ -111,6 +112,7 @@ def visit( google_gemini: typing.Callable[[], T_Result], azure_openai: typing.Callable[[], T_Result], azure_foundry: typing.Callable[[], T_Result], + microsoft_foundry: typing.Callable[[], T_Result], self_hosted_model: typing.Callable[[], T_Result], mcp_server_group: typing.Callable[[], T_Result], pagerduty: typing.Callable[[], T_Result], @@ -203,6 +205,8 @@ def visit( return azure_openai() if self is ProviderAccountProvider.AZURE_FOUNDRY: return azure_foundry() + if self is ProviderAccountProvider.MICROSOFT_FOUNDRY: + return microsoft_foundry() if self is ProviderAccountProvider.SELF_HOSTED_MODEL: return self_hosted_model() if self is ProviderAccountProvider.MCP_SERVER_GROUP: diff --git a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py index 01a5f3eb..7cc06bea 100644 --- a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py @@ -9,6 +9,8 @@ from .collaborator import Collaborator from .custom_tls_settings import CustomTlsSettings from .mcp_server_auth import McpServerAuth +from .mcp_tool_metadata import McpToolMetadata +from .mcp_tool_policy import McpToolPolicy from .mcp_tool_setting import McpToolSetting from .owned_by import OwnedBy @@ -49,8 +51,14 @@ class RemoteMcpServerManifest(UniversalBaseModel): Customize tool descriptions or enable/disable specific tools from the MCP Server. """ + tool_policy: typing.Optional[McpToolPolicy] = None + tool_metadata: typing.Optional[typing.Dict[str, McpToolMetadata]] = pydantic.Field(default=None) + """ + Per-tool description and annotation overrides keyed by tool name. + """ + auth_data: typing.Optional[McpServerAuth] = None - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to this MCP Server """ diff --git a/src/truefoundry_sdk/types/role_binding_manifest.py b/src/truefoundry_sdk/types/role_binding_manifest.py index e6ae232e..53f3d6b3 100644 --- a/src/truefoundry_sdk/types/role_binding_manifest.py +++ b/src/truefoundry_sdk/types/role_binding_manifest.py @@ -21,7 +21,7 @@ class RoleBindingManifest(UniversalBaseModel): subjects: typing.List[RoleBindingSubject] = pydantic.Field() """ - One row per principal; set type and name (email, team name, virtual account name, or external identity name). + One row per principal; set type and name (email, team name, virtual account name, agent name, or external identity name). """ permissions: typing.List[RoleBindingPermission] = pydantic.Field() diff --git a/src/truefoundry_sdk/types/role_binding_subject.py b/src/truefoundry_sdk/types/role_binding_subject.py index 4939ef3b..fe74f5af 100644 --- a/src/truefoundry_sdk/types/role_binding_subject.py +++ b/src/truefoundry_sdk/types/role_binding_subject.py @@ -15,12 +15,12 @@ class RoleBindingSubject(UniversalBaseModel): type: RoleBindingSubjectType = pydantic.Field() """ - Whether this row identifies a user (email), a team (name), or a virtual account (name). + Whether this row identifies a user (email), a team (name), a virtual account (name), or an agent (name). """ name: str = pydantic.Field() """ - User email when type is user; team or virtual account name when type is team or virtualaccount. + User email when type is user; team, virtual account, or agent name otherwise. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/role_binding_subject_type.py b/src/truefoundry_sdk/types/role_binding_subject_type.py index 8893dd46..7675524f 100644 --- a/src/truefoundry_sdk/types/role_binding_subject_type.py +++ b/src/truefoundry_sdk/types/role_binding_subject_type.py @@ -9,12 +9,13 @@ class RoleBindingSubjectType(enum.StrEnum): """ - Whether this row identifies a user (email), a team (name), or a virtual account (name). + Whether this row identifies a user (email), a team (name), a virtual account (name), or an agent (name). """ USER = "user" TEAM = "team" VIRTUALACCOUNT = "virtualaccount" + AGENT = "agent" _UNKNOWN = "__ROLEBINDINGSUBJECTTYPE_UNKNOWN__" """ This member is used for forward compatibility. If the value is not recognized by the enum, it will be stored here, and the raw value is accessible through `.value`. @@ -31,6 +32,7 @@ def visit( user: typing.Callable[[], T_Result], team: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is RoleBindingSubjectType.USER: @@ -39,4 +41,6 @@ def visit( return team() if self is RoleBindingSubjectType.VIRTUALACCOUNT: return virtualaccount() + if self is RoleBindingSubjectType.AGENT: + return agent() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/role_resource_type.py b/src/truefoundry_sdk/types/role_resource_type.py index dfe365e3..0b2ec358 100644 --- a/src/truefoundry_sdk/types/role_resource_type.py +++ b/src/truefoundry_sdk/types/role_resource_type.py @@ -49,8 +49,6 @@ class RoleResourceType(enum.StrEnum): AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" - SSO_BASED_IDENTITY = "sso-based-identity" - EXTERNAL_IDENTITY = "external-identity" MCP_SERVER = "mcp-server" EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" AGENT_IDENTITY = "agent-identity" @@ -104,8 +102,6 @@ def visit( agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], - sso_based_identity: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], mcp_server: typing.Callable[[], T_Result], external_identity_provider: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], @@ -185,10 +181,6 @@ def visit( return gateway_installation() if self is RoleResourceType.VIRTUAL_ACCOUNT: return virtual_account() - if self is RoleResourceType.SSO_BASED_IDENTITY: - return sso_based_identity() - if self is RoleResourceType.EXTERNAL_IDENTITY: - return external_identity() if self is RoleResourceType.MCP_SERVER: return mcp_server() if self is RoleResourceType.EXTERNAL_IDENTITY_PROVIDER: diff --git a/src/truefoundry_sdk/types/role_with_resource_resource_type.py b/src/truefoundry_sdk/types/role_with_resource_resource_type.py index 876ff3de..3803179e 100644 --- a/src/truefoundry_sdk/types/role_with_resource_resource_type.py +++ b/src/truefoundry_sdk/types/role_with_resource_resource_type.py @@ -45,8 +45,6 @@ class RoleWithResourceResourceType(enum.StrEnum): AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" - SSO_BASED_IDENTITY = "sso-based-identity" - EXTERNAL_IDENTITY = "external-identity" MCP_SERVER = "mcp-server" EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" AGENT_IDENTITY = "agent-identity" @@ -100,8 +98,6 @@ def visit( agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], - sso_based_identity: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], mcp_server: typing.Callable[[], T_Result], external_identity_provider: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], @@ -181,10 +177,6 @@ def visit( return gateway_installation() if self is RoleWithResourceResourceType.VIRTUAL_ACCOUNT: return virtual_account() - if self is RoleWithResourceResourceType.SSO_BASED_IDENTITY: - return sso_based_identity() - if self is RoleWithResourceResourceType.EXTERNAL_IDENTITY: - return external_identity() if self is RoleWithResourceResourceType.MCP_SERVER: return mcp_server() if self is RoleWithResourceResourceType.EXTERNAL_IDENTITY_PROVIDER: diff --git a/src/truefoundry_sdk/types/secret_group_manifest.py b/src/truefoundry_sdk/types/secret_group_manifest.py index d26636c5..5779df0e 100644 --- a/src/truefoundry_sdk/types/secret_group_manifest.py +++ b/src/truefoundry_sdk/types/secret_group_manifest.py @@ -26,7 +26,7 @@ class SecretGroupManifest(UniversalBaseModel): Secret Store to be associated with the secret group """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to Secret Group """ diff --git a/src/truefoundry_sdk/types/secret_store_config.py b/src/truefoundry_sdk/types/secret_store_config.py index bdb39c57..df4c6def 100644 --- a/src/truefoundry_sdk/types/secret_store_config.py +++ b/src/truefoundry_sdk/types/secret_store_config.py @@ -2,29 +2,7 @@ import typing -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .secret_store_integration_config import SecretStoreIntegrationConfig +from .tfy_secrets_config import TfySecretsConfig - -class SecretStoreConfig(UniversalBaseModel): - """ - Enable to store the virtual account token in a secret store - """ - - integration_fqn: str = pydantic.Field() - """ - The secret store to store the virtual account token in - """ - - secret_path: str = pydantic.Field() - """ - The path where the virtual account token will be stored in the secret store (example: secret/path/to/virtual-account-token) - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 - else: - - class Config: - smart_union = True - extra = pydantic.Extra.allow +SecretStoreConfig = typing.Union[SecretStoreIntegrationConfig, TfySecretsConfig] diff --git a/src/truefoundry_sdk/types/secret_store_integration_config.py b/src/truefoundry_sdk/types/secret_store_integration_config.py new file mode 100644 index 00000000..1e8be309 --- /dev/null +++ b/src/truefoundry_sdk/types/secret_store_integration_config.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class SecretStoreIntegrationConfig(UniversalBaseModel): + """ + Store the virtual account token directly in an external secret store + """ + + type: typing.Literal["secret-store"] = pydantic.Field(default="secret-store") + """ + +value=secret-store + """ + + integration_fqn: str = pydantic.Field() + """ + The secret store to store the virtual account token in + """ + + secret_path: str = pydantic.Field() + """ + The path where the virtual account token will be stored in the secret store (example: secret/path/to/virtual-account-token) + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/spark_job.py b/src/truefoundry_sdk/types/spark_job.py index 0710a91b..c15ff813 100644 --- a/src/truefoundry_sdk/types/spark_job.py +++ b/src/truefoundry_sdk/types/spark_job.py @@ -4,9 +4,9 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .spark_driver_config import SparkDriverConfig -from .spark_executor_config import SparkExecutorConfig +from .spark_job_driver_config import SparkJobDriverConfig from .spark_job_entrypoint import SparkJobEntrypoint +from .spark_job_executor_config import SparkJobExecutorConfig from .spark_job_image import SparkJobImage from .spark_job_trigger import SparkJobTrigger from .volume_mount import VolumeMount @@ -39,8 +39,8 @@ class SparkJob(UniversalBaseModel): Specify the trigger """ - driver_config: SparkDriverConfig - executor_config: SparkExecutorConfig + driver_config: SparkJobDriverConfig + executor_config: SparkJobExecutorConfig env: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ Configure environment variables to be injected in the service either as plain text. [Docs](https://docs.truefoundry.com/docs/env-variables) diff --git a/src/truefoundry_sdk/types/spark_job_driver_config.py b/src/truefoundry_sdk/types/spark_job_driver_config.py new file mode 100644 index 00000000..38470890 --- /dev/null +++ b/src/truefoundry_sdk/types/spark_job_driver_config.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from .spark_driver_config import SparkDriverConfig + + +class SparkJobDriverConfig(SparkDriverConfig): + """ + Driver Config + """ + + kustomize: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Patch driver pod spec fields like tolerations, nodeSelector, affinity, etc. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/spark_job_executor_config.py b/src/truefoundry_sdk/types/spark_job_executor_config.py new file mode 100644 index 00000000..ece8c18a --- /dev/null +++ b/src/truefoundry_sdk/types/spark_job_executor_config.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from .spark_executor_config import SparkExecutorConfig + + +class SparkJobExecutorConfig(SparkExecutorConfig): + """ + Executor Config + """ + + kustomize: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Patch executor pod spec fields like tolerations, nodeSelector, affinity, etc. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py index 73422f1f..5459a127 100644 --- a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py @@ -8,6 +8,8 @@ from ..core.serialization import FieldMetadata from .collaborator import Collaborator from .mcp_server_env_auth import McpServerEnvAuth +from .mcp_tool_metadata import McpToolMetadata +from .mcp_tool_policy import McpToolPolicy from .mcp_tool_setting import McpToolSetting from .owned_by import OwnedBy @@ -32,7 +34,7 @@ class StdioMcpServerManifest(UniversalBaseModel): Provide a brief description of the purpose of this MCP Server. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to this MCP Server """ @@ -58,6 +60,12 @@ class StdioMcpServerManifest(UniversalBaseModel): Customize tool descriptions or enable/disable specific tools from the MCP Server. """ + tool_policy: typing.Optional[McpToolPolicy] = None + tool_metadata: typing.Optional[typing.Dict[str, McpToolMetadata]] = pydantic.Field(default=None) + """ + Per-tool description and annotation overrides keyed by tool name. + """ + auth_data: typing.Optional[McpServerEnvAuth] = None owned_by: typing_extensions.Annotated[ typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") diff --git a/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py b/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py index 19d411a5..54972dff 100644 --- a/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py +++ b/src/truefoundry_sdk/types/sync_token_in_secret_store_info.py @@ -18,6 +18,17 @@ class SyncTokenInSecretStoreInfo(UniversalBaseModel): ISO timestamp of when the token was synced """ + jwt_id: typing_extensions.Annotated[ + str, + FieldMetadata(alias="jwtId"), + pydantic.Field( + alias="jwtId", description="JWT id of the token that was last successfully written to the secret store" + ), + ] + """ + JWT id of the token that was last successfully written to the secret store + """ + error: typing.Optional[str] = pydantic.Field(default=None) """ Error message if sync failed diff --git a/src/truefoundry_sdk/types/team_data_access_rule.py b/src/truefoundry_sdk/types/team_data_access_rule.py index fae42ca9..d98b0318 100644 --- a/src/truefoundry_sdk/types/team_data_access_rule.py +++ b/src/truefoundry_sdk/types/team_data_access_rule.py @@ -14,7 +14,7 @@ class TeamDataAccessRule(DataAccessRuleBase): scope: typing.Literal["team_data"] = pydantic.Field(default="team_data") """ - Data access scope - access to team data including owned virtual accounts + Data access scope - access to data created by teammates and by virtual accounts owned by the team """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/team_virtual_account_data_access_rule.py b/src/truefoundry_sdk/types/team_virtual_account_data_access_rule.py new file mode 100644 index 00000000..127ecacd --- /dev/null +++ b/src/truefoundry_sdk/types/team_virtual_account_data_access_rule.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from .data_access_rule_base import DataAccessRuleBase + + +class TeamVirtualAccountDataAccessRule(DataAccessRuleBase): + """ + Team Applications Data + """ + + scope: typing.Literal["team_virtual_account_data"] = pydantic.Field(default="team_virtual_account_data") + """ + Data access scope - access only to data created by virtual accounts owned by the team + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py b/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py index 8b62644d..2fa2775a 100644 --- a/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/tfy_managed_mcp_server_manifest.py @@ -7,6 +7,8 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata from .collaborator import Collaborator +from .mcp_tool_metadata import McpToolMetadata +from .mcp_tool_policy import McpToolPolicy from .mcp_tool_setting import McpToolSetting from .owned_by import OwnedBy from .tfy_managed_mcp_server_o_auth import TfyManagedMcpServerOAuth @@ -47,7 +49,13 @@ class TfyManagedMcpServerManifest(UniversalBaseModel): Customize tool descriptions or enable/disable specific tools from the MCP Server. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + tool_policy: typing.Optional[McpToolPolicy] = None + tool_metadata: typing.Optional[typing.Dict[str, McpToolMetadata]] = pydantic.Field(default=None) + """ + Per-tool description and annotation overrides keyed by tool name. + """ + + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to this MCP Server """ diff --git a/src/truefoundry_sdk/types/tfy_secrets_config.py b/src/truefoundry_sdk/types/tfy_secrets_config.py new file mode 100644 index 00000000..44cbf8d0 --- /dev/null +++ b/src/truefoundry_sdk/types/tfy_secrets_config.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TfySecretsConfig(UniversalBaseModel): + """ + Store the virtual account token as a secret in a TrueFoundry secret group + """ + + type: typing.Literal["tfy-secrets"] = pydantic.Field(default="tfy-secrets") + """ + +value=tfy-secrets + """ + + secret_group: str = pydantic.Field() + """ + Name of the secret group to store the virtual account token in + """ + + key: str = pydantic.Field() + """ + The key where the virtual account token will be stored in the secret group + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/tracing_project_manifest.py b/src/truefoundry_sdk/types/tracing_project_manifest.py index fe440331..d662aa46 100644 --- a/src/truefoundry_sdk/types/tracing_project_manifest.py +++ b/src/truefoundry_sdk/types/tracing_project_manifest.py @@ -32,7 +32,7 @@ class TracingProjectManifest(UniversalBaseModel): Description for the Tracing Project. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to Tracing Project """ diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py index eade632b..e91cebaf 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py @@ -72,7 +72,7 @@ class TrueFoundryAgentManifest(UniversalBaseModel): response_format: typing.Optional[TrueFoundryAgentResponseFormat] = None config: typing.Optional[TrueFoundryAgentConfig] = None - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ List of users who have access to this Agent """ diff --git a/src/truefoundry_sdk/types/virtual_account_manifest.py b/src/truefoundry_sdk/types/virtual_account_manifest.py index 729e8558..ebd504c3 100644 --- a/src/truefoundry_sdk/types/virtual_account_manifest.py +++ b/src/truefoundry_sdk/types/virtual_account_manifest.py @@ -26,7 +26,7 @@ class VirtualAccountManifest(UniversalBaseModel): +value=virtual-account """ - permissions: typing.List[Permissions] = pydantic.Field() + permissions: typing.Optional[typing.List[Permissions]] = pydantic.Field(default=None) """ Permissions """ diff --git a/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py index bf268add..2aaab424 100644 --- a/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py @@ -36,12 +36,17 @@ class VirtualMcpServerManifest(UniversalBaseModel): Provide a brief description of the purpose of this Virtual MCP Server. """ + best_effort_mode: typing.Optional[bool] = pydantic.Field(default=False) + """ + When enabled, the virtual MCP server continues with available source servers even if some servers fail. + """ + servers: typing.List[McpServerSource] = pydantic.Field() """ List of source MCP servers to include in this virtual server. """ - collaborators: typing.List[Collaborator] = pydantic.Field() + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) """ Users and Teams that have access to this Virtual MCP Server """ diff --git a/src/truefoundry_sdk/types/virtual_model.py b/src/truefoundry_sdk/types/virtual_model.py index 378ccf78..40aa0f22 100644 --- a/src/truefoundry_sdk/types/virtual_model.py +++ b/src/truefoundry_sdk/types/virtual_model.py @@ -33,6 +33,11 @@ class VirtualModel(UniversalBaseModel): It should be a unique identifier for the virtual model. It is used to uniquely identify the virtual model. It can be used in place of virtualGroupName/virtualModelName. """ + alias: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Alternate identifiers for the virtual model. Can be used in place of virtualGroupName/virtualModelName (same as slug). Slug takes priority if both match. + """ + routing_config: HeaderRoutingConfig if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py b/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py index 53293dd6..02e42fd6 100644 --- a/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py +++ b/src/truefoundry_sdk/users/types/update_user_roles_request_resource_type.py @@ -49,8 +49,6 @@ class UpdateUserRolesRequestResourceType(enum.StrEnum): AGENT_CHANNEL = "agent-channel" GATEWAY_INSTALLATION = "gateway-installation" VIRTUAL_ACCOUNT = "virtual-account" - SSO_BASED_IDENTITY = "sso-based-identity" - EXTERNAL_IDENTITY = "external-identity" MCP_SERVER = "mcp-server" EXTERNAL_IDENTITY_PROVIDER = "external-identity-provider" AGENT_IDENTITY = "agent-identity" @@ -104,8 +102,6 @@ def visit( agent_channel: typing.Callable[[], T_Result], gateway_installation: typing.Callable[[], T_Result], virtual_account: typing.Callable[[], T_Result], - sso_based_identity: typing.Callable[[], T_Result], - external_identity: typing.Callable[[], T_Result], mcp_server: typing.Callable[[], T_Result], external_identity_provider: typing.Callable[[], T_Result], agent_identity: typing.Callable[[], T_Result], @@ -185,10 +181,6 @@ def visit( return gateway_installation() if self is UpdateUserRolesRequestResourceType.VIRTUAL_ACCOUNT: return virtual_account() - if self is UpdateUserRolesRequestResourceType.SSO_BASED_IDENTITY: - return sso_based_identity() - if self is UpdateUserRolesRequestResourceType.EXTERNAL_IDENTITY: - return external_identity() if self is UpdateUserRolesRequestResourceType.MCP_SERVER: return mcp_server() if self is UpdateUserRolesRequestResourceType.EXTERNAL_IDENTITY_PROVIDER: diff --git a/src/truefoundry_sdk/virtual_accounts/client.py b/src/truefoundry_sdk/virtual_accounts/client.py index ffb9e293..8f10161b 100644 --- a/src/truefoundry_sdk/virtual_accounts/client.py +++ b/src/truefoundry_sdk/virtual_accounts/client.py @@ -113,7 +113,7 @@ def create_or_update( request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ - Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. + Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. Omitting `permissions` leaves the existing access untouched; an empty list is rejected. Parameters ---------- @@ -133,7 +133,7 @@ def create_or_update( Examples -------- - from truefoundry_sdk import Permissions, TrueFoundry, VirtualAccountManifest + from truefoundry_sdk import TrueFoundry, VirtualAccountManifest client = TrueFoundry( api_key="YOUR_API_KEY", @@ -142,13 +142,6 @@ def create_or_update( client.virtual_accounts.create_or_update( manifest=VirtualAccountManifest( name="name", - permissions=[ - Permissions( - resource_fqn="resource_fqn", - resource_type="resource_type", - role_id="role_id", - ) - ], ), ) """ @@ -258,16 +251,19 @@ def get_token( return _response.data def sync_to_secret_store( - self, id: str, *, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None ) -> SyncVirtualAccountTokenResponse: """ - Sync the virtual account token to the configured secret store. Returns the sync metadata including timestamp and error (if any). + Sync the virtual account token to the configured secret store. By default the write is skipped when the active jwt already matches the last successful sync (used by the rotation cron). Pass force=true to rewrite unconditionally. Returns the sync metadata including timestamp and error (if any). Parameters ---------- id : str System-generated service account ID. + force : typing.Optional[bool] + When true, rewrite the token to the secret store even if the active jwt was already synced. Defaults to false so periodic syncs stay idempotent. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -288,22 +284,22 @@ def sync_to_secret_store( id="jqfwg345gi25n5ju2yz5iz6m", ) """ - _response = self._raw_client.sync_to_secret_store(id, request_options=request_options) + _response = self._raw_client.sync_to_secret_store(id, force=force, request_options=request_options) return _response.data def regenerate_token( - self, id: str, *, grace_period_in_days: float, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, grace_period_in_minutes: float, request_options: typing.Optional[RequestOptions] = None ) -> GetTokenForVirtualAccountResponse: """ - Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. + Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. Not allowed when the virtual account has identity provider mapping configured. Parameters ---------- id : str System-generated service account ID. - grace_period_in_days : float - Grace period in days for which the old token will remain valid after regeneration + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -323,11 +319,11 @@ def regenerate_token( ) client.virtual_accounts.regenerate_token( id="jqfwg345gi25n5ju2yz5iz6m", - grace_period_in_days=30.0, + grace_period_in_minutes=30.0, ) """ _response = self._raw_client.regenerate_token( - id, grace_period_in_days=grace_period_in_days, request_options=request_options + id, grace_period_in_minutes=grace_period_in_minutes, request_options=request_options ) return _response.data @@ -471,7 +467,7 @@ async def create_or_update( request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ - Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. + Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. Omitting `permissions` leaves the existing access untouched; an empty list is rejected. Parameters ---------- @@ -493,11 +489,7 @@ async def create_or_update( -------- import asyncio - from truefoundry_sdk import ( - AsyncTrueFoundry, - Permissions, - VirtualAccountManifest, - ) + from truefoundry_sdk import AsyncTrueFoundry, VirtualAccountManifest client = AsyncTrueFoundry( api_key="YOUR_API_KEY", @@ -509,13 +501,6 @@ async def main() -> None: await client.virtual_accounts.create_or_update( manifest=VirtualAccountManifest( name="name", - permissions=[ - Permissions( - resource_fqn="resource_fqn", - resource_type="resource_type", - role_id="role_id", - ) - ], ), ) @@ -654,16 +639,19 @@ async def main() -> None: return _response.data async def sync_to_secret_store( - self, id: str, *, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None ) -> SyncVirtualAccountTokenResponse: """ - Sync the virtual account token to the configured secret store. Returns the sync metadata including timestamp and error (if any). + Sync the virtual account token to the configured secret store. By default the write is skipped when the active jwt already matches the last successful sync (used by the rotation cron). Pass force=true to rewrite unconditionally. Returns the sync metadata including timestamp and error (if any). Parameters ---------- id : str System-generated service account ID. + force : typing.Optional[bool] + When true, rewrite the token to the secret store even if the active jwt was already synced. Defaults to false so periodic syncs stay idempotent. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -692,22 +680,22 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.sync_to_secret_store(id, request_options=request_options) + _response = await self._raw_client.sync_to_secret_store(id, force=force, request_options=request_options) return _response.data async def regenerate_token( - self, id: str, *, grace_period_in_days: float, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, grace_period_in_minutes: float, request_options: typing.Optional[RequestOptions] = None ) -> GetTokenForVirtualAccountResponse: """ - Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. + Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. Not allowed when the virtual account has identity provider mapping configured. Parameters ---------- id : str System-generated service account ID. - grace_period_in_days : float - Grace period in days for which the old token will remain valid after regeneration + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -732,14 +720,14 @@ async def regenerate_token( async def main() -> None: await client.virtual_accounts.regenerate_token( id="jqfwg345gi25n5ju2yz5iz6m", - grace_period_in_days=30.0, + grace_period_in_minutes=30.0, ) asyncio.run(main()) """ _response = await self._raw_client.regenerate_token( - id, grace_period_in_days=grace_period_in_days, request_options=request_options + id, grace_period_in_minutes=grace_period_in_minutes, request_options=request_options ) return _response.data diff --git a/src/truefoundry_sdk/virtual_accounts/raw_client.py b/src/truefoundry_sdk/virtual_accounts/raw_client.py index 39b58d4a..5085685c 100644 --- a/src/truefoundry_sdk/virtual_accounts/raw_client.py +++ b/src/truefoundry_sdk/virtual_accounts/raw_client.py @@ -128,7 +128,7 @@ def create_or_update( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetVirtualAccountResponse]: """ - Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. + Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. Omitting `permissions` leaves the existing access untouched; an empty list is rejected. Parameters ---------- @@ -365,16 +365,19 @@ def get_token( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def sync_to_secret_store( - self, id: str, *, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[SyncVirtualAccountTokenResponse]: """ - Sync the virtual account token to the configured secret store. Returns the sync metadata including timestamp and error (if any). + Sync the virtual account token to the configured secret store. By default the write is skipped when the active jwt already matches the last successful sync (used by the rotation cron). Pass force=true to rewrite unconditionally. Returns the sync metadata including timestamp and error (if any). Parameters ---------- id : str System-generated service account ID. + force : typing.Optional[bool] + When true, rewrite the token to the secret store even if the active jwt was already synced. Defaults to false so periodic syncs stay idempotent. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -386,6 +389,9 @@ def sync_to_secret_store( _response = self._client_wrapper.httpx_client.request( f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/sync-to-secret-store", method="POST", + params={ + "force": force, + }, request_options=request_options, ) try: @@ -430,18 +436,18 @@ def sync_to_secret_store( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def regenerate_token( - self, id: str, *, grace_period_in_days: float, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, grace_period_in_minutes: float, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetTokenForVirtualAccountResponse]: """ - Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. + Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. Not allowed when the virtual account has identity provider mapping configured. Parameters ---------- id : str System-generated service account ID. - grace_period_in_days : float - Grace period in days for which the old token will remain valid after regeneration + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -455,7 +461,7 @@ def regenerate_token( f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", method="POST", json={ - "gracePeriodInDays": grace_period_in_days, + "gracePeriodInMinutes": grace_period_in_minutes, }, headers={ "content-type": "application/json", @@ -484,6 +490,17 @@ def regenerate_token( ), ), ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) @@ -634,7 +651,7 @@ async def create_or_update( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetVirtualAccountResponse]: """ - Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. + Create a new virtual account or update an existing one using the provided VirtualAccountManifest. Matching is by name — if the name matches an existing virtual account it is updated, otherwise a new one is created. Omitting `permissions` leaves the existing access untouched; an empty list is rejected. Parameters ---------- @@ -871,16 +888,19 @@ async def get_token( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def sync_to_secret_store( - self, id: str, *, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[SyncVirtualAccountTokenResponse]: """ - Sync the virtual account token to the configured secret store. Returns the sync metadata including timestamp and error (if any). + Sync the virtual account token to the configured secret store. By default the write is skipped when the active jwt already matches the last successful sync (used by the rotation cron). Pass force=true to rewrite unconditionally. Returns the sync metadata including timestamp and error (if any). Parameters ---------- id : str System-generated service account ID. + force : typing.Optional[bool] + When true, rewrite the token to the secret store even if the active jwt was already synced. Defaults to false so periodic syncs stay idempotent. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -892,6 +912,9 @@ async def sync_to_secret_store( _response = await self._client_wrapper.httpx_client.request( f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/sync-to-secret-store", method="POST", + params={ + "force": force, + }, request_options=request_options, ) try: @@ -936,18 +959,18 @@ async def sync_to_secret_store( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def regenerate_token( - self, id: str, *, grace_period_in_days: float, request_options: typing.Optional[RequestOptions] = None + self, id: str, *, grace_period_in_minutes: float, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetTokenForVirtualAccountResponse]: """ - Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. + Regenerate the authentication token for a virtual account. The old token remains valid for the specified grace period. Not allowed when the virtual account has identity provider mapping configured. Parameters ---------- id : str System-generated service account ID. - grace_period_in_days : float - Grace period in days for which the old token will remain valid after regeneration + grace_period_in_minutes : float + Grace period in minutes for which the old token will remain valid after regeneration request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -961,7 +984,7 @@ async def regenerate_token( f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", method="POST", json={ - "gracePeriodInDays": grace_period_in_days, + "gracePeriodInMinutes": grace_period_in_minutes, }, headers={ "content-type": "application/json", @@ -990,6 +1013,17 @@ async def regenerate_token( ), ), ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + HttpError, + parse_obj_as( + type_=HttpError, # type: ignore + object_=_response.json(), + ), + ), + ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index cb69ac0b..b18eb4df 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -11,6 +11,7 @@ HttpClient, _build_url, _should_retry, + drop_content_type_without_body, get_request_body, remove_none_from_dict, ) @@ -121,6 +122,67 @@ def test_explicit_empty_json_body_is_preserved() -> None: assert data_body2 == {} +def test_omitted_body_sends_no_content() -> None: + """A body left at the sentinel was never passed, so nothing is sent. + + This is how an endpoint whose body may be omitted stays bodyless, as opposed to + sending an empty ``{}``. An explicit ``None`` still reaches the wire as ``null``. + """ + omit = cast(Any, ...) + unrelated_request_options: RequestOptions = {"max_retries": 3} + + json_body, data_body = get_request_body(json=omit, data=None, request_options=unrelated_request_options, omit=omit) + assert json_body is None + assert data_body is None + + json_body2, data_body2 = get_request_body( + json=None, data=omit, request_options=unrelated_request_options, omit=omit + ) + assert json_body2 is None + assert data_body2 is None + + # an explicitly passed body is untouched + json_body3, _ = get_request_body(json={"hello": "world"}, data=None, request_options=None, omit=omit) + assert json_body3 == {"hello": "world"} + + +def test_optional_body_sends_no_content_when_every_property_is_omitted() -> None: + """An endpoint that inlines an omittable body sends nothing once every property is omitted. + + The body reaches the client as a dict of sentinels rather than as a single argument, so + ``optional_body`` is what tells the client that an empty result means "no body at all". + """ + omit = cast(Any, ...) + + json_body, data_body = get_request_body( + json={"amount": omit, "source": omit}, data=None, request_options=None, omit=omit, optional_body=True + ) + assert json_body is None + assert data_body is None + + # a body the API requires still goes out as `{}` + required_json_body, _ = get_request_body( + json={"amount": omit, "source": omit}, data=None, request_options=None, omit=omit + ) + assert required_json_body == {} + + # a property the caller did pass keeps the body + populated_json_body, _ = get_request_body( + json={"amount": 1, "source": omit}, data=None, request_options=None, omit=omit, optional_body=True + ) + assert populated_json_body == {"amount": 1} + + # additional body parameters keep the body, since the caller asked for them + with_additional_body_parameters, _ = get_request_body( + json={"amount": omit}, + data=None, + request_options={"additional_body_parameters": {"custom": "value"}}, + omit=omit, + optional_body=True, + ) + assert with_additional_body_parameters == {"custom": "value"} + + def test_json_body_preserves_none_values() -> None: """Test that JSON bodies preserve None values (they become JSON null).""" json_body, data_body = get_request_body( @@ -759,3 +821,33 @@ async def test_async_request_options_timeout_takes_precedence() -> None: ) await http_client.request(path="/test", method="GET", request_options={"timeout": 30, "timeout_in_seconds": 45}) assert dummy_client.last_request_kwargs["timeout"] == 30 + + +def test_drop_content_type_without_body_omits_header_for_bodyless_optional_call() -> None: + """An optional-body endpoint the caller left empty must not advertise a media type. + + `get_request_body` drops the body, but the endpoint still hands over the content type it + would have used, so a server that branches on the header would see a JSON request carrying + nothing at all. + """ + headers = {"content-type": "application/json", "authorization": "Bearer x"} + + assert drop_content_type_without_body(headers, json_body=None, data_body=None, optional_body=True) == { + "authorization": "Bearer x" + } + + +def test_drop_content_type_without_body_keeps_header_when_a_body_is_sent() -> None: + headers = {"content-type": "application/json"} + + assert ( + drop_content_type_without_body(headers, json_body={"amount": 60}, data_body=None, optional_body=True) == headers + ) + assert drop_content_type_without_body(headers, json_body=None, data_body="raw", optional_body=True) == headers + + +def test_drop_content_type_without_body_leaves_required_body_endpoints_alone() -> None: + """Without the opt-in, an endpoint keeps the header it has always sent.""" + headers = {"Content-Type": "application/json"} + + assert drop_content_type_without_body(headers, json_body=None, data_body=None, optional_body=False) == headers From 41dc0f081c438e7f798a44ac7a87c3595bc6b918 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 16:59:01 +0000 Subject: [PATCH 9/9] SDK regeneration --- .fern/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.fern/metadata.json b/.fern/metadata.json index ac819985..3857acbf 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,7 +22,7 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "82be7d4013faa5a458fe5d6ac1e5a48b69113417", + "originGitCommit": "6aac95c20353b28803962915dea2c7dea7491be0", "originGitCommitIsDirty": false, "invokedBy": "ci", "requestedVersion": "0.0.0",