From 62004793b12a97e426efa630911728fa2645a55a Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:59:45 +0000 Subject: [PATCH 1/6] SDK regeneration --- .fern/metadata.json | 5 +- README.md | 73 +- poetry.lock | 951 +++- pyproject.toml | 10 +- reference.md | 4417 ++++++++++------- requirements.txt | 2 +- src/truefoundry_sdk/__init__.py | 299 +- src/truefoundry_sdk/_default_clients.py | 32 + .../agent_skill_versions/__init__.py | 4 + .../agent_skill_versions/client.py | 353 ++ .../agent_skill_versions/raw_client.py | 444 ++ src/truefoundry_sdk/agent_skills/__init__.py | 4 + src/truefoundry_sdk/agent_skills/client.py | 450 ++ .../agent_skills/raw_client.py | 572 +++ src/truefoundry_sdk/alerts/raw_client.py | 10 + .../application_versions/raw_client.py | 28 +- src/truefoundry_sdk/applications/client.py | 4 +- .../applications/raw_client.py | 96 +- .../artifact_versions/client.py | 128 +- .../artifact_versions/raw_client.py | 212 +- src/truefoundry_sdk/artifacts/client.py | 48 +- src/truefoundry_sdk/artifacts/raw_client.py | 92 +- src/truefoundry_sdk/base_client.py | 116 +- src/truefoundry_sdk/clusters/client.py | 4 +- src/truefoundry_sdk/clusters/raw_client.py | 72 +- src/truefoundry_sdk/core/__init__.py | 31 +- src/truefoundry_sdk/core/client_wrapper.py | 11 +- src/truefoundry_sdk/core/custom_pagination.py | 152 - src/truefoundry_sdk/core/datetime_utils.py | 42 + src/truefoundry_sdk/core/http_client.py | 295 +- src/truefoundry_sdk/core/jsonable_encoder.py | 12 + src/truefoundry_sdk/core/logging.py | 107 + src/truefoundry_sdk/core/parse_error.py | 36 + .../core/pydantic_utilities.py | 96 +- .../data_directories/client.py | 204 +- .../data_directories/raw_client.py | 280 +- src/truefoundry_sdk/environments/client.py | 4 +- .../environments/raw_client.py | 48 +- src/truefoundry_sdk/events/raw_client.py | 10 + src/truefoundry_sdk/internal/__init__.py | 5 - .../internal/ai_gateway/raw_client.py | 16 +- .../internal/applications/raw_client.py | 28 +- .../internal/artifact_versions/client.py | 32 +- .../internal/artifact_versions/raw_client.py | 42 +- .../internal/build_logs/raw_client.py | 16 +- .../internal/clusters/raw_client.py | 16 +- .../internal/deployments/raw_client.py | 44 +- .../internal/docker_registries/__init__.py | 33 - .../internal/docker_registries/client.py | 20 +- .../internal/docker_registries/raw_client.py | 54 +- .../docker_registries/types/__init__.py | 38 - ...ker_registries_get_credentials_response.py | 40 - .../internal/metrics/raw_client.py | 16 +- src/truefoundry_sdk/internal/ml/client.py | 20 +- src/truefoundry_sdk/internal/ml/raw_client.py | 38 +- .../types/apply_ml_entity_request_manifest.py | 5 +- .../delete_ml_entity_request_manifest.py | 3 +- src/truefoundry_sdk/internal/raw_client.py | 16 +- .../internal/users/raw_client.py | 10 + .../internal/vcs/raw_client.py | 18 + .../internal/workflows/raw_client.py | 16 +- .../workflows_execute_workflow_response.py | 11 +- src/truefoundry_sdk/jobs/raw_client.py | 56 +- src/truefoundry_sdk/logs/raw_client.py | 10 + src/truefoundry_sdk/ml_repos/client.py | 92 +- src/truefoundry_sdk/ml_repos/raw_client.py | 130 +- src/truefoundry_sdk/model_versions/client.py | 64 +- .../model_versions/raw_client.py | 108 +- src/truefoundry_sdk/models/client.py | 48 +- src/truefoundry_sdk/models/raw_client.py | 92 +- .../personal_access_tokens/client.py | 18 +- .../personal_access_tokens/raw_client.py | 64 +- src/truefoundry_sdk/prompt_versions/client.py | 58 +- .../prompt_versions/raw_client.py | 102 +- src/truefoundry_sdk/prompts/client.py | 46 +- src/truefoundry_sdk/prompts/raw_client.py | 90 +- src/truefoundry_sdk/raw_base_client.py | 22 +- src/truefoundry_sdk/secret_groups/client.py | 26 +- .../secret_groups/raw_client.py | 84 +- src/truefoundry_sdk/secrets/client.py | 12 +- src/truefoundry_sdk/secrets/raw_client.py | 48 +- src/truefoundry_sdk/teams/client.py | 81 +- src/truefoundry_sdk/teams/raw_client.py | 180 +- src/truefoundry_sdk/traces/client.py | 4 +- src/truefoundry_sdk/traces/raw_client.py | 14 +- src/truefoundry_sdk/types/__init__.py | 294 +- src/truefoundry_sdk/types/a2a_framework.py | 30 + src/truefoundry_sdk/types/account.py | 28 +- src/truefoundry_sdk/types/account_info.py | 2 +- src/truefoundry_sdk/types/addon_component.py | 44 +- .../types/addon_component_status.py | 24 +- src/truefoundry_sdk/types/agent_framework.py | 8 + src/truefoundry_sdk/types/agent_manifest.py | 51 +- src/truefoundry_sdk/types/agent_skill.py | 12 +- .../types/agent_skill_manifest.py | 44 + .../types/agent_skill_manifest_source.py | 8 + .../types/agent_skill_source_blob_storage.py | 26 + .../types/agent_skill_source_inline.py | 26 + .../types/agent_skill_version.py | 63 + .../types/ai21provider_account.py | 6 +- .../types/akto_guardrail_config.py | 54 + ...fig.py => akto_guardrail_config_config.py} | 8 +- src/truefoundry_sdk/types/akto_token_auth.py | 30 + src/truefoundry_sdk/types/alert.py | 44 +- .../types/amqp_input_config.py | 2 +- .../types/anthropic_provider_account.py | 6 +- src/truefoundry_sdk/types/application.py | 107 +- .../types/application_debug_info.py | 42 - .../types/apply_ml_entity_response.py | 5 +- .../types/apply_ml_entity_response_data.py | 3 +- src/truefoundry_sdk/types/artifact.py | 63 +- .../types/artifact_manifest.py | 18 +- src/truefoundry_sdk/types/artifact_type.py | 4 + src/truefoundry_sdk/types/artifact_version.py | 68 +- .../types/artifacts_cache_volume.py | 2 +- .../types/async_processor_sidecar.py | 2 +- src/truefoundry_sdk/types/auto_rotate.py | 4 +- src/truefoundry_sdk/types/autoshutdown.py | 2 +- .../types/aws_bedrock_guardrail_config.py | 6 +- .../aws_bedrock_guardrail_config_auth_data.py | 5 +- .../types/aws_bedrock_provider_account.py | 6 +- .../types/aws_parameter_store.py | 5 + .../types/aws_provider_account.py | 6 +- .../types/aws_sagemaker_provider_account.py | 6 +- ...ws_sagemaker_provider_account_auth_data.py | 4 +- .../types/aws_secrets_manager.py | 5 + .../azure_content_safety_guardrail_config.py | 4 +- ..._content_safety_guardrail_config_config.py | 4 +- .../types/azure_foundry_provider_account.py | 6 +- .../types/azure_open_ai_model.py | 10 +- .../azure_open_ai_model_deployment_type.py | 18 +- .../types/azure_open_ai_model_region.py | 190 - .../types/azure_open_ai_provider_account.py | 6 +- .../types/azure_pii_guardrail_config.py | 6 +- .../azure_pii_guardrail_config_config.py | 6 +- .../azure_prompt_shield_guardrail_config.py | 4 +- ...e_prompt_shield_guardrail_config_config.py | 2 +- .../types/azure_provider_account.py | 6 +- .../types/base_artifact_version.py | 41 +- .../types/base_artifact_version_manifest.py | 3 +- src/truefoundry_sdk/types/base_autoscaling.py | 4 +- .../types/base_remote_agent.py | 44 + .../types/base_workbench_input.py | 2 +- .../types/baseten_integrations.py | 5 + src/truefoundry_sdk/types/baseten_key_auth.py | 30 + src/truefoundry_sdk/types/baseten_model.py | 48 + .../types/baseten_provider_account.py | 51 + .../types/bitbucket_provider_account.py | 6 +- src/truefoundry_sdk/types/blue_green.py | 4 +- src/truefoundry_sdk/types/budget_rule.py | 2 +- .../types/cartesia_provider_account.py | 6 +- .../types/cedar_guardrail_config.py | 4 +- .../types/cerebras_provider_account.py | 6 +- .../types/chat_prompt_manifest.py | 16 +- .../types/cloudera_provider_account.py | 6 +- src/truefoundry_sdk/types/cluster.py | 28 +- src/truefoundry_sdk/types/cluster_gateway.py | 12 +- src/truefoundry_sdk/types/cluster_manifest.py | 6 +- .../code_safety_linter_guardrail_config.py | 4 +- .../types/cohere_provider_account.py | 6 +- .../types/common_tools_settings.py | 10 +- .../create_docker_repository_response.py} | 14 +- .../types/create_multi_part_upload_request.py | 17 +- src/truefoundry_sdk/types/cron_metric.py | 2 +- .../types/custom_agent_server_auth.py | 8 + src/truefoundry_sdk/types/custom_framework.py | 25 + .../types/custom_guardrail_config.py | 6 +- .../types/custom_header_auth.py | 30 + .../types/custom_integrations.py | 2 + .../types/custom_provider_account.py | 6 +- .../types/custom_regex_pattern.py | 2 +- .../types/custom_server_header_auth.py | 27 + .../types/custom_server_passthrough.py | 25 + .../types/custom_tls_settings.py | 2 +- .../types/data_access_rule_base.py | 2 +- src/truefoundry_sdk/types/data_directory.py | 53 +- .../types/databricks_job_task_config.py | 69 + .../types/databricks_job_task_config_image.py | 8 + .../types/databricks_provider_account.py | 6 +- .../types/deepgram_provider_account.py | 6 +- .../types/deepinfra_provider_account.py | 6 +- src/truefoundry_sdk/types/deployment.py | 65 +- src/truefoundry_sdk/types/deployment_build.py | 54 +- .../types/deployment_status.py | 24 +- .../types/docker_file_build.py | 4 +- .../types/dockerhub_provider_account.py | 6 +- .../types/eleven_labs_provider_account.py | 6 +- .../types/enkrypt_ai_guardrail_config.py | 6 +- src/truefoundry_sdk/types/environment.py | 26 +- .../types/environment_color.py | 16 +- .../types/environment_manifest.py | 20 +- src/truefoundry_sdk/types/event.py | 36 +- .../types/event_involved_object.py | 12 +- .../types/exact_match_cache_config.py | 2 +- .../types/fiddler_guardrail_config.py | 4 +- src/truefoundry_sdk/types/file_info.py | 29 +- .../types/flyte_launch_plan_id.py | 6 +- .../types/flyte_launch_plan_spec.py | 6 +- .../types/flyte_task_custom_truefoundry.py | 5 +- src/truefoundry_sdk/types/flyte_task_id.py | 6 +- .../types/flyte_workflow_id.py | 6 +- src/truefoundry_sdk/types/function_schema.py | 2 +- .../types/gateway_configuration.py | 22 +- ...gateway_data_routing_config_destination.py | 2 +- .../types/gateway_otel_config.py | 10 +- ...tel_config_otel_metrics_exporter_config.py | 8 + ...otel_config_otel_traces_exporter_config.py | 6 +- .../types/gateway_request_metadata_filter.py | 6 +- src/truefoundry_sdk/types/gcp_api_key_auth.py | 9 +- .../types/gcp_provider_account.py | 6 +- .../types/generic_secret_store_integration.py | 44 + .../types/get_agent_skill_response.py | 22 + .../types/get_agent_skill_version_response.py | 22 + .../get_application_deployment_response.py | 8 +- .../types/get_application_response.py | 5 +- .../types/get_artifact_response.py | 5 +- .../types/get_artifact_version_response.py | 5 +- .../get_authenticated_vcsurl_response.py | 11 +- .../types/get_data_directory_response.py | 5 +- ...et_docker_registry_credentials_response.py | 36 + .../types/get_model_response.py | 5 +- .../types/get_model_version_response.py | 5 +- .../types/get_prompt_response.py | 5 +- .../types/get_prompt_version_response.py | 5 +- .../types/get_signed_ur_ls_request.py | 17 +- .../types/get_signed_ur_ls_response.py | 5 +- .../types/get_team_permissions_response.py | 22 + .../types/get_user_permissions_response.py | 22 + .../types/get_user_teams_response.py | 6 +- .../types/github_provider_account.py | 6 +- .../types/gitlab_provider_account.py | 6 +- .../types/google_gemini_provider_account.py | 6 +- .../google_model_armor_guardrail_config.py | 14 +- ...model_armor_guardrail_config_operation.py} | 10 +- .../types/google_vertex_provider_account.py | 6 +- src/truefoundry_sdk/types/graph.py | 10 +- .../gray_swan_cygnal_guardrail_config.py | 4 +- .../types/groq_provider_account.py | 6 +- .../types/guardrail_config_group.py | 6 +- .../types/guardrail_config_integrations.py | 6 +- .../types/hashicorp_app_role_auth.py | 35 + .../types/hashicorp_provider_account.py | 6 +- .../types/hashicorp_token_auth.py | 2 +- .../types/hashicorp_vault_integration.py | 13 +- .../hashicorp_vault_integration_auth_data.py | 8 + src/truefoundry_sdk/types/header_match.py | 2 +- src/truefoundry_sdk/types/headers_override.py | 33 + src/truefoundry_sdk/types/health_probe.py | 10 +- src/truefoundry_sdk/types/helm.py | 6 +- src/truefoundry_sdk/types/http_error.py | 10 +- src/truefoundry_sdk/types/http_probe.py | 2 +- src/truefoundry_sdk/types/i_change.py | 4 +- .../types/ingress_controller_config.py | 4 +- .../types/internal_artifact_version.py | 80 +- ...nternal_list_artifact_versions_response.py | 11 +- .../types/internal_model_version.py | 92 +- .../types/is_cluster_connected_response.py | 11 +- .../types/jfrog_provider_account.py | 6 +- src/truefoundry_sdk/types/job.py | 2 +- src/truefoundry_sdk/types/job_alert.py | 6 +- src/truefoundry_sdk/types/job_run.py | 133 +- src/truefoundry_sdk/types/json_schema.py | 11 +- src/truefoundry_sdk/types/jwt.py | 20 +- .../types/kafka_input_config.py | 4 +- .../types/kafka_output_config.py | 2 +- .../latency_based_load_balance_target.py | 9 +- .../types/legacy_agent_manifest.py | 52 + .../list_agent_skill_versions_response.py | 28 + .../types/list_agent_skills_response.py | 28 + .../list_application_deployments_response.py | 8 +- .../types/list_applications_response.py | 5 +- .../types/list_artifact_versions_response.py | 11 +- .../types/list_artifacts_response.py | 11 +- .../types/list_data_directories_response.py | 11 +- .../types/list_files_request.py | 26 +- .../types/list_files_response.py | 11 +- .../types/list_ml_repos_response.py | 11 +- .../types/list_model_versions_response.py | 11 +- .../types/list_models_response.py | 11 +- .../types/list_prompt_versions_response.py | 11 +- .../types/list_prompts_response.py | 11 +- .../types/load_balance_target.py | 9 +- src/truefoundry_sdk/types/local_source.py | 4 +- src/truefoundry_sdk/types/log.py | 11 +- src/truefoundry_sdk/types/logging_config.py | 2 +- .../types/logs_filter_query.py | 12 +- .../types/mcp_server_env_auth.py | 36 + .../types/mcp_server_env_auth_auth_level.py | 38 + .../types/mcp_server_header_auth.py | 13 +- .../mcp_server_header_auth_auth_level.py | 38 + .../types/mcp_server_manifest.py | 5 +- .../types/mcp_server_o_auth2.py | 8 +- .../types/mcp_server_o_auth2grant_type.py | 38 + .../types/mcp_server_provider_account.py | 6 +- .../types/mcp_server_with_fqn.py | 2 +- .../types/mcp_server_with_url.py | 2 +- src/truefoundry_sdk/types/mcp_tool_target.py | 31 + .../types/mcp_tools_operator.py | 21 + .../types/mcp_tools_operator_condition.py | 34 + src/truefoundry_sdk/types/metric.py | 23 +- .../types/mistral_ai_provider_account.py | 6 +- src/truefoundry_sdk/types/ml_repo_manifest.py | 6 +- src/truefoundry_sdk/types/model.py | 63 +- src/truefoundry_sdk/types/model_manifest.py | 18 +- .../types/model_provider_account.py | 2 + src/truefoundry_sdk/types/model_type.py | 4 + src/truefoundry_sdk/types/model_version.py | 80 +- .../types/multi_part_upload.py | 29 +- .../types/multi_part_upload_response.py | 5 +- .../types/nats_input_config.py | 2 +- .../types/nats_user_password_auth.py | 2 +- .../types/nomic_provider_account.py | 6 +- .../types/non_negative_float.py | 3 + src/truefoundry_sdk/types/notebook.py | 2 +- .../types/notification_target.py | 3 +- .../notification_target_for_alert_rule.py | 3 +- .../types/ollama_provider_account.py | 6 +- .../types/opa_guardrail_config.py | 4 +- .../open_ai_moderations_guardrail_config.py | 4 +- ..._ai_moderations_guardrail_config_config.py | 9 +- ...config_config_category_thresholds_value.py | 11 - .../types/open_apimcp_server_manifest.py | 6 +- .../types/open_router_provider_account.py | 6 +- .../types/openai_provider_account.py | 6 +- .../types/otel_exporter_grpc_config_base.py | 30 + .../types/otel_exporter_http_config.py | 57 - .../types/otel_exporter_http_config_base.py | 36 + ...tel_exporter_http_config_base_encoding.py} | 10 +- .../otel_metrics_exporter_grpc_config.py | 26 + .../otel_metrics_exporter_http_config.py | 26 + ... => otel_traces_exporter_common_config.py} | 23 +- .../types/otel_traces_exporter_grpc_config.py | 27 + .../types/otel_traces_exporter_http_config.py | 27 + ..._traces_exporter_span_attribute_filter.py} | 2 +- .../types/pager_duty_provider_account.py | 6 +- .../types/palm_provider_account.py | 6 +- .../palo_alto_prisma_airs_guardrail_config.py | 4 +- ...lto_prisma_airs_guardrail_config_config.py | 5 + .../types/pangea_guardrail_config.py | 6 +- .../types/patronus_guardrail_config.py | 4 +- .../types/perplexity_ai_provider_account.py | 6 +- .../types/personal_access_token_manifest.py | 6 +- src/truefoundry_sdk/types/poetry.py | 2 +- .../types/policy_entity_types.py | 4 + src/truefoundry_sdk/types/port.py | 4 +- .../priority_based_load_balance_target.py | 11 +- .../types/private_pricing_tier.py | 13 +- .../types/prometheus_alert_rule.py | 15 +- src/truefoundry_sdk/types/prompt.py | 63 +- .../types/prompt_foo_guard_type.py | 38 - src/truefoundry_sdk/types/prompt_version.py | 74 +- .../types/py_spark_task_config.py | 2 +- src/truefoundry_sdk/types/python_build.py | 2 +- .../types/quay_provider_account.py | 6 +- src/truefoundry_sdk/types/recommendation.py | 56 +- .../types/regex_guardrail_config.py | 6 +- src/truefoundry_sdk/types/remote_agent.py | 5 + .../types/remote_mcp_server_manifest.py | 6 +- src/truefoundry_sdk/types/resources.py | 12 +- ...ment.py => response_format_json_object.py} | 6 +- .../types/response_format_json_schema.py | 20 + ...response_format_json_schema_json_schema.py | 25 + .../types/response_format_text.py | 18 + src/truefoundry_sdk/types/retry_config.py | 2 +- .../types/role_binding_manifest.py | 38 + .../types/role_binding_permission.py | 37 + .../types/role_binding_subject.py | 32 + .../types/role_binding_subject_type.py | 46 + src/truefoundry_sdk/types/role_manifest.py | 24 +- .../types/role_with_resource.py | 12 +- .../types/role_with_resource_resource_type.py | 4 + src/truefoundry_sdk/types/rolling.py | 4 +- .../sagemaker_assumed_role_based_auth.py | 5 + .../types/samba_nova_provider_account.py | 6 +- src/truefoundry_sdk/types/secret.py | 40 +- .../secret_detection_guardrail_config.py | 8 +- ...ecret_detection_guardrail_config_config.py | 2 +- src/truefoundry_sdk/types/secret_group.py | 42 +- .../types/secret_group_manifest.py | 6 +- src/truefoundry_sdk/types/secret_version.py | 18 +- .../types/self_hosted_agent.py | 36 + .../self_hosted_model_provider_account.py | 6 +- .../types/semantic_cache_config.py | 2 +- src/truefoundry_sdk/types/service.py | 2 +- src/truefoundry_sdk/types/session.py | 60 +- src/truefoundry_sdk/types/signed_url.py | 11 +- .../types/slack_provider_account.py | 6 +- src/truefoundry_sdk/types/smtp_credentials.py | 4 +- .../snowflake_cortex_provider_account.py | 6 +- .../types/span_attribute_filter.py | 6 +- .../types/span_field_filter.py | 6 +- src/truefoundry_sdk/types/spark_build.py | 4 +- .../types/spark_executor_dynamic_scaling.py | 4 +- .../types/spark_executor_fixed_instances.py | 2 +- src/truefoundry_sdk/types/spark_image.py | 2 +- src/truefoundry_sdk/types/spark_job.py | 4 +- .../types/spark_job_trigger_input.py | 22 +- .../types/sql_sanitizer_guardrail_config.py | 6 +- .../sql_sanitizer_guardrail_config_config.py | 18 +- src/truefoundry_sdk/types/sqs_input_config.py | 2 +- .../types/stage_artifact_response.py | 17 +- .../types/stdio_mcp_server_manifest.py | 65 + src/truefoundry_sdk/types/sticky_routing.py | 31 + .../types/sticky_session_identifier.py | 31 + .../types/sticky_session_identifier_source.py | 38 + src/truefoundry_sdk/types/subject.py | 56 +- src/truefoundry_sdk/types/subject_clause.py | 6 +- .../types/subject_permission.py | 51 + src/truefoundry_sdk/types/subject_type.py | 4 + .../types/sync_token_in_secret_store_info.py | 10 +- .../sync_virtual_account_token_response.py | 11 +- src/truefoundry_sdk/types/target_clause.py | 13 +- .../types/task_docker_file_build.py | 3 +- .../types/task_py_spark_build.py | 10 +- .../types/task_python_build.py | 1 + src/truefoundry_sdk/types/team.py | 30 +- src/truefoundry_sdk/types/team_manifest.py | 10 +- src/truefoundry_sdk/types/team_metadata.py | 6 +- .../types/terminate_job_response.py | 11 +- ...tfy_content_moderation_guardrail_config.py | 2 +- ...tent_moderation_guardrail_config_config.py | 2 +- .../types/tfy_pii_guardrail_config.py | 6 +- .../tfy_prompt_injection_guardrail_config.py | 2 +- .../types/together_ai_provider_account.py | 6 +- src/truefoundry_sdk/types/token_pagination.py | 23 +- src/truefoundry_sdk/types/trace_span.py | 150 +- .../types/tracing_project_manifest.py | 6 +- .../types/trigger_job_run_response.py | 10 +- .../types/troj_ai_client_id_auth.py | 30 + ..._config.py => troj_ai_guardrail_config.py} | 27 +- .../types/troj_ai_guardrail_config_config.py | 26 + .../troj_ai_guardrail_config_operation.py | 39 + .../types/true_foundry_agent_manifest.py | 100 + ...rue_foundry_agent_manifest_model_params.py | 43 + ..._manifest_model_params_reasoning_effort.py | 50 + ..._foundry_agent_manifest_response_format.py | 11 + .../true_foundry_agent_manifest_sandbox.py | 22 + .../types/true_foundry_agent_mcp_server.py | 32 + ...blem.py => true_foundry_agent_mcp_tool.py} | 3 +- .../types/true_foundry_agent_user_message.py | 26 + .../types/true_foundry_agent_variable.py | 26 + .../true_foundry_apply_request_manifest.py | 2 + .../types/true_foundry_apply_response.py | 10 +- ...oundry_apply_response_existing_manifest.py | 2 + .../true_foundry_delete_request_manifest.py | 2 + .../types/true_foundry_provider_account.py | 6 +- .../types/ttl_provider_account.py | 6 +- src/truefoundry_sdk/types/ttl_registry.py | 2 +- src/truefoundry_sdk/types/upgrade_data.py | 28 +- .../types/usage_code_snippet.py | 19 +- src/truefoundry_sdk/types/user.py | 28 +- src/truefoundry_sdk/types/user_metadata.py | 64 +- src/truefoundry_sdk/types/user_resource.py | 39 +- src/truefoundry_sdk/types/user_team_info.py | 26 + src/truefoundry_sdk/types/uv.py | 2 +- src/truefoundry_sdk/types/virtual_account.py | 60 +- .../types/virtual_account_manifest.py | 10 +- .../types/virtual_mcp_server_manifest.py | 6 +- .../types/virtual_model_provider_account.py | 6 +- .../types/webhook_bearer_auth.py | 2 +- .../types/webhook_provider_account.py | 6 +- .../types/weight_based_load_balancing.py | 3 + src/truefoundry_sdk/types/worker_config.py | 2 +- src/truefoundry_sdk/types/workflow_alert.py | 4 +- src/truefoundry_sdk/types/workspace.py | 44 +- .../types/workspace_manifest.py | 6 +- .../types/xai_provider_account.py | 6 +- src/truefoundry_sdk/users/client.py | 175 +- src/truefoundry_sdk/users/raw_client.py | 323 +- .../virtual_accounts/client.py | 48 +- .../virtual_accounts/raw_client.py | 132 +- src/truefoundry_sdk/workspaces/client.py | 159 +- src/truefoundry_sdk/workspaces/raw_client.py | 217 +- tests/conftest.py | 21 + tests/test_aiohttp_autodetect.py | 116 + tests/utils/test_http_client.py | 362 ++ 476 files changed, 15038 insertions(+), 5149 deletions(-) create mode 100644 src/truefoundry_sdk/_default_clients.py create mode 100644 src/truefoundry_sdk/agent_skill_versions/__init__.py create mode 100644 src/truefoundry_sdk/agent_skill_versions/client.py create mode 100644 src/truefoundry_sdk/agent_skill_versions/raw_client.py create mode 100644 src/truefoundry_sdk/agent_skills/__init__.py create mode 100644 src/truefoundry_sdk/agent_skills/client.py create mode 100644 src/truefoundry_sdk/agent_skills/raw_client.py delete mode 100644 src/truefoundry_sdk/core/custom_pagination.py create mode 100644 src/truefoundry_sdk/core/logging.py create mode 100644 src/truefoundry_sdk/core/parse_error.py delete mode 100644 src/truefoundry_sdk/internal/docker_registries/types/__init__.py delete mode 100644 src/truefoundry_sdk/internal/docker_registries/types/docker_registries_get_credentials_response.py create mode 100644 src/truefoundry_sdk/types/a2a_framework.py create mode 100644 src/truefoundry_sdk/types/agent_framework.py create mode 100644 src/truefoundry_sdk/types/agent_skill_manifest.py create mode 100644 src/truefoundry_sdk/types/agent_skill_manifest_source.py create mode 100644 src/truefoundry_sdk/types/agent_skill_source_blob_storage.py create mode 100644 src/truefoundry_sdk/types/agent_skill_source_inline.py create mode 100644 src/truefoundry_sdk/types/agent_skill_version.py create mode 100644 src/truefoundry_sdk/types/akto_guardrail_config.py rename src/truefoundry_sdk/types/{prompt_foo_guardrail_config_config.py => akto_guardrail_config_config.py} (72%) create mode 100644 src/truefoundry_sdk/types/akto_token_auth.py delete mode 100644 src/truefoundry_sdk/types/application_debug_info.py delete mode 100644 src/truefoundry_sdk/types/azure_open_ai_model_region.py create mode 100644 src/truefoundry_sdk/types/base_remote_agent.py create mode 100644 src/truefoundry_sdk/types/baseten_integrations.py create mode 100644 src/truefoundry_sdk/types/baseten_key_auth.py create mode 100644 src/truefoundry_sdk/types/baseten_model.py create mode 100644 src/truefoundry_sdk/types/baseten_provider_account.py rename src/truefoundry_sdk/{internal/docker_registries/types/docker_registries_create_repository_response.py => types/create_docker_repository_response.py} (50%) create mode 100644 src/truefoundry_sdk/types/custom_agent_server_auth.py create mode 100644 src/truefoundry_sdk/types/custom_framework.py create mode 100644 src/truefoundry_sdk/types/custom_header_auth.py create mode 100644 src/truefoundry_sdk/types/custom_server_header_auth.py create mode 100644 src/truefoundry_sdk/types/custom_server_passthrough.py create mode 100644 src/truefoundry_sdk/types/databricks_job_task_config.py create mode 100644 src/truefoundry_sdk/types/databricks_job_task_config_image.py create mode 100644 src/truefoundry_sdk/types/gateway_otel_config_otel_metrics_exporter_config.py create mode 100644 src/truefoundry_sdk/types/generic_secret_store_integration.py create mode 100644 src/truefoundry_sdk/types/get_agent_skill_response.py create mode 100644 src/truefoundry_sdk/types/get_agent_skill_version_response.py create mode 100644 src/truefoundry_sdk/types/get_docker_registry_credentials_response.py create mode 100644 src/truefoundry_sdk/types/get_team_permissions_response.py create mode 100644 src/truefoundry_sdk/types/get_user_permissions_response.py rename src/truefoundry_sdk/types/{prompt_foo_guardrail_config_operation.py => google_model_armor_guardrail_config_operation.py} (72%) create mode 100644 src/truefoundry_sdk/types/hashicorp_app_role_auth.py create mode 100644 src/truefoundry_sdk/types/hashicorp_vault_integration_auth_data.py create mode 100644 src/truefoundry_sdk/types/headers_override.py create mode 100644 src/truefoundry_sdk/types/legacy_agent_manifest.py create mode 100644 src/truefoundry_sdk/types/list_agent_skill_versions_response.py create mode 100644 src/truefoundry_sdk/types/list_agent_skills_response.py create mode 100644 src/truefoundry_sdk/types/mcp_server_env_auth.py create mode 100644 src/truefoundry_sdk/types/mcp_server_env_auth_auth_level.py create mode 100644 src/truefoundry_sdk/types/mcp_server_header_auth_auth_level.py create mode 100644 src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py create mode 100644 src/truefoundry_sdk/types/mcp_tool_target.py create mode 100644 src/truefoundry_sdk/types/mcp_tools_operator.py create mode 100644 src/truefoundry_sdk/types/mcp_tools_operator_condition.py delete mode 100644 src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value.py create mode 100644 src/truefoundry_sdk/types/otel_exporter_grpc_config_base.py delete mode 100644 src/truefoundry_sdk/types/otel_exporter_http_config.py create mode 100644 src/truefoundry_sdk/types/otel_exporter_http_config_base.py rename src/truefoundry_sdk/types/{otel_exporter_http_config_encoding.py => otel_exporter_http_config_base_encoding.py} (77%) create mode 100644 src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py create mode 100644 src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py rename src/truefoundry_sdk/types/{otel_exporter_grpc_config.py => otel_traces_exporter_common_config.py} (61%) create mode 100644 src/truefoundry_sdk/types/otel_traces_exporter_grpc_config.py create mode 100644 src/truefoundry_sdk/types/otel_traces_exporter_http_config.py rename src/truefoundry_sdk/types/{otel_exporter_span_attribute_filter.py => otel_traces_exporter_span_attribute_filter.py} (93%) delete mode 100644 src/truefoundry_sdk/types/prompt_foo_guard_type.py create mode 100644 src/truefoundry_sdk/types/remote_agent.py rename src/truefoundry_sdk/types/{open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment.py => response_format_json_object.py} (72%) create mode 100644 src/truefoundry_sdk/types/response_format_json_schema.py create mode 100644 src/truefoundry_sdk/types/response_format_json_schema_json_schema.py create mode 100644 src/truefoundry_sdk/types/response_format_text.py create mode 100644 src/truefoundry_sdk/types/role_binding_manifest.py create mode 100644 src/truefoundry_sdk/types/role_binding_permission.py create mode 100644 src/truefoundry_sdk/types/role_binding_subject.py create mode 100644 src/truefoundry_sdk/types/role_binding_subject_type.py create mode 100644 src/truefoundry_sdk/types/sagemaker_assumed_role_based_auth.py create mode 100644 src/truefoundry_sdk/types/self_hosted_agent.py create mode 100644 src/truefoundry_sdk/types/stdio_mcp_server_manifest.py create mode 100644 src/truefoundry_sdk/types/sticky_routing.py create mode 100644 src/truefoundry_sdk/types/sticky_session_identifier.py create mode 100644 src/truefoundry_sdk/types/sticky_session_identifier_source.py create mode 100644 src/truefoundry_sdk/types/subject_permission.py create mode 100644 src/truefoundry_sdk/types/troj_ai_client_id_auth.py rename src/truefoundry_sdk/types/{prompt_foo_guardrail_config.py => troj_ai_guardrail_config.py} (56%) create mode 100644 src/truefoundry_sdk/types/troj_ai_guardrail_config_config.py create mode 100644 src/truefoundry_sdk/types/troj_ai_guardrail_config_operation.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_manifest.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params_reasoning_effort.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_manifest_response_format.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_manifest_sandbox.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py rename src/truefoundry_sdk/types/{application_problem.py => true_foundry_agent_mcp_tool.py} (86%) create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_user_message.py create mode 100644 src/truefoundry_sdk/types/true_foundry_agent_variable.py create mode 100644 src/truefoundry_sdk/types/user_team_info.py create mode 100644 tests/conftest.py create mode 100644 tests/test_aiohttp_autodetect.py diff --git a/.fern/metadata.json b/.fern/metadata.json index ab43faf5..f883100e 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "3.54.1", + "cliVersion": "4.68.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "4.54.2", + "generatorVersion": "5.3.13", "generatorConfig": { "package_name": "truefoundry_sdk", "pydantic_config": { @@ -22,5 +22,6 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, + "originGitCommit": "94e2c4c06e5c9b7c67e60377e31f8929dfd564b0", "sdkVersion": "0.0.0" } \ No newline at end of file diff --git a/README.md b/README.md index 433cba06..e67ed25c 100644 --- a/README.md +++ b/README.md @@ -42,16 +42,14 @@ Instantiate and use the client with the following: ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.applications import ( - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, -) +from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.applications.list( + +client.applications.list( limit=10, offset=0, application_id="applicationId", @@ -70,11 +68,6 @@ response = client.applications.list( lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, is_recommendation_present_and_visible=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` ## Async Client @@ -83,21 +76,18 @@ 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 -from truefoundry_sdk.applications import ( - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, -) client = AsyncTrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) async def main() -> None: - response = await client.applications.list( + await client.applications.list( limit=10, offset=0, application_id="applicationId", @@ -116,12 +106,6 @@ async def main() -> None: lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, is_recommendation_present_and_visible=True, ) - async for item in response: - yield item - - # alternatively, you can paginate page-by-page - async for page in response.iter_pages(): - yield page asyncio.run(main()) @@ -148,27 +132,37 @@ Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.users.list( + +client.applications.list( limit=10, offset=0, - query="query", - show_invalid_users=True, + application_id="applicationId", + workspace_id="workspaceId", + application_name="applicationName", + fqn="fqn", + workspace_fqn="workspaceFqn", + application_type="applicationType", + 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 -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` ```python # You can also iterate through pages and access the typed response per page -pager = client.users.list(...) +pager = client.applications.list(...) for page in pager.iter_pages(): print(page.response) # access the typed response for each page for item in page: @@ -188,11 +182,7 @@ from truefoundry_sdk import TrueFoundry client = TrueFoundry( ..., ) -response = client.applications.with_raw_response.list(...) -print(response.headers) # access the response headers -print(response.status_code) # access the response status code -print(response.data) # access the underlying object -pager = client.users.list(...) +pager = client.applications.list(...) print(pager.response) # access the typed response for the first page for item in pager: print(item) # access the underlying object(s) @@ -227,14 +217,9 @@ client.applications.list(..., request_options={ The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level. ```python - from truefoundry_sdk import TrueFoundry -client = TrueFoundry( - ..., - timeout=20.0, -) - +client = TrueFoundry(..., timeout=20.0) # Override timeout for a specific method client.applications.list(..., request_options={ diff --git a/poetry.lock b/poetry.lock index b0fdabce..9cf7cdbc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,142 @@ # This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +[[package]] +name = "aiohappyeyeballs" +version = "2.4.4" +description = "Happy Eyeballs for asyncio" +optional = true +python-versions = ">=3.8" +files = [ + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, +] + +[[package]] +name = "aiohttp" +version = "3.10.11" +description = "Async http client/server framework (asyncio)" +optional = true +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"}, + {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"}, + {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"}, + {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"}, + {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"}, + {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"}, + {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"}, + {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"}, + {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"}, + {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"}, + {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"}, + {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"}, + {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"}, + {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"}, + {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"}, + {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"}, + {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"}, + {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"}, + {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"}, + {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"}, + {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"}, + {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"}, + {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"}, + {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"}, + {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"}, + {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"}, + {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"}, + {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"}, + {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"}, + {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"}, + {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"}, + {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"}, +] + +[package.dependencies] +aiohappyeyeballs = ">=2.3.0" +aiosignal = ">=1.1.2" +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.12.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = true +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + [[package]] name = "alabaster" version = "0.7.13" @@ -73,6 +210,36 @@ files = [ astroid = ["astroid (>=2,<5)"] test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] +[[package]] +name = "async-timeout" +version = "5.0.1" +description = "Timeout context manager for asyncio programs" +optional = true +python-versions = ">=3.8" +files = [ + {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, + {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, +] + +[[package]] +name = "attrs" +version = "25.3.0" +description = "Classes Without Boilerplate" +optional = true +python-versions = ">=3.8" +files = [ + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + [[package]] name = "babel" version = "2.18.0" @@ -114,124 +281,140 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.5" +version = "3.4.7" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4167a621a9a1a986c73777dbc15d4b5eac8ac5c10393374109a343d4013ec765"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f64c6bf8f32f9133b668c7f7a7cbdbc453412bc95ecdbd157f3b1e377a92990"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:568e3c34b58422075a1b49575a6abc616d9751b4d61b23f712e12ebb78fe47b2"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:036c079aa08a6a592b82487f97c60b439428320ed1b2ea0b3912e99d30c77765"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:340810d34ef83af92148e96e3e44cb2d3f910d2bf95e5618a5c467d9f102231d"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:cd2d0f0ec9aa977a27731a3209ebbcacebebaf41f902bd453a928bfd281cf7f8"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0b362bcd27819f9c07cbf23db4e0e8cd4b44c5ecd900c2ff907b2b92274a7412"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:77be992288f720306ab4108fe5c74797de327f3248368dfc7e1a916d6ed9e5a2"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8b78d8a609a4b82c273257ee9d631ded7fac0d875bdcdccc109f3ee8328cfcb1"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ba20bdf69bd127f66d0174d6f2a93e69045e0b4036dc1ca78e091bcc765830c4"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:76a9d0de4d0eab387822e7b35d8f89367dd237c72e82ab42b9f7bf5e15ada00f"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8fff79bf5978c693c9b1a4d71e4a94fddfb5fe744eb062a318e15f4a2f63a550"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c7e84e0c0005e3bdc1a9211cd4e62c78ba80bc37b2365ef4410cd2007a9047f2"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-win32.whl", hash = "sha256:58ad8270cfa5d4bef1bc85bd387217e14ff154d6630e976c6f56f9a040757475"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:02a9d1b01c1e12c27883b0c9349e0bcd9ae92e727ff1a277207e1a262b1cbf05"}, - {file = "charset_normalizer-3.4.5-cp310-cp310-win_arm64.whl", hash = "sha256:039215608ac7b358c4da0191d10fc76868567fbf276d54c14721bdedeb6de064"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:610f72c0ee565dfb8ae1241b666119582fdbfe7c0975c175be719f940e110694"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60d68e820af339df4ae8358c7a2e7596badeb61e544438e489035f9fbf3246a5"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:10b473fc8dca1c3ad8559985794815f06ca3fc71942c969129070f2c3cdf7281"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d4eb8ac7469b2a5d64b5b8c04f84d8bf3ad340f4514b98523805cbf46e3b3923"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bcb3227c3d9aaf73eaaab1db7ccd80a8995c509ee9941e2aae060ca6e4e5d81"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:75ee9c1cce2911581a70a3c0919d8bccf5b1cbc9b0e5171400ec736b4b569497"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d1401945cb77787dbd3af2446ff2d75912327c4c3a1526ab7955ecf8600687c"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a45e504f5e1be0bd385935a8e1507c442349ca36f511a47057a71c9d1d6ea9e"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e09f671a54ce70b79a1fc1dc6da3072b7ef7251fadb894ed92d9aa8218465a5f"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d01de5e768328646e6a3fa9e562706f8f6641708c115c62588aef2b941a4f88e"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:131716d6786ad5e3dc542f5cc6f397ba3339dc0fb87f87ac30e550e8987756af"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a374cc0b88aa710e8865dc1bd6edb3743c59f27830f0293ab101e4cf3ce9f85"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d31f0d1671e1534e395f9eb84a68e0fb670e1edb1fe819a9d7f564ae3bc4e53f"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-win32.whl", hash = "sha256:cace89841c0599d736d3d74a27bc5821288bb47c5441923277afc6059d7fbcb4"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:f8102ae93c0bc863b1d41ea0f4499c20a83229f52ed870850892df555187154a"}, - {file = "charset_normalizer-3.4.5-cp311-cp311-win_arm64.whl", hash = "sha256:ed98364e1c262cf5f9363c3eca8c2df37024f52a8fa1180a3610014f26eac51c"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed97c282ee4f994ef814042423a529df9497e3c666dca19be1d4cd1129dc7ade"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0294916d6ccf2d069727d65973c3a1ca477d68708db25fd758dd28b0827cff54"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dc57a0baa3eeedd99fafaef7511b5a6ef4581494e8168ee086031744e2679467"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ed1a9a204f317ef879b32f9af507d47e49cd5e7f8e8d5d96358c98373314fc60"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad83b8f9379176c841f8865884f3514d905bcd2a9a3b210eaa446e7d2223e4d"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:a118e2e0b5ae6b0120d5efa5f866e58f2bb826067a646431da4d6a2bdae7950e"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:754f96058e61a5e22e91483f823e07df16416ce76afa4ebf306f8e1d1296d43f"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0c300cefd9b0970381a46394902cd18eaf2aa00163f999590ace991989dcd0fc"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c108f8619e504140569ee7de3f97d234f0fbae338a7f9f360455071ef9855a95"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d1028de43596a315e2720a9849ee79007ab742c06ad8b45a50db8cdb7ed4a82a"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:19092dde50335accf365cce21998a1c6dd8eafd42c7b226eb54b2747cdce2fac"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4354e401eb6dab9aed3c7b4030514328a6c748d05e1c3e19175008ca7de84fb1"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a68766a3c58fde7f9aaa22b3786276f62ab2f594efb02d0a1421b6282e852e98"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-win32.whl", hash = "sha256:1827734a5b308b65ac54e86a618de66f935a4f63a8a462ff1e19a6788d6c2262"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:728c6a963dfab66ef865f49286e45239384249672cd598576765acc2a640a636"}, - {file = "charset_normalizer-3.4.5-cp312-cp312-win_arm64.whl", hash = "sha256:75dfd1afe0b1647449e852f4fb428195a7ed0588947218f7ba929f6538487f02"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac59c15e3f1465f722607800c68713f9fbc2f672b9eb649fe831da4019ae9b23"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:165c7b21d19365464e8f70e5ce5e12524c58b48c78c1f5a57524603c1ab003f8"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:28269983f25a4da0425743d0d257a2d6921ea7d9b83599d4039486ec5b9f911d"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d27ce22ec453564770d29d03a9506d449efbb9fa13c00842262b2f6801c48cce"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:c23eb3263356d94858655b3e63f85ac5d50970c6e8febcdde7830209139cc37d"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e6302ca4ae283deb0af68d2fbf467474b8b6aedcd3dab4db187e07f94c109763"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e51ae7d81c825761d941962450f50d041db028b7278e7b08930b4541b3e45cb9"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:597d10dec876923e5c59e48dbd366e852eacb2b806029491d307daea6b917d7c"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5cffde4032a197bd3b42fd0b9509ec60fb70918d6970e4cc773f20fc9180ca67"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2da4eedcb6338e2321e831a0165759c0c620e37f8cd044a263ff67493be8ffb3"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:65a126fb4b070d05340a84fc709dd9e7c75d9b063b610ece8a60197a291d0adf"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7a80a9242963416bd81f99349d5f3fce1843c303bd404f204918b6d75a75fd6"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-win32.whl", hash = "sha256:f1d725b754e967e648046f00c4facc42d414840f5ccc670c5670f59f83693e4f"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-win_amd64.whl", hash = "sha256:e37bd100d2c5d3ba35db9c7c5ba5a9228cbcffe5c4778dc824b164e5257813d7"}, - {file = "charset_normalizer-3.4.5-cp313-cp313-win_arm64.whl", hash = "sha256:93b3b2cc5cf1b8743660ce77a4f45f3f6d1172068207c1defc779a36eea6bb36"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8197abe5ca1ffb7d91e78360f915eef5addff270f8a71c1fc5be24a56f3e4873"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2aecdb364b8a1802afdc7f9327d55dad5366bc97d8502d0f5854e50712dbc5f"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a66aa5022bf81ab4b1bebfb009db4fd68e0c6d4307a1ce5ef6a26e5878dfc9e4"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d77f97e515688bd615c1d1f795d540f32542d514242067adcb8ef532504cb9ee"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:b2d37d78297b39a9eb9eb92c0f6df98c706467282055419df141389b23f93362"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e71bbb595973622b817c042bd943c3f3667e9c9983ce3d205f973f486fec98a7"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cd966c2559f501c6fd69294d082c2934c8dd4719deb32c22961a5ac6db0df1d"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d5e52d127045d6ae01a1e821acfad2f3a1866c54d0e837828538fabe8d9d1bd6"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:30a2b1a48478c3428d047ed9690d57c23038dac838a87ad624c85c0a78ebeb39"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d8ed79b8f6372ca4254955005830fd61c1ccdd8c0fac6603e2c145c61dd95db6"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:c5af897b45fa606b12464ccbe0014bbf8c09191e0a66aab6aa9d5cf6e77e0c94"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1088345bcc93c58d8d8f3d783eca4a6e7a7752bbff26c3eee7e73c597c191c2e"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-win32.whl", hash = "sha256:ee57b926940ba00bca7ba7041e665cc956e55ef482f851b9b65acb20d867e7a2"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-win_amd64.whl", hash = "sha256:4481e6da1830c8a1cc0b746b47f603b653dadb690bcd851d039ffaefe70533aa"}, - {file = "charset_normalizer-3.4.5-cp314-cp314-win_arm64.whl", hash = "sha256:97ab7787092eb9b50fb47fa04f24c75b768a606af1bcba1957f07f128a7219e4"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e22d1059b951e7ae7c20ef6b06afd10fb95e3c41bf3c4fbc874dba113321c193"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:afca7f78067dd27c2b848f1b234623d26b87529296c6c5652168cc1954f2f3b2"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec56a2266f32bc06ed3c3e2a8f58417ce02f7e0356edc89786e52db13c593c98"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2b970382e4a36bed897c19f310f31d7d13489c11b4f468ddfba42d41cddfb918"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:573ef5814c4b7c0d59a7710aa920eaaaef383bd71626aa420fba27b5cab92e8d"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux_2_31_armv7l.whl", hash = "sha256:50bcbca6603c06a1dcc7b056ed45c37715fb5d2768feb3bcd37d2313c587a5b9"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1f2da5cbb9becfcd607757a169e38fb82aa5fd86fae6653dea716e7b613fe2cf"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fc1c64934b8faf7584924143eb9db4770bbdb16659626e1a1a4d9efbcb68d947"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:ae8b03427410731469c4033934cf473426faff3e04b69d2dfb64a4281a3719f8"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:b3e71afc578b98512bfe7bdb822dd6bc57d4b0093b4b6e5487c1e96ad4ace242"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:4b8551b6e6531e156db71193771c93bda78ffc4d1e6372517fe58ad3b91e4659"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:65b3c403a5b6b8034b655e7385de4f72b7b244869a22b32d4030b99a60593eca"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8ce11cd4d62d11166f2b441e30ace226c19a3899a7cf0796f668fba49a9fb123"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-win32.whl", hash = "sha256:66dee73039277eb35380d1b82cccc69cc82b13a66f9f4a18da32d573acf02b7c"}, - {file = "charset_normalizer-3.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:d29dd9c016f2078b43d0c357511e87eee5b05108f3dd603423cb389b89813969"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:259cd1ca995ad525f638e131dbcc2353a586564c038fc548a3fe450a91882139"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a28afb04baa55abf26df544e3e5c6534245d3daa5178bc4a8eeb48202060d0e"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ff95a9283de8a457e6b12989de3f9f5193430f375d64297d323a615ea52cbdb3"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:708c7acde173eedd4bfa4028484426ba689d2103b28588c513b9db2cd5ecde9c"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa92ec1102eaff840ccd1021478af176a831f1bccb08e526ce844b7ddda85c22"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:5fea359734b140d0d6741189fea5478c6091b54ffc69d7ce119e0a05637d8c99"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e545b51da9f9af5c67815ca0eb40676c0f016d0b0381c86f20451e35696c5f95"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:30987f4a8ed169983f93e1be8ffeea5214a779e27ed0b059835c7afe96550ad7"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:149ec69866c3d6c2fb6f758dbc014ecb09f30b35a5ca90b6a8a2d4e54e18fdfe"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:530beedcec9b6e027e7a4b6ce26eed36678aa39e17da85e6e03d7bd9e8e9d7c9"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:14498a429321de554b140013142abe7608f9d8ccc04d7baf2ad60498374aefa2"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2820a98460c83663dd8ec015d9ddfd1e4879f12e06bb7d0500f044fb477d2770"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:aa2f963b4da26daf46231d9b9e0e2c9408a751f8f0d0f44d2de56d3caf51d294"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-win32.whl", hash = "sha256:82cc7c2ad42faec8b574351f8bc2a0c049043893853317bd9bb309f5aba6cb5a"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:92263f7eca2f4af326cd20de8d16728d2602f7cfea02e790dcde9d83c365d7cc"}, - {file = "charset_normalizer-3.4.5-cp39-cp39-win_arm64.whl", hash = "sha256:014837af6fabf57121b6254fa8ade10dceabc3528b27b721a64bbc7b8b1d4eb4"}, - {file = "charset_normalizer-3.4.5-py3-none-any.whl", hash = "sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0"}, - {file = "charset_normalizer-3.4.5.tar.gz", hash = "sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644"}, + {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"}, ] [[package]] @@ -312,6 +495,107 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] +[[package]] +name = "frozenlist" +version = "1.5.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = true +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, + {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, + {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, + {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, + {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, + {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, + {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, + {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, + {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, + {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, + {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, + {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, + {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, +] + [[package]] name = "h11" version = "0.16.0" @@ -368,6 +652,21 @@ http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "httpx-aiohttp" +version = "0.1.8" +description = "Aiohttp transport for HTTPX" +optional = true +python-versions = ">=3.8" +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"}, +] + +[package.dependencies] +aiohttp = ">=3.10.0,<4" +httpx = ">=0.27.0" + [[package]] name = "idna" version = "3.11" @@ -585,6 +884,110 @@ files = [ [package.dependencies] traitlets = "*" +[[package]] +name = "multidict" +version = "6.1.0" +description = "multidict implementation" +optional = true +python-versions = ">=3.8" +files = [ + {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, + {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, + {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, + {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, + {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, + {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, + {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, + {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, + {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, + {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, + {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, + {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, + {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, + {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, + {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, + {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, + {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, + {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, + {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, + {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, + {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, + {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, + {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, + {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, + {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008"}, + {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f"}, + {file = "multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28"}, + {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b"}, + {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c"}, + {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3"}, + {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44"}, + {file = "multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2"}, + {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3"}, + {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa"}, + {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa"}, + {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4"}, + {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6"}, + {file = "multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81"}, + {file = "multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774"}, + {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392"}, + {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a"}, + {file = "multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2"}, + {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc"}, + {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478"}, + {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4"}, + {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d"}, + {file = "multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6"}, + {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2"}, + {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd"}, + {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6"}, + {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492"}, + {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd"}, + {file = "multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167"}, + {file = "multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef"}, + {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c"}, + {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1"}, + {file = "multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c"}, + {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c"}, + {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f"}, + {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875"}, + {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255"}, + {file = "multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30"}, + {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057"}, + {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657"}, + {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28"}, + {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972"}, + {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43"}, + {file = "multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada"}, + {file = "multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a"}, + {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, + {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} + [[package]] name = "mypy" version = "1.13.0" @@ -750,6 +1153,113 @@ files = [ [package.dependencies] wcwidth = "*" +[[package]] +name = "propcache" +version = "0.2.0" +description = "Accelerated property cache" +optional = true +python-versions = ">=3.8" +files = [ + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, + {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, + {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, + {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, + {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, + {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, + {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, + {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, + {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, + {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, + {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, + {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, + {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, + {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, + {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, + {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, + {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, + {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, + {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, + {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, + {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, + {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, + {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, + {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, + {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, + {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, + {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, + {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, +] + [[package]] name = "ptyprocess" version = "0.7.0" @@ -1246,58 +1756,58 @@ widechars = ["wcwidth"] [[package]] name = "tomli" -version = "2.4.0" +version = "2.4.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"}, - {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"}, - {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"}, - {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"}, - {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"}, - {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"}, - {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"}, - {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"}, - {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"}, - {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"}, - {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"}, - {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"}, - {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"}, - {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"}, - {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"}, - {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"}, - {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"}, - {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"}, - {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"}, - {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"}, - {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"}, - {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"}, - {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"}, - {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"}, - {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"}, - {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"}, - {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"}, - {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"}, - {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"}, - {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"}, - {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"}, - {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"}, - {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"}, - {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"}, - {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"}, - {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"}, - {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"}, - {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"}, - {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"}, - {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"}, - {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"}, - {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"}, - {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"}, - {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"}, - {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"}, - {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"}, - {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"}, + {file = "tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30"}, + {file = "tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a"}, + {file = "tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076"}, + {file = "tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9"}, + {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c"}, + {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc"}, + {file = "tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049"}, + {file = "tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e"}, + {file = "tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece"}, + {file = "tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a"}, + {file = "tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085"}, + {file = "tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9"}, + {file = "tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5"}, + {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585"}, + {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1"}, + {file = "tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917"}, + {file = "tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9"}, + {file = "tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257"}, + {file = "tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54"}, + {file = "tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a"}, + {file = "tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897"}, + {file = "tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f"}, + {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d"}, + {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5"}, + {file = "tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd"}, + {file = "tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36"}, + {file = "tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd"}, + {file = "tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf"}, + {file = "tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac"}, + {file = "tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662"}, + {file = "tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853"}, + {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15"}, + {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba"}, + {file = "tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6"}, + {file = "tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7"}, + {file = "tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232"}, + {file = "tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4"}, + {file = "tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c"}, + {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d"}, + {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41"}, + {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c"}, + {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f"}, + {file = "tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8"}, + {file = "tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26"}, + {file = "tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396"}, + {file = "tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe"}, + {file = "tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f"}, ] [[package]] @@ -1365,6 +1875,118 @@ files = [ {file = "wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159"}, ] +[[package]] +name = "yarl" +version = "1.15.2" +description = "Yet another URL library" +optional = true +python-versions = ">=3.8" +files = [ + {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8"}, + {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172"}, + {file = "yarl-1.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c"}, + {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50"}, + {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01"}, + {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47"}, + {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f"}, + {file = "yarl-1.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed"}, + {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec"}, + {file = "yarl-1.15.2-cp310-cp310-win32.whl", hash = "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75"}, + {file = "yarl-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2"}, + {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5"}, + {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e"}, + {file = "yarl-1.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d"}, + {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417"}, + {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b"}, + {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf"}, + {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c"}, + {file = "yarl-1.15.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931"}, + {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5"}, + {file = "yarl-1.15.2-cp311-cp311-win32.whl", hash = "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d"}, + {file = "yarl-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179"}, + {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94"}, + {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e"}, + {file = "yarl-1.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178"}, + {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c"}, + {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6"}, + {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367"}, + {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f"}, + {file = "yarl-1.15.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715"}, + {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b"}, + {file = "yarl-1.15.2-cp312-cp312-win32.whl", hash = "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8"}, + {file = "yarl-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d"}, + {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84"}, + {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33"}, + {file = "yarl-1.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2"}, + {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611"}, + {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904"}, + {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548"}, + {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b"}, + {file = "yarl-1.15.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644"}, + {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe"}, + {file = "yarl-1.15.2-cp313-cp313-win32.whl", hash = "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9"}, + {file = "yarl-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad"}, + {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16"}, + {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b"}, + {file = "yarl-1.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776"}, + {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7"}, + {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50"}, + {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f"}, + {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d"}, + {file = "yarl-1.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d"}, + {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04"}, + {file = "yarl-1.15.2-cp38-cp38-win32.whl", hash = "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea"}, + {file = "yarl-1.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9"}, + {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc"}, + {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627"}, + {file = "yarl-1.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7"}, + {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2"}, + {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980"}, + {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b"}, + {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb"}, + {file = "yarl-1.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036"}, + {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7"}, + {file = "yarl-1.15.2-cp39-cp39-win32.whl", hash = "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d"}, + {file = "yarl-1.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810"}, + {file = "yarl-1.15.2-py3-none-any.whl", hash = "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a"}, + {file = "yarl-1.15.2.tar.gz", hash = "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +propcache = ">=0.2.0" + [[package]] name = "zipp" version = "3.20.2" @@ -1384,7 +2006,10 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] +[extras] +aiohttp = ["aiohttp", "httpx-aiohttp"] + [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "467d9c9c9207b7d74127c6809b14048829f83d64d12ccd46e8eae6d2b154ad09" +content-hash = "26f2271a4fdfe59582412a00827b9823b335d3a4339ec708219804b8c645da05" diff --git a/pyproject.toml b/pyproject.toml index 299affc5..7654e02b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,9 +39,11 @@ Repository = 'https://github.com/truefoundry/truefoundry-python-sdk' [tool.poetry.dependencies] python = ">=3.8" +aiohttp = { version = ">=3.10.0,<4", optional = true} httpx = ">=0.21.2" +httpx-aiohttp = { version = "0.1.8", optional = true} pydantic = ">= 1.9.2" -pydantic-core = ">=2.18.2" +pydantic-core = ">=2.18.2,<2.44.0" typing_extensions = ">= 4.0.0" [tool.poetry.group.dev.dependencies] @@ -59,6 +61,9 @@ ruff = "==0.11.5" [tool.pytest.ini_options] testpaths = [ "tests" ] asyncio_mode = "auto" +markers = [ + "aiohttp: tests that require httpx_aiohttp to be installed", +] [tool.mypy] plugins = ["pydantic.mypy"] @@ -90,3 +95,6 @@ section-order = ["future", "standard-library", "third-party", "first-party"] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.extras] +aiohttp=["aiohttp", "httpx-aiohttp"] diff --git a/reference.md b/reference.md index 6206656f..5f024d1f 100644 --- a/reference.md +++ b/reference.md @@ -1,5 +1,5 @@ # Reference -
client.apply(...) -> AsyncHttpResponse[TrueFoundryApplyResponse] +
client.apply(...) -> TrueFoundryApplyResponse
@@ -26,14 +26,16 @@ Applies a given manifest to create or update resources of specific types, such a
```python -from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry +from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.apply( manifest=MlRepoManifest( + type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", collaborators=[ @@ -87,7 +89,7 @@ client.apply(
-
client.delete(...) -> AsyncHttpResponse[None] +
client.delete(...)
@@ -114,14 +116,16 @@ Deletes resources of specific types, such as provider-account, cluster, workspac
```python -from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry +from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.delete( manifest=MlRepoManifest( + type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", collaborators=[ @@ -168,7 +172,7 @@ client.delete(
## Internal -
client.internal.get_id_from_fqn(...) -> AsyncHttpResponse[typing.Dict[str, typing.Any]] +
client.internal.get_id_from_fqn(...) -> typing.Dict[str, typing.Any]
@@ -198,9 +202,10 @@ Get IDs associated with the FQN for various entity types, such as deployment, ap from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.get_id_from_fqn( type="type", fqn="fqn", @@ -249,7 +254,7 @@ client.internal.get_id_from_fqn(
## Users -
client.users.list(...) -> AsyncPager[User, ListUsersResponse] +
client.users.list(...) -> ListUsersResponse
@@ -279,20 +284,16 @@ List all users of tenant filtered by query and showInvalidUsers. Pagination is a from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.users.list( + +client.users.list( limit=10, offset=0, query="query", show_invalid_users=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -352,7 +353,7 @@ for page in response.iter_pages():
-
client.users.pre_register_users(...) -> AsyncHttpResponse[RegisterUsersResponse] +
client.users.pre_register_users(...) -> RegisterUsersResponse
@@ -382,9 +383,10 @@ This endpoint allows tenant administrators to register users within their tenant from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.pre_register_users( email="email", ) @@ -455,7 +457,7 @@ client.users.pre_register_users(
-
client.users.update_roles(...) -> AsyncHttpResponse[UpdateUserRolesResponse] +
client.users.update_roles(...) -> UpdateUserRolesResponse
@@ -485,12 +487,15 @@ This endpoint allows tenant administrators to update the roles of a user within from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.update_roles( email="email", - roles=["roles"], + roles=[ + "roles" + ], ) ``` @@ -515,7 +520,7 @@ client.users.update_roles(
-**roles:** `typing.Sequence[str]` — Role names for the user +**roles:** `typing.List[str]` — Role names for the user
@@ -543,7 +548,7 @@ client.users.update_roles(
-
client.users.get(...) -> AsyncHttpResponse[GetUserResponse] +
client.users.get(...) -> GetUserResponse
@@ -573,9 +578,10 @@ Get User associated with provided User id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.get( id="id", ) @@ -614,7 +620,7 @@ client.users.get(
-
client.users.delete(...) -> AsyncHttpResponse[DeleteUserResponse] +
client.users.delete(...) -> DeleteUserResponse
@@ -644,11 +650,13 @@ Delete user if they are not a collaborator in any resource and not part of any t from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.delete( id="id", + tenant_name="tenantName", ) ``` @@ -673,6 +681,14 @@ client.users.delete(
+**tenant_name:** `typing.Optional[str]` — Tenant name + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -685,7 +701,7 @@ client.users.delete(
-
client.users.invite_user(...) -> AsyncHttpResponse[InviteUserResponse] +
client.users.invite_user(...) -> InviteUserResponse
@@ -715,9 +731,10 @@ Invite a user to the tenant from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.invite_user( accept_invite_client_url="/invite-accept", email="email", @@ -765,7 +782,7 @@ client.users.invite_user(
-
client.users.deactivate(...) -> AsyncHttpResponse[DeactivateUserResponse] +
client.users.deactivate(...) -> DeactivateUserResponse
@@ -795,9 +812,10 @@ Deactivate user associated with the provided email within the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.deactivate( email="email", ) @@ -824,6 +842,14 @@ client.users.deactivate(
+**tenant_name:** `typing.Optional[str]` — Tenant name + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -836,7 +862,7 @@ client.users.deactivate(
-
client.users.activate(...) -> AsyncHttpResponse[ActivateUserResponse] +
client.users.activate(...) -> ActivateUserResponse
@@ -866,9 +892,10 @@ Activate user associated with the provided email within the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.activate( email="email", ) @@ -895,6 +922,14 @@ client.users.activate(
+**tenant_name:** `typing.Optional[str]` — Tenant name + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -907,7 +942,7 @@ client.users.activate(
-
client.users.change_password(...) -> AsyncHttpResponse[ChangePasswordResponse] +
client.users.change_password(...) -> ChangePasswordResponse
@@ -937,9 +972,10 @@ Change password for the authenticated user. Requires clientId and loginId in the from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.change_password( login_id="loginId", new_password="newPassword", @@ -996,7 +1032,7 @@ client.users.change_password(
-
client.users.get_resources(...) -> AsyncHttpResponse[GetUserResourcesResponse] +
client.users.get_resources(...) -> GetUserResourcesResponse
@@ -1026,9 +1062,10 @@ Get all resources associated with a user. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.get_resources( id="id", ) @@ -1067,7 +1104,79 @@ client.users.get_resources(
-
client.users.get_teams(...) -> AsyncHttpResponse[GetUserTeamsResponse] +
client.users.get_permissions(...) -> GetUserPermissionsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all role bindings associated with 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="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — User Id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.users.get_teams(...) -> GetUserTeamsResponse
@@ -1079,7 +1188,7 @@ client.users.get_resources(
-Get all manual teams associated with a user. +Get all teams associated with a user, including their role in each team.
@@ -1097,9 +1206,10 @@ Get all manual teams associated with a user. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.users.get_teams( id="id", ) @@ -1139,7 +1249,7 @@ client.users.get_teams(
## Teams -
client.teams.list(...) -> AsyncPager[Team, ListTeamsResponse] +
client.teams.list(...) -> ListTeamsResponse
@@ -1170,19 +1280,15 @@ from truefoundry_sdk import TrueFoundry from truefoundry_sdk.teams import TeamsListRequestType client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.teams.list( + +client.teams.list( limit=10, offset=0, type=TeamsListRequestType.TEAM, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -1234,7 +1340,7 @@ for page in response.iter_pages():
-
client.teams.create_or_update(...) -> AsyncHttpResponse[GetTeamResponse] +
client.teams.create_or_update(...) -> GetTeamResponse
@@ -1261,16 +1367,20 @@ Creates a new team or updates an existing team. It ensures that the team name is
```python -from truefoundry_sdk import TeamManifest, TrueFoundry +from truefoundry_sdk import TrueFoundry, TeamManifest client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.teams.create_or_update( manifest=TeamManifest( + type="team", name="name", - members=["members"], + members=[ + "members" + ], ), ) @@ -1316,7 +1426,7 @@ client.teams.create_or_update(
-
client.teams.get(...) -> AsyncHttpResponse[GetTeamResponse] +
client.teams.get(...) -> GetTeamResponse
@@ -1346,9 +1456,10 @@ Get Team associated with provided team id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.teams.get( id="id", ) @@ -1387,7 +1498,7 @@ client.teams.get(
-
client.teams.delete(...) -> AsyncHttpResponse[DeleteTeamResponse] +
client.teams.delete(...) -> DeleteTeamResponse
@@ -1417,9 +1528,10 @@ Deletes the Team associated with the provided Id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.teams.delete( id="id", ) @@ -1454,12 +1566,84 @@ client.teams.delete(
+ + +
+ +
client.teams.get_permissions(...) -> GetTeamPermissionsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all role bindings associated with a team. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.teams.get_permissions( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Team Id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
## PersonalAccessTokens -
client.personal_access_tokens.list(...) -> AsyncPager[VirtualAccount, ListPersonalAccessTokenResponse] +
client.personal_access_tokens.list(...) -> ListPersonalAccessTokenResponse
@@ -1489,18 +1673,15 @@ List Personal Access Tokens created by the user in the current tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.personal_access_tokens.list( + +client.personal_access_tokens.list( limit=10, offset=0, + name_search_query="nameSearchQuery", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -1532,6 +1713,14 @@ for page in response.iter_pages():
+**name_search_query:** `typing.Optional[str]` — Return personal access tokens with names that contain this string + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1544,7 +1733,7 @@ for page in response.iter_pages():
-
client.personal_access_tokens.create(...) -> AsyncHttpResponse[CreatePersonalAccessTokenResponse] +
client.personal_access_tokens.create(...) -> CreatePersonalAccessTokenResponse
@@ -1574,9 +1763,10 @@ Create Personal Access Token from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.personal_access_tokens.create( name="name", ) @@ -1631,7 +1821,7 @@ client.personal_access_tokens.create(
-
client.personal_access_tokens.revoke_all(...) -> AsyncHttpResponse[RevokeAllPersonalAccessTokenResponse] +
client.personal_access_tokens.revoke_all(...) -> RevokeAllPersonalAccessTokenResponse
@@ -1661,9 +1851,10 @@ Revoke All Personal Access Tokens for the user with the given email from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.personal_access_tokens.revoke_all( email="email", ) @@ -1702,7 +1893,7 @@ client.personal_access_tokens.revoke_all(
-
client.personal_access_tokens.delete(...) -> AsyncHttpResponse[DeletePersonalAccessTokenResponse] +
client.personal_access_tokens.delete(...) -> DeletePersonalAccessTokenResponse
@@ -1732,9 +1923,10 @@ Delete Personal Access Token associated with the provided serviceAccountId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.personal_access_tokens.delete( id="id", ) @@ -1773,7 +1965,7 @@ client.personal_access_tokens.delete(
-
client.personal_access_tokens.get(...) -> AsyncHttpResponse[GetOrCreatePersonalAccessTokenResponse] +
client.personal_access_tokens.get(...) -> GetOrCreatePersonalAccessTokenResponse
@@ -1803,9 +1995,10 @@ Get an existing Personal Access Token by name, if it doesn't exist, it will crea from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.personal_access_tokens.get( name="name", ) @@ -1845,7 +2038,7 @@ client.personal_access_tokens.get(
## VirtualAccounts -
client.virtual_accounts.list(...) -> AsyncPager[VirtualAccount, ListVirtualAccountResponse] +
client.virtual_accounts.list(...) -> ListVirtualAccountResponse
@@ -1875,19 +2068,17 @@ List virtual accounts for the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.virtual_accounts.list( + +client.virtual_accounts.list( limit=10, offset=0, name_search_query="nameSearchQuery", + is_expired=True, + filter="filter", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -1927,6 +2118,30 @@ for page in response.iter_pages():
+**owned_by_teams:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Return virtual accounts owned by these teams + +
+
+ +
+
+ +**is_expired:** `typing.Optional[bool]` — Filter virtual accounts by expiration status. true = expired, false = not expired + +
+
+ +
+
+ +**filter:** `typing.Optional[str]` — JSON string: structured filter tree (AND/OR groups, column leaves on `name`, json_map leaves on manifest.tags). + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1939,7 +2154,7 @@ for page in response.iter_pages():
-
client.virtual_accounts.create_or_update(...) -> AsyncHttpResponse[GetVirtualAccountResponse] +
client.virtual_accounts.create_or_update(...) -> GetVirtualAccountResponse
@@ -1966,15 +2181,17 @@ Creates a new virtual account or updates an existing one based on the provided m
```python -from truefoundry_sdk import Permissions, TrueFoundry, VirtualAccountManifest +from truefoundry_sdk import TrueFoundry, VirtualAccountManifest, Permissions client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.create_or_update( manifest=VirtualAccountManifest( name="name", + type="virtual-account", permissions=[ Permissions( resource_fqn="resource_fqn", @@ -2027,7 +2244,7 @@ client.virtual_accounts.create_or_update(
-
client.virtual_accounts.get(...) -> AsyncHttpResponse[GetVirtualAccountResponse] +
client.virtual_accounts.get(...) -> GetVirtualAccountResponse
@@ -2057,9 +2274,10 @@ Get virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.get( id="id", ) @@ -2098,7 +2316,7 @@ client.virtual_accounts.get(
-
client.virtual_accounts.delete(...) -> AsyncHttpResponse[DeleteVirtualAccountResponse] +
client.virtual_accounts.delete(...) -> DeleteVirtualAccountResponse
@@ -2128,9 +2346,10 @@ Delete a virtual account associated with the provided virtual account id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.delete( id="id", ) @@ -2169,7 +2388,7 @@ client.virtual_accounts.delete(
-
client.virtual_accounts.get_token(...) -> AsyncHttpResponse[GetTokenForVirtualAccountResponse] +
client.virtual_accounts.get_token(...) -> GetTokenForVirtualAccountResponse
@@ -2199,9 +2418,10 @@ Get token for a virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.get_token( id="id", ) @@ -2240,7 +2460,7 @@ client.virtual_accounts.get_token(
-
client.virtual_accounts.sync_to_secret_store(...) -> AsyncHttpResponse[SyncVirtualAccountTokenResponse] +
client.virtual_accounts.sync_to_secret_store(...) -> SyncVirtualAccountTokenResponse
@@ -2270,9 +2490,10 @@ Syncs the virtual account token to the configured secret store. Returns the upda from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.sync_to_secret_store( id="id", ) @@ -2311,7 +2532,7 @@ client.virtual_accounts.sync_to_secret_store(
-
client.virtual_accounts.regenerate_token(...) -> AsyncHttpResponse[GetTokenForVirtualAccountResponse] +
client.virtual_accounts.regenerate_token(...) -> GetTokenForVirtualAccountResponse
@@ -2341,12 +2562,13 @@ Regenerate token for a virtual account by id. The old token will remain valid fo from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.regenerate_token( id="id", - grace_period_in_days=30.0, + grace_period_in_days=30, ) ``` @@ -2391,7 +2613,7 @@ client.virtual_accounts.regenerate_token(
-
client.virtual_accounts.delete_jwt(...) -> AsyncHttpResponse[None] +
client.virtual_accounts.delete_jwt(...)
@@ -2421,9 +2643,10 @@ Delete a JWT for a virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.virtual_accounts.delete_jwt( id="id", jwt_id="jwtId", @@ -2472,7 +2695,7 @@ client.virtual_accounts.delete_jwt(
## Clusters -
client.clusters.list(...) -> AsyncPager[Cluster, ListClustersResponse] +
client.clusters.list(...) -> ListClustersResponse
@@ -2502,18 +2725,14 @@ Retrieves a list of all latest Clusters. Pagination is available based on query from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.clusters.list( + +client.clusters.list( limit=10, offset=0, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -2557,7 +2776,7 @@ for page in response.iter_pages():
-
client.clusters.create_or_update(...) -> AsyncHttpResponse[GetClusterResponse] +
client.clusters.create_or_update(...) -> GetClusterResponse
@@ -2584,22 +2803,21 @@ Create or Update cluster with provided manifest
```python -from truefoundry_sdk import ( - ClusterManifest, - ClusterManifestClusterType, - Collaborator, - TrueFoundry, -) +from truefoundry_sdk import TrueFoundry, ClusterManifest, ClusterManifestClusterType, Collaborator client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.clusters.create_or_update( manifest=ClusterManifest( + type="cluster", name="name", cluster_type=ClusterManifestClusterType.AWS_EKS, - environment_names=["environment_names"], + environment_names=[ + "environment_names" + ], collaborators=[ Collaborator( subject="subject", @@ -2651,7 +2869,7 @@ client.clusters.create_or_update(
-
client.clusters.get(...) -> AsyncHttpResponse[GetClusterResponse] +
client.clusters.get(...) -> GetClusterResponse
@@ -2681,9 +2899,10 @@ Get cluster associated with provided id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.clusters.get( id="id", ) @@ -2722,7 +2941,7 @@ client.clusters.get(
-
client.clusters.delete(...) -> AsyncHttpResponse[ClustersDeleteResponse] +
client.clusters.delete(...) -> ClustersDeleteResponse
@@ -2752,9 +2971,10 @@ Delete cluster associated with provided cluster id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.clusters.delete( id="id", ) @@ -2793,7 +3013,7 @@ client.clusters.delete(
-
client.clusters.get_addons(...) -> AsyncHttpResponse[ListClusterAddonsResponse] +
client.clusters.get_addons(...) -> ListClusterAddonsResponse
@@ -2823,9 +3043,10 @@ List addons for the provided cluster. Pagination is available based on query par from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.clusters.get_addons( id="id", limit=10, @@ -2882,7 +3103,7 @@ client.clusters.get_addons(
-
client.clusters.is_connected(...) -> AsyncHttpResponse[IsClusterConnectedResponse] +
client.clusters.is_connected(...) -> IsClusterConnectedResponse
@@ -2912,9 +3133,10 @@ Get the status of provided cluster from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.clusters.is_connected( id="id", ) @@ -2953,8 +3175,8 @@ client.clusters.is_connected(
-## Environments -
client.environments.list(...) -> AsyncPager[Environment, ListEnvironmentsResponse] +## Applications +
client.applications.list(...) -> ListApplicationsResponse
@@ -2966,7 +3188,7 @@ client.clusters.is_connected(
-List environments, if no environments are found, default environments are created and returned. Pagination is available based on query parameters +Retrieves a list of all latest applications. Supports filtering by application ID, name, type, and other parameters. Pagination is available based on query parameters.
@@ -2982,20 +3204,32 @@ List environments, if no environments are found, default environments are create ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.environments.list( + +client.applications.list( limit=10, offset=0, + application_id="applicationId", + workspace_id="workspaceId", + application_name="applicationName", + fqn="fqn", + workspace_fqn="workspaceFqn", + application_type="applicationType", + 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 -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -3027,19 +3261,638 @@ for page in response.iter_pages():
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**application_id:** `typing.Optional[str]` — Application id of the application
- -
+
+
+**workspace_id:** `typing.Optional[str]` — Workspace id of the application (comma separated for multiple) +
-
-
client.environments.create_or_update(...) -> AsyncHttpResponse[GetEnvironmentResponse] +
+
+ +**application_name:** `typing.Optional[str]` — Name of application + +
+
+ +
+
+ +**fqn:** `typing.Optional[str]` — Fully qualified name (FQN) of the application + +
+
+ +
+
+ +**workspace_fqn:** `typing.Optional[str]` — Fully qualified name (FQN) of the workspace + +
+
+ +
+
+ +**application_type:** `typing.Optional[str]` — Type of application (comma separated for multiple). Allowed Values: async-service, service, job, spark-job, helm, notebook, codeserver, rstudio, ssh-server, volume, application, application-set, intercept, workflow + +
+
+ +
+
+ +**name_search_query:** `typing.Optional[str]` — Search query for application name + +
+
+ +
+
+ +**environment_id:** `typing.Optional[str]` — Filter by Environment ids of the application (comma separated for multiple) + +
+
+ +
+
+ +**cluster_id:** `typing.Optional[str]` — Filter by Cluster ids of the application (comma separated for multiple) + +
+
+ +
+
+ +**application_set_id:** `typing.Optional[str]` — Filter by Application Set id of the application + +
+
+ +
+
+ +**paused:** `typing.Optional[bool]` — Filter by Application Paused status + +
+
+ +
+
+ +**device_type_filter:** `typing.Optional[ApplicationsListRequestDeviceTypeFilter]` — Filter by device type of the application. Allowed values: cpu, nvidia_gpu, aws_inferentia, nvidia_mig_gpu, nvidia_timeslicing_gpu, gcp_tpu + +
+
+ +
+
+ +**last_deployed_by_subjects:** `typing.Optional[str]` — Filter by last deployed by specific users + +
+
+ +
+
+ +**lifecycle_stage:** `typing.Optional[ApplicationsListRequestLifecycleStage]` — Filter by application lifecycle state + +
+
+ +
+
+ +**is_recommendation_present_and_visible:** `typing.Optional[bool]` — Filter out applications with recommendations that are allowed to be shown + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ + + + + + +
+ +
client.applications.create_or_update(...) -> GetApplicationDeploymentResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create a new Application Deployment based on the provided manifest. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.create_or_update( + manifest={ + "key": "value" + }, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**manifest:** `typing.Dict[str, typing.Any]` — Manifest of application + +
+
+ +
+
+ +**dry_run:** `typing.Optional[bool]` — Dry run + +
+
+ +
+
+ +**force_deploy:** `typing.Optional[bool]` — Cancels any ongoing deployments + +
+
+ +
+
+ +**trigger_on_deploy:** `typing.Optional[bool]` — Trigger on deploy + +
+
+ +
+
+ +**workspace_id:** `typing.Optional[str]` — workspace id of the workspace + +
+
+ +
+
+ +**application_id:** `typing.Optional[str]` — Id of the application + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name of application + +
+
+ +
+
+ +**application_set_id:** `typing.Optional[str]` — Application Set Id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.get(...) -> GetApplicationResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get Application associated with the provided application ID. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.get( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Id of the application + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.delete(...) -> DeleteApplicationResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete Application associated with the provided application ID. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.delete( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Id of the application + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.redeploy(...) -> GetApplicationDeploymentResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a new deployment with the same manifest as the given deployment. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.redeploy( + id="id", + deployment_id="deploymentId", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Application id of the application + +
+
+ +
+
+ +**deployment_id:** `str` — Deployment id of the deployment + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.scale_to_zero(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Pause a running application by scaling to 0 replicas +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.scale_to_zero( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Id of the application + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.scale_to_original(...) -> Deployment +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Resume a paused application by scaling back to the original number of replicas +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.applications.scale_to_original( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — Id of the application + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.applications.cancel_deployment(...) -> ApplicationsCancelDeploymentResponse
@@ -3051,7 +3904,7 @@ for page in response.iter_pages():
-Creates a new Environment or updates an existing Environment. +Cancel an ongoing deployment associated with the provided application ID and deployment ID.
@@ -3066,24 +3919,16 @@ Creates a new Environment or updates an existing Environment.
```python -from truefoundry_sdk import ( - EnvironmentColor, - EnvironmentManifest, - EnvironmentOptimizeFor, - TrueFoundry, -) +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.environments.create_or_update( - manifest=EnvironmentManifest( - name="name", - color=EnvironmentColor(), - is_production=True, - optimize_for=EnvironmentOptimizeFor.COST, - ), + +client.applications.cancel_deployment( + id="id", + deployment_id="deploymentId", ) ``` @@ -3100,7 +3945,7 @@ client.environments.create_or_update(
-**manifest:** `EnvironmentManifest` — Environment Manifest +**id:** `str` — Application id of the application
@@ -3108,7 +3953,7 @@ client.environments.create_or_update(
-**dry_run:** `typing.Optional[bool]` — Dry run +**deployment_id:** `str` — Deployment id of the deployment
@@ -3128,7 +3973,8 @@ client.environments.create_or_update(
-
client.environments.get(...) -> AsyncHttpResponse[GetEnvironmentResponse] +## ApplicationVersions +
client.application_versions.list(...) -> ListApplicationDeploymentsResponse
@@ -3140,7 +3986,7 @@ client.environments.create_or_update(
-Get Environment associated with the provided id. +Fetch all deployments for a given application ID with optional filters such as deployment ID or version. Supports pagination.
@@ -3158,11 +4004,16 @@ Get Environment associated with the provided id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.environments.get( + +client.application_versions.list( id="id", + limit=10, + offset=0, + version="1", + deployment_id="deployment123", ) ``` @@ -3179,7 +4030,39 @@ client.environments.get(
-**id:** `str` — Environment id +**id:** `str` — Id of the application + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Number of items per page + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of items to skip + +
+
+ +
+
+ +**version:** `typing.Optional[str]` — Deployment version. Filter deployments by version. + +
+
+ +
+
+ +**deployment_id:** `typing.Optional[str]` — Deployment ID. Filter deployments by a specific ID.
@@ -3199,7 +4082,7 @@ client.environments.get(
-
client.environments.delete(...) -> AsyncHttpResponse[bool] +
client.application_versions.get(...) -> GetApplicationDeploymentResponse
@@ -3211,7 +4094,7 @@ client.environments.get(
-Delete Environment associated with the provided id. +Get Deployment associated with the provided application ID and deployment ID.
@@ -3229,11 +4112,13 @@ Delete Environment associated with the provided id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.environments.delete( + +client.application_versions.get( id="id", + deployment_id="deploymentId", ) ``` @@ -3250,7 +4135,15 @@ client.environments.delete(
-**id:** `str` — Environment id +**id:** `str` — Application id of the application + +
+
+ +
+
+ +**deployment_id:** `str` — Deployment id of the deployment
@@ -3270,8 +4163,8 @@ client.environments.delete(
-## Applications -
client.applications.list(...) -> AsyncPager[Application, ListApplicationsResponse] +## Jobs +
client.jobs.list_runs(...) -> ListJobRunResponse
@@ -3283,7 +4176,7 @@ client.environments.delete(
-Retrieves a list of all latest applications. Supports filtering by application ID, name, type, and other parameters. Pagination is available based on query parameters. +List Job Runs for provided Job Id. Filter the data based on parameters passed in the query
@@ -3298,40 +4191,21 @@ Retrieves a list of all latest applications. Supports filtering by application I
```python -from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.applications import ( - ApplicationsListRequestDeviceTypeFilter, - ApplicationsListRequestLifecycleStage, -) +from truefoundry_sdk import TrueFoundry, JobRunsSortBy, SortDirection client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.applications.list( + +client.jobs.list_runs( + job_id="jobId", limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type="applicationType", - 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, + search_prefix="searchPrefix", + sort_by=JobRunsSortBy.START_TIME, + order=SortDirection.ASC, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -3347,6 +4221,14 @@ for page in response.iter_pages():
+**job_id:** `str` — Job id of the application + +
+
+ +
+
+ **limit:** `typing.Optional[int]` — Number of items per page
@@ -3363,7 +4245,7 @@ for page in response.iter_pages():
-**application_id:** `typing.Optional[str]` — Application id of the application +**search_prefix:** `typing.Optional[str]` — Prefix used to search for job runs by name or identifier
@@ -3371,23 +4253,112 @@ for page in response.iter_pages():
-**workspace_id:** `typing.Optional[str]` — Workspace id of the application (comma separated for multiple) +**sort_by:** `typing.Optional[JobRunsSortBy]` — Attribute to sort by + +
+
+ +
+
+ +**order:** `typing.Optional[SortDirection]` — Sorting order + +
+
+ +
+
+ +**triggered_by:** `typing.Optional[typing.Union[str, 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 number of the deployment + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +
+
+ +
+ + + +
+
+ +
client.jobs.get_run(...) -> GetJobRunResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get Job Run for provided jobRunName and jobId +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.jobs.get_run( + job_id="jobId", + job_run_name="jobRunName", +) + +``` +
+
+#### ⚙️ Parameters +
-**application_name:** `typing.Optional[str]` — Name of application - -
-
-
-**fqn:** `typing.Optional[str]` — Fully qualified name (FQN) of the application +**job_id:** `str` — Application Id of JOB
@@ -3395,7 +4366,7 @@ for page in response.iter_pages():
-**workspace_fqn:** `typing.Optional[str]` — Fully qualified name (FQN) of the workspace +**job_run_name:** `str` — Job run name of the application
@@ -3403,71 +4374,72 @@ for page in response.iter_pages():
-**application_type:** `typing.Optional[str]` — Type of application (comma separated for multiple). Allowed Values: async-service, service, job, spark-job, helm, notebook, codeserver, rstudio, ssh-server, volume, application, application-set, intercept, workflow +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**name_search_query:** `typing.Optional[str]` — Search query for application name -
+
+
client.jobs.delete_run(...) -> DeleteJobRunResponse
-**environment_id:** `typing.Optional[str]` — Filter by Environment ids of the application (comma separated for multiple) - -
-
+#### 📝 Description
-**cluster_id:** `typing.Optional[str]` — Filter by Cluster ids of the application (comma separated for multiple) - -
-
-
-**application_set_id:** `typing.Optional[str]` — Filter by Application Set id of the application - +Delete Job Run for provided jobRunName and jobId +
+
+#### 🔌 Usage +
-**paused:** `typing.Optional[bool]` — Filter by Application Paused status - -
-
-
-**device_type_filter:** `typing.Optional[ApplicationsListRequestDeviceTypeFilter]` — Filter by device type of the application. Allowed values: cpu, nvidia_gpu, aws_inferentia, nvidia_mig_gpu, nvidia_timeslicing_gpu, gcp_tpu - +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.jobs.delete_run( + job_id="jobId", + job_run_name="jobRunName", +) + +``` +
+
+#### ⚙️ Parameters +
-**last_deployed_by_subjects:** `typing.Optional[str]` — Filter by last deployed by specific users - -
-
-
-**lifecycle_stage:** `typing.Optional[ApplicationsListRequestLifecycleStage]` — Filter by application lifecycle state +**job_id:** `str` — Application Id of JOB
@@ -3475,7 +4447,7 @@ for page in response.iter_pages():
-**is_recommendation_present_and_visible:** `typing.Optional[bool]` — Filter out applications with recommendations that are allowed to be shown +**job_run_name:** `str` — Job run name of the application
@@ -3495,7 +4467,7 @@ for page in response.iter_pages():
-
client.applications.create_or_update(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse] +
client.jobs.trigger(...) -> TriggerJobRunResponse
@@ -3507,7 +4479,7 @@ for page in response.iter_pages():
-Create a new Application Deployment based on the provided manifest. +Trigger Job for provided deploymentId or applicationId
@@ -3525,12 +4497,11 @@ Create a new Application Deployment based on the provided manifest. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.create_or_update( - manifest={"key": "value"}, -) + +client.jobs.trigger() ``` @@ -3546,7 +4517,7 @@ client.applications.create_or_update(
-**manifest:** `typing.Dict[str, typing.Any]` — Manifest of application +**deployment_id:** `typing.Optional[str]` — Deployment Id of the job
@@ -3554,7 +4525,7 @@ client.applications.create_or_update(
-**dry_run:** `typing.Optional[bool]` — Dry run +**application_id:** `typing.Optional[str]` — Application Id of the job
@@ -3562,7 +4533,7 @@ client.applications.create_or_update(
-**force_deploy:** `typing.Optional[bool]` — Cancels any ongoing deployments +**input:** `typing.Optional[TriggerJobRequestInput]` — Job trigger input
@@ -3570,7 +4541,7 @@ client.applications.create_or_update(
-**trigger_on_deploy:** `typing.Optional[bool]` — Trigger on deploy +**metadata:** `typing.Optional[Metadata]` — Metadata for the job run including job_alias_name
@@ -3578,23 +4549,72 @@ client.applications.create_or_update(
-**workspace_id:** `typing.Optional[str]` — workspace id of the workspace +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + +
+ +
client.jobs.terminate(...) -> TerminateJobResponse
-**application_id:** `typing.Optional[str]` — Id of the application - +#### 📝 Description + +
+
+ +
+
+ +Terminate Job for provided deploymentId and jobRunName
+
+
+ +#### 🔌 Usage
-**name:** `typing.Optional[str]` — Name of application +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.jobs.terminate( + deployment_id="deploymentId", + job_run_name="jobRunName", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**deployment_id:** `str` — Deployment Id of the Deployment
@@ -3602,7 +4622,7 @@ client.applications.create_or_update(
-**application_set_id:** `typing.Optional[str]` — Application Set Id +**job_run_name:** `str` — Job Run name
@@ -3622,7 +4642,8 @@ client.applications.create_or_update(
-
client.applications.get(...) -> AsyncHttpResponse[GetApplicationResponse] +## Environments +
client.environments.list(...) -> ListEnvironmentsResponse
@@ -3634,7 +4655,7 @@ client.applications.create_or_update(
-Get Application associated with the provided application ID. +List environments, if no environments are found, default environments are created and returned. Pagination is available based on query parameters
@@ -3652,11 +4673,13 @@ Get Application associated with the provided application ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.get( - id="id", + +client.environments.list( + limit=10, + offset=0, ) ``` @@ -3673,7 +4696,15 @@ client.applications.get(
-**id:** `str` — Id of the application +**limit:** `typing.Optional[int]` — Number of items per page + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -3693,7 +4724,7 @@ client.applications.get(
-
client.applications.delete(...) -> AsyncHttpResponse[DeleteApplicationResponse] +
client.environments.create_or_update(...) -> GetEnvironmentResponse
@@ -3705,7 +4736,7 @@ client.applications.get(
-Delete Application associated with the provided application ID. +Creates a new Environment or updates an existing Environment.
@@ -3720,14 +4751,21 @@ Delete Application associated with the provided application ID.
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, EnvironmentManifest, EnvironmentColor, EnvironmentOptimizeFor client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.delete( - id="id", + +client.environments.create_or_update( + manifest=EnvironmentManifest( + type="environment", + name="name", + color=EnvironmentColor(), + is_production=True, + optimize_for=EnvironmentOptimizeFor.COST, + ), ) ``` @@ -3744,7 +4782,15 @@ client.applications.delete(
-**id:** `str` — Id of the application +**manifest:** `EnvironmentManifest` — Environment Manifest + +
+
+ +
+
+ +**dry_run:** `typing.Optional[bool]` — Dry run
@@ -3764,7 +4810,7 @@ client.applications.delete(
-
client.applications.redeploy(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse] +
client.environments.get(...) -> GetEnvironmentResponse
@@ -3776,7 +4822,7 @@ client.applications.delete(
-Creates a new deployment with the same manifest as the given deployment. +Get Environment associated with the provided id.
@@ -3794,12 +4840,12 @@ Creates a new deployment with the same manifest as the given deployment. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.redeploy( + +client.environments.get( id="id", - deployment_id="deploymentId", ) ``` @@ -3816,15 +4862,7 @@ client.applications.redeploy(
-**id:** `str` — Application id of the application - -
-
- -
-
- -**deployment_id:** `str` — Deployment id of the deployment +**id:** `str` — Environment id
@@ -3844,7 +4882,7 @@ client.applications.redeploy(
-
client.applications.scale_to_zero(...) -> AsyncHttpResponse[None] +
client.environments.delete(...) -> bool
@@ -3856,7 +4894,7 @@ client.applications.redeploy(
-Pause a running application by scaling to 0 replicas +Delete Environment associated with the provided id.
@@ -3874,10 +4912,11 @@ Pause a running application by scaling to 0 replicas from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.scale_to_zero( + +client.environments.delete( id="id", ) @@ -3895,7 +4934,7 @@ client.applications.scale_to_zero(
-**id:** `str` — Id of the application +**id:** `str` — Environment id
@@ -3915,7 +4954,8 @@ client.applications.scale_to_zero(
-
client.applications.scale_to_original(...) -> AsyncHttpResponse[Deployment] +## Workspaces +
client.workspaces.list(...) -> ListWorkspacesResponse
@@ -3927,7 +4967,7 @@ client.applications.scale_to_zero(
-Resume a paused application by scaling back to the original number of replicas +List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name.
@@ -3945,11 +4985,17 @@ Resume a paused application by scaling back to the original number of replicas from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.scale_to_original( - id="id", + +client.workspaces.list( + limit=10, + offset=0, + cluster_id="clusterId", + name="name", + fqn="fqn", + include_cluster=True, ) ``` @@ -3966,7 +5012,47 @@ client.applications.scale_to_original(
-**id:** `str` — Id of the application +**limit:** `typing.Optional[int]` — Number of items per page + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of items to skip + +
+
+ +
+
+ +**cluster_id:** `typing.Optional[str]` — ClusterId of the Cluster + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Workspace Name + +
+
+ +
+
+ +**fqn:** `typing.Optional[str]` — Workspace FQN + +
+
+ +
+
+ +**include_cluster:** `typing.Optional[bool]` — When true, each workspace includes cluster information
@@ -3986,7 +5072,7 @@ client.applications.scale_to_original(
-
client.applications.cancel_deployment(...) -> AsyncHttpResponse[ApplicationsCancelDeploymentResponse] +
client.workspaces.create_or_update(...) -> GetWorkspaceResponse
@@ -3998,7 +5084,7 @@ client.applications.scale_to_original(
-Cancel an ongoing deployment associated with the provided application ID and deployment ID. +Creates a new workspace or updates an existing one based on the provided manifest.
@@ -4013,15 +5099,19 @@ Cancel an ongoing deployment associated with the provided application ID and dep
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, WorkspaceManifest client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.applications.cancel_deployment( - id="id", - deployment_id="deploymentId", + +client.workspaces.create_or_update( + manifest=WorkspaceManifest( + type="workspace", + cluster_fqn="cluster_fqn", + name="name", + ), ) ``` @@ -4038,7 +5128,7 @@ client.applications.cancel_deployment(
-**id:** `str` — Application id of the application +**manifest:** `WorkspaceManifest` — Workspace manifest
@@ -4046,7 +5136,7 @@ client.applications.cancel_deployment(
-**deployment_id:** `str` — Deployment id of the deployment +**dry_run:** `typing.Optional[bool]` — Dry run the request
@@ -4066,8 +5156,7 @@ client.applications.cancel_deployment(
-## ApplicationVersions -
client.application_versions.list(...) -> AsyncPager[Deployment, ListApplicationDeploymentsResponse] +
client.workspaces.search(...) -> ListWorkspacesResponse
@@ -4079,7 +5168,7 @@ client.applications.cancel_deployment(
-Fetch all deployments for a given application ID with optional filters such as deployment ID or version. Supports pagination. +List workspaces the user can read with optional structured `filter` (name, id, environmentId, cluster_fqn) and pagination.
@@ -4097,21 +5186,16 @@ Fetch all deployments for a given application ID with optional filters such as d from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.application_versions.list( - id="id", + +client.workspaces.search( limit=10, offset=0, - version="1", - deployment_id="deployment123", + filter="filter", + include_cluster=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -4127,14 +5211,6 @@ for page in response.iter_pages():
-**id:** `str` — Id of the application - -
-
- -
-
- **limit:** `typing.Optional[int]` — Number of items per page
@@ -4151,7 +5227,7 @@ for page in response.iter_pages():
-**version:** `typing.Optional[str]` — Deployment version. Filter deployments by version. +**filter:** `typing.Optional[str]` — JSON string containing array of search filters with string, type and operator
@@ -4159,7 +5235,7 @@ for page in response.iter_pages():
-**deployment_id:** `typing.Optional[str]` — Deployment ID. Filter deployments by a specific ID. +**include_cluster:** `typing.Optional[bool]` — When true, each workspace includes cluster information
@@ -4179,7 +5255,7 @@ for page in response.iter_pages():
-
client.application_versions.get(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse] +
client.workspaces.get(...) -> GetWorkspaceResponse
@@ -4191,7 +5267,7 @@ for page in response.iter_pages():
-Get Deployment associated with the provided application ID and deployment ID. +Get workspace associated with provided workspace id
@@ -4209,12 +5285,12 @@ Get Deployment associated with the provided application ID and deployment ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.application_versions.get( + +client.workspaces.get( id="id", - deployment_id="deploymentId", ) ``` @@ -4231,15 +5307,7 @@ client.application_versions.get(
-**id:** `str` — Application id of the application - -
-
- -
-
- -**deployment_id:** `str` — Deployment id of the deployment +**id:** `str` — Workspace id of the space
@@ -4259,8 +5327,7 @@ client.application_versions.get(
-## Jobs -
client.jobs.list_runs(...) -> AsyncPager[JobRun, ListJobRunResponse] +
client.workspaces.delete(...) -> WorkspacesDeleteResponse
@@ -4272,7 +5339,9 @@ client.application_versions.get(
-List Job Runs for provided Job Id. Filter the data based on parameters passed in the query +Deletes the workspace with the given workspace ID. + - Removes the associated namespace from the cluster. + - Deletes the corresponding authorization entry.
@@ -4287,25 +5356,16 @@ List Job Runs for provided Job Id. Filter the data based on parameters passed in
```python -from truefoundry_sdk import JobRunsSortBy, SortDirection, TrueFoundry +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.jobs.list_runs( - job_id="jobId", - limit=10, - offset=0, - search_prefix="searchPrefix", - sort_by=JobRunsSortBy.START_TIME, - order=SortDirection.ASC, + +client.workspaces.delete( + id="id", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -4321,7 +5381,7 @@ for page in response.iter_pages():
-**job_id:** `str` — Job id of the application +**id:** `str` — Workspace id of the space
@@ -4329,31 +5389,70 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` — Number of items per page +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + + +
+## Secrets +
client.secrets.list(...) -> ListSecretsResponse
-**offset:** `typing.Optional[int]` — Number of items to skip - +#### 📝 Description + +
+
+ +
+
+ +List secrets associated with a user filtered with optional parameters passed in the body. +
+
+#### 🔌 Usage +
-**search_prefix:** `typing.Optional[str]` — Prefix used to search for job runs by name or identifier - +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.secrets.list() + +``` +
+
+#### ⚙️ Parameters +
-**sort_by:** `typing.Optional[JobRunsSortBy]` — Attribute to sort by +
+
+ +**limit:** `typing.Optional[int]` — Number of items per page
@@ -4361,7 +5460,7 @@ for page in response.iter_pages():
-**order:** `typing.Optional[SortDirection]` — Sorting order +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -4369,7 +5468,7 @@ for page in response.iter_pages():
-**triggered_by:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Array of subject slugs +**secret_fqns:** `typing.Optional[typing.List[str]]` — Array of FQNs
@@ -4377,7 +5476,7 @@ for page in response.iter_pages():
-**status:** `typing.Optional[typing.Union[JobRunStatus, typing.Sequence[JobRunStatus]]]` — Status of the job run +**secret_group_id:** `typing.Optional[str]` — Secret Group Id of the secret gourp.
@@ -4385,7 +5484,7 @@ for page in response.iter_pages():
-**version_numbers:** `typing.Optional[typing.Union[float, typing.Sequence[float]]]` — Version number of the deployment +**with_value:** `typing.Optional[bool]` — Whether to include the secret values in the response. Defaults to false.
@@ -4405,7 +5504,7 @@ for page in response.iter_pages():
-
client.jobs.get_run(...) -> AsyncHttpResponse[GetJobRunResponse] +
client.secrets.get(...) -> GetSecretResponse
@@ -4417,7 +5516,7 @@ for page in response.iter_pages():
-Get Job Run for provided jobRunName and jobId +Get Secret associated with provided id. The secret value is not returned if the control plane has `DISABLE_SECRET_VALUE_VIEW` set
@@ -4435,12 +5534,12 @@ Get Job Run for provided jobRunName and jobId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.jobs.get_run( - job_id="jobId", - job_run_name="jobRunName", + +client.secrets.get( + id="id", ) ``` @@ -4457,15 +5556,7 @@ client.jobs.get_run(
-**job_id:** `str` — Application Id of JOB - -
-
- -
-
- -**job_run_name:** `str` — Job run name of the application +**id:** `str` — Secret Id of the secret.
@@ -4485,7 +5576,7 @@ client.jobs.get_run(
-
client.jobs.delete_run(...) -> AsyncHttpResponse[DeleteJobRunResponse] +
client.secrets.delete(...) -> float
@@ -4497,7 +5588,7 @@ client.jobs.get_run(
-Delete Job Run for provided jobRunName and jobId +Deletes a secret and its versions along with its values.
@@ -4515,12 +5606,13 @@ Delete Job Run for provided jobRunName and jobId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.jobs.delete_run( - job_id="jobId", - job_run_name="jobRunName", + +client.secrets.delete( + id="id", + force_delete=True, ) ``` @@ -4537,7 +5629,7 @@ client.jobs.delete_run(
-**job_id:** `str` — Application Id of JOB +**id:** `str` — Secret Id of the secret.
@@ -4545,7 +5637,7 @@ client.jobs.delete_run(
-**job_run_name:** `str` — Job run name of the application +**force_delete:** `typing.Optional[bool]` — Whether to force delete the secret.
@@ -4565,7 +5657,8 @@ client.jobs.delete_run(
-
client.jobs.trigger(...) -> AsyncHttpResponse[TriggerJobRunResponse] +## SecretGroups +
client.secret_groups.list(...) -> ListSecretGroupResponse
@@ -4577,7 +5670,7 @@ client.jobs.delete_run(
-Trigger Job for provided deploymentId or applicationId +List the secret groups associated with a user along with the associated secrets for each group. Filtered with the options passed in the query fields. Note: This method does not return the secret values of the associatedSecrets in the response. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value.
@@ -4595,10 +5688,16 @@ Trigger Job for provided deploymentId or applicationId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.jobs.trigger() + +client.secret_groups.list( + limit=10, + offset=0, + fqn="fqn", + search="search", +) ``` @@ -4614,7 +5713,7 @@ client.jobs.trigger()
-**deployment_id:** `typing.Optional[str]` — Deployment Id of the job +**limit:** `typing.Optional[int]` — Number of items per page
@@ -4622,7 +5721,7 @@ client.jobs.trigger()
-**application_id:** `typing.Optional[str]` — Application Id of the job +**offset:** `typing.Optional[int]` — Number of items to skip
@@ -4630,7 +5729,7 @@ client.jobs.trigger()
-**input:** `typing.Optional[TriggerJobRequestInput]` — Job trigger input +**fqn:** `typing.Optional[str]` — Fqn of secret group.
@@ -4638,7 +5737,7 @@ client.jobs.trigger()
-**metadata:** `typing.Optional[Metadata]` — Metadata for the job run including job_alias_name +**search:** `typing.Optional[str]` — Search query - filters by secret group names that contain the search string
@@ -4658,7 +5757,7 @@ client.jobs.trigger()
-
client.jobs.terminate(...) -> AsyncHttpResponse[TerminateJobResponse] +
client.secret_groups.create(...) -> GetSecretGroupResponse
@@ -4670,7 +5769,7 @@ client.jobs.trigger()
-Terminate Job for provided deploymentId and jobRunName +Creates a secret group with secrets in it. A secret version for each of the created secret is created with version number as 1. The returned secret group does not have any secret values in the associatedSecrets field. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value.
@@ -4685,15 +5784,22 @@ Terminate Job for provided deploymentId and jobRunName
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, SecretInput client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.jobs.terminate( - deployment_id="deploymentId", - job_run_name="jobRunName", + +client.secret_groups.create( + name="name", + integration_id="integrationId", + secrets=[ + SecretInput( + key="key", + value="value", + ) + ], ) ``` @@ -4710,7 +5816,7 @@ client.jobs.terminate(
-**deployment_id:** `str` — Deployment Id of the Deployment +**name:** `str` — Name of the secret group.
@@ -4718,7 +5824,15 @@ client.jobs.terminate(
-**job_run_name:** `str` — Job Run name +**integration_id:** `str` — Id of the provider integration. + +
+
+ +
+
+ +**secrets:** `typing.List[SecretInput]` — The secrets to be associated with the secret group
@@ -4738,8 +5852,7 @@ client.jobs.terminate(
-## Workspaces -
client.workspaces.list(...) -> AsyncPager[Workspace, ListWorkspacesResponse] +
client.secret_groups.create_or_update(...) -> GetSecretGroupResponse
@@ -4751,7 +5864,7 @@ client.jobs.terminate(
-List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Pagination is available based on query parameters. +Creates a new secret group or updates an existing one based on the provided manifest.
@@ -4766,24 +5879,26 @@ List workspaces associated with the user. Optional filters include clusterId, fq
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, SecretGroupManifest, Collaborator client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.workspaces.list( - limit=10, - offset=0, - cluster_id="clusterId", - name="name", - fqn="fqn", + +client.secret_groups.create_or_update( + manifest=SecretGroupManifest( + type="secret-group", + name="name", + integration_fqn="integration_fqn", + collaborators=[ + Collaborator( + subject="subject", + role_id="role_id", + ) + ], + ), ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -4799,31 +5914,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` — Number of items per page - -
-
- -
-
- -**offset:** `typing.Optional[int]` — Number of items to skip - -
-
- -
-
- -**cluster_id:** `typing.Optional[str]` — ClusterId of the Cluster - -
-
- -
-
- -**name:** `typing.Optional[str]` — Workspace Name +**manifest:** `SecretGroupManifest` — Secret Group Manifest
@@ -4831,7 +5922,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` — Workspace FQN +**dry_run:** `typing.Optional[bool]` — Validate the manifest and collaborators without persisting or updating authorizations and secret groups
@@ -4851,7 +5942,7 @@ for page in response.iter_pages():
-
client.workspaces.create_or_update(...) -> AsyncHttpResponse[GetWorkspaceResponse] +
client.secret_groups.get(...) -> GetSecretGroupResponse
@@ -4863,7 +5954,7 @@ for page in response.iter_pages():
-Creates a new workspace or updates an existing one based on the provided manifest. +Get Secret Group by id. This method does not return the secret values of the associatedSecrets in the response. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value.
@@ -4878,17 +5969,15 @@ Creates a new workspace or updates an existing one based on the provided manifes
```python -from truefoundry_sdk import TrueFoundry, WorkspaceManifest +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.workspaces.create_or_update( - manifest=WorkspaceManifest( - cluster_fqn="cluster_fqn", - name="name", - ), + +client.secret_groups.get( + id="id", ) ``` @@ -4905,15 +5994,7 @@ client.workspaces.create_or_update(
-**manifest:** `WorkspaceManifest` — Workspace manifest - -
-
- -
-
- -**dry_run:** `typing.Optional[bool]` — Dry run the request +**id:** `str` — Secret Id of the secret group.
@@ -4933,7 +6014,7 @@ client.workspaces.create_or_update(
-
client.workspaces.get(...) -> AsyncHttpResponse[GetWorkspaceResponse] +
client.secret_groups.update(...) -> GetSecretGroupResponse
@@ -4945,7 +6026,7 @@ client.workspaces.create_or_update(
-Get workspace associated with provided workspace id +Updates the secrets in a secret group with new values. A new secret version is created for every secret that has a modified value and any omitted secrets are deleted. The returned updated secret group does not have any secret values in the associatedSecrets field. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value.
@@ -4960,14 +6041,20 @@ Get workspace associated with provided workspace id
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, UpdateSecretInput client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.workspaces.get( + +client.secret_groups.update( id="id", + secrets=[ + UpdateSecretInput( + key="key", + ) + ], ) ``` @@ -4984,7 +6071,15 @@ client.workspaces.get(
-**id:** `str` — Workspace id of the space +**id:** `str` — Secret Id of the secret group. + +
+
+ +
+
+ +**secrets:** `typing.List[UpdateSecretInput]`
@@ -5004,7 +6099,7 @@ client.workspaces.get(
-
client.workspaces.delete(...) -> AsyncHttpResponse[WorkspacesDeleteResponse] +
client.secret_groups.delete(...) -> DeleteSecretGroupResponse
@@ -5016,9 +6111,7 @@ client.workspaces.get(
-Deletes the workspace with the given workspace ID. - - Removes the associated namespace from the cluster. - - Deletes the corresponding authorization entry. +Deletes the secret group, its associated secrets and secret versions of those secrets.
@@ -5036,10 +6129,11 @@ Deletes the workspace with the given workspace ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.workspaces.delete( + +client.secret_groups.delete( id="id", ) @@ -5057,7 +6151,7 @@ client.workspaces.delete(
-**id:** `str` — Workspace id of the space +**id:** `str` — Secret Id of the secret group.
@@ -5077,8 +6171,8 @@ client.workspaces.delete(
-## Secrets -
client.secrets.list(...) -> AsyncPager[Secret, ListSecretsResponse] +## Events +
client.events.get(...) -> GetEventsResponse
@@ -5090,7 +6184,7 @@ client.workspaces.delete(
-List secrets associated with a user filtered with optional parameters passed in the body. +Get Events for Pod, Job Run, Application. The events are sourced from Kubernetes as well as events captured by truefoundry. Optional query parameters include startTs, endTs for filtering.
@@ -5108,15 +6202,17 @@ List secrets associated with a user filtered with optional parameters passed in from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.secrets.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page + +client.events.get( + start_ts="startTs", + end_ts="endTs", + application_id="applicationId", + application_fqn="applicationFqn", + job_run_name="jobRunName", +) ``` @@ -5132,7 +6228,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` — Number of items per page +**start_ts:** `typing.Optional[str]` — Start timestamp (ISO format) for querying events
@@ -5140,7 +6236,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` — Number of items to skip +**end_ts:** `typing.Optional[str]` — End timestamp (ISO format) for querying events
@@ -5148,7 +6244,7 @@ for page in response.iter_pages():
-**secret_fqns:** `typing.Optional[typing.Sequence[str]]` — Array of FQNs +**application_id:** `typing.Optional[str]` — Application ID
@@ -5156,7 +6252,7 @@ for page in response.iter_pages():
-**secret_group_id:** `typing.Optional[str]` — Secret Group Id of the secret gourp. +**application_fqn:** `typing.Optional[str]` — Application FQN
@@ -5164,7 +6260,15 @@ for page in response.iter_pages():
-**with_value:** `typing.Optional[bool]` — Whether to include the secret values in the response. Defaults to false. +**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Name of the pods + +
+
+ +
+
+ +**job_run_name:** `typing.Optional[str]` — Job run name
@@ -5184,7 +6288,8 @@ for page in response.iter_pages():
-
client.secrets.get(...) -> AsyncHttpResponse[GetSecretResponse] +## Alerts +
client.alerts.list(...) -> GetAlertsResponse
@@ -5196,7 +6301,7 @@ for page in response.iter_pages():
-Get Secret associated with provided id. The secret value is not returned if the control plane has `DISABLE_SECRET_VALUE_VIEW` set +Get alerts for a given application or cluster filtered by start and end timestamp
@@ -5211,14 +6316,19 @@ Get Secret associated with provided id. The secret value is not returned if the
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, AlertStatus client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secrets.get( - id="id", + +client.alerts.list( + start_ts="startTs", + end_ts="endTs", + cluster_id="clusterId", + application_id="applicationId", + alert_status=AlertStatus.FIRING, ) ``` @@ -5235,7 +6345,39 @@ client.secrets.get(
-**id:** `str` — Secret Id of the secret. +**start_ts:** `typing.Optional[str]` — Start timestamp (ISO format) for querying events + +
+
+ +
+
+ +**end_ts:** `typing.Optional[str]` — End timestamp (ISO format) for querying events + +
+
+ +
+
+ +**cluster_id:** `typing.Optional[str]` — Cluster id + +
+
+ +
+
+ +**application_id:** `typing.Optional[str]` — Application id + +
+
+ +
+
+ +**alert_status:** `typing.Optional[AlertStatus]` — Alert status
@@ -5255,7 +6397,8 @@ client.secrets.get(
-
client.secrets.delete(...) -> AsyncHttpResponse[float] +## Logs +
client.logs.get(...) -> GetLogsResponse
@@ -5267,7 +6410,7 @@ client.secrets.get(
-Deletes a secret and its versions along with its values. +Fetch logs for various workload components, including Services, Jobs, Workflows, Job Runs, and Pods. Logs are filtered based on the provided query parameters.
@@ -5282,15 +6425,30 @@ Deletes a secret and its versions along with its values.
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, LogsSortingDirection, LogsSearchFilterType, LogsSearchOperatorType client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secrets.delete( - id="id", - force_delete=True, + +client.logs.get( + start_ts=1000000, + end_ts=1000000, + 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_regex="podNamesRegex", + search_filters="searchFilters", + search_string="searchString", + search_type=LogsSearchFilterType.REGEX, + search_operator=LogsSearchOperatorType.EQUAL, ) ``` @@ -5307,7 +6465,7 @@ client.secrets.delete(
-**id:** `str` — Secret Id of the secret. +**start_ts:** `typing.Optional[int]` — Start timestamp for querying logs, in nanoseconds from the Unix epoch.
@@ -5315,7 +6473,7 @@ client.secrets.delete(
-**force_delete:** `typing.Optional[bool]` — Whether to force delete the secret. +**end_ts:** `typing.Optional[int]` — End timestamp for querying logs, in nanoseconds from the Unix epoch.
@@ -5323,79 +6481,95 @@ client.secrets.delete(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**limit:** `typing.Optional[int]` — Max number of log lines to fetch
-
-
+
+
+**direction:** `typing.Optional[LogsSortingDirection]` — Direction of sorting logs. Can be `asc` or `desc` +
-
-## SecretGroups -
client.secret_groups.list(...) -> AsyncPager[SecretGroup, ListSecretGroupResponse]
-#### 📝 Description +**num_logs_to_ignore:** `typing.Optional[int]` — Number of logs corresponding to the starting timestamp to be ignored. + +
+
+**application_id:** `typing.Optional[str]` — Application ID + +
+
+
-List the secret groups associated with a user along with the associated secrets for each group. Filtered with the options passed in the query fields. Note: This method does not return the secret values of the associatedSecrets in the response. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value. +**application_fqn:** `typing.Optional[str]` — Application FQN +
+ +
+
+ +**deployment_id:** `typing.Optional[str]` — Deployment ID +
-#### 🔌 Usage -
+**job_run_name:** `typing.Optional[str]` — Name of the Job Run for which to fetch logs. + +
+
+
-```python -from truefoundry_sdk import TrueFoundry +**pod_name:** `typing.Optional[str]` — Name of Pod for which to fetch logs. + +
+
-client = TrueFoundry( - api_key="YOUR_API_KEY", - base_url="https://yourhost.com/path/to/api", -) -response = client.secret_groups.list( - limit=10, - offset=0, - fqn="fqn", - search="search", -) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +
+
-``` +**container_name:** `typing.Optional[str]` — Name of the Container for which to fetch logs. +
+ +
+
+ +**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of pod names for which to fetch logs. +
-#### ⚙️ Parameters -
+**pod_names_regex:** `typing.Optional[str]` — Regex pattern for pod names to fetch logs. + +
+
+
-**limit:** `typing.Optional[int]` — Number of items per page +**search_filters:** `typing.Optional[str]` — JSON string containing array of search filters with string, type and operator
@@ -5403,7 +6577,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` — Number of items to skip +**search_string:** `typing.Optional[str]` — String that needs to be matched
@@ -5411,7 +6585,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` — Fqn of secret group. +**search_type:** `typing.Optional[LogsSearchFilterType]` — Query filter type, `regex` `substring` `ignore_case_substring`
@@ -5419,7 +6593,7 @@ for page in response.iter_pages():
-**search:** `typing.Optional[str]` — Search query - filters by secret group names that contain the search string +**search_operator:** `typing.Optional[LogsSearchOperatorType]` — Comparison operator for filter. `equal` or `not_equal`
@@ -5439,7 +6613,8 @@ for page in response.iter_pages():
-
client.secret_groups.create(...) -> AsyncHttpResponse[GetSecretGroupResponse] +## MlRepos +
client.ml_repos.create_or_update(...) -> GetMlRepoResponse
@@ -5451,7 +6626,7 @@ for page in response.iter_pages():
-Creates a secret group with secrets in it. A secret version for each of the created secret is created with version number as 1. The returned secret group does not have any secret values in the associatedSecrets field. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value. +Creates or updates an MLRepo entity based on the provided manifest.
@@ -5466,21 +6641,25 @@ Creates a secret group with secrets in it. A secret version for each of the crea
```python -from truefoundry_sdk import SecretInput, TrueFoundry +from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secret_groups.create( - name="name", - integration_id="integrationId", - secrets=[ - SecretInput( - key="key", - value="value", - ) - ], + +client.ml_repos.create_or_update( + manifest=MlRepoManifest( + type="ml-repo", + name="name", + storage_integration_fqn="storage_integration_fqn", + collaborators=[ + Collaborator( + subject="subject", + role_id="role_id", + ) + ], + ), ) ``` @@ -5497,15 +6676,7 @@ client.secret_groups.create(
-**name:** `str` — Name of the secret group. - -
-
- -
-
- -**integration_id:** `str` — Id of the provider integration. +**manifest:** `MlRepoManifest` — MLRepo manifest
@@ -5513,7 +6684,7 @@ client.secret_groups.create(
-**secrets:** `typing.Sequence[SecretInput]` — The secrets to be associated with the secret group +**dry_run:** `typing.Optional[bool]` — Validate the manifest and collaborators without persisting changes or updating artifact location in the database
@@ -5533,7 +6704,7 @@ client.secret_groups.create(
-
client.secret_groups.create_or_update(...) -> AsyncHttpResponse[GetSecretGroupResponse] +
client.ml_repos.get(...) -> GetMlRepoResponse
@@ -5545,7 +6716,7 @@ client.secret_groups.create(
-Creates a new secret group or updates an existing one based on the provided manifest. +Get an ML Repo by its ID.
@@ -5560,23 +6731,15 @@ Creates a new secret group or updates an existing one based on the provided mani
```python -from truefoundry_sdk import Collaborator, SecretGroupManifest, TrueFoundry +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secret_groups.create_or_update( - manifest=SecretGroupManifest( - name="name", - integration_fqn="integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], - ), + +client.ml_repos.get( + id="id", ) ``` @@ -5593,7 +6756,7 @@ client.secret_groups.create_or_update(
-**manifest:** `SecretGroupManifest` — Secret Group Manifest +**id:** `str`
@@ -5613,7 +6776,7 @@ client.secret_groups.create_or_update(
-
client.secret_groups.get(...) -> AsyncHttpResponse[GetSecretGroupResponse] +
client.ml_repos.delete(...) -> EmptyResponse
@@ -5625,7 +6788,7 @@ client.secret_groups.create_or_update(
-Get Secret Group by id. This method does not return the secret values of the associatedSecrets in the response. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value. +Delete an ML Repo by its ID.
@@ -5643,10 +6806,11 @@ Get Secret Group by id. This method does not return the secret values of the
-**id:** `str` — Secret Id of the secret group. +**id:** `str`
@@ -5684,7 +6848,7 @@ client.secret_groups.get(
-
client.secret_groups.update(...) -> AsyncHttpResponse[GetSecretGroupResponse] +
client.ml_repos.list(...) -> ListMlReposResponse
@@ -5696,7 +6860,7 @@ client.secret_groups.get(
-Updates the secrets in a secret group with new values. A new secret version is created for every secret that has a modified value and any omitted secrets are deleted. The returned updated secret group does not have any secret values in the associatedSecrets field. A separate API call to `/v1/secrets/{id}` should be made to fetch the associated secret value. +List ML Repos with optional filtering by name.
@@ -5711,19 +6875,17 @@ Updates the secrets in a secret group with new values. A new secret version is c
```python -from truefoundry_sdk import TrueFoundry, UpdateSecretInput +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secret_groups.update( - id="id", - secrets=[ - UpdateSecretInput( - key="key", - ) - ], + +client.ml_repos.list( + name="name", + limit=1, + offset=1, ) ``` @@ -5740,7 +6902,15 @@ client.secret_groups.update(
-**id:** `str` — Secret Id of the secret group. +**name:** `typing.Optional[str]` — Name of the ML Repo to filter by + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of ML Repos to return
@@ -5748,7 +6918,7 @@ client.secret_groups.update(
-**secrets:** `typing.Sequence[UpdateSecretInput]` +**offset:** `typing.Optional[int]` — Number of ML Repos to skip for pagination
@@ -5768,24 +6938,11 @@ client.secret_groups.update(
-
client.secret_groups.delete(...) -> AsyncHttpResponse[DeleteSecretGroupResponse] -
-
- -#### 📝 Description - -
-
- +## Traces +
client.traces.query_spans(...) -> QuerySpansResponse
-Deletes the secret group, its associated secrets and secret versions of those secrets. -
-
-
-
- #### 🔌 Usage
@@ -5798,11 +6955,12 @@ Deletes the secret group, its associated secrets and secret versions of those se from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.secret_groups.delete( - id="id", + +client.traces.query_spans( + start_time="startTime", ) ``` @@ -5819,7 +6977,7 @@ client.secret_groups.delete(
-**id:** `str` — Secret Id of the secret group. +**start_time:** `str` — Start time in ISO 8601 format (e.g., 2025-03-12T00:00:09.872Z)
@@ -5827,75 +6985,71 @@ client.secret_groups.delete(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**end_time:** `typing.Optional[str]` — End time in ISO 8601 format (e.g., 2025-03-12T00:10:00.000Z). Defaults to current time if not provided.
-
-
+
+
+**trace_ids:** `typing.Optional[typing.List[str]]` — Array of trace IDs to filter by +
-
-## Events -
client.events.get(...) -> AsyncHttpResponse[GetEventsResponse]
-#### 📝 Description +**span_ids:** `typing.Optional[typing.List[str]]` — Array of span IDs to filter by + +
+
+**parent_span_ids:** `typing.Optional[typing.List[str]]` — Array of parent span IDs to filter by + +
+
+
-Get Events for Pod, Job Run, Application. The events are sourced from Kubernetes as well as events captured by truefoundry. Optional query parameters include startTs, endTs for filtering. -
-
+**created_by_subject_types:** `typing.Optional[typing.List[SubjectType]]` — Array of subject types to filter by + -#### 🔌 Usage -
+**created_by_subject_slugs:** `typing.Optional[typing.List[str]]` — Array of subject slugs to filter by + +
+
+
-```python -from truefoundry_sdk import TrueFoundry - -client = TrueFoundry( - 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", - job_run_name="jobRunName", -) - -``` -
-
+**application_names:** `typing.Optional[typing.List[str]]` — Array of application names to filter by + -#### ⚙️ Parameters -
+**limit:** `typing.Optional[int]` — The maximum number of spans to return per page. Defaults to 200 if not provided. + +
+
+
-**start_ts:** `typing.Optional[str]` — Start timestamp (ISO format) for querying events +**sort_direction:** `typing.Optional[SortDirection]` — Sort direction for results based on time. Defaults to descending (latest first)
@@ -5903,7 +7057,7 @@ client.events.get(
-**end_ts:** `typing.Optional[str]` — End timestamp (ISO format) for querying events +**page_token:** `typing.Optional[str]` — An opaque string that should be passed as-is from previous response for fetching the next page. Pass `$response.pagination.nextPageToken` from previous response for fetching the next page.
@@ -5911,7 +7065,7 @@ client.events.get(
-**application_id:** `typing.Optional[str]` — Application ID +**tracing_project_fqn:** `typing.Optional[str]` — Tracing project FQN (e.g., truefoundry:tracing-project:tfy-default)
@@ -5919,7 +7073,7 @@ client.events.get(
-**application_fqn:** `typing.Optional[str]` — Application FQN +**data_routing_destination:** `typing.Optional[str]` — Data Routing Destination. One of tracingProjectFqn or dataRoutingDestination is required.
@@ -5927,7 +7081,7 @@ client.events.get(
-**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — Name of the pods +**filters:** `typing.Optional[typing.List[QuerySpansRequestFiltersItem]]` — Array of filters
@@ -5935,7 +7089,7 @@ client.events.get(
-**job_run_name:** `typing.Optional[str]` — Job run name +**include_feedbacks:** `typing.Optional[bool]` — When true, feedback data is included in the response. When false, feedback data is excluded (returns empty array).
@@ -5955,8 +7109,8 @@ client.events.get(
-## Alerts -
client.alerts.list(...) -> AsyncHttpResponse[GetAlertsResponse] +## Artifacts +
client.artifacts.get(...) -> GetArtifactResponse
@@ -5968,7 +7122,7 @@ client.events.get(
-Get alerts for a given application or cluster filtered by start and end timestamp +Get an artifact by its ID.
@@ -5983,18 +7137,15 @@ Get alerts for a given application or cluster filtered by start and end timestam
```python -from truefoundry_sdk import AlertStatus, TrueFoundry +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + 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.artifacts.get( + id="id", ) ``` @@ -6011,39 +7162,7 @@ client.alerts.list(
-**start_ts:** `typing.Optional[str]` — Start timestamp (ISO format) for querying events - -
-
- -
-
- -**end_ts:** `typing.Optional[str]` — End timestamp (ISO format) for querying events - -
-
- -
-
- -**cluster_id:** `typing.Optional[str]` — Cluster id - -
-
- -
-
- -**application_id:** `typing.Optional[str]` — Application id - -
-
- -
-
- -**alert_status:** `typing.Optional[AlertStatus]` — Alert status +**id:** `str`
@@ -6063,8 +7182,7 @@ client.alerts.list(
-## Logs -
client.logs.get(...) -> AsyncHttpResponse[GetLogsResponse] +
client.artifacts.delete(...) -> EmptyResponse
@@ -6076,7 +7194,7 @@ client.alerts.list(
-Fetch logs for various workload components, including Services, Jobs, Workflows, Job Runs, and Pods. Logs are filtered based on the provided query parameters. +Delete an artifact by its ID.
@@ -6091,34 +7209,15 @@ Fetch logs for various workload components, including Services, Jobs, Workflows,
```python -from truefoundry_sdk import ( - LogsSearchFilterType, - LogsSearchOperatorType, - LogsSortingDirection, - TrueFoundry, -) +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.logs.get( - start_ts=1000000, - end_ts=1000000, - 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_regex="podNamesRegex", - search_filters="searchFilters", - search_string="searchString", - search_type=LogsSearchFilterType.REGEX, - search_operator=LogsSearchOperatorType.EQUAL, + +client.artifacts.delete( + id="id", ) ``` @@ -6135,7 +7234,7 @@ client.logs.get(
-**start_ts:** `typing.Optional[int]` — Start timestamp for querying logs, in nanoseconds from the Unix epoch. +**id:** `str`
@@ -6143,79 +7242,77 @@ client.logs.get(
-**end_ts:** `typing.Optional[int]` — End timestamp for querying logs, in nanoseconds from the Unix epoch. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**limit:** `typing.Optional[int]` — Max number of log lines to fetch -
-
-
-**direction:** `typing.Optional[LogsSortingDirection]` — Direction of sorting logs. Can be `asc` or `desc` -
+
+
client.artifacts.list(...) -> ListArtifactsResponse
-**num_logs_to_ignore:** `typing.Optional[int]` — Number of logs corresponding to the starting timestamp to be ignored. - -
-
+#### 📝 Description
-**application_id:** `typing.Optional[str]` — Application ID - -
-
-
-**application_fqn:** `typing.Optional[str]` — Application FQN - +List artifacts with optional filtering by FQN, ML Repo, name, or run ID. +
+
+#### 🔌 Usage +
-**deployment_id:** `typing.Optional[str]` — Deployment ID - -
-
-
-**job_run_name:** `typing.Optional[str]` — Name of the Job Run for which to fetch logs. - +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.artifacts.list( + fqn="fqn", + ml_repo_id="ml_repo_id", + name="name", + offset=1, + limit=1, + run_id="run_id", + include_empty_artifacts=True, +) + +``` +
+
+#### ⚙️ Parameters +
-**pod_name:** `typing.Optional[str]` — Name of Pod for which to fetch logs. - -
-
-
-**container_name:** `typing.Optional[str]` — Name of the Container for which to fetch logs. +**fqn:** `typing.Optional[str]` — Fully qualified name to filter artifacts by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}')
@@ -6223,7 +7320,7 @@ client.logs.get(
-**pod_names:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of pod names for which to fetch logs. +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter artifacts by
@@ -6231,7 +7328,7 @@ client.logs.get(
-**pod_names_regex:** `typing.Optional[str]` — Regex pattern for pod names to fetch logs. +**name:** `typing.Optional[str]` — Name of the artifact to filter by
@@ -6239,7 +7336,7 @@ client.logs.get(
-**search_filters:** `typing.Optional[str]` — JSON string containing array of search filters with string, type and operator +**offset:** `typing.Optional[int]` — Number of artifacts to skip for pagination
@@ -6247,7 +7344,7 @@ client.logs.get(
-**search_string:** `typing.Optional[str]` — String that needs to be matched +**limit:** `typing.Optional[int]` — Maximum number of artifacts to return
@@ -6255,7 +7352,7 @@ client.logs.get(
-**search_type:** `typing.Optional[LogsSearchFilterType]` — Query filter type, `regex` `substring` `ignore_case_substring` +**run_id:** `typing.Optional[str]` — ID of the run to filter artifacts by
@@ -6263,7 +7360,7 @@ client.logs.get(
-**search_operator:** `typing.Optional[LogsSearchOperatorType]` — Comparison operator for filter. `equal` or `not_equal` +**include_empty_artifacts:** `typing.Optional[bool]` — Whether to include artifacts that have no versions
@@ -6283,8 +7380,7 @@ client.logs.get(
-## MlRepos -
client.ml_repos.create_or_update(...) -> AsyncHttpResponse[GetMlRepoResponse] +
client.artifacts.create_or_update(...) -> GetArtifactVersionResponse
@@ -6296,7 +7392,7 @@ client.logs.get(
-Creates or updates an MLRepo entity based on the provided manifest. +Create or update an artifact version.
@@ -6311,22 +7407,24 @@ Creates or updates an MLRepo entity based on the provided manifest.
```python -from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry +from truefoundry_sdk import TrueFoundry, ArtifactManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.ml_repos.create_or_update( - manifest=MlRepoManifest( + +client.artifacts.create_or_update( + manifest=ArtifactManifest( name="name", - storage_integration_fqn="storage_integration_fqn", - collaborators=[ - Collaborator( - subject="subject", - role_id="role_id", - ) - ], + metadata={ + "key": "value" + }, + ml_repo="ml_repo", + type="artifact-version", + source=TrueFoundryManagedSource( + type="truefoundry", + ), ), ) @@ -6344,7 +7442,7 @@ client.ml_repos.create_or_update(
-**manifest:** `MlRepoManifest` — MLRepo manifest +**manifest:** `ArtifactManifest` — Manifest containing metadata for the artifact to apply
@@ -6364,7 +7462,8 @@ client.ml_repos.create_or_update(
-
client.ml_repos.get(...) -> AsyncHttpResponse[GetMlRepoResponse] +## Prompts +
client.prompts.get(...) -> GetPromptResponse
@@ -6376,13 +7475,7 @@ client.ml_repos.create_or_update(
-Get a ml repo by id -Args: - id: Unique identifier of the ml repo to get - user_info: Authenticated user information - -Returns: - GetMLRepoResponse: The ml repo +Get a prompt by its ID.
@@ -6400,10 +7493,11 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.ml_repos.get( + +client.prompts.get( id="id", ) @@ -6441,7 +7535,7 @@ client.ml_repos.get(
-
client.ml_repos.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.prompts.delete(...) -> EmptyResponse
@@ -6453,13 +7547,7 @@ client.ml_repos.get(
-Delete a ml repo -Args: - id: Unique identifier of the ml repo to delete - user_info: Authenticated user information - -Returns: - EmptyResponse: Empty response indicating successful deletion +Delete a prompt by its ID.
@@ -6477,10 +7565,11 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.ml_repos.delete( + +client.prompts.delete( id="id", ) @@ -6518,7 +7607,7 @@ client.ml_repos.delete(
-
client.ml_repos.list(...) -> AsyncPager[MlRepo, ListMlReposResponse] +
client.prompts.list(...) -> ListPromptsResponse
@@ -6530,13 +7619,7 @@ client.ml_repos.delete(
-List ml repos -Args: - filters: Filters for the ml repos - user_info: Authenticated user information - -Returns: - ListMLReposResponse: List of ml repos +List prompts with optional filtering by FQN, ML Repo, or name.
@@ -6554,19 +7637,18 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.ml_repos.list( + +client.prompts.list( + fqn="fqn", + ml_repo_id="ml_repo_id", name="name", - limit=1, offset=1, + limit=1, + include_empty_prompts=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -6582,7 +7664,31 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter prompts by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}') + +
+
+ +
+
+ +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter prompts by + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name of the prompt to filter by + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of prompts to skip for pagination
@@ -6590,7 +7696,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Maximum number of prompts to return
@@ -6598,7 +7704,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**include_empty_prompts:** `typing.Optional[bool]` — Whether to include prompts that have no versions
@@ -6618,11 +7724,24 @@ for page in response.iter_pages():
-## Traces -
client.traces.query_spans(...) -> AsyncPager[TraceSpan, QuerySpansResponse] +
client.prompts.create_or_update(...) -> GetPromptVersionResponse +
+
+ +#### 📝 Description + +
+
+
+Create or update a prompt version. +
+
+
+
+ #### 🔌 Usage
@@ -6632,20 +7751,29 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, ChatPromptManifest, SystemMessage client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.traces.query_spans( - start_time="startTime", + +client.prompts.create_or_update( + manifest=ChatPromptManifest( + name="name", + metadata={ + "key": "value" + }, + ml_repo="ml_repo", + type="chat_prompt", + messages=[ + SystemMessage( + role="system", + content="content", + ) + ], + ), ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -6661,7 +7789,7 @@ for page in response.iter_pages():
-**start_time:** `str` — Start time in ISO 8601 format (e.g., 2025-03-12T00:00:09.872Z) +**manifest:** `ChatPromptManifest` — Manifest containing metadata for the prompt to apply
@@ -6669,63 +7797,72 @@ for page in response.iter_pages():
-**end_time:** `typing.Optional[str]` — End time in ISO 8601 format (e.g., 2025-03-12T00:10:00.000Z). Defaults to current time if not provided. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**trace_ids:** `typing.Optional[typing.Sequence[str]]` — Array of trace IDs to filter by -
+
+## Models +
client.models.get(...) -> GetModelResponse
-**span_ids:** `typing.Optional[typing.Sequence[str]]` — Array of span IDs to filter by - -
-
+#### 📝 Description
-**parent_span_ids:** `typing.Optional[typing.Sequence[str]]` — Array of parent span IDs to filter by - -
-
-
-**created_by_subject_types:** `typing.Optional[typing.Sequence[SubjectType]]` — Array of subject types to filter by - +Get a model by its ID. +
+
+#### 🔌 Usage +
-**created_by_subject_slugs:** `typing.Optional[typing.Sequence[str]]` — Array of subject slugs to filter by - -
-
-
-**application_names:** `typing.Optional[typing.Sequence[str]]` — Array of application names to filter by - +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.models.get( + id="id", +) + +``` +
+
+#### ⚙️ Parameters +
-**limit:** `typing.Optional[int]` — The maximum number of spans to return per page. Defaults to 200 if not provided. +
+
+ +**id:** `str`
@@ -6733,47 +7870,71 @@ for page in response.iter_pages():
-**sort_direction:** `typing.Optional[SortDirection]` — Sort direction for results based on time. Defaults to descending (latest first) +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
-
-
-**page_token:** `typing.Optional[str]` — An opaque string that should be passed as-is from previous response for fetching the next page. Pass `$response.pagination.nextPageToken` from previous response for fetching the next page. -
+
+
client.models.delete(...) -> EmptyResponse
-**tracing_project_fqn:** `typing.Optional[str]` — Tracing project FQN (e.g., truefoundry:tracing-project:tfy-default) - -
-
+#### 📝 Description
-**data_routing_destination:** `typing.Optional[str]` — Data Routing Destination. One of tracingProjectFqn or dataRoutingDestination is required. - +
+
+ +Delete a model by its ID. +
+
+#### 🔌 Usage +
-**filters:** `typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]]` — Array of filters - +
+
+ +```python +from truefoundry_sdk import TrueFoundry + +client = TrueFoundry( + api_key="", + base_url="https://yourhost.com/path/to/api", +) + +client.models.delete( + id="id", +) + +``` +
+
+#### ⚙️ Parameters +
-**include_feedbacks:** `typing.Optional[bool]` — When true, feedback data is included in the response. When false, feedback data is excluded (returns empty array). +
+
+ +**id:** `str`
@@ -6793,11 +7954,24 @@ for page in response.iter_pages():
-## Artifacts -
client.artifacts.get(...) -> AsyncHttpResponse[GetArtifactResponse] +
client.models.list(...) -> ListModelsResponse +
+
+ +#### 📝 Description + +
+
+
+List models with optional filtering by FQN, ML Repo, name, or run ID. +
+
+
+
+ #### 🔌 Usage
@@ -6810,11 +7984,18 @@ for page in response.iter_pages(): from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifacts.get( - id="id", + +client.models.list( + fqn="fqn", + ml_repo_id="ml_repo_id", + name="name", + offset=1, + limit=1, + run_id="run_id", + include_empty_models=True, ) ``` @@ -6831,7 +8012,55 @@ client.artifacts.get(
-**id:** `str` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter models by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}') + +
+
+ +
+
+ +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter models by + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — Name of the model to filter by + +
+
+ +
+
+ +**offset:** `typing.Optional[int]` — Number of models to skip for pagination + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of models to return + +
+
+ +
+
+ +**run_id:** `typing.Optional[str]` — ID of the run to filter models by + +
+
+ +
+
+ +**include_empty_models:** `typing.Optional[bool]` — Whether to include models that have no versions
@@ -6851,10 +8080,24 @@ client.artifacts.get(
-
client.artifacts.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.models.create_or_update(...) -> GetModelVersionResponse +
+
+ +#### 📝 Description +
+
+
+ +Create or update a model version. +
+
+
+
+ #### 🔌 Usage
@@ -6864,14 +8107,25 @@ client.artifacts.get(
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifacts.delete( - id="id", + +client.models.create_or_update( + manifest=ModelManifest( + name="name", + metadata={ + "key": "value" + }, + ml_repo="ml_repo", + type="model-version", + source=TrueFoundryManagedSource( + type="truefoundry", + ), + ), ) ``` @@ -6888,7 +8142,7 @@ client.artifacts.delete(
-**id:** `str` +**manifest:** `ModelManifest` — Manifest containing metadata for the model to apply
@@ -6908,10 +8162,25 @@ client.artifacts.delete(
-
client.artifacts.list(...) -> AsyncPager[Artifact, ListArtifactsResponse] +## ArtifactVersions +
client.artifact_versions.apply_tags(...) -> EmptyResponse +
+
+ +#### 📝 Description +
+
+
+ +Apply tags to an artifact version. +
+
+
+
+ #### 🔌 Usage
@@ -6924,23 +8193,16 @@ client.artifacts.delete( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.artifacts.list( - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - offset=1, - limit=1, - run_id="run_id", - include_empty_artifacts=True, + +client.artifact_versions.apply_tags( + artifact_version_id="artifact_version_id", + tags=[ + "tags" + ], ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -6956,7 +8218,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**artifact_version_id:** `str` — ID of the artifact version to apply tags to
@@ -6964,7 +8226,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**tags:** `typing.List[str]` — List of tags to apply to the artifact version
@@ -6972,7 +8234,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**force:** `typing.Optional[bool]` — Whether to overwrite existing tags if they conflict
@@ -6980,54 +8242,36 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**limit:** `typing.Optional[int]` -
+
+
client.artifact_versions.get(...) -> GetArtifactVersionResponse
-**run_id:** `typing.Optional[str]` - -
-
+#### 📝 Description
-**include_empty_artifacts:** `typing.Optional[bool]` - -
-
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - +Get an artifact version by its ID.
- - - -
- -
client.artifacts.create_or_update(...) -> AsyncHttpResponse[GetArtifactVersionResponse] -
-
- #### 🔌 Usage
@@ -7037,23 +8281,15 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import ( - ArtifactManifest, - TrueFoundry, - TrueFoundryManagedSource, -) +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifacts.create_or_update( - manifest=ArtifactManifest( - name="name", - metadata={"key": "value"}, - ml_repo="ml_repo", - source=TrueFoundryManagedSource(), - ), + +client.artifact_versions.get( + id="id", ) ``` @@ -7070,7 +8306,7 @@ client.artifacts.create_or_update(
-**manifest:** `ArtifactManifest` +**id:** `str`
@@ -7090,11 +8326,24 @@ client.artifacts.create_or_update(
-## Prompts -
client.prompts.get(...) -> AsyncHttpResponse[GetPromptResponse] +
client.artifact_versions.delete(...) -> EmptyResponse +
+
+ +#### 📝 Description + +
+
+
+Delete an artifact version by its ID. +
+
+
+
+ #### 🔌 Usage
@@ -7107,10 +8356,11 @@ client.artifacts.create_or_update( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompts.get( + +client.artifact_versions.delete( id="id", ) @@ -7148,10 +8398,24 @@ client.prompts.get(
-
client.prompts.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.artifact_versions.list(...) -> ListArtifactVersionsResponse +
+
+ +#### 📝 Description + +
+
+
+List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo, name, version, run IDs, or run steps. +
+
+
+
+ #### 🔌 Usage
@@ -7164,11 +8428,20 @@ client.prompts.get( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompts.delete( - id="id", + +client.artifact_versions.list( + tag="tag", + fqn="fqn", + artifact_id="artifact_id", + ml_repo_id="ml_repo_id", + name="name", + version=1, + offset=1, + limit=1, + include_internal_metadata=True, ) ``` @@ -7185,7 +8458,7 @@ client.prompts.delete(
-**id:** `str` +**tag:** `typing.Optional[str]` — Tag to filter artifact versions by
@@ -7193,66 +8466,39 @@ client.prompts.delete(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**fqn:** `typing.Optional[str]` — Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}')
-
-
+
+
+**artifact_id:** `typing.Optional[str]` — ID of the artifact to filter versions by +
-
-
client.prompts.list(...) -> AsyncPager[Prompt, ListPromptsResponse]
-#### 🔌 Usage - -
-
+**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter artifact versions by + +
+
-```python -from truefoundry_sdk import TrueFoundry - -client = TrueFoundry( - api_key="YOUR_API_KEY", - base_url="https://yourhost.com/path/to/api", -) -response = client.prompts.list( - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - offset=1, - limit=1, - include_empty_prompts=True, -) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page - -``` -
-
+**name:** `typing.Optional[str]` — Name of the artifact to filter versions by +
-#### ⚙️ Parameters -
-
-
- -**fqn:** `typing.Optional[str]` +**version:** `typing.Optional[int]` — Version number (positive integer) or 'latest' to filter by specific version
@@ -7260,7 +8506,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of run IDs to filter artifact versions by
@@ -7268,7 +8514,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` — List of run step numbers to filter artifact versions by
@@ -7276,7 +8522,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**offset:** `typing.Optional[int]` — Number of artifact versions to skip for pagination
@@ -7284,7 +8530,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Maximum number of artifact versions to return
@@ -7292,7 +8538,7 @@ for page in response.iter_pages():
-**include_empty_prompts:** `typing.Optional[bool]` +**include_internal_metadata:** `typing.Optional[bool]` — Whether to include internal metadata in the response
@@ -7312,10 +8558,24 @@ for page in response.iter_pages():
-
client.prompts.create_or_update(...) -> AsyncHttpResponse[GetPromptVersionResponse] +
client.artifact_versions.get_signed_urls(...) -> GetSignedUrLsResponse +
+
+ +#### 📝 Description +
+
+
+ +Get pre-signed URLs for reading or writing files in an artifact version. +
+
+
+
+ #### 🔌 Usage
@@ -7325,23 +8585,19 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import ChatPromptManifest, SystemMessage, TrueFoundry +from truefoundry_sdk import TrueFoundry, Operation client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompts.create_or_update( - manifest=ChatPromptManifest( - name="name", - metadata={"key": "value"}, - ml_repo="ml_repo", - messages=[ - SystemMessage( - content="content", - ) - ], - ), + +client.artifact_versions.get_signed_urls( + id="id", + paths=[ + "paths" + ], + operation=Operation.READ, ) ``` @@ -7358,7 +8614,7 @@ client.prompts.create_or_update(
-**manifest:** `ChatPromptManifest` +**request:** `GetSignedUrLsRequest`
@@ -7378,11 +8634,24 @@ client.prompts.create_or_update(
-## Models -
client.models.get(...) -> AsyncHttpResponse[GetModelResponse] +
client.artifact_versions.create_multi_part_upload(...) -> MultiPartUploadResponse +
+
+ +#### 📝 Description + +
+
+
+Create a multipart upload for large files in an artifact version. +
+
+
+
+ #### 🔌 Usage
@@ -7395,11 +8664,14 @@ client.prompts.create_or_update( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.models.get( + +client.artifact_versions.create_multi_part_upload( id="id", + path="path", + num_parts=1, ) ``` @@ -7416,7 +8688,7 @@ client.models.get(
-**id:** `str` +**request:** `CreateMultiPartUploadRequest`
@@ -7436,10 +8708,24 @@ client.models.get(
-
client.models.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.artifact_versions.stage(...) -> StageArtifactResponse +
+
+ +#### 📝 Description +
+
+
+ +Stage an artifact version for upload, returning storage location and version ID. +
+
+
+
+ #### 🔌 Usage
@@ -7449,14 +8735,25 @@ client.models.get(
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.models.delete( - id="id", + +client.artifact_versions.stage( + manifest=ModelManifest( + name="name", + metadata={ + "key": "value" + }, + ml_repo="ml_repo", + type="model-version", + source=TrueFoundryManagedSource( + type="truefoundry", + ), + ), ) ``` @@ -7473,7 +8770,7 @@ client.models.delete(
-**id:** `str` +**manifest:** `StageArtifactRequestManifest` — Manifest containing metadata for the artifact to be staged (model or generic artifact)
@@ -7487,15 +8784,29 @@ client.models.delete(
- - + + + + +
+ +
client.artifact_versions.list_files(...) -> ListFilesResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List files and directories in an artifact version. +
+
-
- -
client.models.list(...) -> AsyncPager[Model, ListModelsResponse] -
-
#### 🔌 Usage @@ -7509,23 +8820,13 @@ client.models.delete( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.models.list( - fqn="fqn", - ml_repo_id="ml_repo_id", - name="name", - offset=1, - limit=1, - run_id="run_id", - include_empty_models=True, + +client.artifact_versions.list_files( + id="id", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -7541,7 +8842,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**request:** `ListFilesRequest`
@@ -7549,69 +8850,35 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` - -
-
- -
-
- -**name:** `typing.Optional[str]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**offset:** `typing.Optional[int]` -
-
-
-**limit:** `typing.Optional[int]` -
+
+
client.artifact_versions.mark_stage_failure(...) -> EmptyResponse
-**run_id:** `typing.Optional[str]` - -
-
+#### 📝 Description
-**include_empty_models:** `typing.Optional[bool]` - -
-
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+Mark a staged artifact version as failed. - - -
- -
client.models.create_or_update(...) -> AsyncHttpResponse[GetModelVersionResponse] -
-
#### 🔌 Usage @@ -7622,19 +8889,15 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.models.create_or_update( - manifest=ModelManifest( - name="name", - metadata={"key": "value"}, - ml_repo="ml_repo", - source=TrueFoundryManagedSource(), - ), + +client.artifact_versions.mark_stage_failure( + id="id", ) ``` @@ -7651,7 +8914,7 @@ client.models.create_or_update(
-**manifest:** `ModelManifest` +**id:** `str` — ID of the staged artifact version to mark as failed
@@ -7671,11 +8934,25 @@ client.models.create_or_update(
-## ArtifactVersions -
client.artifact_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse] +## ModelVersions +
client.model_versions.apply_tags(...) -> EmptyResponse +
+
+ +#### 📝 Description + +
+
+
+Apply tags to a model version. +
+
+
+
+ #### 🔌 Usage
@@ -7688,12 +8965,15 @@ client.models.create_or_update( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.apply_tags( - artifact_version_id="artifact_version_id", - tags=["tags"], + +client.model_versions.apply_tags( + model_version_id="model_version_id", + tags=[ + "tags" + ], ) ``` @@ -7710,7 +8990,7 @@ client.artifact_versions.apply_tags(
-**artifact_version_id:** `str` +**model_version_id:** `str` — ID of the model version to apply tags to
@@ -7718,7 +8998,7 @@ client.artifact_versions.apply_tags(
-**tags:** `typing.Sequence[str]` +**tags:** `typing.List[str]` — List of tags to apply to the model version
@@ -7726,7 +9006,7 @@ client.artifact_versions.apply_tags(
-**force:** `typing.Optional[bool]` +**force:** `typing.Optional[bool]` — Whether to overwrite existing tags if they conflict
@@ -7746,7 +9026,7 @@ client.artifact_versions.apply_tags(
-
client.artifact_versions.get(...) -> AsyncHttpResponse[GetArtifactVersionResponse] +
client.model_versions.get(...) -> GetModelVersionResponse
@@ -7758,7 +9038,7 @@ client.artifact_versions.apply_tags(
-Get artifact version API +Get a model version by its ID.
@@ -7776,10 +9056,11 @@ Get artifact version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.get( + +client.model_versions.get( id="id", ) @@ -7817,7 +9098,7 @@ client.artifact_versions.get(
-
client.artifact_versions.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.model_versions.delete(...) -> EmptyResponse
@@ -7829,7 +9110,7 @@ client.artifact_versions.get(
-Delete artifact versions API +Delete a model version by its ID.
@@ -7847,10 +9128,11 @@ Delete artifact versions API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.delete( + +client.model_versions.delete( id="id", ) @@ -7888,7 +9170,7 @@ client.artifact_versions.delete(
-
client.artifact_versions.list(...) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse] +
client.model_versions.list(...) -> ListModelVersionsResponse
@@ -7900,7 +9182,7 @@ client.artifact_versions.delete(
-List artifact version API +List model versions with optional filtering by tag, FQN, model ID, ML Repo, name, version, run IDs, or run steps.
@@ -7918,13 +9200,14 @@ List artifact version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.artifact_versions.list( + +client.model_versions.list( tag="tag", fqn="fqn", - artifact_id="artifact_id", + model_id="model_id", ml_repo_id="ml_repo_id", name="name", version=1, @@ -7932,11 +9215,6 @@ response = client.artifact_versions.list( limit=1, include_internal_metadata=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -7952,7 +9230,7 @@ for page in response.iter_pages():
-**tag:** `typing.Optional[str]` +**tag:** `typing.Optional[str]` — Tag to filter model versions by
@@ -7960,7 +9238,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter model versions by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}' or 'model:{tenant_name}/{ml_repo_name}/{model_name}:{version}')
@@ -7968,7 +9246,7 @@ for page in response.iter_pages():
-**artifact_id:** `typing.Optional[str]` +**model_id:** `typing.Optional[str]` — ID of the model to filter versions by
@@ -7976,7 +9254,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter model versions by
@@ -7984,7 +9262,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Name of the model to filter versions by
@@ -7992,7 +9270,7 @@ for page in response.iter_pages():
-**version:** `typing.Optional[int]` +**version:** `typing.Optional[int]` — Version number (positive integer) or 'latest' to filter by specific version
@@ -8000,7 +9278,7 @@ for page in response.iter_pages():
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` +**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of run IDs to filter model versions by
@@ -8008,7 +9286,7 @@ for page in response.iter_pages():
-**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` +**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` — List of run step numbers to filter model versions by
@@ -8016,7 +9294,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**offset:** `typing.Optional[int]` — Number of model versions to skip for pagination
@@ -8024,7 +9302,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Maximum number of model versions to return
@@ -8032,7 +9310,7 @@ for page in response.iter_pages():
-**include_internal_metadata:** `typing.Optional[bool]` +**include_internal_metadata:** `typing.Optional[bool]` — Whether to include internal metadata in the response
@@ -8052,10 +9330,25 @@ for page in response.iter_pages():
-
client.artifact_versions.get_signed_urls(...) -> AsyncHttpResponse[GetSignedUrLsResponse] +## PromptVersions +
client.prompt_versions.apply_tags(...) -> EmptyResponse +
+
+ +#### 📝 Description +
+
+
+ +Apply tags to a prompt version. +
+
+
+
+ #### 🔌 Usage
@@ -8065,16 +9358,18 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import Operation, TrueFoundry +from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.get_signed_urls( - id="id", - paths=["paths"], - operation=Operation.READ, + +client.prompt_versions.apply_tags( + prompt_version_id="prompt_version_id", + tags=[ + "tags" + ], ) ``` @@ -8091,7 +9386,7 @@ client.artifact_versions.get_signed_urls(
-**id:** `str` +**prompt_version_id:** `str` — ID of the prompt version to apply tags to
@@ -8099,7 +9394,7 @@ client.artifact_versions.get_signed_urls(
-**paths:** `typing.Sequence[str]` +**tags:** `typing.List[str]` — List of tags to apply to the prompt version
@@ -8107,7 +9402,7 @@ client.artifact_versions.get_signed_urls(
-**operation:** `Operation` +**force:** `typing.Optional[bool]` — Whether to overwrite existing tags if they conflict
@@ -8127,10 +9422,24 @@ client.artifact_versions.get_signed_urls(
-
client.artifact_versions.create_multi_part_upload(...) -> AsyncHttpResponse[MultiPartUploadResponse] +
client.prompt_versions.get(...) -> GetPromptVersionResponse +
+
+ +#### 📝 Description + +
+
+
+Get a prompt version by its ID. +
+
+
+
+ #### 🔌 Usage
@@ -8143,13 +9452,12 @@ client.artifact_versions.get_signed_urls( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.create_multi_part_upload( + +client.prompt_versions.get( id="id", - path="path", - num_parts=1, ) ``` @@ -8174,22 +9482,6 @@ client.artifact_versions.create_multi_part_upload(
-**path:** `str` - -
-
- -
-
- -**num_parts:** `int` - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8202,71 +9494,23 @@ client.artifact_versions.create_multi_part_upload(
-
client.artifact_versions.stage(...) -> AsyncHttpResponse[StageArtifactResponse] -
-
- -#### 🔌 Usage - -
-
- +
client.prompt_versions.delete(...) -> EmptyResponse
-```python -from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource - -client = TrueFoundry( - api_key="YOUR_API_KEY", - base_url="https://yourhost.com/path/to/api", -) -client.artifact_versions.stage( - manifest=ModelManifest( - name="name", - metadata={"key": "value"}, - ml_repo="ml_repo", - source=TrueFoundryManagedSource(), - ), -) - -``` -
-
-
-
- -#### ⚙️ Parameters - -
-
+#### 📝 Description
-**manifest:** `StageArtifactRequestManifest` - -
-
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+Delete a prompt version by its ID.
- -
-
- -
client.artifact_versions.list_files(...) -> AsyncPager[FileInfo, ListFilesResponse] -
-
#### 🔌 Usage @@ -8280,17 +9524,13 @@ client.artifact_versions.stage( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.artifact_versions.list_files( + +client.prompt_versions.delete( id="id", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -8314,45 +9554,35 @@ for page in response.iter_pages():
-**path:** `typing.Optional[str]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**limit:** `typing.Optional[int]` -
+
+
client.prompt_versions.list(...) -> ListPromptVersionsResponse
-**page_token:** `typing.Optional[str]` - -
-
+#### 📝 Description
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+
+
+ +List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, name, or version.
- - -
- -
client.artifact_versions.mark_stage_failure(...) -> AsyncHttpResponse[EmptyResponse] -
-
#### 🔌 Usage @@ -8366,11 +9596,19 @@ for page in response.iter_pages(): from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.artifact_versions.mark_stage_failure( - id="id", + +client.prompt_versions.list( + tag="tag", + fqn="fqn", + prompt_id="prompt_id", + ml_repo_id="ml_repo_id", + name="name", + version=1, + offset=1, + limit=1, ) ``` @@ -8387,7 +9625,7 @@ client.artifact_versions.mark_stage_failure(
-**id:** `str` +**tag:** `typing.Optional[str]` — Tag to filter prompt versions by
@@ -8395,58 +9633,39 @@ client.artifact_versions.mark_stage_failure(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**fqn:** `typing.Optional[str]` — Fully qualified name to filter prompt versions by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}' or 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}:{version}')
-
-
- - - - -
- -## ModelVersions -
client.model_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse] -
-
- -#### 🔌 Usage - -
-
-```python -from truefoundry_sdk import TrueFoundry - -client = TrueFoundry( - api_key="YOUR_API_KEY", - base_url="https://yourhost.com/path/to/api", -) -client.model_versions.apply_tags( - model_version_id="model_version_id", - tags=["tags"], -) - -``` +**prompt_id:** `typing.Optional[str]` — ID of the prompt to filter versions by +
+ +
+
+ +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter prompt versions by +
-#### ⚙️ Parameters -
+**name:** `typing.Optional[str]` — Name of the prompt to filter versions by + +
+
+
-**model_version_id:** `str` +**version:** `typing.Optional[int]` — Version number (positive integer) or 'latest' to filter by specific version
@@ -8454,7 +9673,7 @@ client.model_versions.apply_tags(
-**tags:** `typing.Sequence[str]` +**offset:** `typing.Optional[int]` — Number of prompt versions to skip for pagination
@@ -8462,7 +9681,7 @@ client.model_versions.apply_tags(
-**force:** `typing.Optional[bool]` +**limit:** `typing.Optional[int]` — Maximum number of prompt versions to return
@@ -8482,7 +9701,8 @@ client.model_versions.apply_tags(
-
client.model_versions.get(...) -> AsyncHttpResponse[GetModelVersionResponse] +## AgentSkills +
client.agent_skills.get(...) -> GetAgentSkillResponse
@@ -8494,7 +9714,7 @@ client.model_versions.apply_tags(
-Get model version API +Get an agent skill artifact by its ID.
@@ -8512,11 +9732,12 @@ Get model version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.model_versions.get( - id="id", + +client.agent_skills.get( + agent_skill_id="agent_skill_id", ) ``` @@ -8533,7 +9754,7 @@ client.model_versions.get(
-**id:** `str` +**agent_skill_id:** `str`
@@ -8553,7 +9774,7 @@ client.model_versions.get(
-
client.model_versions.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.agent_skills.delete(...) -> EmptyResponse
@@ -8565,7 +9786,7 @@ client.model_versions.get(
-Delete model versions API +Delete an agent skill artifact by its ID.
@@ -8583,11 +9804,12 @@ Delete model versions API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.model_versions.delete( - id="id", + +client.agent_skills.delete( + agent_skill_id="agent_skill_id", ) ``` @@ -8604,7 +9826,7 @@ client.model_versions.delete(
-**id:** `str` +**agent_skill_id:** `str`
@@ -8624,7 +9846,7 @@ client.model_versions.delete(
-
client.model_versions.list(...) -> AsyncPager[ModelVersion, ListModelVersionsResponse] +
client.agent_skills.list(...) -> ListAgentSkillsResponse
@@ -8636,7 +9858,7 @@ client.model_versions.delete(
-List model version API +List agent skills with optional filtering by FQN, ML Repo, or name. When present, `latest_version.manifest.source` is `blob-storage` with `description` only; use GET agent skill version for full SKILL.md (inline `source` with `skill_md`).
@@ -8654,25 +9876,18 @@ List model version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.model_versions.list( - tag="tag", + +client.agent_skills.list( fqn="fqn", - model_id="model_id", ml_repo_id="ml_repo_id", name="name", - version=1, offset=1, limit=1, - include_internal_metadata=True, + include_empty_agent_skills=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -8688,7 +9903,7 @@ for page in response.iter_pages():
-**tag:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter agent skills by (format: 'agent_skill:{tenant}/{ml_repo}/{agent_skill_name}')
@@ -8696,7 +9911,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**ml_repo_id:** `typing.Optional[str]` — ML Repo ID filter
@@ -8704,7 +9919,7 @@ for page in response.iter_pages():
-**model_id:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Agent skill name filter
@@ -8712,7 +9927,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**offset:** `typing.Optional[int]` — Pagination offset
@@ -8720,7 +9935,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**limit:** `typing.Optional[int]` — Page size
@@ -8728,7 +9943,7 @@ for page in response.iter_pages():
-**version:** `typing.Optional[int]` +**include_empty_agent_skills:** `typing.Optional[bool]` — Whether to include agent skills that have no versions
@@ -8736,62 +9951,35 @@ for page in response.iter_pages():
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` -
-
-
-**offset:** `typing.Optional[int]` -
+
+
client.agent_skills.create_or_update(...) -> GetAgentSkillVersionResponse
-**limit:** `typing.Optional[int]` - -
-
+#### 📝 Description
-**include_internal_metadata:** `typing.Optional[bool]` - -
-
-
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+Create or update an agent skill version from a manifest. - - -
- -## PromptVersions -
client.prompt_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse] -
-
#### 🔌 Usage @@ -8802,15 +9990,26 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import TrueFoundry, AgentSkillManifest, AgentSkillSourceInline client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompt_versions.apply_tags( - prompt_version_id="prompt_version_id", - tags=["tags"], + +client.agent_skills.create_or_update( + manifest=AgentSkillManifest( + name="name", + metadata={ + "key": "value" + }, + ml_repo="ml_repo", + type="agent_skill", + source=AgentSkillSourceInline( + type="inline", + skill_md="skill_md", + ), + ), ) ``` @@ -8827,23 +10026,7 @@ client.prompt_versions.apply_tags(
-**prompt_version_id:** `str` - -
-
- -
-
- -**tags:** `typing.Sequence[str]` - -
-
- -
-
- -**force:** `typing.Optional[bool]` +**manifest:** `AgentSkillManifest` — Manifest containing metadata for the agent skill to apply
@@ -8863,24 +10046,11 @@ client.prompt_versions.apply_tags(
-
client.prompt_versions.get(...) -> AsyncHttpResponse[GetPromptVersionResponse] -
-
- -#### 📝 Description - +## AgentSkillVersions +
client.agent_skill_versions.get(...) -> GetAgentSkillVersionResponse
-
-
- -Get prompt version API -
-
-
-
- #### 🔌 Usage
@@ -8893,11 +10063,12 @@ Get prompt version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompt_versions.get( - id="id", + +client.agent_skill_versions.get( + agent_skill_version_id="agent_skill_version_id", ) ``` @@ -8914,7 +10085,7 @@ client.prompt_versions.get(
-**id:** `str` +**agent_skill_version_id:** `str`
@@ -8934,24 +10105,10 @@ client.prompt_versions.get(
-
client.prompt_versions.delete(...) -> AsyncHttpResponse[EmptyResponse] -
-
- -#### 📝 Description - -
-
- +
client.agent_skill_versions.delete(...) -> EmptyResponse
-Delete prompt versions API -
-
-
-
- #### 🔌 Usage
@@ -8964,11 +10121,12 @@ Delete prompt versions API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -client.prompt_versions.delete( - id="id", + +client.agent_skill_versions.delete( + agent_skill_version_id="agent_skill_version_id", ) ``` @@ -8985,7 +10143,7 @@ client.prompt_versions.delete(
-**id:** `str` +**agent_skill_version_id:** `str`
@@ -9005,7 +10163,7 @@ client.prompt_versions.delete(
-
client.prompt_versions.list(...) -> AsyncPager[PromptVersion, ListPromptVersionsResponse] +
client.agent_skill_versions.list(...) -> ListAgentSkillVersionsResponse
@@ -9017,7 +10175,7 @@ client.prompt_versions.delete(
-List prompt version API +List agent skill versions. Each manifest has `source.type` `blob-storage` and `description` only; use GET for full SKILL.md content.
@@ -9035,24 +10193,19 @@ List prompt version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.prompt_versions.list( - tag="tag", + +client.agent_skill_versions.list( fqn="fqn", - prompt_id="prompt_id", + agent_skill_id="agent_skill_id", ml_repo_id="ml_repo_id", name="name", version=1, offset=1, limit=1, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -9068,7 +10221,7 @@ for page in response.iter_pages():
-**tag:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — FQN filter for agent skill versions
@@ -9076,7 +10229,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**agent_skill_id:** `typing.Optional[str]` — Parent agent skill artifact ID
@@ -9084,7 +10237,7 @@ for page in response.iter_pages():
-**prompt_id:** `typing.Optional[str]` +**ml_repo_id:** `typing.Optional[str]` — ML Repo ID filter
@@ -9092,7 +10245,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Agent skill name filter
@@ -9100,7 +10253,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**version:** `typing.Optional[int]` — Version number or 'latest'
@@ -9108,7 +10261,7 @@ for page in response.iter_pages():
-**version:** `typing.Optional[int]` +**offset:** `typing.Optional[int]` — Pagination offset
@@ -9116,15 +10269,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` - -
-
- -
-
- -**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Page size
@@ -9145,7 +10290,7 @@ for page in response.iter_pages():
## DataDirectories -
client.data_directories.get(...) -> AsyncHttpResponse[GetDataDirectoryResponse] +
client.data_directories.get(...) -> GetDataDirectoryResponse
@@ -9158,13 +10303,6 @@ for page in response.iter_pages():
Get a data directory by its ID. - -Args: - id (str): The ID of the data directory to retrieve - user_info: Current authenticated user info - -Returns: - DataDirectoryResponse: Response containing the retrieved data directory
@@ -9182,9 +10320,10 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.get( id="id", ) @@ -9223,7 +10362,7 @@ client.data_directories.get(
-
client.data_directories.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.data_directories.delete(...) -> EmptyResponse
@@ -9235,15 +10374,7 @@ client.data_directories.get(
-Delete a data directory and optionally its contents. - -Args: - id: Unique identifier of the data directory to delete - delete_contents: If True, also deletes the data directory's contents - user_info: Authenticated user information - -Returns: - EmptyResponse: Empty response indicating successful deletion +Delete a data directory, optionally including its contents.
@@ -9261,9 +10392,10 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.delete( id="id", delete_contents=True, @@ -9311,7 +10443,7 @@ client.data_directories.delete(
-
client.data_directories.list(...) -> AsyncPager[DataDirectory, ListDataDirectoriesResponse] +
client.data_directories.list(...) -> ListDataDirectoriesResponse
@@ -9323,18 +10455,7 @@ client.data_directories.delete(
-List all data directories with optional filtering and pagination. - -Args: - filters: Query parameters for filtering and pagination - - ml_repo_id: Filter data directories by ml repo ID - - name: Optional filter data directories by name - - limit: Optional maximum number of data directories to return - - offset: Optional number of data directories to skip - user_info: Authenticated user information - -Returns: - ListDataDirectoriesResponse: List of data directories and pagination info +List data directories with optional filtering by FQN, ML Repo, or name.
@@ -9352,21 +10473,17 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.data_directories.list( + +client.data_directories.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", limit=1, offset=1, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -9382,7 +10499,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter data directories by
@@ -9390,7 +10507,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter data directories by
@@ -9398,7 +10515,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Name of the data directory to filter by
@@ -9406,7 +10523,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Maximum number of data directories to return
@@ -9414,7 +10531,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**offset:** `typing.Optional[int]` — Number of data directories to skip for pagination
@@ -9434,10 +10551,24 @@ for page in response.iter_pages():
-
client.data_directories.create_or_update(...) -> AsyncHttpResponse[GetDataDirectoryResponse] +
client.data_directories.create_or_update(...) -> GetDataDirectoryResponse
+#### 📝 Description + +
+
+ +
+
+ +Create or update a data directory. +
+
+
+
+ #### 🔌 Usage
@@ -9447,22 +10578,24 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import ( - DataDirectoryManifest, - TrueFoundry, - TrueFoundryManagedSource, -) +from truefoundry_sdk import TrueFoundry, DataDirectoryManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.create_or_update( manifest=DataDirectoryManifest( + type="data-dir", name="name", ml_repo="ml_repo", - metadata={"key": "value"}, - source=TrueFoundryManagedSource(), + metadata={ + "key": "value" + }, + source=TrueFoundryManagedSource( + type="truefoundry", + ), ), ) @@ -9480,7 +10613,7 @@ client.data_directories.create_or_update(
-**manifest:** `DataDirectoryManifest` +**manifest:** `DataDirectoryManifest` — Manifest containing metadata for the data directory to apply
@@ -9500,7 +10633,7 @@ client.data_directories.create_or_update(
-
client.data_directories.list_files(...) -> AsyncPager[FileInfo, ListFilesResponse] +
client.data_directories.list_files(...) -> ListFilesResponse
@@ -9512,14 +10645,7 @@ client.data_directories.create_or_update(
-List files in a dataset. - -Args: - request_dto: Request containing dataset ID, path, page token and limit - user_info: Authenticated user information - -Returns: - ListFilesResponse: Response containing files and pagination info +List files and directories in a data directory.
@@ -9537,17 +10663,13 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.data_directories.list_files( + +client.data_directories.list_files( id="id", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -9563,31 +10685,7 @@ for page in response.iter_pages():
-**id:** `str` - -
-
- -
-
- -**path:** `typing.Optional[str]` - -
-
- -
-
- -**limit:** `typing.Optional[int]` - -
-
- -
-
- -**page_token:** `typing.Optional[str]` +**request:** `ListFilesRequest`
@@ -9607,7 +10705,7 @@ for page in response.iter_pages():
-
client.data_directories.delete_files(...) -> AsyncHttpResponse[EmptyResponse] +
client.data_directories.delete_files(...) -> EmptyResponse
@@ -9619,14 +10717,7 @@ for page in response.iter_pages():
-Delete files from the dataset. - -Args: - request_dto: Request containing dataset ID and paths - user_info: Authenticated user information - -Returns: - EmptyResponse: Empty response indicating successful deletion +Delete files from a data directory.
@@ -9644,12 +10735,15 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.delete_files( id="id", - paths=["paths"], + paths=[ + "paths" + ], ) ``` @@ -9666,7 +10760,7 @@ client.data_directories.delete_files(
-**id:** `str` +**id:** `str` — ID of the artifact version to delete files from
@@ -9674,7 +10768,7 @@ client.data_directories.delete_files(
-**paths:** `typing.Sequence[str]` +**paths:** `typing.List[str]` — List of relative file paths within the artifact version to delete
@@ -9694,7 +10788,7 @@ client.data_directories.delete_files(
-
client.data_directories.get_signed_urls(...) -> AsyncHttpResponse[GetSignedUrLsResponse] +
client.data_directories.get_signed_urls(...) -> GetSignedUrLsResponse
@@ -9706,14 +10800,7 @@ client.data_directories.delete_files(
-Get signed URLs for a dataset. - -Args: - request_dto: Request containing dataset ID, paths and operation - user_info: Authenticated user information - -Returns: - GetSignedURLsResponse: Response containing signed URLs +Get pre-signed URLs for reading or writing files in a data directory.
@@ -9728,15 +10815,18 @@ Returns:
```python -from truefoundry_sdk import Operation, TrueFoundry +from truefoundry_sdk import TrueFoundry, Operation client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.get_signed_urls( id="id", - paths=["paths"], + paths=[ + "paths" + ], operation=Operation.READ, ) @@ -9754,23 +10844,7 @@ client.data_directories.get_signed_urls(
-**id:** `str` - -
-
- -
-
- -**paths:** `typing.Sequence[str]` - -
-
- -
-
- -**operation:** `Operation` +**request:** `GetSignedUrLsRequest`
@@ -9790,7 +10864,7 @@ client.data_directories.get_signed_urls(
-
client.data_directories.create_multipart_upload(...) -> AsyncHttpResponse[MultiPartUploadResponse] +
client.data_directories.create_multipart_upload(...) -> MultiPartUploadResponse
@@ -9802,14 +10876,7 @@ client.data_directories.get_signed_urls(
-Create a multipart upload for a dataset - -Args: - request_dto: Request containing dataset ID, path and number of parts - user_info: Authenticated user information - -Returns: - MultiPartUploadResponse: Response containing multipart upload info +Create a multipart upload for large files in a data directory.
@@ -9827,9 +10894,10 @@ Returns: from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.data_directories.create_multipart_upload( id="id", path="path", @@ -9850,23 +10918,7 @@ client.data_directories.create_multipart_upload(
-**id:** `str` - -
-
- -
-
- -**path:** `str` - -
-
- -
-
- -**num_parts:** `int` +**request:** `CreateMultiPartUploadRequest`
@@ -9887,7 +10939,7 @@ client.data_directories.create_multipart_upload(
## Internal Users -
client.internal.users.get_info() -> AsyncHttpResponse[Session] +
client.internal.users.get_info() -> Session
@@ -9917,9 +10969,10 @@ Get the user session details for the currently authenticated user from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.users.get_info() ``` @@ -9949,7 +11002,7 @@ client.internal.users.get_info()
## Internal AiGateway -
client.internal.ai_gateway.get_gateway_config(...) -> AsyncHttpResponse[GatewayConfiguration] +
client.internal.ai_gateway.get_gateway_config(...) -> GatewayConfiguration
@@ -9977,14 +11030,13 @@ Get Gateway configuration based on type for the tenant. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.internal.ai_gateway import ( - AiGatewayGetGatewayConfigRequestType, -) +from truefoundry_sdk.internal.ai_gateway import AiGatewayGetGatewayConfigRequestType client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.ai_gateway.get_gateway_config( type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, ) @@ -10024,7 +11076,7 @@ client.internal.ai_gateway.get_gateway_config(
## Internal Clusters -
client.internal.clusters.get_autoprovisioning_state(...) -> AsyncHttpResponse[GetAutoProvisioningStateResponse] +
client.internal.clusters.get_autoprovisioning_state(...) -> GetAutoProvisioningStateResponse
@@ -10054,9 +11106,10 @@ Get the auto provisioning status for the provided cluster from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.clusters.get_autoprovisioning_state( id="id", ) @@ -10096,7 +11149,7 @@ client.internal.clusters.get_autoprovisioning_state(
## Internal Deployments -
client.internal.deployments.get_deployment_statuses(...) -> AsyncHttpResponse[typing.List[DeploymentStatus]] +
client.internal.deployments.get_deployment_statuses(...) -> typing.List[DeploymentStatus]
@@ -10126,9 +11179,10 @@ This endpoint returns all statuses for a specific deployment in a given applicat from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.deployments.get_deployment_statuses( id="id", deployment_id="deploymentId", @@ -10176,7 +11230,7 @@ client.internal.deployments.get_deployment_statuses(
-
client.internal.deployments.get_builds(...) -> AsyncHttpResponse[typing.List[DeploymentBuild]] +
client.internal.deployments.get_builds(...) -> typing.List[DeploymentBuild]
@@ -10206,9 +11260,10 @@ This endpoint returns all build details associated with a specific deployment in from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.deployments.get_builds( id="id", deployment_id="deploymentId", @@ -10256,7 +11311,7 @@ client.internal.deployments.get_builds(
-
client.internal.deployments.get_code_upload_url(...) -> AsyncHttpResponse[PresignedUrlObject] +
client.internal.deployments.get_code_upload_url(...) -> PresignedUrlObject
@@ -10286,9 +11341,10 @@ Generate presigned URL to upload code for given serviceName and workspaceFqn from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.deployments.get_code_upload_url( service_name="serviceName", workspace_fqn="workspaceFqn", @@ -10336,7 +11392,7 @@ client.internal.deployments.get_code_upload_url(
-
client.internal.deployments.get_suggested_endpoint(...) -> AsyncHttpResponse[GetSuggestedDeploymentEndpointResponse] +
client.internal.deployments.get_suggested_endpoint(...) -> GetSuggestedDeploymentEndpointResponse
@@ -10363,12 +11419,13 @@ Generate deployment endpoint based on the provided query parameters.
```python -from truefoundry_sdk import ApplicationType, TrueFoundry +from truefoundry_sdk import TrueFoundry, ApplicationType client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.deployments.get_suggested_endpoint( application_type=ApplicationType.ASYNC_SERVICE, application_name="applicationName", @@ -10453,7 +11510,7 @@ client.internal.deployments.get_suggested_endpoint(
## Internal Applications -
client.internal.applications.promote_rollout(...) -> AsyncHttpResponse[None] +
client.internal.applications.promote_rollout(...)
@@ -10483,9 +11540,10 @@ Promote an application rollout for canary and blue-green. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.applications.promote_rollout( id="id", full=True, @@ -10533,7 +11591,7 @@ client.internal.applications.promote_rollout(
-
client.internal.applications.get_pod_template_hash_to_deployment_version(...) -> AsyncHttpResponse[typing.Dict[str, float]] +
client.internal.applications.get_pod_template_hash_to_deployment_version(...) -> typing.Dict[str, float]
@@ -10563,9 +11621,10 @@ This endpoint fetches the pod template hash to deployment version map for a spec from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.applications.get_pod_template_hash_to_deployment_version( id="id", pod_template_hashes="podTemplateHashes", @@ -10614,7 +11673,7 @@ client.internal.applications.get_pod_template_hash_to_deployment_version(
## Internal Metrics -
client.internal.metrics.get_charts(...) -> AsyncHttpResponse[GetChartsResponse] +
client.internal.metrics.get_charts(...) -> GetChartsResponse
@@ -10645,9 +11704,10 @@ from truefoundry_sdk import TrueFoundry from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.metrics.get_charts( workspace_id="workspaceId", application_id="applicationId", @@ -10732,7 +11792,7 @@ client.internal.metrics.get_charts(
## Internal Vcs -
client.internal.vcs.get_repository_details(...) -> AsyncHttpResponse[GitRepositoryExistsResponse] +
client.internal.vcs.get_repository_details(...) -> GitRepositoryExistsResponse
@@ -10748,9 +11808,10 @@ client.internal.metrics.get_charts( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.vcs.get_repository_details( repo_url="repoURL", ) @@ -10797,7 +11858,7 @@ client.internal.vcs.get_repository_details(
-
client.internal.vcs.get_authenticated_url(...) -> AsyncHttpResponse[GetAuthenticatedVcsurlResponse] +
client.internal.vcs.get_authenticated_url(...) -> GetAuthenticatedVcsurlResponse
@@ -10813,9 +11874,10 @@ client.internal.vcs.get_repository_details( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.vcs.get_authenticated_url( repo_url="repoURL", ) @@ -10855,7 +11917,7 @@ client.internal.vcs.get_authenticated_url(
## Internal DockerRegistries -
client.internal.docker_registries.create_repository(...) -> AsyncHttpResponse[DockerRegistriesCreateRepositoryResponse] +
client.internal.docker_registries.create_repository(...) -> CreateDockerRepositoryResponse
@@ -10885,9 +11947,10 @@ Create a docker repository in the provided workspace. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.docker_registries.create_repository( fqn="fqn", application_name="applicationName", @@ -10944,7 +12007,7 @@ client.internal.docker_registries.create_repository(
-
client.internal.docker_registries.get_credentials(...) -> AsyncHttpResponse[DockerRegistriesGetCredentialsResponse] +
client.internal.docker_registries.get_credentials(...) -> GetDockerRegistryCredentialsResponse
@@ -10974,9 +12037,10 @@ Get docker registry credentials for building and pushing an image. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.docker_registries.get_credentials( fqn="fqn", cluster_id="clusterId", @@ -11025,7 +12089,7 @@ client.internal.docker_registries.get_credentials(
## Internal Workflows -
client.internal.workflows.execute_workflow(...) -> AsyncHttpResponse[WorkflowsExecuteWorkflowResponse] +
client.internal.workflows.execute_workflow(...) -> WorkflowsExecuteWorkflowResponse
@@ -11055,9 +12119,10 @@ Execute a workflow for the specified application from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.workflows.execute_workflow( application_id="applicationId", ) @@ -11113,7 +12178,7 @@ client.internal.workflows.execute_workflow(
## Internal BuildLogs -
client.internal.build_logs.get(...) -> AsyncHttpResponse[LogsResponse] +
client.internal.build_logs.get(...) -> LogsResponse
@@ -11143,9 +12208,10 @@ Get logs for a given pipeline run by its name, with optional filters and time ra from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.build_logs.get( pipeline_run_name="pipelineRunName", start_ts="1635467890123456789", @@ -11238,10 +12304,7 @@ client.internal.build_logs.get(
## Internal ArtifactVersions -
client.internal.artifact_versions.list(...) -> AsyncPager[ - InternalListArtifactVersionsResponseDataItem, - InternalListArtifactVersionsResponse, -] +
client.internal.artifact_versions.list(...) -> InternalListArtifactVersionsResponse
@@ -11253,7 +12316,7 @@ client.internal.build_logs.get(
-List artifact version API +List artifact versions with internal metadata, optionally including model versions.
@@ -11271,10 +12334,11 @@ List artifact version API from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) -response = client.internal.artifact_versions.list( + +client.internal.artifact_versions.list( tag="tag", fqn="fqn", artifact_id="artifact_id", @@ -11286,11 +12350,6 @@ response = client.internal.artifact_versions.list( include_internal_metadata=True, include_model_versions=True, ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -11306,7 +12365,7 @@ for page in response.iter_pages():
-**tag:** `typing.Optional[str]` +**tag:** `typing.Optional[str]` — Tag to filter artifact versions by
@@ -11314,7 +12373,7 @@ for page in response.iter_pages():
-**fqn:** `typing.Optional[str]` +**fqn:** `typing.Optional[str]` — Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}')
@@ -11322,7 +12381,7 @@ for page in response.iter_pages():
-**artifact_id:** `typing.Optional[str]` +**artifact_id:** `typing.Optional[str]` — ID of the artifact to filter versions by
@@ -11330,7 +12389,7 @@ for page in response.iter_pages():
-**ml_repo_id:** `typing.Optional[str]` +**ml_repo_id:** `typing.Optional[str]` — ID of the ML Repo to filter artifact versions by
@@ -11338,7 +12397,7 @@ for page in response.iter_pages():
-**name:** `typing.Optional[str]` +**name:** `typing.Optional[str]` — Name of the artifact to filter versions by
@@ -11346,7 +12405,7 @@ for page in response.iter_pages():
-**version:** `typing.Optional[int]` +**version:** `typing.Optional[int]` — Version number (positive integer) or 'latest' to filter by specific version
@@ -11354,7 +12413,7 @@ for page in response.iter_pages():
-**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` +**run_ids:** `typing.Optional[typing.Union[str, typing.Sequence[str]]]` — List of run IDs to filter artifact versions by
@@ -11362,7 +12421,7 @@ for page in response.iter_pages():
-**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` +**run_steps:** `typing.Optional[typing.Union[int, typing.Sequence[int]]]` — List of run step numbers to filter artifact versions by
@@ -11370,7 +12429,7 @@ for page in response.iter_pages():
-**offset:** `typing.Optional[int]` +**offset:** `typing.Optional[int]` — Number of artifact versions to skip for pagination
@@ -11378,7 +12437,7 @@ for page in response.iter_pages():
-**limit:** `typing.Optional[int]` +**limit:** `typing.Optional[int]` — Maximum number of artifact versions to return
@@ -11386,7 +12445,7 @@ for page in response.iter_pages():
-**include_internal_metadata:** `typing.Optional[bool]` +**include_internal_metadata:** `typing.Optional[bool]` — Whether to include internal metadata in the response
@@ -11394,7 +12453,7 @@ for page in response.iter_pages():
-**include_model_versions:** `typing.Optional[bool]` +**include_model_versions:** `typing.Optional[bool]` — Whether to include model versions in the results (internal use only)
@@ -11415,10 +12474,24 @@ for page in response.iter_pages():
## Internal Ml -
client.internal.ml.apply(...) -> AsyncHttpResponse[ApplyMlEntityResponse] +
client.internal.ml.apply(...) -> ApplyMlEntityResponse +
+
+ +#### 📝 Description + +
+
+
+Create or update an ML entity (model, prompt, artifact, or data directory). +
+
+
+
+ #### 🔌 Usage
@@ -11428,18 +12501,24 @@ for page in response.iter_pages():
```python -from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource +from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.ml.apply( manifest=ModelManifest( name="name", - metadata={"key": "value"}, + metadata={ + "key": "value" + }, ml_repo="ml_repo", - source=TrueFoundryManagedSource(), + type="model-version", + source=TrueFoundryManagedSource( + type="truefoundry", + ), ), ) @@ -11457,7 +12536,7 @@ client.internal.ml.apply(
-**manifest:** `ApplyMlEntityRequestManifest` +**manifest:** `ApplyMlEntityRequestManifest` — Manifest containing metadata for the ML entity to apply (model, prompt, artifact, agent skill, or data directory)
@@ -11477,10 +12556,24 @@ client.internal.ml.apply(
-
client.internal.ml.delete(...) -> AsyncHttpResponse[EmptyResponse] +
client.internal.ml.delete(...) -> EmptyResponse +
+
+ +#### 📝 Description + +
+
+
+Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML Repo) by manifest. +
+
+
+
+ #### 🔌 Usage
@@ -11490,18 +12583,24 @@ client.internal.ml.apply(
```python -from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource +from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource client = TrueFoundry( - api_key="YOUR_API_KEY", + api_key="", base_url="https://yourhost.com/path/to/api", ) + client.internal.ml.delete( manifest=ModelManifest( name="name", - metadata={"key": "value"}, + metadata={ + "key": "value" + }, ml_repo="ml_repo", - source=TrueFoundryManagedSource(), + type="model-version", + source=TrueFoundryManagedSource( + type="truefoundry", + ), ), ) @@ -11519,7 +12618,7 @@ client.internal.ml.delete(
-**manifest:** `DeleteMlEntityRequestManifest` +**manifest:** `DeleteMlEntityRequestManifest` — Manifest identifying the ML entity to delete (model, prompt, artifact, agent skill, data directory, or ML Repo)
diff --git a/requirements.txt b/requirements.txt index e80f640a..0141a1a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ httpx>=0.21.2 pydantic>= 1.9.2 -pydantic-core>=2.18.2 +pydantic-core>=2.18.2,<2.44.0 typing_extensions>= 4.0.0 diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 137af53b..f65b2955 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -7,6 +7,7 @@ if typing.TYPE_CHECKING: from .types import ( + A2AFramework, Account, AccountInfo, ActivateUserResponse, @@ -14,14 +15,23 @@ AddonComponent, AddonComponentName, AddonComponentStatus, + AgentFramework, AgentManifest, AgentSkill, + AgentSkillManifest, + AgentSkillManifestSource, + AgentSkillSourceBlobStorage, + AgentSkillSourceInline, + AgentSkillVersion, AgentSource, Ai21Integrations, Ai21KeyAuth, Ai21Model, Ai21ProviderAccount, AiFeaturesSettings, + AktoGuardrailConfig, + AktoGuardrailConfigConfig, + AktoTokenAuth, Alert, AlertConfig, AlertConfigResource, @@ -38,10 +48,8 @@ AnthropicModel, AnthropicProviderAccount, Application, - ApplicationDebugInfo, ApplicationLifecycleStage, ApplicationMetadata, - ApplicationProblem, ApplicationSet, ApplicationSetComponentsItem, ApplicationType, @@ -114,7 +122,6 @@ AzureOAuth, AzureOpenAiModel, AzureOpenAiModelDeploymentType, - AzureOpenAiModelRegion, AzureOpenAiProviderAccount, AzureOpenAiProviderAccountAuthData, AzurePiiCategory, @@ -134,11 +141,16 @@ BaseAutoscaling, BaseOAuth2Login, BaseOAuth2LoginJwtSource, + BaseRemoteAgent, BaseService, BaseServiceImage, BaseServiceMountsItem, BaseWorkbenchInput, BaseWorkbenchInputMountsItem, + BasetenIntegrations, + BasetenKeyAuth, + BasetenModel, + BasetenProviderAccount, BasicAuthCreds, BedrockModel, BitbucketIntegration, @@ -203,22 +215,28 @@ ContainerTaskConfigMountsItem, CoreNatsOutputConfig, CpuUtilizationMetric, + CreateDockerRepositoryResponse, CreateMultiPartUploadRequest, CreatePersonalAccessTokenResponse, CronMetric, + CustomAgentServerAuth, CustomBasicAuth, CustomBearerAuth, CustomBlobStorage, + CustomFramework, CustomGuardrailConfig, CustomGuardrailConfigAuthData, CustomGuardrailConfigConfig, CustomGuardrailConfigOperation, CustomGuardrailConfigTarget, + CustomHeaderAuth, CustomHelmRepo, CustomIntegrations, CustomJwtAuthIntegration, CustomProviderAccount, CustomRegexPattern, + CustomServerHeaderAuth, + CustomServerPassthrough, CustomTlsSettings, CustomUsernamePasswordArtifactsRegistry, DataAccessRule, @@ -228,6 +246,8 @@ DataDirectoryManifestSource, DatabricksApiKeyAuth, DatabricksIntegrations, + DatabricksJobTaskConfig, + DatabricksJobTaskConfigImage, DatabricksModel, DatabricksProviderAccount, DatabricksProviderAccountAuthData, @@ -327,6 +347,7 @@ GatewayMetadataRule, GatewayMetadataWhen, GatewayOtelConfig, + GatewayOtelConfigOtelMetricsExporterConfig, GatewayOtelConfigOtelTracesExporterConfig, GatewayRequestMetadataFilter, GatewayRequestMetadataFilterOperator, @@ -343,6 +364,9 @@ GcpRegion, GcpTpu, GeminiModel, + GenericSecretStoreIntegration, + GetAgentSkillResponse, + GetAgentSkillVersionResponse, GetAlertsResponse, GetApplicationDeploymentResponse, GetApplicationResponse, @@ -353,6 +377,7 @@ GetChartsResponse, GetClusterResponse, GetDataDirectoryResponse, + GetDockerRegistryCredentialsResponse, GetEnvironmentResponse, GetEventsResponse, GetJobRunResponse, @@ -368,8 +393,10 @@ GetSignedUrLsRequest, GetSignedUrLsResponse, GetSuggestedDeploymentEndpointResponse, + GetTeamPermissionsResponse, GetTeamResponse, GetTokenForVirtualAccountResponse, + GetUserPermissionsResponse, GetUserResourcesResponse, GetUserResponse, GetUserTeamsResponse, @@ -389,6 +416,7 @@ GoogleModelArmorGuardrailConfig, GoogleModelArmorGuardrailConfigAuthData, GoogleModelArmorGuardrailConfigConfig, + GoogleModelArmorGuardrailConfigOperation, GoogleModelArmorKeyFileAuth, GoogleModelArmorKeyFileAuthKeyFileContent, GoogleVertexProviderAccount, @@ -409,12 +437,15 @@ GuardrailsRule, GuardrailsWhen, H2OFramework, + HashicorpAppRoleAuth, HashicorpIntegrations, HashicorpProviderAccount, HashicorpTokenAuth, HashicorpVaultIntegration, + HashicorpVaultIntegrationAuthData, HeaderMatch, HeaderRoutingConfig, + HeadersOverride, HealthProbe, Helm, HelmRepo, @@ -478,8 +509,11 @@ LatencyBasedLoadBalanceTarget, LatencyBasedLoadBalancing, LatencyBasedLoadBalancingRule, + LegacyAgentManifest, LibraryName, LightGbmFramework, + ListAgentSkillVersionsResponse, + ListAgentSkillsResponse, ListApplicationDeploymentsResponse, ListApplicationsResponse, ListArtifactVersionsResponse, @@ -524,13 +558,17 @@ LogsSortingDirection, Manual, McpServerAuth, + McpServerEnvAuth, + McpServerEnvAuthAuthLevel, McpServerHeaderAuth, + McpServerHeaderAuthAuthLevel, McpServerHeaderOverrideAuth, McpServerIntegration, McpServerIntegrationTransport, McpServerIntegrations, McpServerManifest, McpServerOAuth2, + McpServerOAuth2GrantType, McpServerOAuth2JwtSource, McpServerPassthrough, McpServerProviderAccount, @@ -540,6 +578,9 @@ McpServerWithUrl, McpTool, McpToolSetting, + McpToolTarget, + McpToolsOperator, + McpToolsOperatorCondition, Metadata, Metric, MimeType, @@ -600,8 +641,6 @@ OpenAiModel, OpenAiModerationsGuardrailConfig, OpenAiModerationsGuardrailConfigConfig, - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue, - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment, OpenApiSpecSource, OpenApimcpServerManifest, OpenApimcpToolSetting, @@ -613,10 +652,15 @@ OpenaiApiKeyAuth, OpenaiProviderAccount, Operation, - OtelExporterGrpcConfig, - OtelExporterHttpConfig, - OtelExporterHttpConfigEncoding, - OtelExporterSpanAttributeFilter, + OtelExporterGrpcConfigBase, + OtelExporterHttpConfigBase, + OtelExporterHttpConfigBaseEncoding, + OtelMetricsExporterGrpcConfig, + OtelMetricsExporterHttpConfig, + OtelTracesExporterCommonConfig, + OtelTracesExporterGrpcConfig, + OtelTracesExporterHttpConfig, + OtelTracesExporterSpanAttributeFilter, OwnDataAccessRule, OwnedBy, PaddleFramework, @@ -691,10 +735,6 @@ PrivatePricingTier, PrometheusAlertRule, Prompt, - PromptFooGuardType, - PromptFooGuardrailConfig, - PromptFooGuardrailConfigConfig, - PromptFooGuardrailConfigOperation, PromptSource, PromptVersion, ProviderAccounts, @@ -723,19 +763,29 @@ RegexGuardrailConfigConfig, RegexGuardrailConfigOperation, RegisterUsersResponse, + RemoteAgent, RemoteMcpServerManifest, RemoteSource, RemoteSpecSource, Resources, ResourcesDevicesItem, ResourcesNode, + ResponseFormatJsonObject, + ResponseFormatJsonSchema, + ResponseFormatJsonSchemaJsonSchema, + ResponseFormatText, RetryConfig, RevokeAllPersonalAccessTokenResponse, + RoleBindingManifest, + RoleBindingPermission, + RoleBindingSubject, + RoleBindingSubjectType, RoleManifest, RoleWithResource, RoleWithResourceResourceType, Rolling, RpsMetric, + SagemakerAssumedRoleBasedAuth, SagemakerModel, SambaNovaIntegrations, SambaNovaKeyAuth, @@ -754,6 +804,7 @@ SecretMount, SecretStoreConfig, SecretVersion, + SelfHostedAgent, SelfHostedModel, SelfHostedModelAuthData, SelfHostedModelIntegrations, @@ -827,12 +878,17 @@ StageArtifactResponse, StaticVolumeConfig, StatsModelsFramework, + StdioMcpServerManifest, + StickyRouting, + StickySessionIdentifier, + StickySessionIdentifierSource, StringDataMount, SubAgent, Subject, SubjectClause, SubjectConditionGroup, SubjectConditionGroupOperator, + SubjectPermission, SubjectType, SyncTokenInSecretStoreInfo, SyncVirtualAccountTokenResponse, @@ -874,6 +930,19 @@ TracingProjectStorageConfig, TransformersFramework, TriggerJobRunResponse, + TrojAiClientIdAuth, + TrojAiGuardrailConfig, + TrojAiGuardrailConfigConfig, + TrojAiGuardrailConfigOperation, + TrueFoundryAgentManifest, + TrueFoundryAgentManifestModelParams, + TrueFoundryAgentManifestModelParamsReasoningEffort, + TrueFoundryAgentManifestResponseFormat, + TrueFoundryAgentManifestSandbox, + TrueFoundryAgentMcpServer, + TrueFoundryAgentMcpTool, + TrueFoundryAgentUserMessage, + TrueFoundryAgentVariable, TrueFoundryApplyRequestManifest, TrueFoundryApplyResponse, TrueFoundryApplyResponseAction, @@ -900,6 +969,7 @@ UserMetadata, UserMetadataTenantRoleManagedBy, UserResource, + UserTeamInfo, Uv, ValidationError, ValidationErrorLocItem, @@ -957,6 +1027,8 @@ UnprocessableEntityError, ) from . import ( + agent_skill_versions, + agent_skills, alerts, application_versions, applications, @@ -983,6 +1055,7 @@ virtual_accounts, workspaces, ) + from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient from .applications import ( ApplicationsCancelDeploymentResponse, ApplicationsListRequestDeviceTypeFilter, @@ -997,6 +1070,7 @@ from .version import __version__ from .workspaces import WorkspacesDeleteResponse _dynamic_imports: typing.Dict[str, str] = { + "A2AFramework": ".types", "Account": ".types", "AccountInfo": ".types", "ActivateUserResponse": ".types", @@ -1004,14 +1078,23 @@ "AddonComponent": ".types", "AddonComponentName": ".types", "AddonComponentStatus": ".types", + "AgentFramework": ".types", "AgentManifest": ".types", "AgentSkill": ".types", + "AgentSkillManifest": ".types", + "AgentSkillManifestSource": ".types", + "AgentSkillSourceBlobStorage": ".types", + "AgentSkillSourceInline": ".types", + "AgentSkillVersion": ".types", "AgentSource": ".types", "Ai21Integrations": ".types", "Ai21KeyAuth": ".types", "Ai21Model": ".types", "Ai21ProviderAccount": ".types", "AiFeaturesSettings": ".types", + "AktoGuardrailConfig": ".types", + "AktoGuardrailConfigConfig": ".types", + "AktoTokenAuth": ".types", "Alert": ".types", "AlertConfig": ".types", "AlertConfigResource": ".types", @@ -1028,10 +1111,8 @@ "AnthropicModel": ".types", "AnthropicProviderAccount": ".types", "Application": ".types", - "ApplicationDebugInfo": ".types", "ApplicationLifecycleStage": ".types", "ApplicationMetadata": ".types", - "ApplicationProblem": ".types", "ApplicationSet": ".types", "ApplicationSetComponentsItem": ".types", "ApplicationType": ".types", @@ -1108,7 +1189,6 @@ "AzureOAuth": ".types", "AzureOpenAiModel": ".types", "AzureOpenAiModelDeploymentType": ".types", - "AzureOpenAiModelRegion": ".types", "AzureOpenAiProviderAccount": ".types", "AzureOpenAiProviderAccountAuthData": ".types", "AzurePiiCategory": ".types", @@ -1129,11 +1209,16 @@ "BaseAutoscaling": ".types", "BaseOAuth2Login": ".types", "BaseOAuth2LoginJwtSource": ".types", + "BaseRemoteAgent": ".types", "BaseService": ".types", "BaseServiceImage": ".types", "BaseServiceMountsItem": ".types", "BaseWorkbenchInput": ".types", "BaseWorkbenchInputMountsItem": ".types", + "BasetenIntegrations": ".types", + "BasetenKeyAuth": ".types", + "BasetenModel": ".types", + "BasetenProviderAccount": ".types", "BasicAuthCreds": ".types", "BedrockModel": ".types", "BitbucketIntegration": ".types", @@ -1200,22 +1285,28 @@ "ContainerTaskConfigMountsItem": ".types", "CoreNatsOutputConfig": ".types", "CpuUtilizationMetric": ".types", + "CreateDockerRepositoryResponse": ".types", "CreateMultiPartUploadRequest": ".types", "CreatePersonalAccessTokenResponse": ".types", "CronMetric": ".types", + "CustomAgentServerAuth": ".types", "CustomBasicAuth": ".types", "CustomBearerAuth": ".types", "CustomBlobStorage": ".types", + "CustomFramework": ".types", "CustomGuardrailConfig": ".types", "CustomGuardrailConfigAuthData": ".types", "CustomGuardrailConfigConfig": ".types", "CustomGuardrailConfigOperation": ".types", "CustomGuardrailConfigTarget": ".types", + "CustomHeaderAuth": ".types", "CustomHelmRepo": ".types", "CustomIntegrations": ".types", "CustomJwtAuthIntegration": ".types", "CustomProviderAccount": ".types", "CustomRegexPattern": ".types", + "CustomServerHeaderAuth": ".types", + "CustomServerPassthrough": ".types", "CustomTlsSettings": ".types", "CustomUsernamePasswordArtifactsRegistry": ".types", "DataAccessRule": ".types", @@ -1225,6 +1316,8 @@ "DataDirectoryManifestSource": ".types", "DatabricksApiKeyAuth": ".types", "DatabricksIntegrations": ".types", + "DatabricksJobTaskConfig": ".types", + "DatabricksJobTaskConfigImage": ".types", "DatabricksModel": ".types", "DatabricksProviderAccount": ".types", "DatabricksProviderAccountAuthData": ".types", @@ -1237,6 +1330,8 @@ "DeepinfraKeyAuth": ".types", "DeepinfraModel": ".types", "DeepinfraProviderAccount": ".types", + "DefaultAioHttpClient": "._default_clients", + "DefaultAsyncHttpxClient": "._default_clients", "DeleteApplicationResponse": ".types", "DeleteJobRunResponse": ".types", "DeletePersonalAccessTokenResponse": ".types", @@ -1327,6 +1422,7 @@ "GatewayMetadataRule": ".types", "GatewayMetadataWhen": ".types", "GatewayOtelConfig": ".types", + "GatewayOtelConfigOtelMetricsExporterConfig": ".types", "GatewayOtelConfigOtelTracesExporterConfig": ".types", "GatewayRequestMetadataFilter": ".types", "GatewayRequestMetadataFilterOperator": ".types", @@ -1343,6 +1439,9 @@ "GcpRegion": ".types", "GcpTpu": ".types", "GeminiModel": ".types", + "GenericSecretStoreIntegration": ".types", + "GetAgentSkillResponse": ".types", + "GetAgentSkillVersionResponse": ".types", "GetAlertsResponse": ".types", "GetApplicationDeploymentResponse": ".types", "GetApplicationResponse": ".types", @@ -1353,6 +1452,7 @@ "GetChartsResponse": ".types", "GetClusterResponse": ".types", "GetDataDirectoryResponse": ".types", + "GetDockerRegistryCredentialsResponse": ".types", "GetEnvironmentResponse": ".types", "GetEventsResponse": ".types", "GetJobRunResponse": ".types", @@ -1368,8 +1468,10 @@ "GetSignedUrLsRequest": ".types", "GetSignedUrLsResponse": ".types", "GetSuggestedDeploymentEndpointResponse": ".types", + "GetTeamPermissionsResponse": ".types", "GetTeamResponse": ".types", "GetTokenForVirtualAccountResponse": ".types", + "GetUserPermissionsResponse": ".types", "GetUserResourcesResponse": ".types", "GetUserResponse": ".types", "GetUserTeamsResponse": ".types", @@ -1389,6 +1491,7 @@ "GoogleModelArmorGuardrailConfig": ".types", "GoogleModelArmorGuardrailConfigAuthData": ".types", "GoogleModelArmorGuardrailConfigConfig": ".types", + "GoogleModelArmorGuardrailConfigOperation": ".types", "GoogleModelArmorKeyFileAuth": ".types", "GoogleModelArmorKeyFileAuthKeyFileContent": ".types", "GoogleVertexProviderAccount": ".types", @@ -1409,12 +1512,15 @@ "GuardrailsRule": ".types", "GuardrailsWhen": ".types", "H2OFramework": ".types", + "HashicorpAppRoleAuth": ".types", "HashicorpIntegrations": ".types", "HashicorpProviderAccount": ".types", "HashicorpTokenAuth": ".types", "HashicorpVaultIntegration": ".types", + "HashicorpVaultIntegrationAuthData": ".types", "HeaderMatch": ".types", "HeaderRoutingConfig": ".types", + "HeadersOverride": ".types", "HealthProbe": ".types", "Helm": ".types", "HelmRepo": ".types", @@ -1478,8 +1584,11 @@ "LatencyBasedLoadBalanceTarget": ".types", "LatencyBasedLoadBalancing": ".types", "LatencyBasedLoadBalancingRule": ".types", + "LegacyAgentManifest": ".types", "LibraryName": ".types", "LightGbmFramework": ".types", + "ListAgentSkillVersionsResponse": ".types", + "ListAgentSkillsResponse": ".types", "ListApplicationDeploymentsResponse": ".types", "ListApplicationsResponse": ".types", "ListArtifactVersionsResponse": ".types", @@ -1524,13 +1633,17 @@ "LogsSortingDirection": ".types", "Manual": ".types", "McpServerAuth": ".types", + "McpServerEnvAuth": ".types", + "McpServerEnvAuthAuthLevel": ".types", "McpServerHeaderAuth": ".types", + "McpServerHeaderAuthAuthLevel": ".types", "McpServerHeaderOverrideAuth": ".types", "McpServerIntegration": ".types", "McpServerIntegrationTransport": ".types", "McpServerIntegrations": ".types", "McpServerManifest": ".types", "McpServerOAuth2": ".types", + "McpServerOAuth2GrantType": ".types", "McpServerOAuth2JwtSource": ".types", "McpServerPassthrough": ".types", "McpServerProviderAccount": ".types", @@ -1540,6 +1653,9 @@ "McpServerWithUrl": ".types", "McpTool": ".types", "McpToolSetting": ".types", + "McpToolTarget": ".types", + "McpToolsOperator": ".types", + "McpToolsOperatorCondition": ".types", "Metadata": ".types", "MethodNotAllowedError": ".errors", "Metric": ".types", @@ -1603,8 +1719,6 @@ "OpenAiModel": ".types", "OpenAiModerationsGuardrailConfig": ".types", "OpenAiModerationsGuardrailConfigConfig": ".types", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue": ".types", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment": ".types", "OpenApiSpecSource": ".types", "OpenApimcpServerManifest": ".types", "OpenApimcpToolSetting": ".types", @@ -1616,10 +1730,15 @@ "OpenaiApiKeyAuth": ".types", "OpenaiProviderAccount": ".types", "Operation": ".types", - "OtelExporterGrpcConfig": ".types", - "OtelExporterHttpConfig": ".types", - "OtelExporterHttpConfigEncoding": ".types", - "OtelExporterSpanAttributeFilter": ".types", + "OtelExporterGrpcConfigBase": ".types", + "OtelExporterHttpConfigBase": ".types", + "OtelExporterHttpConfigBaseEncoding": ".types", + "OtelMetricsExporterGrpcConfig": ".types", + "OtelMetricsExporterHttpConfig": ".types", + "OtelTracesExporterCommonConfig": ".types", + "OtelTracesExporterGrpcConfig": ".types", + "OtelTracesExporterHttpConfig": ".types", + "OtelTracesExporterSpanAttributeFilter": ".types", "OwnDataAccessRule": ".types", "OwnedBy": ".types", "PaddleFramework": ".types", @@ -1694,10 +1813,6 @@ "PrivatePricingTier": ".types", "PrometheusAlertRule": ".types", "Prompt": ".types", - "PromptFooGuardType": ".types", - "PromptFooGuardrailConfig": ".types", - "PromptFooGuardrailConfigConfig": ".types", - "PromptFooGuardrailConfigOperation": ".types", "PromptSource": ".types", "PromptVersion": ".types", "ProviderAccounts": ".types", @@ -1727,19 +1842,29 @@ "RegexGuardrailConfigConfig": ".types", "RegexGuardrailConfigOperation": ".types", "RegisterUsersResponse": ".types", + "RemoteAgent": ".types", "RemoteMcpServerManifest": ".types", "RemoteSource": ".types", "RemoteSpecSource": ".types", "Resources": ".types", "ResourcesDevicesItem": ".types", "ResourcesNode": ".types", + "ResponseFormatJsonObject": ".types", + "ResponseFormatJsonSchema": ".types", + "ResponseFormatJsonSchemaJsonSchema": ".types", + "ResponseFormatText": ".types", "RetryConfig": ".types", "RevokeAllPersonalAccessTokenResponse": ".types", + "RoleBindingManifest": ".types", + "RoleBindingPermission": ".types", + "RoleBindingSubject": ".types", + "RoleBindingSubjectType": ".types", "RoleManifest": ".types", "RoleWithResource": ".types", "RoleWithResourceResourceType": ".types", "Rolling": ".types", "RpsMetric": ".types", + "SagemakerAssumedRoleBasedAuth": ".types", "SagemakerModel": ".types", "SambaNovaIntegrations": ".types", "SambaNovaKeyAuth": ".types", @@ -1758,6 +1883,7 @@ "SecretMount": ".types", "SecretStoreConfig": ".types", "SecretVersion": ".types", + "SelfHostedAgent": ".types", "SelfHostedModel": ".types", "SelfHostedModelAuthData": ".types", "SelfHostedModelIntegrations": ".types", @@ -1832,12 +1958,17 @@ "StageArtifactResponse": ".types", "StaticVolumeConfig": ".types", "StatsModelsFramework": ".types", + "StdioMcpServerManifest": ".types", + "StickyRouting": ".types", + "StickySessionIdentifier": ".types", + "StickySessionIdentifierSource": ".types", "StringDataMount": ".types", "SubAgent": ".types", "Subject": ".types", "SubjectClause": ".types", "SubjectConditionGroup": ".types", "SubjectConditionGroupOperator": ".types", + "SubjectPermission": ".types", "SubjectType": ".types", "SyncTokenInSecretStoreInfo": ".types", "SyncVirtualAccountTokenResponse": ".types", @@ -1881,7 +2012,20 @@ "TransformersFramework": ".types", "TriggerJobRequestInput": ".jobs", "TriggerJobRunResponse": ".types", + "TrojAiClientIdAuth": ".types", + "TrojAiGuardrailConfig": ".types", + "TrojAiGuardrailConfigConfig": ".types", + "TrojAiGuardrailConfigOperation": ".types", "TrueFoundry": ".client", + "TrueFoundryAgentManifest": ".types", + "TrueFoundryAgentManifestModelParams": ".types", + "TrueFoundryAgentManifestModelParamsReasoningEffort": ".types", + "TrueFoundryAgentManifestResponseFormat": ".types", + "TrueFoundryAgentManifestSandbox": ".types", + "TrueFoundryAgentMcpServer": ".types", + "TrueFoundryAgentMcpTool": ".types", + "TrueFoundryAgentUserMessage": ".types", + "TrueFoundryAgentVariable": ".types", "TrueFoundryApplyRequestManifest": ".types", "TrueFoundryApplyResponse": ".types", "TrueFoundryApplyResponseAction": ".types", @@ -1910,6 +2054,7 @@ "UserMetadata": ".types", "UserMetadataTenantRoleManagedBy": ".types", "UserResource": ".types", + "UserTeamInfo": ".types", "Uv": ".types", "ValidationError": ".types", "ValidationErrorLocItem": ".types", @@ -1955,6 +2100,8 @@ "XgBoostModelSchema": ".types", "XgBoostSerializationFormat": ".types", "__version__": ".version", + "agent_skill_versions": ".agent_skill_versions", + "agent_skills": ".agent_skills", "alerts": ".alerts", "application_versions": ".application_versions", "applications": ".applications", @@ -2005,6 +2152,7 @@ def __dir__(): __all__ = [ + "A2AFramework", "Account", "AccountInfo", "ActivateUserResponse", @@ -2012,14 +2160,23 @@ def __dir__(): "AddonComponent", "AddonComponentName", "AddonComponentStatus", + "AgentFramework", "AgentManifest", "AgentSkill", + "AgentSkillManifest", + "AgentSkillManifestSource", + "AgentSkillSourceBlobStorage", + "AgentSkillSourceInline", + "AgentSkillVersion", "AgentSource", "Ai21Integrations", "Ai21KeyAuth", "Ai21Model", "Ai21ProviderAccount", "AiFeaturesSettings", + "AktoGuardrailConfig", + "AktoGuardrailConfigConfig", + "AktoTokenAuth", "Alert", "AlertConfig", "AlertConfigResource", @@ -2036,10 +2193,8 @@ def __dir__(): "AnthropicModel", "AnthropicProviderAccount", "Application", - "ApplicationDebugInfo", "ApplicationLifecycleStage", "ApplicationMetadata", - "ApplicationProblem", "ApplicationSet", "ApplicationSetComponentsItem", "ApplicationType", @@ -2116,7 +2271,6 @@ def __dir__(): "AzureOAuth", "AzureOpenAiModel", "AzureOpenAiModelDeploymentType", - "AzureOpenAiModelRegion", "AzureOpenAiProviderAccount", "AzureOpenAiProviderAccountAuthData", "AzurePiiCategory", @@ -2137,11 +2291,16 @@ def __dir__(): "BaseAutoscaling", "BaseOAuth2Login", "BaseOAuth2LoginJwtSource", + "BaseRemoteAgent", "BaseService", "BaseServiceImage", "BaseServiceMountsItem", "BaseWorkbenchInput", "BaseWorkbenchInputMountsItem", + "BasetenIntegrations", + "BasetenKeyAuth", + "BasetenModel", + "BasetenProviderAccount", "BasicAuthCreds", "BedrockModel", "BitbucketIntegration", @@ -2208,22 +2367,28 @@ def __dir__(): "ContainerTaskConfigMountsItem", "CoreNatsOutputConfig", "CpuUtilizationMetric", + "CreateDockerRepositoryResponse", "CreateMultiPartUploadRequest", "CreatePersonalAccessTokenResponse", "CronMetric", + "CustomAgentServerAuth", "CustomBasicAuth", "CustomBearerAuth", "CustomBlobStorage", + "CustomFramework", "CustomGuardrailConfig", "CustomGuardrailConfigAuthData", "CustomGuardrailConfigConfig", "CustomGuardrailConfigOperation", "CustomGuardrailConfigTarget", + "CustomHeaderAuth", "CustomHelmRepo", "CustomIntegrations", "CustomJwtAuthIntegration", "CustomProviderAccount", "CustomRegexPattern", + "CustomServerHeaderAuth", + "CustomServerPassthrough", "CustomTlsSettings", "CustomUsernamePasswordArtifactsRegistry", "DataAccessRule", @@ -2233,6 +2398,8 @@ def __dir__(): "DataDirectoryManifestSource", "DatabricksApiKeyAuth", "DatabricksIntegrations", + "DatabricksJobTaskConfig", + "DatabricksJobTaskConfigImage", "DatabricksModel", "DatabricksProviderAccount", "DatabricksProviderAccountAuthData", @@ -2245,6 +2412,8 @@ def __dir__(): "DeepinfraKeyAuth", "DeepinfraModel", "DeepinfraProviderAccount", + "DefaultAioHttpClient", + "DefaultAsyncHttpxClient", "DeleteApplicationResponse", "DeleteJobRunResponse", "DeletePersonalAccessTokenResponse", @@ -2335,6 +2504,7 @@ def __dir__(): "GatewayMetadataRule", "GatewayMetadataWhen", "GatewayOtelConfig", + "GatewayOtelConfigOtelMetricsExporterConfig", "GatewayOtelConfigOtelTracesExporterConfig", "GatewayRequestMetadataFilter", "GatewayRequestMetadataFilterOperator", @@ -2351,6 +2521,9 @@ def __dir__(): "GcpRegion", "GcpTpu", "GeminiModel", + "GenericSecretStoreIntegration", + "GetAgentSkillResponse", + "GetAgentSkillVersionResponse", "GetAlertsResponse", "GetApplicationDeploymentResponse", "GetApplicationResponse", @@ -2361,6 +2534,7 @@ def __dir__(): "GetChartsResponse", "GetClusterResponse", "GetDataDirectoryResponse", + "GetDockerRegistryCredentialsResponse", "GetEnvironmentResponse", "GetEventsResponse", "GetJobRunResponse", @@ -2376,8 +2550,10 @@ def __dir__(): "GetSignedUrLsRequest", "GetSignedUrLsResponse", "GetSuggestedDeploymentEndpointResponse", + "GetTeamPermissionsResponse", "GetTeamResponse", "GetTokenForVirtualAccountResponse", + "GetUserPermissionsResponse", "GetUserResourcesResponse", "GetUserResponse", "GetUserTeamsResponse", @@ -2397,6 +2573,7 @@ def __dir__(): "GoogleModelArmorGuardrailConfig", "GoogleModelArmorGuardrailConfigAuthData", "GoogleModelArmorGuardrailConfigConfig", + "GoogleModelArmorGuardrailConfigOperation", "GoogleModelArmorKeyFileAuth", "GoogleModelArmorKeyFileAuthKeyFileContent", "GoogleVertexProviderAccount", @@ -2417,12 +2594,15 @@ def __dir__(): "GuardrailsRule", "GuardrailsWhen", "H2OFramework", + "HashicorpAppRoleAuth", "HashicorpIntegrations", "HashicorpProviderAccount", "HashicorpTokenAuth", "HashicorpVaultIntegration", + "HashicorpVaultIntegrationAuthData", "HeaderMatch", "HeaderRoutingConfig", + "HeadersOverride", "HealthProbe", "Helm", "HelmRepo", @@ -2486,8 +2666,11 @@ def __dir__(): "LatencyBasedLoadBalanceTarget", "LatencyBasedLoadBalancing", "LatencyBasedLoadBalancingRule", + "LegacyAgentManifest", "LibraryName", "LightGbmFramework", + "ListAgentSkillVersionsResponse", + "ListAgentSkillsResponse", "ListApplicationDeploymentsResponse", "ListApplicationsResponse", "ListArtifactVersionsResponse", @@ -2532,13 +2715,17 @@ def __dir__(): "LogsSortingDirection", "Manual", "McpServerAuth", + "McpServerEnvAuth", + "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", + "McpServerHeaderAuthAuthLevel", "McpServerHeaderOverrideAuth", "McpServerIntegration", "McpServerIntegrationTransport", "McpServerIntegrations", "McpServerManifest", "McpServerOAuth2", + "McpServerOAuth2GrantType", "McpServerOAuth2JwtSource", "McpServerPassthrough", "McpServerProviderAccount", @@ -2548,6 +2735,9 @@ def __dir__(): "McpServerWithUrl", "McpTool", "McpToolSetting", + "McpToolTarget", + "McpToolsOperator", + "McpToolsOperatorCondition", "Metadata", "MethodNotAllowedError", "Metric", @@ -2611,8 +2801,6 @@ def __dir__(): "OpenAiModel", "OpenAiModerationsGuardrailConfig", "OpenAiModerationsGuardrailConfigConfig", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment", "OpenApiSpecSource", "OpenApimcpServerManifest", "OpenApimcpToolSetting", @@ -2624,10 +2812,15 @@ def __dir__(): "OpenaiApiKeyAuth", "OpenaiProviderAccount", "Operation", - "OtelExporterGrpcConfig", - "OtelExporterHttpConfig", - "OtelExporterHttpConfigEncoding", - "OtelExporterSpanAttributeFilter", + "OtelExporterGrpcConfigBase", + "OtelExporterHttpConfigBase", + "OtelExporterHttpConfigBaseEncoding", + "OtelMetricsExporterGrpcConfig", + "OtelMetricsExporterHttpConfig", + "OtelTracesExporterCommonConfig", + "OtelTracesExporterGrpcConfig", + "OtelTracesExporterHttpConfig", + "OtelTracesExporterSpanAttributeFilter", "OwnDataAccessRule", "OwnedBy", "PaddleFramework", @@ -2702,10 +2895,6 @@ def __dir__(): "PrivatePricingTier", "PrometheusAlertRule", "Prompt", - "PromptFooGuardType", - "PromptFooGuardrailConfig", - "PromptFooGuardrailConfigConfig", - "PromptFooGuardrailConfigOperation", "PromptSource", "PromptVersion", "ProviderAccounts", @@ -2735,19 +2924,29 @@ def __dir__(): "RegexGuardrailConfigConfig", "RegexGuardrailConfigOperation", "RegisterUsersResponse", + "RemoteAgent", "RemoteMcpServerManifest", "RemoteSource", "RemoteSpecSource", "Resources", "ResourcesDevicesItem", "ResourcesNode", + "ResponseFormatJsonObject", + "ResponseFormatJsonSchema", + "ResponseFormatJsonSchemaJsonSchema", + "ResponseFormatText", "RetryConfig", "RevokeAllPersonalAccessTokenResponse", + "RoleBindingManifest", + "RoleBindingPermission", + "RoleBindingSubject", + "RoleBindingSubjectType", "RoleManifest", "RoleWithResource", "RoleWithResourceResourceType", "Rolling", "RpsMetric", + "SagemakerAssumedRoleBasedAuth", "SagemakerModel", "SambaNovaIntegrations", "SambaNovaKeyAuth", @@ -2766,6 +2965,7 @@ def __dir__(): "SecretMount", "SecretStoreConfig", "SecretVersion", + "SelfHostedAgent", "SelfHostedModel", "SelfHostedModelAuthData", "SelfHostedModelIntegrations", @@ -2840,12 +3040,17 @@ def __dir__(): "StageArtifactResponse", "StaticVolumeConfig", "StatsModelsFramework", + "StdioMcpServerManifest", + "StickyRouting", + "StickySessionIdentifier", + "StickySessionIdentifierSource", "StringDataMount", "SubAgent", "Subject", "SubjectClause", "SubjectConditionGroup", "SubjectConditionGroupOperator", + "SubjectPermission", "SubjectType", "SyncTokenInSecretStoreInfo", "SyncVirtualAccountTokenResponse", @@ -2889,7 +3094,20 @@ def __dir__(): "TransformersFramework", "TriggerJobRequestInput", "TriggerJobRunResponse", + "TrojAiClientIdAuth", + "TrojAiGuardrailConfig", + "TrojAiGuardrailConfigConfig", + "TrojAiGuardrailConfigOperation", "TrueFoundry", + "TrueFoundryAgentManifest", + "TrueFoundryAgentManifestModelParams", + "TrueFoundryAgentManifestModelParamsReasoningEffort", + "TrueFoundryAgentManifestResponseFormat", + "TrueFoundryAgentManifestSandbox", + "TrueFoundryAgentMcpServer", + "TrueFoundryAgentMcpTool", + "TrueFoundryAgentUserMessage", + "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", "TrueFoundryApplyResponse", "TrueFoundryApplyResponseAction", @@ -2918,6 +3136,7 @@ def __dir__(): "UserMetadata", "UserMetadataTenantRoleManagedBy", "UserResource", + "UserTeamInfo", "Uv", "ValidationError", "ValidationErrorLocItem", @@ -2963,6 +3182,8 @@ def __dir__(): "XgBoostModelSchema", "XgBoostSerializationFormat", "__version__", + "agent_skill_versions", + "agent_skills", "alerts", "application_versions", "applications", diff --git a/src/truefoundry_sdk/_default_clients.py b/src/truefoundry_sdk/_default_clients.py new file mode 100644 index 00000000..84661579 --- /dev/null +++ b/src/truefoundry_sdk/_default_clients.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import httpx + +SDK_DEFAULT_TIMEOUT = 60 + +try: + import httpx_aiohttp # type: ignore[import-not-found] +except ImportError: + + class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore + def __init__(self, **kwargs: typing.Any) -> None: + raise RuntimeError( + "To use the aiohttp client, install the aiohttp extra: pip install truefoundry-sdk[aiohttp]" + ) + +else: + + class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore + def __init__(self, **kwargs: typing.Any) -> None: + kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) + kwargs.setdefault("follow_redirects", True) + super().__init__(**kwargs) + + +class DefaultAsyncHttpxClient(httpx.AsyncClient): + def __init__(self, **kwargs: typing.Any) -> None: + kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) + kwargs.setdefault("follow_redirects", True) + super().__init__(**kwargs) diff --git a/src/truefoundry_sdk/agent_skill_versions/__init__.py b/src/truefoundry_sdk/agent_skill_versions/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/truefoundry_sdk/agent_skill_versions/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/truefoundry_sdk/agent_skill_versions/client.py b/src/truefoundry_sdk/agent_skill_versions/client.py new file mode 100644 index 00000000..b45861a1 --- /dev/null +++ b/src/truefoundry_sdk/agent_skill_versions/client.py @@ -0,0 +1,353 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from ..types.agent_skill_version import AgentSkillVersion +from ..types.empty_response import EmptyResponse +from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse +from ..types.list_agent_skill_versions_response import ListAgentSkillVersionsResponse +from .raw_client import AsyncRawAgentSkillVersionsClient, RawAgentSkillVersionsClient + + +class AgentSkillVersionsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawAgentSkillVersionsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawAgentSkillVersionsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawAgentSkillVersionsClient + """ + return self._raw_client + + def get( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillVersionResponse: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillVersionResponse + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agent_skill_versions.get( + agent_skill_version_id="agent_skill_version_id", + ) + """ + _response = self._raw_client.get(agent_skill_version_id, request_options=request_options) + return _response.data + + def delete( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EmptyResponse: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmptyResponse + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agent_skill_versions.delete( + agent_skill_version_id="agent_skill_version_id", + ) + """ + _response = self._raw_client.delete(agent_skill_version_id, request_options=request_options) + return _response.data + + def list( + self, + *, + fqn: typing.Optional[str] = None, + agent_skill_id: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + version: typing.Optional[int] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse]: + """ + List agent skill versions. Each manifest has `source.type` `blob-storage` and `description` only; use GET for full SKILL.md content. + + Parameters + ---------- + fqn : typing.Optional[str] + FQN filter for agent skill versions + + agent_skill_id : typing.Optional[str] + Parent agent skill artifact ID + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + version : typing.Optional[int] + Version number or 'latest' + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse] + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + response = client.agent_skill_versions.list( + fqn="fqn", + agent_skill_id="agent_skill_id", + ml_repo_id="ml_repo_id", + name="name", + version=1, + offset=1, + limit=1, + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + fqn=fqn, + agent_skill_id=agent_skill_id, + ml_repo_id=ml_repo_id, + name=name, + version=version, + offset=offset, + limit=limit, + request_options=request_options, + ) + + +class AsyncAgentSkillVersionsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawAgentSkillVersionsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawAgentSkillVersionsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawAgentSkillVersionsClient + """ + return self._raw_client + + async def get( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillVersionResponse: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillVersionResponse + Successful Response + + 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.agent_skill_versions.get( + agent_skill_version_id="agent_skill_version_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_skill_version_id, request_options=request_options) + return _response.data + + async def delete( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EmptyResponse: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmptyResponse + Successful Response + + 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.agent_skill_versions.delete( + agent_skill_version_id="agent_skill_version_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete(agent_skill_version_id, request_options=request_options) + return _response.data + + async def list( + self, + *, + fqn: typing.Optional[str] = None, + agent_skill_id: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + version: typing.Optional[int] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse]: + """ + List agent skill versions. Each manifest has `source.type` `blob-storage` and `description` only; use GET for full SKILL.md content. + + Parameters + ---------- + fqn : typing.Optional[str] + FQN filter for agent skill versions + + agent_skill_id : typing.Optional[str] + Parent agent skill artifact ID + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + version : typing.Optional[int] + Version number or 'latest' + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse] + Successful Response + + 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: + response = await client.agent_skill_versions.list( + fqn="fqn", + agent_skill_id="agent_skill_id", + ml_repo_id="ml_repo_id", + name="name", + version=1, + offset=1, + limit=1, + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + fqn=fqn, + agent_skill_id=agent_skill_id, + ml_repo_id=ml_repo_id, + name=name, + version=version, + offset=offset, + limit=limit, + request_options=request_options, + ) diff --git a/src/truefoundry_sdk/agent_skill_versions/raw_client.py b/src/truefoundry_sdk/agent_skill_versions/raw_client.py new file mode 100644 index 00000000..6370de14 --- /dev/null +++ b/src/truefoundry_sdk/agent_skill_versions/raw_client.py @@ -0,0 +1,444 @@ +# 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.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.agent_skill_version import AgentSkillVersion +from ..types.empty_response import EmptyResponse +from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse +from ..types.list_agent_skill_versions_response import ListAgentSkillVersionsResponse +from pydantic import ValidationError + + +class RawAgentSkillVersionsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetAgentSkillVersionResponse]: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentSkillVersionResponse] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillVersionResponse, + parse_obj_as( + type_=GetAgentSkillVersionResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[EmptyResponse]: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EmptyResponse] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmptyResponse, + parse_obj_as( + type_=EmptyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 list( + self, + *, + fqn: typing.Optional[str] = None, + agent_skill_id: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + version: typing.Optional[int] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse]: + """ + List agent skill versions. Each manifest has `source.type` `blob-storage` and `description` only; use GET for full SKILL.md content. + + Parameters + ---------- + fqn : typing.Optional[str] + FQN filter for agent skill versions + + agent_skill_id : typing.Optional[str] + Parent agent skill artifact ID + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + version : typing.Optional[int] + Version number or 'latest' + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse] + Successful Response + """ + offset = offset if offset is not None else 0 + + _response = self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skill-versions", + method="GET", + params={ + "fqn": fqn, + "agent_skill_id": agent_skill_id, + "ml_repo_id": ml_repo_id, + "name": name, + "version": version, + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListAgentSkillVersionsResponse, + parse_obj_as( + type_=ListAgentSkillVersionsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + _get_next = lambda: self.list( + fqn=fqn, + agent_skill_id=agent_skill_id, + ml_repo_id=ml_repo_id, + name=name, + version=version, + offset=offset + len(_items or []), + limit=limit, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 AsyncRawAgentSkillVersionsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get( + self, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetAgentSkillVersionResponse]: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentSkillVersionResponse] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillVersionResponse, + parse_obj_as( + type_=GetAgentSkillVersionResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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, agent_skill_version_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[EmptyResponse]: + """ + Parameters + ---------- + agent_skill_version_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EmptyResponse] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmptyResponse, + parse_obj_as( + type_=EmptyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 list( + self, + *, + fqn: typing.Optional[str] = None, + agent_skill_id: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + version: typing.Optional[int] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse]: + """ + List agent skill versions. Each manifest has `source.type` `blob-storage` and `description` only; use GET for full SKILL.md content. + + Parameters + ---------- + fqn : typing.Optional[str] + FQN filter for agent skill versions + + agent_skill_id : typing.Optional[str] + Parent agent skill artifact ID + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + version : typing.Optional[int] + Version number or 'latest' + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse] + Successful Response + """ + offset = offset if offset is not None else 0 + + _response = await self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skill-versions", + method="GET", + params={ + "fqn": fqn, + "agent_skill_id": agent_skill_id, + "ml_repo_id": ml_repo_id, + "name": name, + "version": version, + "offset": offset, + "limit": limit, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListAgentSkillVersionsResponse, + parse_obj_as( + type_=ListAgentSkillVersionsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + + async def _get_next(): + return await self.list( + fqn=fqn, + agent_skill_id=agent_skill_id, + ml_repo_id=ml_repo_id, + name=name, + version=version, + offset=offset + len(_items or []), + limit=limit, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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/agent_skills/__init__.py b/src/truefoundry_sdk/agent_skills/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/src/truefoundry_sdk/agent_skills/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/truefoundry_sdk/agent_skills/client.py b/src/truefoundry_sdk/agent_skills/client.py new file mode 100644 index 00000000..69c069d5 --- /dev/null +++ b/src/truefoundry_sdk/agent_skills/client.py @@ -0,0 +1,450 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.pagination import AsyncPager, SyncPager +from ..core.request_options import RequestOptions +from ..types.agent_skill import AgentSkill +from ..types.agent_skill_manifest import AgentSkillManifest +from ..types.empty_response import EmptyResponse +from ..types.get_agent_skill_response import GetAgentSkillResponse +from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse +from ..types.list_agent_skills_response import ListAgentSkillsResponse +from .raw_client import AsyncRawAgentSkillsClient, RawAgentSkillsClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class AgentSkillsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawAgentSkillsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawAgentSkillsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawAgentSkillsClient + """ + return self._raw_client + + def get( + self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillResponse: + """ + Get an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillResponse + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agent_skills.get( + agent_skill_id="agent_skill_id", + ) + """ + _response = self._raw_client.get(agent_skill_id, request_options=request_options) + return _response.data + + def delete(self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: + """ + Delete an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmptyResponse + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agent_skills.delete( + agent_skill_id="agent_skill_id", + ) + """ + _response = self._raw_client.delete(agent_skill_id, request_options=request_options) + return _response.data + + def list( + self, + *, + fqn: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + include_empty_agent_skills: typing.Optional[bool] = True, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkill, ListAgentSkillsResponse]: + """ + List agent skills with optional filtering by FQN, ML Repo, or name. When present, `latest_version.manifest.source` is `blob-storage` with `description` only; use GET agent skill version for full SKILL.md (inline `source` with `skill_md`). + + Parameters + ---------- + fqn : typing.Optional[str] + Fully qualified name to filter agent skills by (format: 'agent_skill:{tenant}/{ml_repo}/{agent_skill_name}') + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + include_empty_agent_skills : typing.Optional[bool] + Whether to include agent skills that have no versions + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkill, ListAgentSkillsResponse] + Successful Response + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + response = client.agent_skills.list( + fqn="fqn", + ml_repo_id="ml_repo_id", + name="name", + offset=1, + limit=1, + include_empty_agent_skills=True, + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.list( + fqn=fqn, + ml_repo_id=ml_repo_id, + name=name, + offset=offset, + limit=limit, + include_empty_agent_skills=include_empty_agent_skills, + request_options=request_options, + ) + + def create_or_update( + self, *, manifest: AgentSkillManifest, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillVersionResponse: + """ + Create or update an agent skill version from a manifest. + + Parameters + ---------- + manifest : AgentSkillManifest + Manifest containing metadata for the agent skill to apply + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillVersionResponse + The created or updated agent skill version + + Examples + -------- + from truefoundry_sdk import ( + AgentSkillManifest, + AgentSkillSourceInline, + TrueFoundry, + ) + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.agent_skills.create_or_update( + manifest=AgentSkillManifest( + name="name", + metadata={"key": "value"}, + ml_repo="ml_repo", + source=AgentSkillSourceInline( + skill_md="skill_md", + ), + ), + ) + """ + _response = self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + return _response.data + + +class AsyncAgentSkillsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawAgentSkillsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawAgentSkillsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawAgentSkillsClient + """ + return self._raw_client + + async def get( + self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillResponse: + """ + Get an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillResponse + Successful Response + + 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.agent_skills.get( + agent_skill_id="agent_skill_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get(agent_skill_id, request_options=request_options) + return _response.data + + async def delete( + self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> EmptyResponse: + """ + Delete an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmptyResponse + Successful Response + + 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.agent_skills.delete( + agent_skill_id="agent_skill_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete(agent_skill_id, request_options=request_options) + return _response.data + + async def list( + self, + *, + fqn: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + include_empty_agent_skills: typing.Optional[bool] = True, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkill, ListAgentSkillsResponse]: + """ + List agent skills with optional filtering by FQN, ML Repo, or name. When present, `latest_version.manifest.source` is `blob-storage` with `description` only; use GET agent skill version for full SKILL.md (inline `source` with `skill_md`). + + Parameters + ---------- + fqn : typing.Optional[str] + Fully qualified name to filter agent skills by (format: 'agent_skill:{tenant}/{ml_repo}/{agent_skill_name}') + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + include_empty_agent_skills : typing.Optional[bool] + Whether to include agent skills that have no versions + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkill, ListAgentSkillsResponse] + Successful Response + + 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: + response = await client.agent_skills.list( + fqn="fqn", + ml_repo_id="ml_repo_id", + name="name", + offset=1, + limit=1, + include_empty_agent_skills=True, + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.list( + fqn=fqn, + ml_repo_id=ml_repo_id, + name=name, + offset=offset, + limit=limit, + include_empty_agent_skills=include_empty_agent_skills, + request_options=request_options, + ) + + async def create_or_update( + self, *, manifest: AgentSkillManifest, request_options: typing.Optional[RequestOptions] = None + ) -> GetAgentSkillVersionResponse: + """ + Create or update an agent skill version from a manifest. + + Parameters + ---------- + manifest : AgentSkillManifest + Manifest containing metadata for the agent skill to apply + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetAgentSkillVersionResponse + The created or updated agent skill version + + Examples + -------- + import asyncio + + from truefoundry_sdk import ( + AgentSkillManifest, + AgentSkillSourceInline, + AsyncTrueFoundry, + ) + + client = AsyncTrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.agent_skills.create_or_update( + manifest=AgentSkillManifest( + name="name", + metadata={"key": "value"}, + ml_repo="ml_repo", + source=AgentSkillSourceInline( + skill_md="skill_md", + ), + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + return _response.data diff --git a/src/truefoundry_sdk/agent_skills/raw_client.py b/src/truefoundry_sdk/agent_skills/raw_client.py new file mode 100644 index 00000000..b5e7b7df --- /dev/null +++ b/src/truefoundry_sdk/agent_skills/raw_client.py @@ -0,0 +1,572 @@ +# 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.pagination import AsyncPager, SyncPager +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.unprocessable_entity_error import UnprocessableEntityError +from ..types.agent_skill import AgentSkill +from ..types.agent_skill_manifest import AgentSkillManifest +from ..types.empty_response import EmptyResponse +from ..types.get_agent_skill_response import GetAgentSkillResponse +from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse +from ..types.list_agent_skills_response import ListAgentSkillsResponse +from pydantic import ValidationError + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawAgentSkillsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get( + self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetAgentSkillResponse]: + """ + Get an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentSkillResponse] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillResponse, + parse_obj_as( + type_=GetAgentSkillResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[EmptyResponse]: + """ + Delete an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EmptyResponse] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmptyResponse, + parse_obj_as( + type_=EmptyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 list( + self, + *, + fqn: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + include_empty_agent_skills: typing.Optional[bool] = True, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[AgentSkill, ListAgentSkillsResponse]: + """ + List agent skills with optional filtering by FQN, ML Repo, or name. When present, `latest_version.manifest.source` is `blob-storage` with `description` only; use GET agent skill version for full SKILL.md (inline `source` with `skill_md`). + + Parameters + ---------- + fqn : typing.Optional[str] + Fully qualified name to filter agent skills by (format: 'agent_skill:{tenant}/{ml_repo}/{agent_skill_name}') + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + include_empty_agent_skills : typing.Optional[bool] + Whether to include agent skills that have no versions + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[AgentSkill, ListAgentSkillsResponse] + Successful Response + """ + offset = offset if offset is not None else 0 + + _response = self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skills", + method="GET", + params={ + "fqn": fqn, + "ml_repo_id": ml_repo_id, + "name": name, + "offset": offset, + "limit": limit, + "include_empty_agent_skills": include_empty_agent_skills, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListAgentSkillsResponse, + parse_obj_as( + type_=ListAgentSkillsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + _get_next = lambda: self.list( + fqn=fqn, + ml_repo_id=ml_repo_id, + name=name, + offset=offset + len(_items or []), + limit=limit, + include_empty_agent_skills=include_empty_agent_skills, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 create_or_update( + self, *, manifest: AgentSkillManifest, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetAgentSkillVersionResponse]: + """ + Create or update an agent skill version from a manifest. + + Parameters + ---------- + manifest : AgentSkillManifest + Manifest containing metadata for the agent skill to apply + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetAgentSkillVersionResponse] + The created or updated agent skill version + """ + _response = self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skill-versions", + method="PUT", + json={ + "manifest": convert_and_respect_annotation_metadata( + object_=manifest, annotation=AgentSkillManifest, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillVersionResponse, + parse_obj_as( + type_=GetAgentSkillVersionResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 AsyncRawAgentSkillsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get( + self, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetAgentSkillResponse]: + """ + Get an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentSkillResponse] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillResponse, + parse_obj_as( + type_=GetAgentSkillResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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, agent_skill_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[EmptyResponse]: + """ + Delete an agent skill artifact by its ID. + + Parameters + ---------- + agent_skill_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EmptyResponse] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmptyResponse, + parse_obj_as( + type_=EmptyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 list( + self, + *, + fqn: typing.Optional[str] = None, + ml_repo_id: typing.Optional[str] = None, + name: typing.Optional[str] = None, + offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = 100, + include_empty_agent_skills: typing.Optional[bool] = True, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[AgentSkill, ListAgentSkillsResponse]: + """ + List agent skills with optional filtering by FQN, ML Repo, or name. When present, `latest_version.manifest.source` is `blob-storage` with `description` only; use GET agent skill version for full SKILL.md (inline `source` with `skill_md`). + + Parameters + ---------- + fqn : typing.Optional[str] + Fully qualified name to filter agent skills by (format: 'agent_skill:{tenant}/{ml_repo}/{agent_skill_name}') + + ml_repo_id : typing.Optional[str] + ML Repo ID filter + + name : typing.Optional[str] + Agent skill name filter + + offset : typing.Optional[int] + Pagination offset + + limit : typing.Optional[int] + Page size + + include_empty_agent_skills : typing.Optional[bool] + Whether to include agent skills that have no versions + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[AgentSkill, ListAgentSkillsResponse] + Successful Response + """ + offset = offset if offset is not None else 0 + + _response = await self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skills", + method="GET", + params={ + "fqn": fqn, + "ml_repo_id": ml_repo_id, + "name": name, + "offset": offset, + "limit": limit, + "include_empty_agent_skills": include_empty_agent_skills, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListAgentSkillsResponse, + parse_obj_as( + type_=ListAgentSkillsResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + + async def _get_next(): + return await self.list( + fqn=fqn, + ml_repo_id=ml_repo_id, + name=name, + offset=offset + len(_items or []), + limit=limit, + include_empty_agent_skills=include_empty_agent_skills, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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 create_or_update( + self, *, manifest: AgentSkillManifest, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetAgentSkillVersionResponse]: + """ + Create or update an agent skill version from a manifest. + + Parameters + ---------- + manifest : AgentSkillManifest + Manifest containing metadata for the agent skill to apply + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetAgentSkillVersionResponse] + The created or updated agent skill version + """ + _response = await self._client_wrapper.httpx_client.request( + "api/ml/v1/agent-skill-versions", + method="PUT", + json={ + "manifest": convert_and_respect_annotation_metadata( + object_=manifest, annotation=AgentSkillManifest, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetAgentSkillVersionResponse, + parse_obj_as( + type_=GetAgentSkillVersionResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + 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/alerts/raw_client.py b/src/truefoundry_sdk/alerts/raw_client.py index 430342fe..565af1a0 100644 --- a/src/truefoundry_sdk/alerts/raw_client.py +++ b/src/truefoundry_sdk/alerts/raw_client.py @@ -6,6 +6,7 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -13,6 +14,7 @@ from ..types.alert_status import AlertStatus from ..types.get_alerts_response import GetAlertsResponse from ..types.http_error import HttpError +from pydantic import ValidationError class RawAlertsClient: @@ -104,6 +106,10 @@ def list( _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) @@ -196,4 +202,8 @@ async def list( _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/raw_client.py b/src/truefoundry_sdk/application_versions/raw_client.py index fb685a39..08b9cd2b 100644 --- a/src/truefoundry_sdk/application_versions/raw_client.py +++ b/src/truefoundry_sdk/application_versions/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.forbidden_error import ForbiddenError @@ -16,6 +17,7 @@ from ..types.get_application_deployment_response import GetApplicationDeploymentResponse from ..types.http_error import HttpError from ..types.list_application_deployments_response import ListApplicationDeploymentsResponse +from pydantic import ValidationError class RawApplicationVersionsClient: @@ -63,7 +65,7 @@ def list( offset = offset if offset is not None else 0 _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments", method="GET", params={ "limit": limit, @@ -118,6 +120,10 @@ def list( _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( @@ -143,7 +149,7 @@ def get( Deployment details returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}", method="GET", request_options=request_options, ) @@ -182,6 +188,10 @@ def get( _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) @@ -230,7 +240,7 @@ async def list( offset = offset if offset is not None else 0 _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments", method="GET", params={ "limit": limit, @@ -288,6 +298,10 @@ async def _get_next(): _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( @@ -313,7 +327,7 @@ async def get( Deployment details returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}", method="GET", request_options=request_options, ) @@ -352,4 +366,8 @@ async def get( _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/applications/client.py b/src/truefoundry_sdk/applications/client.py index cd2f97c9..045dda83 100644 --- a/src/truefoundry_sdk/applications/client.py +++ b/src/truefoundry_sdk/applications/client.py @@ -183,7 +183,7 @@ def create_or_update( self, *, manifest: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -633,7 +633,7 @@ async def create_or_update( self, *, manifest: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, diff --git a/src/truefoundry_sdk/applications/raw_client.py b/src/truefoundry_sdk/applications/raw_client.py index 49f9dd55..46d5308f 100644 --- a/src/truefoundry_sdk/applications/raw_client.py +++ b/src/truefoundry_sdk/applications/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -26,6 +27,7 @@ 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 pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -193,13 +195,17 @@ def list( _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: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -324,6 +330,10 @@ def create_or_update( _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( @@ -346,7 +356,7 @@ def get( Application details retrieved successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}", + f"api/svc/v1/apps/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -385,6 +395,10 @@ def get( _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( @@ -407,7 +421,7 @@ def delete( Delete application response. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}", + f"api/svc/v1/apps/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -446,6 +460,10 @@ def delete( _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 redeploy( @@ -471,7 +489,7 @@ def redeploy( Returns the new deployment. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/redeploy", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/redeploy", method="POST", request_options=request_options, ) @@ -510,6 +528,10 @@ def redeploy( _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 scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[None]: @@ -529,7 +551,7 @@ def scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOpti HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-zero", + f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-zero", method="PATCH", request_options=request_options, ) @@ -583,6 +605,10 @@ def scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOpti _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 scale_to_original( @@ -605,7 +631,7 @@ def scale_to_original( Scales back a paused applicaion to the original number of replicas """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-original", + f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-original", method="PATCH", request_options=request_options, ) @@ -655,6 +681,10 @@ def scale_to_original( _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 cancel_deployment( @@ -680,7 +710,7 @@ def cancel_deployment( Deployment cancelled successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/cancel", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/cancel", method="POST", request_options=request_options, ) @@ -730,6 +760,10 @@ def cancel_deployment( _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) @@ -898,13 +932,17 @@ async def _get_next(): _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: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -1029,6 +1067,10 @@ async def create_or_update( _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( @@ -1051,7 +1093,7 @@ async def get( Application details retrieved successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}", + f"api/svc/v1/apps/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -1090,6 +1132,10 @@ async def get( _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( @@ -1112,7 +1158,7 @@ async def delete( Delete application response. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}", + f"api/svc/v1/apps/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -1151,6 +1197,10 @@ async def delete( _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 redeploy( @@ -1176,7 +1226,7 @@ async def redeploy( Returns the new deployment. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/redeploy", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/redeploy", method="POST", request_options=request_options, ) @@ -1215,6 +1265,10 @@ async def redeploy( _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 scale_to_zero( @@ -1236,7 +1290,7 @@ async def scale_to_zero( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-zero", + f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-zero", method="PATCH", request_options=request_options, ) @@ -1290,6 +1344,10 @@ async def scale_to_zero( _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 scale_to_original( @@ -1312,7 +1370,7 @@ async def scale_to_original( Scales back a paused applicaion to the original number of replicas """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-original", + f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-original", method="PATCH", request_options=request_options, ) @@ -1362,6 +1420,10 @@ async def scale_to_original( _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 cancel_deployment( @@ -1387,7 +1449,7 @@ async def cancel_deployment( Deployment cancelled successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/cancel", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/cancel", method="POST", request_options=request_options, ) @@ -1437,4 +1499,8 @@ async def cancel_deployment( _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/artifact_versions/client.py b/src/truefoundry_sdk/artifact_versions/client.py index 3f435486..9e0967e7 100644 --- a/src/truefoundry_sdk/artifact_versions/client.py +++ b/src/truefoundry_sdk/artifact_versions/client.py @@ -42,17 +42,22 @@ def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to an artifact version. + Parameters ---------- artifact_version_id : str + ID of the artifact version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the artifact version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -60,7 +65,7 @@ def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -82,7 +87,7 @@ def apply_tags( def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetArtifactVersionResponse: """ - Get artifact version API + Get an artifact version by its ID. Parameters ---------- @@ -94,7 +99,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetArtifactVersionResponse - Successful Response + The artifact version data Examples -------- @@ -113,7 +118,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete artifact versions API + Delete an artifact version by its ID. Parameters ---------- @@ -125,7 +130,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -159,31 +164,42 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ArtifactVersion, ListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -191,7 +207,7 @@ def list( Returns ------- SyncPager[ArtifactVersion, ListArtifactVersionsResponse] - Successful Response + List of artifact versions matching the query with pagination information Examples -------- @@ -242,13 +258,18 @@ def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> GetSignedUrLsResponse: """ + Get pre-signed URLs for reading or writing files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -256,7 +277,7 @@ def get_signed_urls( Returns ------- GetSignedUrLsResponse - Successful Response + List of signed URLs for the requested file paths Examples -------- @@ -281,13 +302,18 @@ def create_multi_part_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> MultiPartUploadResponse: """ + Create a multipart upload for large files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -295,7 +321,7 @@ def create_multi_part_upload( Returns ------- MultiPartUploadResponse - Successful Response + Multipart upload information including signed URLs for each part Examples -------- @@ -320,9 +346,12 @@ def stage( self, *, manifest: StageArtifactRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> StageArtifactResponse: """ + Stage an artifact version for upload, returning storage location and version ID. + Parameters ---------- manifest : StageArtifactRequestManifest + Manifest containing metadata for the artifact to be staged (model or generic artifact) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -330,7 +359,7 @@ def stage( Returns ------- StageArtifactResponse - Successful Response + Staging information including version ID, storage root, and artifact ID Examples -------- @@ -362,15 +391,21 @@ def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[FileInfo, ListFilesResponse]: """ + List files and directories in an artifact version. + Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -378,7 +413,7 @@ def list_files( Returns ------- SyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information Examples -------- @@ -403,9 +438,12 @@ def list_files( def mark_stage_failure(self, *, id: str, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Mark a staged artifact version as failed. + Parameters ---------- id : str + ID of the staged artifact version to mark as failed request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -413,7 +451,7 @@ def mark_stage_failure(self, *, id: str, request_options: typing.Optional[Reques Returns ------- EmptyResponse - Successful Response + Empty response indicating successful failure marking Examples -------- @@ -451,17 +489,22 @@ async def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to an artifact version. + Parameters ---------- artifact_version_id : str + ID of the artifact version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the artifact version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -469,7 +512,7 @@ async def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -501,7 +544,7 @@ async def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetArtifactVersionResponse: """ - Get artifact version API + Get an artifact version by its ID. Parameters ---------- @@ -513,7 +556,7 @@ async def get( Returns ------- GetArtifactVersionResponse - Successful Response + The artifact version data Examples -------- @@ -540,7 +583,7 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete artifact versions API + Delete an artifact version by its ID. Parameters ---------- @@ -552,7 +595,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -594,31 +637,42 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -626,7 +680,7 @@ async def list( Returns ------- AsyncPager[ArtifactVersion, ListArtifactVersionsResponse] - Successful Response + List of artifact versions matching the query with pagination information Examples -------- @@ -686,13 +740,18 @@ async def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> GetSignedUrLsResponse: """ + Get pre-signed URLs for reading or writing files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -700,7 +759,7 @@ async def get_signed_urls( Returns ------- GetSignedUrLsResponse - Successful Response + List of signed URLs for the requested file paths Examples -------- @@ -733,13 +792,18 @@ async def create_multi_part_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> MultiPartUploadResponse: """ + Create a multipart upload for large files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -747,7 +811,7 @@ async def create_multi_part_upload( Returns ------- MultiPartUploadResponse - Successful Response + Multipart upload information including signed URLs for each part Examples -------- @@ -780,9 +844,12 @@ async def stage( self, *, manifest: StageArtifactRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> StageArtifactResponse: """ + Stage an artifact version for upload, returning storage location and version ID. + Parameters ---------- manifest : StageArtifactRequestManifest + Manifest containing metadata for the artifact to be staged (model or generic artifact) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -790,7 +857,7 @@ async def stage( Returns ------- StageArtifactResponse - Successful Response + Staging information including version ID, storage root, and artifact ID Examples -------- @@ -834,15 +901,21 @@ async def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[FileInfo, ListFilesResponse]: """ + List files and directories in an artifact version. + Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -850,7 +923,7 @@ async def list_files( Returns ------- AsyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information Examples -------- @@ -886,9 +959,12 @@ async def mark_stage_failure( self, *, id: str, request_options: typing.Optional[RequestOptions] = None ) -> EmptyResponse: """ + Mark a staged artifact version as failed. + Parameters ---------- id : str + ID of the staged artifact version to mark as failed request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -896,7 +972,7 @@ async def mark_stage_failure( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful failure marking Examples -------- diff --git a/src/truefoundry_sdk/artifact_versions/raw_client.py b/src/truefoundry_sdk/artifact_versions/raw_client.py index 335f56fd..74451a6e 100644 --- a/src/truefoundry_sdk/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/artifact_versions/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -23,6 +24,7 @@ from ..types.operation import Operation from ..types.stage_artifact_response import StageArtifactResponse from .types.stage_artifact_request_manifest import StageArtifactRequestManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -37,17 +39,22 @@ def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ + Apply tags to an artifact version. + Parameters ---------- artifact_version_id : str + ID of the artifact version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the artifact version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -55,7 +62,7 @@ def apply_tags( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/tags", @@ -95,13 +102,17 @@ def apply_tags( _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[GetArtifactVersionResponse]: """ - Get artifact version API + Get an artifact version by its ID. Parameters ---------- @@ -113,10 +124,10 @@ def get( Returns ------- HttpResponse[GetArtifactVersionResponse] - Successful Response + The artifact version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", + f"api/ml/v1/artifact-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -144,13 +155,17 @@ def get( _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[EmptyResponse]: """ - Delete artifact versions API + Delete an artifact version by its ID. Parameters ---------- @@ -162,10 +177,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", + f"api/ml/v1/artifact-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -193,6 +208,10 @@ def delete( _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 list( @@ -212,31 +231,42 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ArtifactVersion, ListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -244,7 +274,7 @@ def list( Returns ------- SyncPager[ArtifactVersion, ListArtifactVersionsResponse] - Successful Response + List of artifact versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -306,6 +336,10 @@ def list( _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_signed_urls( @@ -317,13 +351,18 @@ def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetSignedUrLsResponse]: """ + Get pre-signed URLs for reading or writing files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -331,7 +370,7 @@ def get_signed_urls( Returns ------- HttpResponse[GetSignedUrLsResponse] - Successful Response + List of signed URLs for the requested file paths """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/signed-urls", @@ -371,19 +410,28 @@ def get_signed_urls( _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_multi_part_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[MultiPartUploadResponse]: """ + Create a multipart upload for large files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -391,7 +439,7 @@ def create_multi_part_upload( Returns ------- HttpResponse[MultiPartUploadResponse] - Successful Response + Multipart upload information including signed URLs for each part """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/signed-urls/multipart", @@ -431,15 +479,22 @@ def create_multi_part_upload( _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 stage( self, *, manifest: StageArtifactRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[StageArtifactResponse]: """ + Stage an artifact version for upload, returning storage location and version ID. + Parameters ---------- manifest : StageArtifactRequestManifest + Manifest containing metadata for the artifact to be staged (model or generic artifact) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -447,7 +502,7 @@ def stage( Returns ------- HttpResponse[StageArtifactResponse] - Successful Response + Staging information including version ID, storage root, and artifact ID """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/stage", @@ -487,6 +542,10 @@ def stage( _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 list_files( @@ -499,15 +558,21 @@ def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[FileInfo, ListFilesResponse]: """ + List files and directories in an artifact version. + Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -515,7 +580,7 @@ def list_files( Returns ------- SyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/files", @@ -569,15 +634,22 @@ def list_files( _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 mark_stage_failure( self, *, id: str, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[EmptyResponse]: """ + Mark a staged artifact version as failed. + Parameters ---------- id : str + ID of the staged artifact version to mark as failed request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -585,7 +657,7 @@ def mark_stage_failure( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful failure marking """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/mark-stage-failure", @@ -623,6 +695,10 @@ def mark_stage_failure( _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) @@ -635,17 +711,22 @@ async def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ + Apply tags to an artifact version. + Parameters ---------- artifact_version_id : str + ID of the artifact version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the artifact version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -653,7 +734,7 @@ async def apply_tags( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/tags", @@ -693,13 +774,17 @@ async def apply_tags( _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[GetArtifactVersionResponse]: """ - Get artifact version API + Get an artifact version by its ID. Parameters ---------- @@ -711,10 +796,10 @@ async def get( Returns ------- AsyncHttpResponse[GetArtifactVersionResponse] - Successful Response + The artifact version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", + f"api/ml/v1/artifact-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -742,13 +827,17 @@ async def get( _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[EmptyResponse]: """ - Delete artifact versions API + Delete an artifact version by its ID. Parameters ---------- @@ -760,10 +849,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", + f"api/ml/v1/artifact-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -791,6 +880,10 @@ async def delete( _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 list( @@ -810,31 +903,42 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -842,7 +946,7 @@ async def list( Returns ------- AsyncPager[ArtifactVersion, ListArtifactVersionsResponse] - Successful Response + List of artifact versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -907,6 +1011,10 @@ async def _get_next(): _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_signed_urls( @@ -918,13 +1026,18 @@ async def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetSignedUrLsResponse]: """ + Get pre-signed URLs for reading or writing files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -932,7 +1045,7 @@ async def get_signed_urls( Returns ------- AsyncHttpResponse[GetSignedUrLsResponse] - Successful Response + List of signed URLs for the requested file paths """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/signed-urls", @@ -972,19 +1085,28 @@ async def get_signed_urls( _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_multi_part_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[MultiPartUploadResponse]: """ + Create a multipart upload for large files in an artifact version. + Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -992,7 +1114,7 @@ async def create_multi_part_upload( Returns ------- AsyncHttpResponse[MultiPartUploadResponse] - Successful Response + Multipart upload information including signed URLs for each part """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/signed-urls/multipart", @@ -1032,15 +1154,22 @@ async def create_multi_part_upload( _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 stage( self, *, manifest: StageArtifactRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[StageArtifactResponse]: """ + Stage an artifact version for upload, returning storage location and version ID. + Parameters ---------- manifest : StageArtifactRequestManifest + Manifest containing metadata for the artifact to be staged (model or generic artifact) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1048,7 +1177,7 @@ async def stage( Returns ------- AsyncHttpResponse[StageArtifactResponse] - Successful Response + Staging information including version ID, storage root, and artifact ID """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/stage", @@ -1088,6 +1217,10 @@ async def stage( _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 list_files( @@ -1100,15 +1233,21 @@ async def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[FileInfo, ListFilesResponse]: """ + List files and directories in an artifact version. + Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1116,7 +1255,7 @@ async def list_files( Returns ------- AsyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/files", @@ -1173,15 +1312,22 @@ async def _get_next(): _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 mark_stage_failure( self, *, id: str, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[EmptyResponse]: """ + Mark a staged artifact version as failed. + Parameters ---------- id : str + ID of the staged artifact version to mark as failed request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1189,7 +1335,7 @@ async def mark_stage_failure( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful failure marking """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions/mark-stage-failure", @@ -1227,4 +1373,8 @@ async def mark_stage_failure( _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/artifacts/client.py b/src/truefoundry_sdk/artifacts/client.py index 6540a335..ce8c584b 100644 --- a/src/truefoundry_sdk/artifacts/client.py +++ b/src/truefoundry_sdk/artifacts/client.py @@ -34,6 +34,8 @@ def with_raw_response(self) -> RawArtifactsClient: def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetArtifactResponse: """ + Get an artifact by its ID. + Parameters ---------- id : str @@ -44,7 +46,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetArtifactResponse - Successful Response + The artifact data Examples -------- @@ -63,6 +65,8 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete an artifact by its ID. + Parameters ---------- id : str @@ -73,7 +77,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -103,21 +107,30 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Artifact, ListArtifactsResponse]: """ + List artifacts with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter artifacts by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifacts by name : typing.Optional[str] + Name of the artifact to filter by offset : typing.Optional[int] + Number of artifacts to skip for pagination limit : typing.Optional[int] + Maximum number of artifacts to return run_id : typing.Optional[str] + ID of the run to filter artifacts by include_empty_artifacts : typing.Optional[bool] + Whether to include artifacts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -125,7 +138,7 @@ def list( Returns ------- SyncPager[Artifact, ListArtifactsResponse] - Successful Response + List of artifacts matching the query with pagination information Examples -------- @@ -165,9 +178,12 @@ def create_or_update( self, *, manifest: ArtifactManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetArtifactVersionResponse: """ + Create or update an artifact version. + Parameters ---------- manifest : ArtifactManifest + Manifest containing metadata for the artifact to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -175,7 +191,7 @@ def create_or_update( Returns ------- GetArtifactVersionResponse - Successful Response + The created or updated artifact version Examples -------- @@ -219,6 +235,8 @@ def with_raw_response(self) -> AsyncRawArtifactsClient: async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetArtifactResponse: """ + Get an artifact by its ID. + Parameters ---------- id : str @@ -229,7 +247,7 @@ async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetArtifactResponse - Successful Response + The artifact data Examples -------- @@ -256,6 +274,8 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete an artifact by its ID. + Parameters ---------- id : str @@ -266,7 +286,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -304,21 +324,30 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Artifact, ListArtifactsResponse]: """ + List artifacts with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter artifacts by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifacts by name : typing.Optional[str] + Name of the artifact to filter by offset : typing.Optional[int] + Number of artifacts to skip for pagination limit : typing.Optional[int] + Maximum number of artifacts to return run_id : typing.Optional[str] + ID of the run to filter artifacts by include_empty_artifacts : typing.Optional[bool] + Whether to include artifacts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -326,7 +355,7 @@ async def list( Returns ------- AsyncPager[Artifact, ListArtifactsResponse] - Successful Response + List of artifacts matching the query with pagination information Examples -------- @@ -375,9 +404,12 @@ async def create_or_update( self, *, manifest: ArtifactManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetArtifactVersionResponse: """ + Create or update an artifact version. + Parameters ---------- manifest : ArtifactManifest + Manifest containing metadata for the artifact to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -385,7 +417,7 @@ async def create_or_update( Returns ------- GetArtifactVersionResponse - Successful Response + The created or updated artifact version Examples -------- diff --git a/src/truefoundry_sdk/artifacts/raw_client.py b/src/truefoundry_sdk/artifacts/raw_client.py index 4b2b8b32..bf64b13b 100644 --- a/src/truefoundry_sdk/artifacts/raw_client.py +++ b/src/truefoundry_sdk/artifacts/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -18,6 +19,7 @@ from ..types.get_artifact_response import GetArtifactResponse from ..types.get_artifact_version_response import GetArtifactVersionResponse from ..types.list_artifacts_response import ListArtifactsResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,6 +33,8 @@ def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetArtifactResponse]: """ + Get an artifact by its ID. + Parameters ---------- id : str @@ -41,10 +45,10 @@ def get( Returns ------- HttpResponse[GetArtifactResponse] - Successful Response + The artifact data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{jsonable_encoder(id)}", + f"api/ml/v1/artifacts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -72,12 +76,18 @@ def get( _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[EmptyResponse]: """ + Delete an artifact by its ID. + Parameters ---------- id : str @@ -88,10 +98,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{jsonable_encoder(id)}", + f"api/ml/v1/artifacts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -119,6 +129,10 @@ def delete( _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 list( @@ -134,21 +148,30 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Artifact, ListArtifactsResponse]: """ + List artifacts with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter artifacts by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifacts by name : typing.Optional[str] + Name of the artifact to filter by offset : typing.Optional[int] + Number of artifacts to skip for pagination limit : typing.Optional[int] + Maximum number of artifacts to return run_id : typing.Optional[str] + ID of the run to filter artifacts by include_empty_artifacts : typing.Optional[bool] + Whether to include artifacts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -156,7 +179,7 @@ def list( Returns ------- SyncPager[Artifact, ListArtifactsResponse] - Successful Response + List of artifacts matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -210,15 +233,22 @@ def list( _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: ArtifactManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetArtifactVersionResponse]: """ + Create or update an artifact version. + Parameters ---------- manifest : ArtifactManifest + Manifest containing metadata for the artifact to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -226,7 +256,7 @@ def create_or_update( Returns ------- HttpResponse[GetArtifactVersionResponse] - Successful Response + The created or updated artifact version """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions", @@ -266,6 +296,10 @@ def create_or_update( _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) @@ -277,6 +311,8 @@ async def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetArtifactResponse]: """ + Get an artifact by its ID. + Parameters ---------- id : str @@ -287,10 +323,10 @@ async def get( Returns ------- AsyncHttpResponse[GetArtifactResponse] - Successful Response + The artifact data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{jsonable_encoder(id)}", + f"api/ml/v1/artifacts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -318,12 +354,18 @@ async def get( _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[EmptyResponse]: """ + Delete an artifact by its ID. + Parameters ---------- id : str @@ -334,10 +376,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{jsonable_encoder(id)}", + f"api/ml/v1/artifacts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -365,6 +407,10 @@ async def delete( _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 list( @@ -380,21 +426,30 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Artifact, ListArtifactsResponse]: """ + List artifacts with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter artifacts by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifacts by name : typing.Optional[str] + Name of the artifact to filter by offset : typing.Optional[int] + Number of artifacts to skip for pagination limit : typing.Optional[int] + Maximum number of artifacts to return run_id : typing.Optional[str] + ID of the run to filter artifacts by include_empty_artifacts : typing.Optional[bool] + Whether to include artifacts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -402,7 +457,7 @@ async def list( Returns ------- AsyncPager[Artifact, ListArtifactsResponse] - Successful Response + List of artifacts matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -459,15 +514,22 @@ async def _get_next(): _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: ArtifactManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetArtifactVersionResponse]: """ + Create or update an artifact version. + Parameters ---------- manifest : ArtifactManifest + Manifest containing metadata for the artifact to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -475,7 +537,7 @@ async def create_or_update( Returns ------- AsyncHttpResponse[GetArtifactVersionResponse] - Successful Response + The created or updated artifact version """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/artifact-versions", @@ -515,4 +577,8 @@ async def create_or_update( _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 bec32f63..1a90b255 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -8,6 +8,7 @@ import httpx from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .core.logging import LogConfig, Logger from .core.request_options import RequestOptions from .raw_base_client import AsyncRawBaseTrueFoundry, RawBaseTrueFoundry from .types.true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest @@ -15,6 +16,8 @@ from .types.true_foundry_delete_request_manifest import TrueFoundryDeleteRequestManifest if typing.TYPE_CHECKING: + from .agent_skill_versions.client import AgentSkillVersionsClient, AsyncAgentSkillVersionsClient + from .agent_skills.client import AgentSkillsClient, AsyncAgentSkillsClient from .alerts.client import AlertsClient, AsyncAlertsClient from .application_versions.client import ApplicationVersionsClient, AsyncApplicationVersionsClient from .applications.client import ApplicationsClient, AsyncApplicationsClient @@ -66,6 +69,9 @@ class BaseTrueFoundry: httpx_client : typing.Optional[httpx.Client] The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. + logging : typing.Optional[typing.Union[LogConfig, Logger]] + Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance. + Examples -------- from truefoundry_sdk import TrueFoundry @@ -85,6 +91,7 @@ def __init__( timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, 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 @@ -101,6 +108,7 @@ def __init__( if follow_redirects is not None else httpx.Client(timeout=_defaulted_timeout), timeout=_defaulted_timeout, + logging=logging, ) self._raw_client = RawBaseTrueFoundry(client_wrapper=self._client_wrapper) self._internal: typing.Optional[InternalClient] = None @@ -109,10 +117,10 @@ def __init__( self._personal_access_tokens: typing.Optional[PersonalAccessTokensClient] = None self._virtual_accounts: typing.Optional[VirtualAccountsClient] = None self._clusters: typing.Optional[ClustersClient] = None - self._environments: typing.Optional[EnvironmentsClient] = None self._applications: typing.Optional[ApplicationsClient] = None self._application_versions: typing.Optional[ApplicationVersionsClient] = None self._jobs: typing.Optional[JobsClient] = None + self._environments: typing.Optional[EnvironmentsClient] = None self._workspaces: typing.Optional[WorkspacesClient] = None self._secrets: typing.Optional[SecretsClient] = None self._secret_groups: typing.Optional[SecretGroupsClient] = None @@ -127,6 +135,8 @@ def __init__( self._artifact_versions: typing.Optional[ArtifactVersionsClient] = None self._model_versions: typing.Optional[ModelVersionsClient] = None self._prompt_versions: typing.Optional[PromptVersionsClient] = None + self._agent_skills: typing.Optional[AgentSkillsClient] = None + self._agent_skill_versions: typing.Optional[AgentSkillVersionsClient] = None self._data_directories: typing.Optional[DataDirectoriesClient] = None @property @@ -144,7 +154,7 @@ def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ @@ -280,14 +290,6 @@ def clusters(self): self._clusters = ClustersClient(client_wrapper=self._client_wrapper) return self._clusters - @property - def environments(self): - if self._environments is None: - from .environments.client import EnvironmentsClient # noqa: E402 - - self._environments = EnvironmentsClient(client_wrapper=self._client_wrapper) - return self._environments - @property def applications(self): if self._applications is None: @@ -312,6 +314,14 @@ def jobs(self): self._jobs = JobsClient(client_wrapper=self._client_wrapper) return self._jobs + @property + def environments(self): + if self._environments is None: + from .environments.client import EnvironmentsClient # noqa: E402 + + self._environments = EnvironmentsClient(client_wrapper=self._client_wrapper) + return self._environments + @property def workspaces(self): if self._workspaces is None: @@ -424,6 +434,22 @@ def prompt_versions(self): self._prompt_versions = PromptVersionsClient(client_wrapper=self._client_wrapper) return self._prompt_versions + @property + def agent_skills(self): + if self._agent_skills is None: + from .agent_skills.client import AgentSkillsClient # noqa: E402 + + self._agent_skills = AgentSkillsClient(client_wrapper=self._client_wrapper) + return self._agent_skills + + @property + def agent_skill_versions(self): + if self._agent_skill_versions is None: + from .agent_skill_versions.client import AgentSkillVersionsClient # noqa: E402 + + self._agent_skill_versions = AgentSkillVersionsClient(client_wrapper=self._client_wrapper) + return self._agent_skill_versions + @property def data_directories(self): if self._data_directories is None: @@ -433,6 +459,24 @@ def data_directories(self): return self._data_directories +def _make_default_async_client( + timeout: typing.Optional[float], + follow_redirects: typing.Optional[bool], +) -> httpx.AsyncClient: + try: + import httpx_aiohttp # type: ignore[import-not-found] + except ImportError: + pass + else: + if follow_redirects is not None: + return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects) + return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout) + + if follow_redirects is not None: + return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects) + return httpx.AsyncClient(timeout=timeout) + + class AsyncBaseTrueFoundry: """ Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions. @@ -446,6 +490,9 @@ class AsyncBaseTrueFoundry: headers : typing.Optional[typing.Dict[str, str]] Additional headers to send with every request. + async_token : typing.Optional[typing.Callable[[], typing.Awaitable[str]]] + An async callable that returns a bearer token. Use this when token acquisition involves async I/O (e.g., refreshing tokens via an async HTTP client). When provided, this is used instead of the synchronous token for async requests. + timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -455,6 +502,9 @@ class AsyncBaseTrueFoundry: httpx_client : typing.Optional[httpx.AsyncClient] The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. + logging : typing.Optional[typing.Union[LogConfig, Logger]] + Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance. + Examples -------- from truefoundry_sdk import AsyncTrueFoundry @@ -471,9 +521,11 @@ def __init__( base_url: str, api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("TFY_API_KEY"), headers: typing.Optional[typing.Dict[str, str]] = None, + async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, 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 @@ -484,12 +536,12 @@ def __init__( base_url=base_url, api_key=api_key, headers=headers, + async_token=async_token, httpx_client=httpx_client if httpx_client is not None - else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects) - if follow_redirects is not None - else httpx.AsyncClient(timeout=_defaulted_timeout), + else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects), timeout=_defaulted_timeout, + logging=logging, ) self._raw_client = AsyncRawBaseTrueFoundry(client_wrapper=self._client_wrapper) self._internal: typing.Optional[AsyncInternalClient] = None @@ -498,10 +550,10 @@ def __init__( self._personal_access_tokens: typing.Optional[AsyncPersonalAccessTokensClient] = None self._virtual_accounts: typing.Optional[AsyncVirtualAccountsClient] = None self._clusters: typing.Optional[AsyncClustersClient] = None - self._environments: typing.Optional[AsyncEnvironmentsClient] = None self._applications: typing.Optional[AsyncApplicationsClient] = None self._application_versions: typing.Optional[AsyncApplicationVersionsClient] = None self._jobs: typing.Optional[AsyncJobsClient] = None + self._environments: typing.Optional[AsyncEnvironmentsClient] = None self._workspaces: typing.Optional[AsyncWorkspacesClient] = None self._secrets: typing.Optional[AsyncSecretsClient] = None self._secret_groups: typing.Optional[AsyncSecretGroupsClient] = None @@ -516,6 +568,8 @@ def __init__( self._artifact_versions: typing.Optional[AsyncArtifactVersionsClient] = None self._model_versions: typing.Optional[AsyncModelVersionsClient] = None self._prompt_versions: typing.Optional[AsyncPromptVersionsClient] = None + self._agent_skills: typing.Optional[AsyncAgentSkillsClient] = None + self._agent_skill_versions: typing.Optional[AsyncAgentSkillVersionsClient] = None self._data_directories: typing.Optional[AsyncDataDirectoriesClient] = None @property @@ -533,7 +587,7 @@ async def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ @@ -685,14 +739,6 @@ def clusters(self): self._clusters = AsyncClustersClient(client_wrapper=self._client_wrapper) return self._clusters - @property - def environments(self): - if self._environments is None: - from .environments.client import AsyncEnvironmentsClient # noqa: E402 - - self._environments = AsyncEnvironmentsClient(client_wrapper=self._client_wrapper) - return self._environments - @property def applications(self): if self._applications is None: @@ -717,6 +763,14 @@ def jobs(self): self._jobs = AsyncJobsClient(client_wrapper=self._client_wrapper) return self._jobs + @property + def environments(self): + if self._environments is None: + from .environments.client import AsyncEnvironmentsClient # noqa: E402 + + self._environments = AsyncEnvironmentsClient(client_wrapper=self._client_wrapper) + return self._environments + @property def workspaces(self): if self._workspaces is None: @@ -829,6 +883,22 @@ def prompt_versions(self): self._prompt_versions = AsyncPromptVersionsClient(client_wrapper=self._client_wrapper) return self._prompt_versions + @property + def agent_skills(self): + if self._agent_skills is None: + from .agent_skills.client import AsyncAgentSkillsClient # noqa: E402 + + self._agent_skills = AsyncAgentSkillsClient(client_wrapper=self._client_wrapper) + return self._agent_skills + + @property + def agent_skill_versions(self): + if self._agent_skill_versions is None: + from .agent_skill_versions.client import AsyncAgentSkillVersionsClient # noqa: E402 + + self._agent_skill_versions = AsyncAgentSkillVersionsClient(client_wrapper=self._client_wrapper) + return self._agent_skill_versions + @property def data_directories(self): if self._data_directories is None: diff --git a/src/truefoundry_sdk/clusters/client.py b/src/truefoundry_sdk/clusters/client.py index 6a90b240..53113207 100644 --- a/src/truefoundry_sdk/clusters/client.py +++ b/src/truefoundry_sdk/clusters/client.py @@ -83,7 +83,7 @@ def create_or_update( self, *, manifest: ClusterManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetClusterResponse: """ @@ -357,7 +357,7 @@ async def create_or_update( self, *, manifest: ClusterManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetClusterResponse: """ diff --git a/src/truefoundry_sdk/clusters/raw_client.py b/src/truefoundry_sdk/clusters/raw_client.py index d549625c..859b088e 100644 --- a/src/truefoundry_sdk/clusters/raw_client.py +++ b/src/truefoundry_sdk/clusters/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -23,6 +24,7 @@ from ..types.list_cluster_addons_response import ListClusterAddonsResponse from ..types.list_clusters_response import ListClustersResponse from .types.clusters_delete_response import ClustersDeleteResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -100,13 +102,17 @@ def list( _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: ClusterManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetClusterResponse]: """ @@ -189,6 +195,10 @@ def create_or_update( _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( @@ -211,7 +221,7 @@ def get( Return the cluster associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}", + f"api/svc/v1/clusters/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -250,6 +260,10 @@ def get( _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( @@ -272,7 +286,7 @@ def delete( Returns success message on successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}", + f"api/svc/v1/clusters/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -311,6 +325,10 @@ def delete( _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_addons( @@ -344,7 +362,7 @@ def get_addons( Returns a paginated list of addons for the cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/get-addons", + f"api/svc/v1/clusters/{encode_path_param(id)}/get-addons", method="GET", params={ "limit": limit, @@ -387,6 +405,10 @@ def get_addons( _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 is_connected( @@ -409,7 +431,7 @@ def is_connected( Returns the status of provided cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/is-connected", + f"api/svc/v1/clusters/{encode_path_param(id)}/is-connected", method="GET", request_options=request_options, ) @@ -437,6 +459,10 @@ def is_connected( _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) @@ -515,13 +541,17 @@ async def _get_next(): _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: ClusterManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetClusterResponse]: """ @@ -604,6 +634,10 @@ async def create_or_update( _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( @@ -626,7 +660,7 @@ async def get( Return the cluster associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}", + f"api/svc/v1/clusters/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -665,6 +699,10 @@ async def get( _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( @@ -687,7 +725,7 @@ async def delete( Returns success message on successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}", + f"api/svc/v1/clusters/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -726,6 +764,10 @@ async def delete( _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_addons( @@ -759,7 +801,7 @@ async def get_addons( Returns a paginated list of addons for the cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/get-addons", + f"api/svc/v1/clusters/{encode_path_param(id)}/get-addons", method="GET", params={ "limit": limit, @@ -802,6 +844,10 @@ async def get_addons( _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 is_connected( @@ -824,7 +870,7 @@ async def is_connected( Returns the status of provided cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/is-connected", + f"api/svc/v1/clusters/{encode_path_param(id)}/is-connected", method="GET", request_options=request_options, ) @@ -852,4 +898,8 @@ async def is_connected( _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/core/__init__.py b/src/truefoundry_sdk/core/__init__.py index 3b5240ad..e2be580f 100644 --- a/src/truefoundry_sdk/core/__init__.py +++ b/src/truefoundry_sdk/core/__init__.py @@ -8,13 +8,14 @@ if typing.TYPE_CHECKING: from .api_error import ApiError from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper - from .custom_pagination import AsyncCustomPager, SyncCustomPager - from .datetime_utils import serialize_datetime + from .datetime_utils import Rfc2822DateTime, parse_rfc2822_datetime, serialize_datetime from .file import File, convert_file_dict_to_httpx_tuples, with_content_type from .http_client import AsyncHttpClient, HttpClient from .http_response import AsyncHttpResponse, HttpResponse - from .jsonable_encoder import jsonable_encoder + from .jsonable_encoder import encode_path_param, jsonable_encoder + from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger from .pagination import AsyncPager, SyncPager + from .parse_error import ParsingError from .pydantic_utilities import ( IS_PYDANTIC_V2, UniversalBaseModel, @@ -31,27 +32,35 @@ _dynamic_imports: typing.Dict[str, str] = { "ApiError": ".api_error", "AsyncClientWrapper": ".client_wrapper", - "AsyncCustomPager": ".custom_pagination", "AsyncHttpClient": ".http_client", "AsyncHttpResponse": ".http_response", "AsyncPager": ".pagination", "BaseClientWrapper": ".client_wrapper", + "ConsoleLogger": ".logging", "FieldMetadata": ".serialization", "File": ".file", "HttpClient": ".http_client", "HttpResponse": ".http_response", + "ILogger": ".logging", "IS_PYDANTIC_V2": ".pydantic_utilities", + "LogConfig": ".logging", + "LogLevel": ".logging", + "Logger": ".logging", + "ParsingError": ".parse_error", "RequestOptions": ".request_options", + "Rfc2822DateTime": ".datetime_utils", "SyncClientWrapper": ".client_wrapper", - "SyncCustomPager": ".custom_pagination", "SyncPager": ".pagination", "UniversalBaseModel": ".pydantic_utilities", "UniversalRootModel": ".pydantic_utilities", "convert_and_respect_annotation_metadata": ".serialization", "convert_file_dict_to_httpx_tuples": ".file", + "create_logger": ".logging", + "encode_path_param": ".jsonable_encoder", "encode_query": ".query_encoder", "jsonable_encoder": ".jsonable_encoder", "parse_obj_as": ".pydantic_utilities", + "parse_rfc2822_datetime": ".datetime_utils", "remove_none_from_dict": ".remove_none_from_dict", "serialize_datetime": ".datetime_utils", "universal_field_validator": ".pydantic_utilities", @@ -85,27 +94,35 @@ def __dir__(): __all__ = [ "ApiError", "AsyncClientWrapper", - "AsyncCustomPager", "AsyncHttpClient", "AsyncHttpResponse", "AsyncPager", "BaseClientWrapper", + "ConsoleLogger", "FieldMetadata", "File", "HttpClient", "HttpResponse", + "ILogger", "IS_PYDANTIC_V2", + "LogConfig", + "LogLevel", + "Logger", + "ParsingError", "RequestOptions", + "Rfc2822DateTime", "SyncClientWrapper", - "SyncCustomPager", "SyncPager", "UniversalBaseModel", "UniversalRootModel", "convert_and_respect_annotation_metadata", "convert_file_dict_to_httpx_tuples", + "create_logger", + "encode_path_param", "encode_query", "jsonable_encoder", "parse_obj_as", + "parse_rfc2822_datetime", "remove_none_from_dict", "serialize_datetime", "universal_field_validator", diff --git a/src/truefoundry_sdk/core/client_wrapper.py b/src/truefoundry_sdk/core/client_wrapper.py index 18d1f335..9cc2e02f 100644 --- a/src/truefoundry_sdk/core/client_wrapper.py +++ b/src/truefoundry_sdk/core/client_wrapper.py @@ -4,6 +4,7 @@ import httpx from .http_client import AsyncHttpClient, HttpClient +from .logging import LogConfig, Logger class BaseClientWrapper: @@ -14,11 +15,13 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self._api_key = api_key self._headers = headers self._base_url = base_url self._timeout = timeout + self._logging = logging def get_headers(self) -> typing.Dict[str, str]: import platform @@ -59,14 +62,16 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, httpx_client: httpx.Client, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout) + super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) self.httpx_client = HttpClient( httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout, base_url=self.get_base_url, + logging_config=self._logging, ) @@ -78,10 +83,11 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, + logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None, httpx_client: httpx.AsyncClient, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout) + super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) self._async_token = async_token self.httpx_client = AsyncHttpClient( httpx_client=httpx_client, @@ -89,6 +95,7 @@ def __init__( base_timeout=self.get_timeout, base_url=self.get_base_url, async_base_headers=self.async_get_headers, + logging_config=self._logging, ) async def async_get_headers(self) -> typing.Dict[str, str]: diff --git a/src/truefoundry_sdk/core/custom_pagination.py b/src/truefoundry_sdk/core/custom_pagination.py deleted file mode 100644 index 5de2c7a8..00000000 --- a/src/truefoundry_sdk/core/custom_pagination.py +++ /dev/null @@ -1,152 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -""" -Custom Pagination Support - -This file is designed to be modified by SDK users to implement their own -pagination logic. The generator will import SyncCustomPager and AsyncCustomPager -from this module when custom pagination is used. - -Users should: -1. Implement their custom pager (e.g., PayrocPager, MyCustomPager, etc.) -2. Create adapter classes (SyncCustomPager/AsyncCustomPager) that bridge - between the generated SDK code and their custom pager implementation -""" - -from __future__ import annotations - -from typing import Any, AsyncIterator, Generic, Iterator, TypeVar - -# Import the base utilities you'll need -# Adjust these imports based on your actual structure -try: - from .client_wrapper import AsyncClientWrapper, SyncClientWrapper -except ImportError: - # Fallback for type hints - AsyncClientWrapper = Any # type: ignore - SyncClientWrapper = Any # type: ignore - -TItem = TypeVar("TItem") -TResponse = TypeVar("TResponse") - - -class SyncCustomPager(Generic[TItem, TResponse]): - """ - Adapter for custom synchronous pagination. - - The generator will call this with: - SyncCustomPager(initial_response=response, client_wrapper=client_wrapper) - - Implement this class to extract pagination metadata from your response - and delegate to your custom pager implementation. - - Example implementation: - - class SyncCustomPager(Generic[TItem, TResponse]): - def __init__( - self, - *, - initial_response: TResponse, - client_wrapper: SyncClientWrapper, - ): - # Extract data and pagination metadata from response - data = initial_response.data # Adjust based on your response structure - links = initial_response.links - - # Initialize your custom pager - self._pager = MyCustomPager( - current_page=Page(data), - httpx_client=client_wrapper.httpx_client, - get_headers=client_wrapper.get_headers, - # ... other parameters - ) - - def __iter__(self): - return iter(self._pager) - - # Delegate other methods to your pager... - """ - - def __init__( - self, - *, - initial_response: TResponse, - client_wrapper: SyncClientWrapper, - ): - """ - Initialize the custom pager. - - Args: - initial_response: The parsed API response from the first request - client_wrapper: The client wrapper providing HTTP client and utilities - """ - raise NotImplementedError( - "SyncCustomPager must be implemented. " - "Please implement this class in core/custom_pagination.py to define your pagination logic. " - "See the class docstring for examples." - ) - - def __iter__(self) -> Iterator[TItem]: - """Iterate through all items across all pages.""" - raise NotImplementedError("Must implement __iter__ method") - - -class AsyncCustomPager(Generic[TItem, TResponse]): - """ - Adapter for custom asynchronous pagination. - - The generator will call this with: - AsyncCustomPager(initial_response=response, client_wrapper=client_wrapper) - - Implement this class to extract pagination metadata from your response - and delegate to your custom async pager implementation. - - Example implementation: - - class AsyncCustomPager(Generic[TItem, TResponse]): - def __init__( - self, - *, - initial_response: TResponse, - client_wrapper: AsyncClientWrapper, - ): - # Extract data and pagination metadata from response - data = initial_response.data # Adjust based on your response structure - links = initial_response.links - - # Initialize your custom async pager - self._pager = MyAsyncCustomPager( - current_page=Page(data), - httpx_client=client_wrapper.httpx_client, - get_headers=client_wrapper.get_headers, - # ... other parameters - ) - - async def __aiter__(self): - return self._pager.__aiter__() - - # Delegate other methods to your pager... - """ - - def __init__( - self, - *, - initial_response: TResponse, - client_wrapper: AsyncClientWrapper, - ): - """ - Initialize the custom async pager. - - Args: - initial_response: The parsed API response from the first request - client_wrapper: The client wrapper providing HTTP client and utilities - """ - raise NotImplementedError( - "AsyncCustomPager must be implemented. " - "Please implement this class in core/custom_pagination.py to define your pagination logic. " - "See the class docstring for examples." - ) - - async def __aiter__(self) -> AsyncIterator[TItem]: - """Asynchronously iterate through all items across all pages.""" - raise NotImplementedError("Must implement __aiter__ method") diff --git a/src/truefoundry_sdk/core/datetime_utils.py b/src/truefoundry_sdk/core/datetime_utils.py index 7c9864a9..a12b2ad0 100644 --- a/src/truefoundry_sdk/core/datetime_utils.py +++ b/src/truefoundry_sdk/core/datetime_utils.py @@ -1,6 +1,48 @@ # This file was auto-generated by Fern from our API Definition. import datetime as dt +from email.utils import parsedate_to_datetime +from typing import Any + +import pydantic + +IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") + + +def parse_rfc2822_datetime(v: Any) -> dt.datetime: + """ + Parse an RFC 2822 datetime string (e.g., "Wed, 02 Oct 2002 13:00:00 GMT") + into a datetime object. If the value is already a datetime, return it as-is. + Falls back to ISO 8601 parsing if RFC 2822 parsing fails. + """ + if isinstance(v, dt.datetime): + return v + if isinstance(v, str): + try: + return parsedate_to_datetime(v) + except Exception: + pass + # Fallback to ISO 8601 parsing + return dt.datetime.fromisoformat(v.replace("Z", "+00:00")) + raise ValueError(f"Expected str or datetime, got {type(v)}") + + +class Rfc2822DateTime(dt.datetime): + """A datetime subclass that parses RFC 2822 date strings. + + On Pydantic V1, uses __get_validators__ for pre-validation. + On Pydantic V2, uses __get_pydantic_core_schema__ for BeforeValidator-style parsing. + """ + + @classmethod + def __get_validators__(cls): # type: ignore[no-untyped-def] + yield parse_rfc2822_datetime + + @classmethod + def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> Any: # type: ignore[override] + from pydantic_core import core_schema + + return core_schema.no_info_before_validator_function(parse_rfc2822_datetime, core_schema.datetime_schema()) def serialize_datetime(v: dt.datetime) -> str: diff --git a/src/truefoundry_sdk/core/http_client.py b/src/truefoundry_sdk/core/http_client.py index 7c6c936f..f0a39ca8 100644 --- a/src/truefoundry_sdk/core/http_client.py +++ b/src/truefoundry_sdk/core/http_client.py @@ -12,6 +12,7 @@ from .file import File, convert_file_dict_to_httpx_tuples from .force_multipart import FORCE_MULTIPART from .jsonable_encoder import jsonable_encoder +from .logging import LogConfig, Logger, create_logger from .query_encoder import encode_query from .remove_none_from_dict import remove_none_from_dict as remove_none_from_dict from .request_options import RequestOptions @@ -117,11 +118,43 @@ def _retry_timeout(response: httpx.Response, retries: int) -> float: return _add_symmetric_jitter(backoff) +def _retry_timeout_from_retries(retries: int) -> float: + """Determine retry timeout using exponential backoff when no response is available.""" + backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS) + return _add_symmetric_jitter(backoff) + + def _should_retry(response: httpx.Response) -> bool: retryable_400s = [429, 408, 409] return response.status_code >= 500 or response.status_code in retryable_400s +_SENSITIVE_HEADERS = frozenset( + { + "authorization", + "www-authenticate", + "x-api-key", + "api-key", + "apikey", + "x-api-token", + "x-auth-token", + "auth-token", + "cookie", + "set-cookie", + "proxy-authorization", + "proxy-authenticate", + "x-csrf-token", + "x-xsrf-token", + "x-session-token", + "x-access-token", + } +) + + +def _redact_headers(headers: typing.Dict[str, str]) -> typing.Dict[str, str]: + return {k: ("[REDACTED]" if k.lower() in _SENSITIVE_HEADERS else v) for k, v in headers.items()} + + def _build_url(base_url: str, path: typing.Optional[str]) -> str: """ Build a full URL by joining a base URL with a path. @@ -238,11 +271,15 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, + base_max_retries: int = 2, + logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers + self.base_max_retries = base_max_retries self.httpx_client = httpx_client + self.logger = create_logger(logging_config) def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str: base_url = maybe_base_url @@ -315,27 +352,64 @@ def request( ) ) - response = self.httpx_client.request( - method=method, - url=_build_url(base_url, path), - headers=jsonable_encoder( - remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } - ) - ), - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, + _request_url = _build_url(base_url, path) + _request_headers = jsonable_encoder( + remove_none_from_dict( + { + **self.base_headers(), + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), + } + ) ) - max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 + if self.logger.is_debug(): + self.logger.debug( + "Making HTTP request", + method=method, + url=_request_url, + headers=_redact_headers(_request_headers), + has_body=json_body is not None or data_body is not None, + ) + + max_retries: int = ( + request_options.get("max_retries", self.base_max_retries) + if request_options is not None + else self.base_max_retries + ) + + try: + response = self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, + ) + except (httpx.ConnectError, httpx.RemoteProtocolError): + if retries < max_retries: + time.sleep(_retry_timeout_from_retries(retries=retries)) + return self.request( + path=path, + method=method, + base_url=base_url, + params=params, + json=json, + data=data, + content=content, + files=files, + headers=headers, + request_options=request_options, + retries=retries + 1, + omit=omit, + force_multipart=force_multipart, + ) + raise + if _should_retry(response=response): if retries < max_retries: time.sleep(_retry_timeout(response=response, retries=retries)) @@ -345,12 +419,32 @@ def request( base_url=base_url, params=params, json=json, + data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, + force_multipart=force_multipart, + ) + + if self.logger.is_debug(): + if 200 <= response.status_code < 400: + self.logger.debug( + "HTTP request succeeded", + method=method, + url=_request_url, + status_code=response.status_code, + ) + + if self.logger.is_error(): + if response.status_code >= 400: + self.logger.error( + "HTTP request failed with error status", + method=method, + url=_request_url, + status_code=response.status_code, ) return response @@ -418,18 +512,29 @@ def stream( ) ) + _request_url = _build_url(base_url, path) + _request_headers = jsonable_encoder( + remove_none_from_dict( + { + **self.base_headers(), + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ) + + if self.logger.is_debug(): + self.logger.debug( + "Making streaming HTTP request", + method=method, + url=_request_url, + headers=_redact_headers(_request_headers), + ) + with self.httpx_client.stream( method=method, - url=_build_url(base_url, path), - headers=jsonable_encoder( - remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } - ) - ), + url=_request_url, + headers=_request_headers, params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, @@ -448,13 +553,17 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, + base_max_retries: int = 2, async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None, + logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers + self.base_max_retries = base_max_retries self.async_base_headers = async_base_headers self.httpx_client = httpx_client + self.logger = create_logger(logging_config) async def _get_headers(self) -> typing.Dict[str, str]: if self.async_base_headers is not None: @@ -535,28 +644,64 @@ async def request( ) ) - # Add the input to each of these and do None-safety checks - response = await self.httpx_client.request( - method=method, - url=_build_url(base_url, path), - headers=jsonable_encoder( - remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } - ) - ), - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, + _request_url = _build_url(base_url, path) + _request_headers = jsonable_encoder( + remove_none_from_dict( + { + **_headers, + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), + } + ) ) - max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 + if self.logger.is_debug(): + self.logger.debug( + "Making HTTP request", + method=method, + url=_request_url, + headers=_redact_headers(_request_headers), + has_body=json_body is not None or data_body is not None, + ) + + max_retries: int = ( + request_options.get("max_retries", self.base_max_retries) + if request_options is not None + else self.base_max_retries + ) + + try: + response = await self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, + ) + except (httpx.ConnectError, httpx.RemoteProtocolError): + if retries < max_retries: + await asyncio.sleep(_retry_timeout_from_retries(retries=retries)) + return await self.request( + path=path, + method=method, + base_url=base_url, + params=params, + json=json, + data=data, + content=content, + files=files, + headers=headers, + request_options=request_options, + retries=retries + 1, + omit=omit, + force_multipart=force_multipart, + ) + raise + if _should_retry(response=response): if retries < max_retries: await asyncio.sleep(_retry_timeout(response=response, retries=retries)) @@ -566,13 +711,34 @@ async def request( base_url=base_url, params=params, json=json, + data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, + force_multipart=force_multipart, + ) + + if self.logger.is_debug(): + if 200 <= response.status_code < 400: + self.logger.debug( + "HTTP request succeeded", + method=method, + url=_request_url, + status_code=response.status_code, ) + + if self.logger.is_error(): + if response.status_code >= 400: + self.logger.error( + "HTTP request failed with error status", + method=method, + url=_request_url, + status_code=response.status_code, + ) + return response @asynccontextmanager @@ -641,18 +807,29 @@ async def stream( ) ) + _request_url = _build_url(base_url, path) + _request_headers = jsonable_encoder( + remove_none_from_dict( + { + **_headers, + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ) + + if self.logger.is_debug(): + self.logger.debug( + "Making streaming HTTP request", + method=method, + url=_request_url, + headers=_redact_headers(_request_headers), + ) + async with self.httpx_client.stream( method=method, - url=_build_url(base_url, path), - headers=jsonable_encoder( - remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } - ) - ), + url=_request_url, + headers=_request_headers, params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, diff --git a/src/truefoundry_sdk/core/jsonable_encoder.py b/src/truefoundry_sdk/core/jsonable_encoder.py index f8beaeaf..5b0902eb 100644 --- a/src/truefoundry_sdk/core/jsonable_encoder.py +++ b/src/truefoundry_sdk/core/jsonable_encoder.py @@ -106,3 +106,15 @@ def fallback_serializer(o: Any) -> Any: return jsonable_encoder(data, custom_encoder=custom_encoder) return to_jsonable_with_fallback(obj, fallback_serializer) + + +def encode_path_param(obj: Any) -> str: + """Encode a value for use in a URL path segment. + + Ensures proper string conversion for all types, including + booleans which need lowercase 'true'/'false' rather than + Python's 'True'/'False'. + """ + if isinstance(obj, bool): + return "true" if obj else "false" + return str(jsonable_encoder(obj)) diff --git a/src/truefoundry_sdk/core/logging.py b/src/truefoundry_sdk/core/logging.py new file mode 100644 index 00000000..e5e57245 --- /dev/null +++ b/src/truefoundry_sdk/core/logging.py @@ -0,0 +1,107 @@ +# This file was auto-generated by Fern from our API Definition. + +import logging +import typing + +LogLevel = typing.Literal["debug", "info", "warn", "error"] + +_LOG_LEVEL_MAP: typing.Dict[LogLevel, int] = { + "debug": 1, + "info": 2, + "warn": 3, + "error": 4, +} + + +class ILogger(typing.Protocol): + def debug(self, message: str, **kwargs: typing.Any) -> None: ... + def info(self, message: str, **kwargs: typing.Any) -> None: ... + def warn(self, message: str, **kwargs: typing.Any) -> None: ... + def error(self, message: str, **kwargs: typing.Any) -> None: ... + + +class ConsoleLogger: + _logger: logging.Logger + + def __init__(self) -> None: + self._logger = logging.getLogger("fern") + if not self._logger.handlers: + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter("%(levelname)s - %(message)s")) + self._logger.addHandler(handler) + self._logger.setLevel(logging.DEBUG) + + def debug(self, message: str, **kwargs: typing.Any) -> None: + self._logger.debug(message, extra=kwargs) + + def info(self, message: str, **kwargs: typing.Any) -> None: + self._logger.info(message, extra=kwargs) + + def warn(self, message: str, **kwargs: typing.Any) -> None: + self._logger.warning(message, extra=kwargs) + + def error(self, message: str, **kwargs: typing.Any) -> None: + self._logger.error(message, extra=kwargs) + + +class LogConfig(typing.TypedDict, total=False): + level: LogLevel + logger: ILogger + silent: bool + + +class Logger: + _level: int + _logger: ILogger + _silent: bool + + def __init__(self, *, level: LogLevel, logger: ILogger, silent: bool) -> None: + self._level = _LOG_LEVEL_MAP[level] + self._logger = logger + self._silent = silent + + def _should_log(self, level: LogLevel) -> bool: + return not self._silent and self._level <= _LOG_LEVEL_MAP[level] + + def is_debug(self) -> bool: + return self._should_log("debug") + + def is_info(self) -> bool: + return self._should_log("info") + + def is_warn(self) -> bool: + return self._should_log("warn") + + def is_error(self) -> bool: + return self._should_log("error") + + def debug(self, message: str, **kwargs: typing.Any) -> None: + if self.is_debug(): + self._logger.debug(message, **kwargs) + + def info(self, message: str, **kwargs: typing.Any) -> None: + if self.is_info(): + self._logger.info(message, **kwargs) + + def warn(self, message: str, **kwargs: typing.Any) -> None: + if self.is_warn(): + self._logger.warn(message, **kwargs) + + def error(self, message: str, **kwargs: typing.Any) -> None: + if self.is_error(): + self._logger.error(message, **kwargs) + + +_default_logger: Logger = Logger(level="info", logger=ConsoleLogger(), silent=True) + + +def create_logger(config: typing.Optional[typing.Union[LogConfig, Logger]] = None) -> Logger: + if config is None: + return _default_logger + if isinstance(config, Logger): + return config + return Logger( + level=config.get("level", "info"), + logger=config.get("logger", ConsoleLogger()), + silent=config.get("silent", True), + ) diff --git a/src/truefoundry_sdk/core/parse_error.py b/src/truefoundry_sdk/core/parse_error.py new file mode 100644 index 00000000..4527c6a8 --- /dev/null +++ b/src/truefoundry_sdk/core/parse_error.py @@ -0,0 +1,36 @@ +# This file was auto-generated by Fern from our API Definition. + +from typing import Any, Dict, Optional + + +class ParsingError(Exception): + """ + Raised when the SDK fails to parse/validate a response from the server. + This typically indicates that the server returned a response whose shape + does not match the expected schema. + """ + + headers: Optional[Dict[str, str]] + status_code: Optional[int] + body: Any + cause: Optional[Exception] + + def __init__( + self, + *, + headers: Optional[Dict[str, str]] = None, + status_code: Optional[int] = None, + body: Any = None, + cause: Optional[Exception] = None, + ) -> None: + self.headers = headers + self.status_code = status_code + self.body = body + self.cause = cause + super().__init__() + if cause is not None: + self.__cause__ = cause + + def __str__(self) -> str: + cause_str = f", cause: {self.cause}" if self.cause is not None else "" + return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}{cause_str}" diff --git a/src/truefoundry_sdk/core/pydantic_utilities.py b/src/truefoundry_sdk/core/pydantic_utilities.py index 789081b0..fea3a08d 100644 --- a/src/truefoundry_sdk/core/pydantic_utilities.py +++ b/src/truefoundry_sdk/core/pydantic_utilities.py @@ -26,6 +26,7 @@ import pydantic import typing_extensions +from pydantic.fields import FieldInfo as _FieldInfo _logger = logging.getLogger(__name__) @@ -35,22 +36,95 @@ IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") if IS_PYDANTIC_V2: - from pydantic.v1.datetime_parse import parse_date as parse_date - from pydantic.v1.datetime_parse import parse_datetime as parse_datetime - from pydantic.v1.fields import ModelField as ModelField - from pydantic.v1.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[attr-defined] - from pydantic.v1.typing import get_args as get_args - from pydantic.v1.typing import get_origin as get_origin - from pydantic.v1.typing import is_literal_type as is_literal_type - from pydantic.v1.typing import is_union as is_union + _datetime_adapter = pydantic.TypeAdapter(dt.datetime) # type: ignore[attr-defined] + _date_adapter = pydantic.TypeAdapter(dt.date) # type: ignore[attr-defined] + + def parse_datetime(value: Any) -> dt.datetime: # type: ignore[misc] + if isinstance(value, dt.datetime): + return value + return _datetime_adapter.validate_python(value) + + def parse_date(value: Any) -> dt.date: # type: ignore[misc] + if isinstance(value, dt.datetime): + return value.date() + if isinstance(value, dt.date): + return value + return _date_adapter.validate_python(value) + + # Avoid importing from pydantic.v1 to maintain Python 3.14 compatibility. + from typing import get_args as get_args # type: ignore[assignment] + from typing import get_origin as get_origin # type: ignore[assignment] + + def is_literal_type(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc] + return typing_extensions.get_origin(tp) is typing_extensions.Literal + + def is_union(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc] + return tp is Union or typing_extensions.get_origin(tp) is Union # type: ignore[comparison-overlap] + + # Inline encoders_by_type to avoid importing from pydantic.v1.json + import re as _re + from collections import deque as _deque + from decimal import Decimal as _Decimal + from enum import Enum as _Enum + from ipaddress import ( + IPv4Address as _IPv4Address, + ) + from ipaddress import ( + IPv4Interface as _IPv4Interface, + ) + from ipaddress import ( + IPv4Network as _IPv4Network, + ) + from ipaddress import ( + IPv6Address as _IPv6Address, + ) + from ipaddress import ( + IPv6Interface as _IPv6Interface, + ) + from ipaddress import ( + IPv6Network as _IPv6Network, + ) + from pathlib import Path as _Path + from types import GeneratorType as _GeneratorType + from uuid import UUID as _UUID + + from pydantic.fields import FieldInfo as ModelField # type: ignore[no-redef, assignment] + + def _decimal_encoder(dec_value: Any) -> Any: + if dec_value.as_tuple().exponent >= 0: + return int(dec_value) + return float(dec_value) + + encoders_by_type: Dict[Type[Any], Callable[[Any], Any]] = { # type: ignore[no-redef] + bytes: lambda o: o.decode(), + dt.date: lambda o: o.isoformat(), + dt.datetime: lambda o: o.isoformat(), + dt.time: lambda o: o.isoformat(), + dt.timedelta: lambda td: td.total_seconds(), + _Decimal: _decimal_encoder, + _Enum: lambda o: o.value, + frozenset: list, + _deque: list, + _GeneratorType: list, + _IPv4Address: str, + _IPv4Interface: str, + _IPv4Network: str, + _IPv6Address: str, + _IPv6Interface: str, + _IPv6Network: str, + _Path: str, + _re.Pattern: lambda o: o.pattern, + set: list, + _UUID: str, + } else: from pydantic.datetime_parse import parse_date as parse_date # type: ignore[no-redef] from pydantic.datetime_parse import parse_datetime as parse_datetime # type: ignore[no-redef] - from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef] + from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef, assignment] from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[no-redef] from pydantic.typing import get_args as get_args # type: ignore[no-redef] from pydantic.typing import get_origin as get_origin # type: ignore[no-redef] - from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef] + from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef, assignment] from pydantic.typing import is_union as is_union # type: ignore[no-redef] from .datetime_utils import serialize_datetime @@ -537,7 +611,7 @@ def decorator(func: AnyCallable) -> AnyCallable: return decorator -PydanticField = Union[ModelField, pydantic.fields.FieldInfo] +PydanticField = Union[ModelField, _FieldInfo] def _get_model_fields(model: Type["Model"]) -> Mapping[str, PydanticField]: diff --git a/src/truefoundry_sdk/data_directories/client.py b/src/truefoundry_sdk/data_directories/client.py index d3a58fce..f8473f8a 100644 --- a/src/truefoundry_sdk/data_directories/client.py +++ b/src/truefoundry_sdk/data_directories/client.py @@ -40,13 +40,6 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non """ Get a data directory by its ID. - Args: - id (str): The ID of the data directory to retrieve - user_info: Current authenticated user info - - Returns: - DataDirectoryResponse: Response containing the retrieved data directory - Parameters ---------- id : str @@ -57,7 +50,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetDataDirectoryResponse - Successful Response + The data directory data Examples -------- @@ -82,15 +75,7 @@ def delete( request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ - Delete a data directory and optionally its contents. - - Args: - id: Unique identifier of the data directory to delete - delete_contents: If True, also deletes the data directory's contents - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete a data directory, optionally including its contents. Parameters ---------- @@ -104,7 +89,7 @@ def delete( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -133,30 +118,24 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[DataDirectory, ListDataDirectoriesResponse]: """ - List all data directories with optional filtering and pagination. - - Args: - filters: Query parameters for filtering and pagination - - ml_repo_id: Filter data directories by ml repo ID - - name: Optional filter data directories by name - - limit: Optional maximum number of data directories to return - - offset: Optional number of data directories to skip - user_info: Authenticated user information - - Returns: - ListDataDirectoriesResponse: List of data directories and pagination info + List data directories with optional filtering by FQN, ML Repo, or name. Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter data directories by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter data directories by name : typing.Optional[str] + Name of the data directory to filter by limit : typing.Optional[int] + Maximum number of data directories to return offset : typing.Optional[int] + Number of data directories to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -164,7 +143,7 @@ def list( Returns ------- SyncPager[DataDirectory, ListDataDirectoriesResponse] - Successful Response + List of data directories matching the query with pagination information Examples -------- @@ -195,9 +174,12 @@ def create_or_update( self, *, manifest: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetDataDirectoryResponse: """ + Create or update a data directory. + Parameters ---------- manifest : DataDirectoryManifest + Manifest containing metadata for the data directory to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -205,7 +187,7 @@ def create_or_update( Returns ------- GetDataDirectoryResponse - Successful Response + The created or updated data directory Examples -------- @@ -241,24 +223,21 @@ def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[FileInfo, ListFilesResponse]: """ - List files in a dataset. - - Args: - request_dto: Request containing dataset ID, path, page token and limit - user_info: Authenticated user information - - Returns: - ListFilesResponse: Response containing files and pagination info + List files and directories in a data directory. Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -266,7 +245,7 @@ def list_files( Returns ------- SyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information Examples -------- @@ -293,20 +272,15 @@ def delete_files( self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None ) -> EmptyResponse: """ - Delete files from the dataset. - - Args: - request_dto: Request containing dataset ID and paths - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete files from a data directory. Parameters ---------- id : str + ID of the artifact version to delete files from paths : typing.Sequence[str] + List of relative file paths within the artifact version to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -314,7 +288,7 @@ def delete_files( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -341,22 +315,18 @@ def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> GetSignedUrLsResponse: """ - Get signed URLs for a dataset. - - Args: - request_dto: Request containing dataset ID, paths and operation - user_info: Authenticated user information - - Returns: - GetSignedURLsResponse: Response containing signed URLs + Get pre-signed URLs for reading or writing files in a data directory. Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -364,7 +334,7 @@ def get_signed_urls( Returns ------- GetSignedUrLsResponse - Successful Response + List of signed URLs for the requested file paths Examples -------- @@ -389,22 +359,18 @@ def create_multipart_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> MultiPartUploadResponse: """ - Create a multipart upload for a dataset - - Args: - request_dto: Request containing dataset ID, path and number of parts - user_info: Authenticated user information - - Returns: - MultiPartUploadResponse: Response containing multipart upload info + Create a multipart upload for large files in a data directory. Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -412,7 +378,7 @@ def create_multipart_upload( Returns ------- MultiPartUploadResponse - Successful Response + Multipart upload information including signed URLs for each part Examples -------- @@ -455,13 +421,6 @@ async def get( """ Get a data directory by its ID. - Args: - id (str): The ID of the data directory to retrieve - user_info: Current authenticated user info - - Returns: - DataDirectoryResponse: Response containing the retrieved data directory - Parameters ---------- id : str @@ -472,7 +431,7 @@ async def get( Returns ------- GetDataDirectoryResponse - Successful Response + The data directory data Examples -------- @@ -505,15 +464,7 @@ async def delete( request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ - Delete a data directory and optionally its contents. - - Args: - id: Unique identifier of the data directory to delete - delete_contents: If True, also deletes the data directory's contents - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete a data directory, optionally including its contents. Parameters ---------- @@ -527,7 +478,7 @@ async def delete( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -564,30 +515,24 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[DataDirectory, ListDataDirectoriesResponse]: """ - List all data directories with optional filtering and pagination. - - Args: - filters: Query parameters for filtering and pagination - - ml_repo_id: Filter data directories by ml repo ID - - name: Optional filter data directories by name - - limit: Optional maximum number of data directories to return - - offset: Optional number of data directories to skip - user_info: Authenticated user information - - Returns: - ListDataDirectoriesResponse: List of data directories and pagination info + List data directories with optional filtering by FQN, ML Repo, or name. Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter data directories by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter data directories by name : typing.Optional[str] + Name of the data directory to filter by limit : typing.Optional[int] + Maximum number of data directories to return offset : typing.Optional[int] + Number of data directories to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -595,7 +540,7 @@ async def list( Returns ------- AsyncPager[DataDirectory, ListDataDirectoriesResponse] - Successful Response + List of data directories matching the query with pagination information Examples -------- @@ -635,9 +580,12 @@ async def create_or_update( self, *, manifest: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetDataDirectoryResponse: """ + Create or update a data directory. + Parameters ---------- manifest : DataDirectoryManifest + Manifest containing metadata for the data directory to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -645,7 +593,7 @@ async def create_or_update( Returns ------- GetDataDirectoryResponse - Successful Response + The created or updated data directory Examples -------- @@ -689,24 +637,21 @@ async def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[FileInfo, ListFilesResponse]: """ - List files in a dataset. - - Args: - request_dto: Request containing dataset ID, path, page token and limit - user_info: Authenticated user information - - Returns: - ListFilesResponse: Response containing files and pagination info + List files and directories in a data directory. Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -714,7 +659,7 @@ async def list_files( Returns ------- AsyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information Examples -------- @@ -750,20 +695,15 @@ async def delete_files( self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None ) -> EmptyResponse: """ - Delete files from the dataset. - - Args: - request_dto: Request containing dataset ID and paths - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete files from a data directory. Parameters ---------- id : str + ID of the artifact version to delete files from paths : typing.Sequence[str] + List of relative file paths within the artifact version to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -771,7 +711,7 @@ async def delete_files( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -806,22 +746,18 @@ async def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> GetSignedUrLsResponse: """ - Get signed URLs for a dataset. - - Args: - request_dto: Request containing dataset ID, paths and operation - user_info: Authenticated user information - - Returns: - GetSignedURLsResponse: Response containing signed URLs + Get pre-signed URLs for reading or writing files in a data directory. Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -829,7 +765,7 @@ async def get_signed_urls( Returns ------- GetSignedUrLsResponse - Successful Response + List of signed URLs for the requested file paths Examples -------- @@ -862,22 +798,18 @@ async def create_multipart_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> MultiPartUploadResponse: """ - Create a multipart upload for a dataset - - Args: - request_dto: Request containing dataset ID, path and number of parts - user_info: Authenticated user information - - Returns: - MultiPartUploadResponse: Response containing multipart upload info + Create a multipart upload for large files in a data directory. Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -885,7 +817,7 @@ async def create_multipart_upload( Returns ------- MultiPartUploadResponse - Successful Response + Multipart upload information including signed URLs for each part Examples -------- diff --git a/src/truefoundry_sdk/data_directories/raw_client.py b/src/truefoundry_sdk/data_directories/raw_client.py index 13c03d74..2bfe761e 100644 --- a/src/truefoundry_sdk/data_directories/raw_client.py +++ b/src/truefoundry_sdk/data_directories/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -22,6 +23,7 @@ from ..types.list_files_response import ListFilesResponse from ..types.multi_part_upload_response import MultiPartUploadResponse from ..types.operation import Operation +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -37,13 +39,6 @@ def get( """ Get a data directory by its ID. - Args: - id (str): The ID of the data directory to retrieve - user_info: Current authenticated user info - - Returns: - DataDirectoryResponse: Response containing the retrieved data directory - Parameters ---------- id : str @@ -54,10 +49,10 @@ def get( Returns ------- HttpResponse[GetDataDirectoryResponse] - Successful Response + The data directory data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{jsonable_encoder(id)}", + f"api/ml/v1/data-directories/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -85,6 +80,10 @@ def get( _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( @@ -95,15 +94,7 @@ def delete( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ - Delete a data directory and optionally its contents. - - Args: - id: Unique identifier of the data directory to delete - delete_contents: If True, also deletes the data directory's contents - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete a data directory, optionally including its contents. Parameters ---------- @@ -117,10 +108,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{jsonable_encoder(id)}", + f"api/ml/v1/data-directories/{encode_path_param(id)}", method="DELETE", params={ "delete_contents": delete_contents, @@ -151,6 +142,10 @@ def delete( _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 list( @@ -164,30 +159,24 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[DataDirectory, ListDataDirectoriesResponse]: """ - List all data directories with optional filtering and pagination. - - Args: - filters: Query parameters for filtering and pagination - - ml_repo_id: Filter data directories by ml repo ID - - name: Optional filter data directories by name - - limit: Optional maximum number of data directories to return - - offset: Optional number of data directories to skip - user_info: Authenticated user information - - Returns: - ListDataDirectoriesResponse: List of data directories and pagination info + List data directories with optional filtering by FQN, ML Repo, or name. Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter data directories by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter data directories by name : typing.Optional[str] + Name of the data directory to filter by limit : typing.Optional[int] + Maximum number of data directories to return offset : typing.Optional[int] + Number of data directories to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -195,7 +184,7 @@ def list( Returns ------- SyncPager[DataDirectory, ListDataDirectoriesResponse] - Successful Response + List of data directories matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -245,15 +234,22 @@ def list( _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: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetDataDirectoryResponse]: """ + Create or update a data directory. + Parameters ---------- manifest : DataDirectoryManifest + Manifest containing metadata for the data directory to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -261,7 +257,7 @@ def create_or_update( Returns ------- HttpResponse[GetDataDirectoryResponse] - Successful Response + The created or updated data directory """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories", @@ -301,6 +297,10 @@ def create_or_update( _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 list_files( @@ -313,24 +313,21 @@ def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[FileInfo, ListFilesResponse]: """ - List files in a dataset. - - Args: - request_dto: Request containing dataset ID, path, page token and limit - user_info: Authenticated user information - - Returns: - ListFilesResponse: Response containing files and pagination info + List files and directories in a data directory. Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -338,7 +335,7 @@ def list_files( Returns ------- SyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/files", @@ -392,26 +389,25 @@ def list_files( _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_files( self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[EmptyResponse]: """ - Delete files from the dataset. - - Args: - request_dto: Request containing dataset ID and paths - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete files from a data directory. Parameters ---------- id : str + ID of the artifact version to delete files from paths : typing.Sequence[str] + List of relative file paths within the artifact version to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -419,7 +415,7 @@ def delete_files( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/files", @@ -458,6 +454,10 @@ def delete_files( _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_signed_urls( @@ -469,22 +469,18 @@ def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetSignedUrLsResponse]: """ - Get signed URLs for a dataset. - - Args: - request_dto: Request containing dataset ID, paths and operation - user_info: Authenticated user information - - Returns: - GetSignedURLsResponse: Response containing signed URLs + Get pre-signed URLs for reading or writing files in a data directory. Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -492,7 +488,7 @@ def get_signed_urls( Returns ------- HttpResponse[GetSignedUrLsResponse] - Successful Response + List of signed URLs for the requested file paths """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/signed-urls", @@ -532,28 +528,28 @@ def get_signed_urls( _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_multipart_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[MultiPartUploadResponse]: """ - Create a multipart upload for a dataset - - Args: - request_dto: Request containing dataset ID, path and number of parts - user_info: Authenticated user information - - Returns: - MultiPartUploadResponse: Response containing multipart upload info + Create a multipart upload for large files in a data directory. Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -561,7 +557,7 @@ def create_multipart_upload( Returns ------- HttpResponse[MultiPartUploadResponse] - Successful Response + Multipart upload information including signed URLs for each part """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/signed-urls/multipart", @@ -601,6 +597,10 @@ def create_multipart_upload( _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) @@ -614,13 +614,6 @@ async def get( """ Get a data directory by its ID. - Args: - id (str): The ID of the data directory to retrieve - user_info: Current authenticated user info - - Returns: - DataDirectoryResponse: Response containing the retrieved data directory - Parameters ---------- id : str @@ -631,10 +624,10 @@ async def get( Returns ------- AsyncHttpResponse[GetDataDirectoryResponse] - Successful Response + The data directory data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{jsonable_encoder(id)}", + f"api/ml/v1/data-directories/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -662,6 +655,10 @@ async def get( _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( @@ -672,15 +669,7 @@ async def delete( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ - Delete a data directory and optionally its contents. - - Args: - id: Unique identifier of the data directory to delete - delete_contents: If True, also deletes the data directory's contents - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete a data directory, optionally including its contents. Parameters ---------- @@ -694,10 +683,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{jsonable_encoder(id)}", + f"api/ml/v1/data-directories/{encode_path_param(id)}", method="DELETE", params={ "delete_contents": delete_contents, @@ -728,6 +717,10 @@ async def delete( _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 list( @@ -741,30 +734,24 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[DataDirectory, ListDataDirectoriesResponse]: """ - List all data directories with optional filtering and pagination. - - Args: - filters: Query parameters for filtering and pagination - - ml_repo_id: Filter data directories by ml repo ID - - name: Optional filter data directories by name - - limit: Optional maximum number of data directories to return - - offset: Optional number of data directories to skip - user_info: Authenticated user information - - Returns: - ListDataDirectoriesResponse: List of data directories and pagination info + List data directories with optional filtering by FQN, ML Repo, or name. Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter data directories by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter data directories by name : typing.Optional[str] + Name of the data directory to filter by limit : typing.Optional[int] + Maximum number of data directories to return offset : typing.Optional[int] + Number of data directories to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -772,7 +759,7 @@ async def list( Returns ------- AsyncPager[DataDirectory, ListDataDirectoriesResponse] - Successful Response + List of data directories matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -825,15 +812,22 @@ async def _get_next(): _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: DataDirectoryManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetDataDirectoryResponse]: """ + Create or update a data directory. + Parameters ---------- manifest : DataDirectoryManifest + Manifest containing metadata for the data directory to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -841,7 +835,7 @@ async def create_or_update( Returns ------- AsyncHttpResponse[GetDataDirectoryResponse] - Successful Response + The created or updated data directory """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories", @@ -881,6 +875,10 @@ async def create_or_update( _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 list_files( @@ -893,24 +891,21 @@ async def list_files( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[FileInfo, ListFilesResponse]: """ - List files in a dataset. - - Args: - request_dto: Request containing dataset ID, path, page token and limit - user_info: Authenticated user information - - Returns: - ListFilesResponse: Response containing files and pagination info + List files and directories in a data directory. Parameters ---------- id : str + ID of the artifact version to list files from path : typing.Optional[str] + Relative path within the artifact version to list files from (defaults to root) limit : typing.Optional[int] + Maximum number of files/directories to return page_token : typing.Optional[str] + Token to retrieve the next page of results request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -918,7 +913,7 @@ async def list_files( Returns ------- AsyncPager[FileInfo, ListFilesResponse] - Successful Response + List of files and directories with pagination information """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/files", @@ -975,26 +970,25 @@ async def _get_next(): _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_files( self, *, id: str, paths: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[EmptyResponse]: """ - Delete files from the dataset. - - Args: - request_dto: Request containing dataset ID and paths - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete files from a data directory. Parameters ---------- id : str + ID of the artifact version to delete files from paths : typing.Sequence[str] + List of relative file paths within the artifact version to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1002,7 +996,7 @@ async def delete_files( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/files", @@ -1041,6 +1035,10 @@ async def delete_files( _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_signed_urls( @@ -1052,22 +1050,18 @@ async def get_signed_urls( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetSignedUrLsResponse]: """ - Get signed URLs for a dataset. - - Args: - request_dto: Request containing dataset ID, paths and operation - user_info: Authenticated user information - - Returns: - GetSignedURLsResponse: Response containing signed URLs + Get pre-signed URLs for reading or writing files in a data directory. Parameters ---------- id : str + ID of the artifact version to get signed URLs for paths : typing.Sequence[str] + List of relative file paths within the artifact version to get signed URLs for operation : Operation + Operation type for the signed URL (e.g., 'READ' or 'WRITE') request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1075,7 +1069,7 @@ async def get_signed_urls( Returns ------- AsyncHttpResponse[GetSignedUrLsResponse] - Successful Response + List of signed URLs for the requested file paths """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/signed-urls", @@ -1115,28 +1109,28 @@ async def get_signed_urls( _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_multipart_upload( self, *, id: str, path: str, num_parts: int, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[MultiPartUploadResponse]: """ - Create a multipart upload for a dataset - - Args: - request_dto: Request containing dataset ID, path and number of parts - user_info: Authenticated user information - - Returns: - MultiPartUploadResponse: Response containing multipart upload info + Create a multipart upload for large files in a data directory. Parameters ---------- id : str + ID of the artifact version to upload files to path : str + Relative path within the artifact version where the file should be uploaded num_parts : int + Number of parts to split the upload into for multipart upload request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1144,7 +1138,7 @@ async def create_multipart_upload( Returns ------- AsyncHttpResponse[MultiPartUploadResponse] - Successful Response + Multipart upload information including signed URLs for each part """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/data-directories/signed-urls/multipart", @@ -1184,4 +1178,8 @@ async def create_multipart_upload( _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/environments/client.py b/src/truefoundry_sdk/environments/client.py index 0718d420..9095e64a 100644 --- a/src/truefoundry_sdk/environments/client.py +++ b/src/truefoundry_sdk/environments/client.py @@ -80,7 +80,7 @@ def create_or_update( self, *, manifest: EnvironmentManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetEnvironmentResponse: """ @@ -268,7 +268,7 @@ async def create_or_update( self, *, manifest: EnvironmentManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetEnvironmentResponse: """ diff --git a/src/truefoundry_sdk/environments/raw_client.py b/src/truefoundry_sdk/environments/raw_client.py index 42bf0255..0526b7a5 100644 --- a/src/truefoundry_sdk/environments/raw_client.py +++ b/src/truefoundry_sdk/environments/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -19,6 +20,7 @@ from ..types.get_environment_response import GetEnvironmentResponse from ..types.http_error import HttpError from ..types.list_environments_response import ListEnvironmentsResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -85,13 +87,17 @@ def list( _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: EnvironmentManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetEnvironmentResponse]: """ @@ -152,6 +158,10 @@ def create_or_update( _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( @@ -174,7 +184,7 @@ def get( Returns the Environment associated with the provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{jsonable_encoder(id)}", + f"api/svc/v1/environments/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -191,6 +201,10 @@ def get( _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[bool]: @@ -211,7 +225,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns true if the Environment is deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{jsonable_encoder(id)}", + f"api/svc/v1/environments/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -250,6 +264,10 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = _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) @@ -317,13 +335,17 @@ async def _get_next(): _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: EnvironmentManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetEnvironmentResponse]: """ @@ -384,6 +406,10 @@ async def create_or_update( _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( @@ -406,7 +432,7 @@ async def get( Returns the Environment associated with the provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{jsonable_encoder(id)}", + f"api/svc/v1/environments/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -423,6 +449,10 @@ async def get( _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( @@ -445,7 +475,7 @@ async def delete( Returns true if the Environment is deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{jsonable_encoder(id)}", + f"api/svc/v1/environments/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -484,4 +514,8 @@ async def delete( _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/events/raw_client.py b/src/truefoundry_sdk/events/raw_client.py index 80ada6d8..fd7dfbc9 100644 --- a/src/truefoundry_sdk/events/raw_client.py +++ b/src/truefoundry_sdk/events/raw_client.py @@ -6,6 +6,7 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -13,6 +14,7 @@ from ..errors.not_found_error import NotFoundError from ..types.get_events_response import GetEventsResponse from ..types.http_error import HttpError +from pydantic import ValidationError class RawEventsClient: @@ -120,6 +122,10 @@ def get( _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) @@ -228,4 +234,8 @@ async def get( _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/internal/__init__.py b/src/truefoundry_sdk/internal/__init__.py index ff0779df..b0722e58 100644 --- a/src/truefoundry_sdk/internal/__init__.py +++ b/src/truefoundry_sdk/internal/__init__.py @@ -21,7 +21,6 @@ workflows, ) from .ai_gateway import AiGatewayGetGatewayConfigRequestType - from .docker_registries import DockerRegistriesCreateRepositoryResponse, DockerRegistriesGetCredentialsResponse from .metrics import MetricsGetChartsRequestFilterEntity from .ml import ApplyMlEntityRequestManifest, DeleteMlEntityRequestManifest from .workflows import WorkflowsExecuteWorkflowResponse @@ -29,8 +28,6 @@ "AiGatewayGetGatewayConfigRequestType": ".ai_gateway", "ApplyMlEntityRequestManifest": ".ml", "DeleteMlEntityRequestManifest": ".ml", - "DockerRegistriesCreateRepositoryResponse": ".docker_registries", - "DockerRegistriesGetCredentialsResponse": ".docker_registries", "MetricsGetChartsRequestFilterEntity": ".metrics", "WorkflowsExecuteWorkflowResponse": ".workflows", "ai_gateway": ".ai_gateway", @@ -73,8 +70,6 @@ def __dir__(): "AiGatewayGetGatewayConfigRequestType", "ApplyMlEntityRequestManifest", "DeleteMlEntityRequestManifest", - "DockerRegistriesCreateRepositoryResponse", - "DockerRegistriesGetCredentialsResponse", "MetricsGetChartsRequestFilterEntity", "WorkflowsExecuteWorkflowResponse", "ai_gateway", diff --git a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py index 60880dd9..4efccb72 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py +++ b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py @@ -6,11 +6,13 @@ 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 jsonable_encoder +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 ...types.gateway_configuration import GatewayConfiguration from .types.ai_gateway_get_gateway_config_request_type import AiGatewayGetGatewayConfigRequestType +from pydantic import ValidationError class RawAiGatewayClient: @@ -37,7 +39,7 @@ def get_gateway_config( Gateway configuration retrieved successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/llm-gateway/config/{jsonable_encoder(type)}", + f"api/svc/v1/llm-gateway/config/{encode_path_param(type)}", method="GET", request_options=request_options, ) @@ -54,6 +56,10 @@ def get_gateway_config( _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) @@ -81,7 +87,7 @@ async def get_gateway_config( Gateway configuration retrieved successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/llm-gateway/config/{jsonable_encoder(type)}", + f"api/svc/v1/llm-gateway/config/{encode_path_param(type)}", method="GET", request_options=request_options, ) @@ -98,4 +104,8 @@ async def get_gateway_config( _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/internal/applications/raw_client.py b/src/truefoundry_sdk/internal/applications/raw_client.py index f0f62538..516ba969 100644 --- a/src/truefoundry_sdk/internal/applications/raw_client.py +++ b/src/truefoundry_sdk/internal/applications/raw_client.py @@ -6,12 +6,14 @@ 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 jsonable_encoder +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 ...errors.bad_request_error import BadRequestError from ...errors.method_not_allowed_error import MethodNotAllowedError from ...errors.not_found_error import NotFoundError +from pydantic import ValidationError class RawApplicationsClient: @@ -40,7 +42,7 @@ def promote_rollout( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/rollout/promote", + f"api/svc/v1/apps/{encode_path_param(id)}/rollout/promote", method="POST", params={ "full": full, @@ -75,6 +77,10 @@ def promote_rollout( _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_pod_template_hash_to_deployment_version( @@ -104,7 +110,7 @@ def get_pod_template_hash_to_deployment_version( Successfully retrieved the pod template hash to deployment version map. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/pod-template-hash-deployment-version-map", + f"api/svc/v1/apps/{encode_path_param(id)}/pod-template-hash-deployment-version-map", method="GET", params={ "podTemplateHashes": pod_template_hashes, @@ -135,6 +141,10 @@ def get_pod_template_hash_to_deployment_version( _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) @@ -164,7 +174,7 @@ async def promote_rollout( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/rollout/promote", + f"api/svc/v1/apps/{encode_path_param(id)}/rollout/promote", method="POST", params={ "full": full, @@ -199,6 +209,10 @@ async def promote_rollout( _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_pod_template_hash_to_deployment_version( @@ -228,7 +242,7 @@ async def get_pod_template_hash_to_deployment_version( Successfully retrieved the pod template hash to deployment version map. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/pod-template-hash-deployment-version-map", + f"api/svc/v1/apps/{encode_path_param(id)}/pod-template-hash-deployment-version-map", method="GET", params={ "podTemplateHashes": pod_template_hashes, @@ -259,4 +273,8 @@ async def get_pod_template_hash_to_deployment_version( _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/internal/artifact_versions/client.py b/src/truefoundry_sdk/internal/artifact_versions/client.py index d79328ec..78f07044 100644 --- a/src/truefoundry_sdk/internal/artifact_versions/client.py +++ b/src/truefoundry_sdk/internal/artifact_versions/client.py @@ -43,33 +43,45 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with internal metadata, optionally including model versions. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response include_model_versions : typing.Optional[bool] + Whether to include model versions in the results (internal use only) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -77,7 +89,7 @@ def list( Returns ------- SyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse] - Successful Response + List of artifact versions with internal metadata and pagination information Examples -------- @@ -155,33 +167,45 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with internal metadata, optionally including model versions. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response include_model_versions : typing.Optional[bool] + Whether to include model versions in the results (internal use only) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -189,7 +213,7 @@ async def list( Returns ------- AsyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse] - Successful Response + List of artifact versions with internal metadata and pagination information Examples -------- diff --git a/src/truefoundry_sdk/internal/artifact_versions/raw_client.py b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py index 56f5859c..89679e71 100644 --- a/src/truefoundry_sdk/internal/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py @@ -6,11 +6,13 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.pagination import AsyncPager, SyncPager +from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.unprocessable_entity_error import UnprocessableEntityError from ...types.internal_list_artifact_versions_response import InternalListArtifactVersionsResponse from ...types.internal_list_artifact_versions_response_data_item import InternalListArtifactVersionsResponseDataItem +from pydantic import ValidationError class RawArtifactVersionsClient: @@ -35,33 +37,45 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with internal metadata, optionally including model versions. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response include_model_versions : typing.Optional[bool] + Whether to include model versions in the results (internal use only) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -69,7 +83,7 @@ def list( Returns ------- SyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse] - Successful Response + List of artifact versions with internal metadata and pagination information """ offset = offset if offset is not None else 0 @@ -133,6 +147,10 @@ def list( _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) @@ -158,33 +176,45 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse]: """ - List artifact version API + List artifact versions with internal metadata, optionally including model versions. Parameters ---------- tag : typing.Optional[str] + Tag to filter artifact versions by fqn : typing.Optional[str] + Fully qualified name to filter artifact versions by (format: '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' or '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}') artifact_id : typing.Optional[str] + ID of the artifact to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter artifact versions by name : typing.Optional[str] + Name of the artifact to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter artifact versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter artifact versions by offset : typing.Optional[int] + Number of artifact versions to skip for pagination limit : typing.Optional[int] + Maximum number of artifact versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response include_model_versions : typing.Optional[bool] + Whether to include model versions in the results (internal use only) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -192,7 +222,7 @@ async def list( Returns ------- AsyncPager[InternalListArtifactVersionsResponseDataItem, InternalListArtifactVersionsResponse] - Successful Response + List of artifact versions with internal metadata and pagination information """ offset = offset if offset is not None else 0 @@ -259,4 +289,8 @@ async def _get_next(): _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/internal/build_logs/raw_client.py b/src/truefoundry_sdk/internal/build_logs/raw_client.py index aa0cbb56..9f7afbbd 100644 --- a/src/truefoundry_sdk/internal/build_logs/raw_client.py +++ b/src/truefoundry_sdk/internal/build_logs/raw_client.py @@ -6,13 +6,15 @@ 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 jsonable_encoder +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 ...types.logs_filter_query import LogsFilterQuery from ...types.logs_response import LogsResponse +from pydantic import ValidationError class RawBuildLogsClient: @@ -66,7 +68,7 @@ def get( Successfully retrieved build logs for the pipeline run """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/build-logs/{jsonable_encoder(pipeline_run_name)}", + f"api/svc/v1/build-logs/{encode_path_param(pipeline_run_name)}", method="GET", params={ "startTs": start_ts, @@ -104,6 +106,10 @@ def get( _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) @@ -158,7 +164,7 @@ async def get( Successfully retrieved build logs for the pipeline run """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/build-logs/{jsonable_encoder(pipeline_run_name)}", + f"api/svc/v1/build-logs/{encode_path_param(pipeline_run_name)}", method="GET", params={ "startTs": start_ts, @@ -196,4 +202,8 @@ async def get( _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/internal/clusters/raw_client.py b/src/truefoundry_sdk/internal/clusters/raw_client.py index 1a68dcda..24143c34 100644 --- a/src/truefoundry_sdk/internal/clusters/raw_client.py +++ b/src/truefoundry_sdk/internal/clusters/raw_client.py @@ -6,12 +6,14 @@ 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 jsonable_encoder +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 ...errors.unauthorized_error import UnauthorizedError from ...types.get_auto_provisioning_state_response import GetAutoProvisioningStateResponse from ...types.http_error import HttpError +from pydantic import ValidationError class RawClustersClient: @@ -38,7 +40,7 @@ def get_autoprovisioning_state( Returns the auto provisioning status for the cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/autoprovisioning-state", + f"api/svc/v1/clusters/{encode_path_param(id)}/autoprovisioning-state", method="GET", request_options=request_options, ) @@ -66,6 +68,10 @@ def get_autoprovisioning_state( _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) @@ -93,7 +99,7 @@ async def get_autoprovisioning_state( Returns the auto provisioning status for the cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{jsonable_encoder(id)}/autoprovisioning-state", + f"api/svc/v1/clusters/{encode_path_param(id)}/autoprovisioning-state", method="GET", request_options=request_options, ) @@ -121,4 +127,8 @@ async def get_autoprovisioning_state( _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/internal/deployments/raw_client.py b/src/truefoundry_sdk/internal/deployments/raw_client.py index 6b820904..e96b1cb4 100644 --- a/src/truefoundry_sdk/internal/deployments/raw_client.py +++ b/src/truefoundry_sdk/internal/deployments/raw_client.py @@ -6,7 +6,8 @@ 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 jsonable_encoder +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 ...errors.bad_request_error import BadRequestError @@ -16,6 +17,7 @@ from ...types.deployment_status import DeploymentStatus from ...types.get_suggested_deployment_endpoint_response import GetSuggestedDeploymentEndpointResponse from ...types.presigned_url_object import PresignedUrlObject +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -48,7 +50,7 @@ def get_deployment_statuses( Deployment statuses returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/statuses", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/statuses", method="GET", request_options=request_options, ) @@ -76,6 +78,10 @@ def get_deployment_statuses( _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_builds( @@ -101,7 +107,7 @@ def get_builds( Deployment builds returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/builds", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/builds", method="GET", request_options=request_options, ) @@ -129,6 +135,10 @@ def get_builds( _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_code_upload_url( @@ -179,6 +189,10 @@ def get_code_upload_url( _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_suggested_endpoint( @@ -260,6 +274,10 @@ def get_suggested_endpoint( _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) @@ -290,7 +308,7 @@ async def get_deployment_statuses( Deployment statuses returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/statuses", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/statuses", method="GET", request_options=request_options, ) @@ -318,6 +336,10 @@ async def get_deployment_statuses( _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_builds( @@ -343,7 +365,7 @@ async def get_builds( Deployment builds returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/builds", + f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/builds", method="GET", request_options=request_options, ) @@ -371,6 +393,10 @@ async def get_builds( _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_code_upload_url( @@ -421,6 +447,10 @@ async def get_code_upload_url( _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_suggested_endpoint( @@ -502,4 +532,8 @@ async def get_suggested_endpoint( _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/internal/docker_registries/__init__.py b/src/truefoundry_sdk/internal/docker_registries/__init__.py index 5d663781..5cde0202 100644 --- a/src/truefoundry_sdk/internal/docker_registries/__init__.py +++ b/src/truefoundry_sdk/internal/docker_registries/__init__.py @@ -2,36 +2,3 @@ # isort: skip_file -import typing -from importlib import import_module - -if typing.TYPE_CHECKING: - from .types import DockerRegistriesCreateRepositoryResponse, DockerRegistriesGetCredentialsResponse -_dynamic_imports: typing.Dict[str, str] = { - "DockerRegistriesCreateRepositoryResponse": ".types", - "DockerRegistriesGetCredentialsResponse": ".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__ = ["DockerRegistriesCreateRepositoryResponse", "DockerRegistriesGetCredentialsResponse"] diff --git a/src/truefoundry_sdk/internal/docker_registries/client.py b/src/truefoundry_sdk/internal/docker_registries/client.py index b96f1594..5e7c0924 100644 --- a/src/truefoundry_sdk/internal/docker_registries/client.py +++ b/src/truefoundry_sdk/internal/docker_registries/client.py @@ -4,9 +4,9 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.request_options import RequestOptions +from ...types.create_docker_repository_response import CreateDockerRepositoryResponse +from ...types.get_docker_registry_credentials_response import GetDockerRegistryCredentialsResponse from .raw_client import AsyncRawDockerRegistriesClient, RawDockerRegistriesClient -from .types.docker_registries_create_repository_response import DockerRegistriesCreateRepositoryResponse -from .types.docker_registries_get_credentials_response import DockerRegistriesGetCredentialsResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -34,7 +34,7 @@ def create_repository( application_name: str, workspace_fqn: str, request_options: typing.Optional[RequestOptions] = None, - ) -> DockerRegistriesCreateRepositoryResponse: + ) -> CreateDockerRepositoryResponse: """ Create a docker repository in the provided workspace. @@ -54,7 +54,7 @@ def create_repository( Returns ------- - DockerRegistriesCreateRepositoryResponse + CreateDockerRepositoryResponse Returns the Repository name. Examples @@ -82,7 +82,7 @@ def get_credentials( fqn: typing.Optional[str] = None, cluster_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> DockerRegistriesGetCredentialsResponse: + ) -> GetDockerRegistryCredentialsResponse: """ Get docker registry credentials for building and pushing an image. @@ -99,7 +99,7 @@ def get_credentials( Returns ------- - DockerRegistriesGetCredentialsResponse + GetDockerRegistryCredentialsResponse Returns the docker registry credentials. Examples @@ -141,7 +141,7 @@ async def create_repository( application_name: str, workspace_fqn: str, request_options: typing.Optional[RequestOptions] = None, - ) -> DockerRegistriesCreateRepositoryResponse: + ) -> CreateDockerRepositoryResponse: """ Create a docker repository in the provided workspace. @@ -161,7 +161,7 @@ async def create_repository( Returns ------- - DockerRegistriesCreateRepositoryResponse + CreateDockerRepositoryResponse Returns the Repository name. Examples @@ -197,7 +197,7 @@ async def get_credentials( fqn: typing.Optional[str] = None, cluster_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> DockerRegistriesGetCredentialsResponse: + ) -> GetDockerRegistryCredentialsResponse: """ Get docker registry credentials for building and pushing an image. @@ -214,7 +214,7 @@ async def get_credentials( Returns ------- - DockerRegistriesGetCredentialsResponse + GetDockerRegistryCredentialsResponse Returns the docker registry credentials. Examples diff --git a/src/truefoundry_sdk/internal/docker_registries/raw_client.py b/src/truefoundry_sdk/internal/docker_registries/raw_client.py index fba97a3a..f23aaaa7 100644 --- a/src/truefoundry_sdk/internal/docker_registries/raw_client.py +++ b/src/truefoundry_sdk/internal/docker_registries/raw_client.py @@ -6,11 +6,13 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.not_found_error import NotFoundError -from .types.docker_registries_create_repository_response import DockerRegistriesCreateRepositoryResponse -from .types.docker_registries_get_credentials_response import DockerRegistriesGetCredentialsResponse +from ...types.create_docker_repository_response import CreateDockerRepositoryResponse +from ...types.get_docker_registry_credentials_response import GetDockerRegistryCredentialsResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -27,7 +29,7 @@ def create_repository( application_name: str, workspace_fqn: str, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[DockerRegistriesCreateRepositoryResponse]: + ) -> HttpResponse[CreateDockerRepositoryResponse]: """ Create a docker repository in the provided workspace. @@ -47,7 +49,7 @@ def create_repository( Returns ------- - HttpResponse[DockerRegistriesCreateRepositoryResponse] + HttpResponse[CreateDockerRepositoryResponse] Returns the Repository name. """ _response = self._client_wrapper.httpx_client.request( @@ -67,9 +69,9 @@ def create_repository( try: if 200 <= _response.status_code < 300: _data = typing.cast( - DockerRegistriesCreateRepositoryResponse, + CreateDockerRepositoryResponse, parse_obj_as( - type_=DockerRegistriesCreateRepositoryResponse, # type: ignore + type_=CreateDockerRepositoryResponse, # type: ignore object_=_response.json(), ), ) @@ -88,6 +90,10 @@ def create_repository( _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_credentials( @@ -96,7 +102,7 @@ def get_credentials( fqn: typing.Optional[str] = None, cluster_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[DockerRegistriesGetCredentialsResponse]: + ) -> HttpResponse[GetDockerRegistryCredentialsResponse]: """ Get docker registry credentials for building and pushing an image. @@ -113,7 +119,7 @@ def get_credentials( Returns ------- - HttpResponse[DockerRegistriesGetCredentialsResponse] + HttpResponse[GetDockerRegistryCredentialsResponse] Returns the docker registry credentials. """ _response = self._client_wrapper.httpx_client.request( @@ -128,9 +134,9 @@ def get_credentials( try: if 200 <= _response.status_code < 300: _data = typing.cast( - DockerRegistriesGetCredentialsResponse, + GetDockerRegistryCredentialsResponse, parse_obj_as( - type_=DockerRegistriesGetCredentialsResponse, # type: ignore + type_=GetDockerRegistryCredentialsResponse, # type: ignore object_=_response.json(), ), ) @@ -138,6 +144,10 @@ def get_credentials( _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) @@ -152,7 +162,7 @@ async def create_repository( application_name: str, workspace_fqn: str, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[DockerRegistriesCreateRepositoryResponse]: + ) -> AsyncHttpResponse[CreateDockerRepositoryResponse]: """ Create a docker repository in the provided workspace. @@ -172,7 +182,7 @@ async def create_repository( Returns ------- - AsyncHttpResponse[DockerRegistriesCreateRepositoryResponse] + AsyncHttpResponse[CreateDockerRepositoryResponse] Returns the Repository name. """ _response = await self._client_wrapper.httpx_client.request( @@ -192,9 +202,9 @@ async def create_repository( try: if 200 <= _response.status_code < 300: _data = typing.cast( - DockerRegistriesCreateRepositoryResponse, + CreateDockerRepositoryResponse, parse_obj_as( - type_=DockerRegistriesCreateRepositoryResponse, # type: ignore + type_=CreateDockerRepositoryResponse, # type: ignore object_=_response.json(), ), ) @@ -213,6 +223,10 @@ async def create_repository( _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_credentials( @@ -221,7 +235,7 @@ async def get_credentials( fqn: typing.Optional[str] = None, cluster_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[DockerRegistriesGetCredentialsResponse]: + ) -> AsyncHttpResponse[GetDockerRegistryCredentialsResponse]: """ Get docker registry credentials for building and pushing an image. @@ -238,7 +252,7 @@ async def get_credentials( Returns ------- - AsyncHttpResponse[DockerRegistriesGetCredentialsResponse] + AsyncHttpResponse[GetDockerRegistryCredentialsResponse] Returns the docker registry credentials. """ _response = await self._client_wrapper.httpx_client.request( @@ -253,9 +267,9 @@ async def get_credentials( try: if 200 <= _response.status_code < 300: _data = typing.cast( - DockerRegistriesGetCredentialsResponse, + GetDockerRegistryCredentialsResponse, parse_obj_as( - type_=DockerRegistriesGetCredentialsResponse, # type: ignore + type_=GetDockerRegistryCredentialsResponse, # type: ignore object_=_response.json(), ), ) @@ -263,4 +277,8 @@ async def get_credentials( _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/internal/docker_registries/types/__init__.py b/src/truefoundry_sdk/internal/docker_registries/types/__init__.py deleted file mode 100644 index 985a750e..00000000 --- a/src/truefoundry_sdk/internal/docker_registries/types/__init__.py +++ /dev/null @@ -1,38 +0,0 @@ -# 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 .docker_registries_create_repository_response import DockerRegistriesCreateRepositoryResponse - from .docker_registries_get_credentials_response import DockerRegistriesGetCredentialsResponse -_dynamic_imports: typing.Dict[str, str] = { - "DockerRegistriesCreateRepositoryResponse": ".docker_registries_create_repository_response", - "DockerRegistriesGetCredentialsResponse": ".docker_registries_get_credentials_response", -} - - -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__ = ["DockerRegistriesCreateRepositoryResponse", "DockerRegistriesGetCredentialsResponse"] diff --git a/src/truefoundry_sdk/internal/docker_registries/types/docker_registries_get_credentials_response.py b/src/truefoundry_sdk/internal/docker_registries/types/docker_registries_get_credentials_response.py deleted file mode 100644 index 002717a9..00000000 --- a/src/truefoundry_sdk/internal/docker_registries/types/docker_registries_get_credentials_response.py +++ /dev/null @@ -1,40 +0,0 @@ -# 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 DockerRegistriesGetCredentialsResponse(UniversalBaseModel): - fqn: typing.Optional[str] = pydantic.Field(default=None) - """ - Docker registry FQN - """ - - registry_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="registryUrl")] = ( - pydantic.Field(alias="registryUrl", default=None) - ) - """ - Docker registry URL - """ - - username: typing.Optional[str] = pydantic.Field(default=None) - """ - Username - """ - - password: typing.Optional[str] = pydantic.Field(default=None) - """ - Password - """ - - 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/internal/metrics/raw_client.py b/src/truefoundry_sdk/internal/metrics/raw_client.py index 1b6b7d28..263ddf63 100644 --- a/src/truefoundry_sdk/internal/metrics/raw_client.py +++ b/src/truefoundry_sdk/internal/metrics/raw_client.py @@ -6,7 +6,8 @@ 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 jsonable_encoder +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 ...errors.bad_request_error import BadRequestError @@ -14,6 +15,7 @@ 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 pydantic import ValidationError class RawMetricsClient: @@ -60,7 +62,7 @@ def get_charts( Charts have been successfully retrieved. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/metrics/{jsonable_encoder(workspace_id)}/charts", + f"api/svc/v1/metrics/{encode_path_param(workspace_id)}/charts", method="GET", params={ "applicationId": application_id, @@ -117,6 +119,10 @@ def get_charts( _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) @@ -164,7 +170,7 @@ async def get_charts( Charts have been successfully retrieved. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/metrics/{jsonable_encoder(workspace_id)}/charts", + f"api/svc/v1/metrics/{encode_path_param(workspace_id)}/charts", method="GET", params={ "applicationId": application_id, @@ -221,4 +227,8 @@ async def get_charts( _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/internal/ml/client.py b/src/truefoundry_sdk/internal/ml/client.py index 5158ce6f..03fa418d 100644 --- a/src/truefoundry_sdk/internal/ml/client.py +++ b/src/truefoundry_sdk/internal/ml/client.py @@ -33,9 +33,12 @@ def apply( self, *, manifest: ApplyMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> ApplyMlEntityResponse: """ + Create or update an ML entity (model, prompt, artifact, or data directory). + Parameters ---------- manifest : ApplyMlEntityRequestManifest + Manifest containing metadata for the ML entity to apply (model, prompt, artifact, agent skill, or data directory) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -43,7 +46,7 @@ def apply( Returns ------- ApplyMlEntityResponse - Successful Response + The created or updated ML entity Examples -------- @@ -69,9 +72,12 @@ def delete( self, *, manifest: DeleteMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> EmptyResponse: """ + Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML Repo) by manifest. + Parameters ---------- manifest : DeleteMlEntityRequestManifest + Manifest identifying the ML entity to delete (model, prompt, artifact, agent skill, data directory, or ML Repo) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -79,7 +85,7 @@ def delete( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -121,9 +127,12 @@ async def apply( self, *, manifest: ApplyMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> ApplyMlEntityResponse: """ + Create or update an ML entity (model, prompt, artifact, or data directory). + Parameters ---------- manifest : ApplyMlEntityRequestManifest + Manifest containing metadata for the ML entity to apply (model, prompt, artifact, agent skill, or data directory) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -131,7 +140,7 @@ async def apply( Returns ------- ApplyMlEntityResponse - Successful Response + The created or updated ML entity Examples -------- @@ -169,9 +178,12 @@ async def delete( self, *, manifest: DeleteMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> EmptyResponse: """ + Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML Repo) by manifest. + Parameters ---------- manifest : DeleteMlEntityRequestManifest + Manifest identifying the ML entity to delete (model, prompt, artifact, agent skill, data directory, or ML Repo) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -179,7 +191,7 @@ async def delete( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- diff --git a/src/truefoundry_sdk/internal/ml/raw_client.py b/src/truefoundry_sdk/internal/ml/raw_client.py index c855e797..6d0e28cc 100644 --- a/src/truefoundry_sdk/internal/ml/raw_client.py +++ b/src/truefoundry_sdk/internal/ml/raw_client.py @@ -6,6 +6,7 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse +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 @@ -14,6 +15,7 @@ from ...types.empty_response import EmptyResponse from .types.apply_ml_entity_request_manifest import ApplyMlEntityRequestManifest from .types.delete_ml_entity_request_manifest import DeleteMlEntityRequestManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -27,9 +29,12 @@ def apply( self, *, manifest: ApplyMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[ApplyMlEntityResponse]: """ + Create or update an ML entity (model, prompt, artifact, or data directory). + Parameters ---------- manifest : ApplyMlEntityRequestManifest + Manifest containing metadata for the ML entity to apply (model, prompt, artifact, agent skill, or data directory) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -37,7 +42,7 @@ def apply( Returns ------- HttpResponse[ApplyMlEntityResponse] - Successful Response + The created or updated ML entity """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/apply", @@ -77,15 +82,22 @@ def apply( _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, *, manifest: DeleteMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[EmptyResponse]: """ + Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML Repo) by manifest. + Parameters ---------- manifest : DeleteMlEntityRequestManifest + Manifest identifying the ML entity to delete (model, prompt, artifact, agent skill, data directory, or ML Repo) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -93,7 +105,7 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/delete", @@ -133,6 +145,10 @@ def delete( _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) @@ -144,9 +160,12 @@ async def apply( self, *, manifest: ApplyMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[ApplyMlEntityResponse]: """ + Create or update an ML entity (model, prompt, artifact, or data directory). + Parameters ---------- manifest : ApplyMlEntityRequestManifest + Manifest containing metadata for the ML entity to apply (model, prompt, artifact, agent skill, or data directory) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -154,7 +173,7 @@ async def apply( Returns ------- AsyncHttpResponse[ApplyMlEntityResponse] - Successful Response + The created or updated ML entity """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/apply", @@ -194,15 +213,22 @@ async def apply( _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, *, manifest: DeleteMlEntityRequestManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[EmptyResponse]: """ + Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML Repo) by manifest. + Parameters ---------- manifest : DeleteMlEntityRequestManifest + Manifest identifying the ML entity to delete (model, prompt, artifact, agent skill, data directory, or ML Repo) request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -210,7 +236,7 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/delete", @@ -250,4 +276,8 @@ async def delete( _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/internal/ml/types/apply_ml_entity_request_manifest.py b/src/truefoundry_sdk/internal/ml/types/apply_ml_entity_request_manifest.py index a880b6b2..a3a06ac0 100644 --- a/src/truefoundry_sdk/internal/ml/types/apply_ml_entity_request_manifest.py +++ b/src/truefoundry_sdk/internal/ml/types/apply_ml_entity_request_manifest.py @@ -2,9 +2,12 @@ import typing +from ....types.agent_skill_manifest import AgentSkillManifest from ....types.artifact_manifest import ArtifactManifest from ....types.chat_prompt_manifest import ChatPromptManifest from ....types.data_directory_manifest import DataDirectoryManifest from ....types.model_manifest import ModelManifest -ApplyMlEntityRequestManifest = typing.Union[ModelManifest, ChatPromptManifest, ArtifactManifest, DataDirectoryManifest] +ApplyMlEntityRequestManifest = typing.Union[ + ModelManifest, ChatPromptManifest, ArtifactManifest, AgentSkillManifest, DataDirectoryManifest +] diff --git a/src/truefoundry_sdk/internal/ml/types/delete_ml_entity_request_manifest.py b/src/truefoundry_sdk/internal/ml/types/delete_ml_entity_request_manifest.py index 76f0f09b..fbf3baa6 100644 --- a/src/truefoundry_sdk/internal/ml/types/delete_ml_entity_request_manifest.py +++ b/src/truefoundry_sdk/internal/ml/types/delete_ml_entity_request_manifest.py @@ -2,6 +2,7 @@ import typing +from ....types.agent_skill_manifest import AgentSkillManifest from ....types.artifact_manifest import ArtifactManifest from ....types.chat_prompt_manifest import ChatPromptManifest from ....types.data_directory_manifest import DataDirectoryManifest @@ -9,5 +10,5 @@ from ....types.model_manifest import ModelManifest DeleteMlEntityRequestManifest = typing.Union[ - ModelManifest, ChatPromptManifest, ArtifactManifest, DataDirectoryManifest, MlRepoManifest + ModelManifest, ChatPromptManifest, ArtifactManifest, AgentSkillManifest, DataDirectoryManifest, MlRepoManifest ] diff --git a/src/truefoundry_sdk/internal/raw_client.py b/src/truefoundry_sdk/internal/raw_client.py index cc90b88a..ba915ec2 100644 --- a/src/truefoundry_sdk/internal/raw_client.py +++ b/src/truefoundry_sdk/internal/raw_client.py @@ -6,11 +6,13 @@ 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 jsonable_encoder +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 ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError +from pydantic import ValidationError class RawInternalClient: @@ -40,7 +42,7 @@ def get_id_from_fqn( Returns the IDs for the specified entity type based on the provided FQN. For example, deploymentId, applicationId, and workspaceId for type deployment, or applicationId and workspaceId for type app. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/fqn/{jsonable_encoder(type)}", + f"api/svc/v1/fqn/{encode_path_param(type)}", method="GET", params={ "fqn": fqn, @@ -82,6 +84,10 @@ def get_id_from_fqn( _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) @@ -112,7 +118,7 @@ async def get_id_from_fqn( Returns the IDs for the specified entity type based on the provided FQN. For example, deploymentId, applicationId, and workspaceId for type deployment, or applicationId and workspaceId for type app. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/fqn/{jsonable_encoder(type)}", + f"api/svc/v1/fqn/{encode_path_param(type)}", method="GET", params={ "fqn": fqn, @@ -154,4 +160,8 @@ async def get_id_from_fqn( _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/internal/users/raw_client.py b/src/truefoundry_sdk/internal/users/raw_client.py index ddc359a2..fbed119e 100644 --- a/src/truefoundry_sdk/internal/users/raw_client.py +++ b/src/truefoundry_sdk/internal/users/raw_client.py @@ -6,9 +6,11 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...types.session import Session +from pydantic import ValidationError class RawUsersClient: @@ -47,6 +49,10 @@ def get_info(self, *, request_options: typing.Optional[RequestOptions] = None) - _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) @@ -86,4 +92,8 @@ async def get_info(self, *, request_options: typing.Optional[RequestOptions] = N _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/internal/vcs/raw_client.py b/src/truefoundry_sdk/internal/vcs/raw_client.py index fb35c9df..cda33908 100644 --- a/src/truefoundry_sdk/internal/vcs/raw_client.py +++ b/src/truefoundry_sdk/internal/vcs/raw_client.py @@ -6,10 +6,12 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...types.get_authenticated_vcsurl_response import GetAuthenticatedVcsurlResponse from ...types.git_repository_exists_response import GitRepositoryExistsResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -65,6 +67,10 @@ def get_repository_details( _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_authenticated_url( @@ -109,6 +115,10 @@ def get_authenticated_url( _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) @@ -162,6 +172,10 @@ async def get_repository_details( _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_authenticated_url( @@ -206,4 +220,8 @@ async def get_authenticated_url( _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/internal/workflows/raw_client.py b/src/truefoundry_sdk/internal/workflows/raw_client.py index 7ce6bb72..01a14081 100644 --- a/src/truefoundry_sdk/internal/workflows/raw_client.py +++ b/src/truefoundry_sdk/internal/workflows/raw_client.py @@ -6,12 +6,14 @@ 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 jsonable_encoder +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 ...errors.bad_request_error import BadRequestError from ...errors.not_found_error import NotFoundError from .types.workflows_execute_workflow_response import WorkflowsExecuteWorkflowResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -52,7 +54,7 @@ def execute_workflow( Returns execution name of the workflow """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workflow/{jsonable_encoder(application_id)}/executions", + f"api/svc/v1/workflow/{encode_path_param(application_id)}/executions", method="POST", json={ "inputs": inputs, @@ -99,6 +101,10 @@ def execute_workflow( _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) @@ -137,7 +143,7 @@ async def execute_workflow( Returns execution name of the workflow """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workflow/{jsonable_encoder(application_id)}/executions", + f"api/svc/v1/workflow/{encode_path_param(application_id)}/executions", method="POST", json={ "inputs": inputs, @@ -184,4 +190,8 @@ async def execute_workflow( _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/internal/workflows/types/workflows_execute_workflow_response.py b/src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py index 73238ca3..438fbed8 100644 --- a/src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py +++ b/src/truefoundry_sdk/internal/workflows/types/workflows_execute_workflow_response.py @@ -9,12 +9,11 @@ class WorkflowsExecuteWorkflowResponse(UniversalBaseModel): - execution_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="executionName")] = ( - pydantic.Field(alias="executionName", default=None) - ) - """ - The name of the execution - """ + execution_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="executionName"), + pydantic.Field(alias="executionName", description="The name of the execution"), + ] = 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/jobs/raw_client.py b/src/truefoundry_sdk/jobs/raw_client.py index fbc137b4..9df855f1 100644 --- a/src/truefoundry_sdk/jobs/raw_client.py +++ b/src/truefoundry_sdk/jobs/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -29,6 +30,7 @@ from ..types.terminate_job_response import TerminateJobResponse from ..types.trigger_job_run_response import TriggerJobRunResponse from .types.trigger_job_request_input import TriggerJobRequestInput +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -95,7 +97,7 @@ def list_runs( offset = offset if offset is not None else 0 _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs", method="GET", params={ "limit": limit, @@ -169,6 +171,10 @@ def list_runs( _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_run( @@ -194,7 +200,7 @@ def get_run( Return JobRun details of the provided jobRunName """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", method="GET", request_options=request_options, ) @@ -233,6 +239,10 @@ def get_run( _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_run( @@ -258,7 +268,7 @@ def delete_run( Job Run deleted """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", method="DELETE", request_options=request_options, ) @@ -308,6 +318,10 @@ def delete_run( _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 trigger( @@ -420,6 +434,10 @@ def trigger( _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 terminate( @@ -510,6 +528,10 @@ def terminate( _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) @@ -574,7 +596,7 @@ async def list_runs( offset = offset if offset is not None else 0 _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs", method="GET", params={ "limit": limit, @@ -651,6 +673,10 @@ async def _get_next(): _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_run( @@ -676,7 +702,7 @@ async def get_run( Return JobRun details of the provided jobRunName """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", method="GET", request_options=request_options, ) @@ -715,6 +741,10 @@ async def get_run( _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_run( @@ -740,7 +770,7 @@ async def delete_run( Job Run deleted """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", + f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", method="DELETE", request_options=request_options, ) @@ -790,6 +820,10 @@ async def delete_run( _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 trigger( @@ -902,6 +936,10 @@ async def trigger( _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 terminate( @@ -992,4 +1030,8 @@ async def terminate( _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/logs/raw_client.py b/src/truefoundry_sdk/logs/raw_client.py index ddc35056..8abc89d7 100644 --- a/src/truefoundry_sdk/logs/raw_client.py +++ b/src/truefoundry_sdk/logs/raw_client.py @@ -6,6 +6,7 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -13,6 +14,7 @@ from ..types.logs_search_filter_type import LogsSearchFilterType from ..types.logs_search_operator_type import LogsSearchOperatorType from ..types.logs_sorting_direction import LogsSortingDirection +from pydantic import ValidationError class RawLogsClient: @@ -153,6 +155,10 @@ def get( _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) @@ -294,4 +300,8 @@ async def get( _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/ml_repos/client.py b/src/truefoundry_sdk/ml_repos/client.py index 3e8deca9..59080e60 100644 --- a/src/truefoundry_sdk/ml_repos/client.py +++ b/src/truefoundry_sdk/ml_repos/client.py @@ -32,7 +32,11 @@ def with_raw_response(self) -> RawMlReposClient: return self._raw_client def create_or_update( - self, *, manifest: MlRepoManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: MlRepoManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> GetMlRepoResponse: """ Creates or updates an MLRepo entity based on the provided manifest. @@ -42,6 +46,9 @@ def create_or_update( manifest : MlRepoManifest MLRepo manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting changes or updating artifact location in the database + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -71,18 +78,14 @@ def create_or_update( ), ) """ - _response = self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + _response = self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) return _response.data def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetMlRepoResponse: """ - Get a ml repo by id - Args: - id: Unique identifier of the ml repo to get - user_info: Authenticated user information - - Returns: - GetMLRepoResponse: The ml repo + Get an ML Repo by its ID. Parameters ---------- @@ -94,7 +97,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetMlRepoResponse - Successful Response + The ML Repo data Examples -------- @@ -113,13 +116,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete a ml repo - Args: - id: Unique identifier of the ml repo to delete - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete an ML Repo by its ID. Parameters ---------- @@ -131,7 +128,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -157,21 +154,18 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[MlRepo, ListMlReposResponse]: """ - List ml repos - Args: - filters: Filters for the ml repos - user_info: Authenticated user information - - Returns: - ListMLReposResponse: List of ml repos + List ML Repos with optional filtering by name. Parameters ---------- name : typing.Optional[str] + Name of the ML Repo to filter by limit : typing.Optional[int] + Maximum number of ML Repos to return offset : typing.Optional[int] + Number of ML Repos to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -179,7 +173,7 @@ def list( Returns ------- SyncPager[MlRepo, ListMlReposResponse] - Successful Response + List of ML Repos matching the query with pagination information Examples -------- @@ -219,7 +213,11 @@ def with_raw_response(self) -> AsyncRawMlReposClient: return self._raw_client async def create_or_update( - self, *, manifest: MlRepoManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: MlRepoManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> GetMlRepoResponse: """ Creates or updates an MLRepo entity based on the provided manifest. @@ -229,6 +227,9 @@ async def create_or_update( manifest : MlRepoManifest MLRepo manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting changes or updating artifact location in the database + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -266,18 +267,14 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + _response = await self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) return _response.data async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetMlRepoResponse: """ - Get a ml repo by id - Args: - id: Unique identifier of the ml repo to get - user_info: Authenticated user information - - Returns: - GetMLRepoResponse: The ml repo + Get an ML Repo by its ID. Parameters ---------- @@ -289,7 +286,7 @@ async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetMlRepoResponse - Successful Response + The ML Repo data Examples -------- @@ -316,13 +313,7 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete a ml repo - Args: - id: Unique identifier of the ml repo to delete - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete an ML Repo by its ID. Parameters ---------- @@ -334,7 +325,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -368,21 +359,18 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[MlRepo, ListMlReposResponse]: """ - List ml repos - Args: - filters: Filters for the ml repos - user_info: Authenticated user information - - Returns: - ListMLReposResponse: List of ml repos + List ML Repos with optional filtering by name. Parameters ---------- name : typing.Optional[str] + Name of the ML Repo to filter by limit : typing.Optional[int] + Maximum number of ML Repos to return offset : typing.Optional[int] + Number of ML Repos to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -390,7 +378,7 @@ async def list( Returns ------- AsyncPager[MlRepo, ListMlReposResponse] - Successful Response + List of ML Repos matching the query with pagination information Examples -------- diff --git a/src/truefoundry_sdk/ml_repos/raw_client.py b/src/truefoundry_sdk/ml_repos/raw_client.py index c63fafe9..8c8297e9 100644 --- a/src/truefoundry_sdk/ml_repos/raw_client.py +++ b/src/truefoundry_sdk/ml_repos/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -21,6 +22,7 @@ from ..types.list_ml_repos_response import ListMlReposResponse from ..types.ml_repo import MlRepo from ..types.ml_repo_manifest import MlRepoManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,7 +33,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def create_or_update( - self, *, manifest: MlRepoManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: MlRepoManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetMlRepoResponse]: """ Creates or updates an MLRepo entity based on the provided manifest. @@ -41,6 +47,9 @@ def create_or_update( manifest : MlRepoManifest MLRepo manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting changes or updating artifact location in the database + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -56,6 +65,7 @@ def create_or_update( "manifest": convert_and_respect_annotation_metadata( object_=manifest, annotation=MlRepoManifest, direction="write" ), + "dryRun": dry_run, }, headers={ "content-type": "application/json", @@ -120,19 +130,17 @@ def create_or_update( _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[GetMlRepoResponse]: """ - Get a ml repo by id - Args: - id: Unique identifier of the ml repo to get - user_info: Authenticated user information - - Returns: - GetMLRepoResponse: The ml repo + Get an ML Repo by its ID. Parameters ---------- @@ -144,10 +152,10 @@ def get( Returns ------- HttpResponse[GetMlRepoResponse] - Successful Response + The ML Repo data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", + f"api/ml/v1/ml-repos/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -175,19 +183,17 @@ def get( _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[EmptyResponse]: """ - Delete a ml repo - Args: - id: Unique identifier of the ml repo to delete - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete an ML Repo by its ID. Parameters ---------- @@ -199,10 +205,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", + f"api/ml/v1/ml-repos/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -230,6 +236,10 @@ def delete( _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 list( @@ -241,21 +251,18 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[MlRepo, ListMlReposResponse]: """ - List ml repos - Args: - filters: Filters for the ml repos - user_info: Authenticated user information - - Returns: - ListMLReposResponse: List of ml repos + List ML Repos with optional filtering by name. Parameters ---------- name : typing.Optional[str] + Name of the ML Repo to filter by limit : typing.Optional[int] + Maximum number of ML Repos to return offset : typing.Optional[int] + Number of ML Repos to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -263,7 +270,7 @@ def list( Returns ------- SyncPager[MlRepo, ListMlReposResponse] - Successful Response + List of ML Repos matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -309,6 +316,10 @@ def list( _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) @@ -317,7 +328,11 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def create_or_update( - self, *, manifest: MlRepoManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: MlRepoManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetMlRepoResponse]: """ Creates or updates an MLRepo entity based on the provided manifest. @@ -327,6 +342,9 @@ async def create_or_update( manifest : MlRepoManifest MLRepo manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting changes or updating artifact location in the database + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -342,6 +360,7 @@ async def create_or_update( "manifest": convert_and_respect_annotation_metadata( object_=manifest, annotation=MlRepoManifest, direction="write" ), + "dryRun": dry_run, }, headers={ "content-type": "application/json", @@ -406,19 +425,17 @@ async def create_or_update( _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[GetMlRepoResponse]: """ - Get a ml repo by id - Args: - id: Unique identifier of the ml repo to get - user_info: Authenticated user information - - Returns: - GetMLRepoResponse: The ml repo + Get an ML Repo by its ID. Parameters ---------- @@ -430,10 +447,10 @@ async def get( Returns ------- AsyncHttpResponse[GetMlRepoResponse] - Successful Response + The ML Repo data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", + f"api/ml/v1/ml-repos/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -461,19 +478,17 @@ async def get( _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[EmptyResponse]: """ - Delete a ml repo - Args: - id: Unique identifier of the ml repo to delete - user_info: Authenticated user information - - Returns: - EmptyResponse: Empty response indicating successful deletion + Delete an ML Repo by its ID. Parameters ---------- @@ -485,10 +500,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", + f"api/ml/v1/ml-repos/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -516,6 +531,10 @@ async def delete( _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 list( @@ -527,21 +546,18 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[MlRepo, ListMlReposResponse]: """ - List ml repos - Args: - filters: Filters for the ml repos - user_info: Authenticated user information - - Returns: - ListMLReposResponse: List of ml repos + List ML Repos with optional filtering by name. Parameters ---------- name : typing.Optional[str] + Name of the ML Repo to filter by limit : typing.Optional[int] + Maximum number of ML Repos to return offset : typing.Optional[int] + Number of ML Repos to skip for pagination request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -549,7 +565,7 @@ async def list( Returns ------- AsyncPager[MlRepo, ListMlReposResponse] - Successful Response + List of ML Repos matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -598,4 +614,8 @@ async def _get_next(): _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/model_versions/client.py b/src/truefoundry_sdk/model_versions/client.py index 3fe771ca..dfdedc47 100644 --- a/src/truefoundry_sdk/model_versions/client.py +++ b/src/truefoundry_sdk/model_versions/client.py @@ -35,17 +35,22 @@ def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to a model version. + Parameters ---------- model_version_id : str + ID of the model version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the model version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -53,7 +58,7 @@ def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -75,7 +80,7 @@ def apply_tags( def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetModelVersionResponse: """ - Get model version API + Get a model version by its ID. Parameters ---------- @@ -87,7 +92,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetModelVersionResponse - Successful Response + The model version data Examples -------- @@ -106,7 +111,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete model versions API + Delete a model version by its ID. Parameters ---------- @@ -118,7 +123,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -152,31 +157,42 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ModelVersion, ListModelVersionsResponse]: """ - List model version API + List model versions with optional filtering by tag, FQN, model ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter model versions by fqn : typing.Optional[str] + Fully qualified name to filter model versions by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}' or 'model:{tenant_name}/{ml_repo_name}/{model_name}:{version}') model_id : typing.Optional[str] + ID of the model to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter model versions by name : typing.Optional[str] + Name of the model to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter model versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter model versions by offset : typing.Optional[int] + Number of model versions to skip for pagination limit : typing.Optional[int] + Maximum number of model versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -184,7 +200,7 @@ def list( Returns ------- SyncPager[ModelVersion, ListModelVersionsResponse] - Successful Response + List of model versions matching the query with pagination information Examples -------- @@ -247,17 +263,22 @@ async def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to a model version. + Parameters ---------- model_version_id : str + ID of the model version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the model version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -265,7 +286,7 @@ async def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -295,7 +316,7 @@ async def main() -> None: async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetModelVersionResponse: """ - Get model version API + Get a model version by its ID. Parameters ---------- @@ -307,7 +328,7 @@ async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetModelVersionResponse - Successful Response + The model version data Examples -------- @@ -334,7 +355,7 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete model versions API + Delete a model version by its ID. Parameters ---------- @@ -346,7 +367,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -388,31 +409,42 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ModelVersion, ListModelVersionsResponse]: """ - List model version API + List model versions with optional filtering by tag, FQN, model ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter model versions by fqn : typing.Optional[str] + Fully qualified name to filter model versions by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}' or 'model:{tenant_name}/{ml_repo_name}/{model_name}:{version}') model_id : typing.Optional[str] + ID of the model to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter model versions by name : typing.Optional[str] + Name of the model to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter model versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter model versions by offset : typing.Optional[int] + Number of model versions to skip for pagination limit : typing.Optional[int] + Maximum number of model versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -420,7 +452,7 @@ async def list( Returns ------- AsyncPager[ModelVersion, ListModelVersionsResponse] - Successful Response + List of model versions matching the query with pagination information Examples -------- diff --git a/src/truefoundry_sdk/model_versions/raw_client.py b/src/truefoundry_sdk/model_versions/raw_client.py index 2fa4d564..b8e3d3ea 100644 --- a/src/truefoundry_sdk/model_versions/raw_client.py +++ b/src/truefoundry_sdk/model_versions/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.unprocessable_entity_error import UnprocessableEntityError @@ -15,6 +16,7 @@ from ..types.get_model_version_response import GetModelVersionResponse from ..types.list_model_versions_response import ListModelVersionsResponse from ..types.model_version import ModelVersion +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -29,17 +31,22 @@ def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ + Apply tags to a model version. + Parameters ---------- model_version_id : str + ID of the model version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the model version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -47,7 +54,7 @@ def apply_tags( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/model-versions/tags", @@ -87,13 +94,17 @@ def apply_tags( _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[GetModelVersionResponse]: """ - Get model version API + Get a model version by its ID. Parameters ---------- @@ -105,10 +116,10 @@ def get( Returns ------- HttpResponse[GetModelVersionResponse] - Successful Response + The model version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{jsonable_encoder(id)}", + f"api/ml/v1/model-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -136,13 +147,17 @@ def get( _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[EmptyResponse]: """ - Delete model versions API + Delete a model version by its ID. Parameters ---------- @@ -154,10 +169,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{jsonable_encoder(id)}", + f"api/ml/v1/model-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -185,6 +200,10 @@ def delete( _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 list( @@ -204,31 +223,42 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ModelVersion, ListModelVersionsResponse]: """ - List model version API + List model versions with optional filtering by tag, FQN, model ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter model versions by fqn : typing.Optional[str] + Fully qualified name to filter model versions by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}' or 'model:{tenant_name}/{ml_repo_name}/{model_name}:{version}') model_id : typing.Optional[str] + ID of the model to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter model versions by name : typing.Optional[str] + Name of the model to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter model versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter model versions by offset : typing.Optional[int] + Number of model versions to skip for pagination limit : typing.Optional[int] + Maximum number of model versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -236,7 +266,7 @@ def list( Returns ------- SyncPager[ModelVersion, ListModelVersionsResponse] - Successful Response + List of model versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -298,6 +328,10 @@ def list( _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) @@ -310,17 +344,22 @@ async def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ + Apply tags to a model version. + Parameters ---------- model_version_id : str + ID of the model version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the model version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -328,7 +367,7 @@ async def apply_tags( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/model-versions/tags", @@ -368,13 +407,17 @@ async def apply_tags( _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[GetModelVersionResponse]: """ - Get model version API + Get a model version by its ID. Parameters ---------- @@ -386,10 +429,10 @@ async def get( Returns ------- AsyncHttpResponse[GetModelVersionResponse] - Successful Response + The model version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{jsonable_encoder(id)}", + f"api/ml/v1/model-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -417,13 +460,17 @@ async def get( _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[EmptyResponse]: """ - Delete model versions API + Delete a model version by its ID. Parameters ---------- @@ -435,10 +482,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{jsonable_encoder(id)}", + f"api/ml/v1/model-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -466,6 +513,10 @@ async def delete( _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 list( @@ -485,31 +536,42 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ModelVersion, ListModelVersionsResponse]: """ - List model version API + List model versions with optional filtering by tag, FQN, model ID, ML Repo, name, version, run IDs, or run steps. Parameters ---------- tag : typing.Optional[str] + Tag to filter model versions by fqn : typing.Optional[str] + Fully qualified name to filter model versions by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}' or 'model:{tenant_name}/{ml_repo_name}/{model_name}:{version}') model_id : typing.Optional[str] + ID of the model to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter model versions by name : typing.Optional[str] + Name of the model to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version run_ids : typing.Optional[typing.Union[str, typing.Sequence[str]]] + List of run IDs to filter model versions by run_steps : typing.Optional[typing.Union[int, typing.Sequence[int]]] + List of run step numbers to filter model versions by offset : typing.Optional[int] + Number of model versions to skip for pagination limit : typing.Optional[int] + Maximum number of model versions to return include_internal_metadata : typing.Optional[bool] + Whether to include internal metadata in the response request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -517,7 +579,7 @@ async def list( Returns ------- AsyncPager[ModelVersion, ListModelVersionsResponse] - Successful Response + List of model versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -582,4 +644,8 @@ async def _get_next(): _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/models/client.py b/src/truefoundry_sdk/models/client.py index fd75b966..e8832131 100644 --- a/src/truefoundry_sdk/models/client.py +++ b/src/truefoundry_sdk/models/client.py @@ -34,6 +34,8 @@ def with_raw_response(self) -> RawModelsClient: def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetModelResponse: """ + Get a model by its ID. + Parameters ---------- id : str @@ -44,7 +46,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetModelResponse - Successful Response + The model data Examples -------- @@ -63,6 +65,8 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete a model by its ID. + Parameters ---------- id : str @@ -73,7 +77,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -103,21 +107,30 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Model, ListModelsResponse]: """ + List models with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter models by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter models by name : typing.Optional[str] + Name of the model to filter by offset : typing.Optional[int] + Number of models to skip for pagination limit : typing.Optional[int] + Maximum number of models to return run_id : typing.Optional[str] + ID of the run to filter models by include_empty_models : typing.Optional[bool] + Whether to include models that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -125,7 +138,7 @@ def list( Returns ------- SyncPager[Model, ListModelsResponse] - Successful Response + List of models matching the query with pagination information Examples -------- @@ -165,9 +178,12 @@ def create_or_update( self, *, manifest: ModelManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetModelVersionResponse: """ + Create or update a model version. + Parameters ---------- manifest : ModelManifest + Manifest containing metadata for the model to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -175,7 +191,7 @@ def create_or_update( Returns ------- GetModelVersionResponse - Successful Response + The created or updated model version Examples -------- @@ -215,6 +231,8 @@ def with_raw_response(self) -> AsyncRawModelsClient: async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetModelResponse: """ + Get a model by its ID. + Parameters ---------- id : str @@ -225,7 +243,7 @@ async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetModelResponse - Successful Response + The model data Examples -------- @@ -252,6 +270,8 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete a model by its ID. + Parameters ---------- id : str @@ -262,7 +282,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -300,21 +320,30 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Model, ListModelsResponse]: """ + List models with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter models by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter models by name : typing.Optional[str] + Name of the model to filter by offset : typing.Optional[int] + Number of models to skip for pagination limit : typing.Optional[int] + Maximum number of models to return run_id : typing.Optional[str] + ID of the run to filter models by include_empty_models : typing.Optional[bool] + Whether to include models that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -322,7 +351,7 @@ async def list( Returns ------- AsyncPager[Model, ListModelsResponse] - Successful Response + List of models matching the query with pagination information Examples -------- @@ -371,9 +400,12 @@ async def create_or_update( self, *, manifest: ModelManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetModelVersionResponse: """ + Create or update a model version. + Parameters ---------- manifest : ModelManifest + Manifest containing metadata for the model to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -381,7 +413,7 @@ async def create_or_update( Returns ------- GetModelVersionResponse - Successful Response + The created or updated model version Examples -------- diff --git a/src/truefoundry_sdk/models/raw_client.py b/src/truefoundry_sdk/models/raw_client.py index 96efc07c..e8115cb2 100644 --- a/src/truefoundry_sdk/models/raw_client.py +++ b/src/truefoundry_sdk/models/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -18,6 +19,7 @@ from ..types.list_models_response import ListModelsResponse from ..types.model import Model from ..types.model_manifest import ModelManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,6 +33,8 @@ def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetModelResponse]: """ + Get a model by its ID. + Parameters ---------- id : str @@ -41,10 +45,10 @@ def get( Returns ------- HttpResponse[GetModelResponse] - Successful Response + The model data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{jsonable_encoder(id)}", + f"api/ml/v1/models/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -72,12 +76,18 @@ def get( _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[EmptyResponse]: """ + Delete a model by its ID. + Parameters ---------- id : str @@ -88,10 +98,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{jsonable_encoder(id)}", + f"api/ml/v1/models/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -119,6 +129,10 @@ def delete( _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 list( @@ -134,21 +148,30 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Model, ListModelsResponse]: """ + List models with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter models by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter models by name : typing.Optional[str] + Name of the model to filter by offset : typing.Optional[int] + Number of models to skip for pagination limit : typing.Optional[int] + Maximum number of models to return run_id : typing.Optional[str] + ID of the run to filter models by include_empty_models : typing.Optional[bool] + Whether to include models that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -156,7 +179,7 @@ def list( Returns ------- SyncPager[Model, ListModelsResponse] - Successful Response + List of models matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -210,15 +233,22 @@ def list( _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: ModelManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetModelVersionResponse]: """ + Create or update a model version. + Parameters ---------- manifest : ModelManifest + Manifest containing metadata for the model to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -226,7 +256,7 @@ def create_or_update( Returns ------- HttpResponse[GetModelVersionResponse] - Successful Response + The created or updated model version """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/model-versions", @@ -266,6 +296,10 @@ def create_or_update( _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) @@ -277,6 +311,8 @@ async def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetModelResponse]: """ + Get a model by its ID. + Parameters ---------- id : str @@ -287,10 +323,10 @@ async def get( Returns ------- AsyncHttpResponse[GetModelResponse] - Successful Response + The model data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{jsonable_encoder(id)}", + f"api/ml/v1/models/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -318,12 +354,18 @@ async def get( _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[EmptyResponse]: """ + Delete a model by its ID. + Parameters ---------- id : str @@ -334,10 +376,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{jsonable_encoder(id)}", + f"api/ml/v1/models/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -365,6 +407,10 @@ async def delete( _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 list( @@ -380,21 +426,30 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Model, ListModelsResponse]: """ + List models with optional filtering by FQN, ML Repo, name, or run ID. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter models by (format: 'model:{tenant_name}/{ml_repo_name}/{model_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter models by name : typing.Optional[str] + Name of the model to filter by offset : typing.Optional[int] + Number of models to skip for pagination limit : typing.Optional[int] + Maximum number of models to return run_id : typing.Optional[str] + ID of the run to filter models by include_empty_models : typing.Optional[bool] + Whether to include models that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -402,7 +457,7 @@ async def list( Returns ------- AsyncPager[Model, ListModelsResponse] - Successful Response + List of models matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -459,15 +514,22 @@ async def _get_next(): _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: ModelManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetModelVersionResponse]: """ + Create or update a model version. + Parameters ---------- manifest : ModelManifest + Manifest containing metadata for the model to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -475,7 +537,7 @@ async def create_or_update( Returns ------- AsyncHttpResponse[GetModelVersionResponse] - Successful Response + The created or updated model version """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/model-versions", @@ -515,4 +577,8 @@ async def create_or_update( _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/personal_access_tokens/client.py b/src/truefoundry_sdk/personal_access_tokens/client.py index 65ed5a09..06e61b99 100644 --- a/src/truefoundry_sdk/personal_access_tokens/client.py +++ b/src/truefoundry_sdk/personal_access_tokens/client.py @@ -37,6 +37,7 @@ def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + name_search_query: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[VirtualAccount, ListPersonalAccessTokenResponse]: """ @@ -50,6 +51,9 @@ def list( offset : typing.Optional[int] Number of items to skip + name_search_query : typing.Optional[str] + Return personal access tokens with names that contain this string + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -69,6 +73,7 @@ def list( response = client.personal_access_tokens.list( limit=10, offset=0, + name_search_query="nameSearchQuery", ) for item in response: yield item @@ -76,7 +81,9 @@ def list( for page in response.iter_pages(): yield page """ - return self._raw_client.list(limit=limit, offset=offset, request_options=request_options) + return self._raw_client.list( + limit=limit, offset=offset, name_search_query=name_search_query, request_options=request_options + ) def create( self, @@ -247,6 +254,7 @@ async def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + name_search_query: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[VirtualAccount, ListPersonalAccessTokenResponse]: """ @@ -260,6 +268,9 @@ async def list( offset : typing.Optional[int] Number of items to skip + name_search_query : typing.Optional[str] + Return personal access tokens with names that contain this string + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -284,6 +295,7 @@ async def main() -> None: response = await client.personal_access_tokens.list( limit=10, offset=0, + name_search_query="nameSearchQuery", ) async for item in response: yield item @@ -295,7 +307,9 @@ async def main() -> None: asyncio.run(main()) """ - return await self._raw_client.list(limit=limit, offset=offset, request_options=request_options) + return await self._raw_client.list( + limit=limit, offset=offset, name_search_query=name_search_query, request_options=request_options + ) async def create( self, diff --git a/src/truefoundry_sdk/personal_access_tokens/raw_client.py b/src/truefoundry_sdk/personal_access_tokens/raw_client.py index 5d9707bc..0b9474dd 100644 --- a/src/truefoundry_sdk/personal_access_tokens/raw_client.py +++ b/src/truefoundry_sdk/personal_access_tokens/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -20,6 +21,7 @@ from ..types.list_personal_access_token_response import ListPersonalAccessTokenResponse from ..types.revoke_all_personal_access_token_response import RevokeAllPersonalAccessTokenResponse from ..types.virtual_account import VirtualAccount +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -34,6 +36,7 @@ def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + name_search_query: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[VirtualAccount, ListPersonalAccessTokenResponse]: """ @@ -47,6 +50,9 @@ def list( offset : typing.Optional[int] Number of items to skip + name_search_query : typing.Optional[str] + Return personal access tokens with names that contain this string + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -63,6 +69,7 @@ def list( params={ "limit": limit, "offset": offset, + "nameSearchQuery": name_search_query, }, request_options=request_options, ) @@ -80,12 +87,17 @@ def list( _get_next = lambda: self.list( limit=limit, offset=offset + len(_items or []), + name_search_query=name_search_query, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) _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( @@ -167,6 +179,10 @@ def create( _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( @@ -224,6 +240,10 @@ def revoke_all( _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( @@ -246,7 +266,7 @@ def delete( Personal Access Token deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{jsonable_encoder(id)}", + f"api/svc/v1/personal-access-tokens/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -274,6 +294,10 @@ def delete( _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( @@ -295,7 +319,7 @@ def get( Personal Access Token found successfully and returned with token """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{jsonable_encoder(name)}", + f"api/svc/v1/personal-access-tokens/{encode_path_param(name)}", method="GET", request_options=request_options, ) @@ -323,6 +347,10 @@ def get( _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) @@ -335,6 +363,7 @@ async def list( *, limit: typing.Optional[int] = 100, offset: typing.Optional[int] = 0, + name_search_query: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[VirtualAccount, ListPersonalAccessTokenResponse]: """ @@ -348,6 +377,9 @@ async def list( offset : typing.Optional[int] Number of items to skip + name_search_query : typing.Optional[str] + Return personal access tokens with names that contain this string + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -364,6 +396,7 @@ async def list( params={ "limit": limit, "offset": offset, + "nameSearchQuery": name_search_query, }, request_options=request_options, ) @@ -383,6 +416,7 @@ async def _get_next(): return await self.list( limit=limit, offset=offset + len(_items or []), + name_search_query=name_search_query, request_options=request_options, ) @@ -390,6 +424,10 @@ async def _get_next(): _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( @@ -471,6 +509,10 @@ async def create( _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( @@ -528,6 +570,10 @@ async def revoke_all( _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( @@ -550,7 +596,7 @@ async def delete( Personal Access Token deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{jsonable_encoder(id)}", + f"api/svc/v1/personal-access-tokens/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -578,6 +624,10 @@ async def delete( _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( @@ -599,7 +649,7 @@ async def get( Personal Access Token found successfully and returned with token """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{jsonable_encoder(name)}", + f"api/svc/v1/personal-access-tokens/{encode_path_param(name)}", method="GET", request_options=request_options, ) @@ -627,4 +677,8 @@ async def get( _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/prompt_versions/client.py b/src/truefoundry_sdk/prompt_versions/client.py index 8f28a448..f7ad6733 100644 --- a/src/truefoundry_sdk/prompt_versions/client.py +++ b/src/truefoundry_sdk/prompt_versions/client.py @@ -35,17 +35,22 @@ def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to a prompt version. + Parameters ---------- prompt_version_id : str + ID of the prompt version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the prompt version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -53,7 +58,7 @@ def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -75,7 +80,7 @@ def apply_tags( def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPromptVersionResponse: """ - Get prompt version API + Get a prompt version by its ID. Parameters ---------- @@ -87,7 +92,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetPromptVersionResponse - Successful Response + The prompt version data Examples -------- @@ -106,7 +111,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete prompt versions API + Delete a prompt version by its ID. Parameters ---------- @@ -118,7 +123,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -149,25 +154,33 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[PromptVersion, ListPromptVersionsResponse]: """ - List prompt version API + List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, name, or version. Parameters ---------- tag : typing.Optional[str] + Tag to filter prompt versions by fqn : typing.Optional[str] + Fully qualified name to filter prompt versions by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}' or 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}:{version}') prompt_id : typing.Optional[str] + ID of the prompt to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompt versions by name : typing.Optional[str] + Name of the prompt to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version offset : typing.Optional[int] + Number of prompt versions to skip for pagination limit : typing.Optional[int] + Maximum number of prompt versions to return request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -175,7 +188,7 @@ def list( Returns ------- SyncPager[PromptVersion, ListPromptVersionsResponse] - Successful Response + List of prompt versions matching the query with pagination information Examples -------- @@ -234,17 +247,22 @@ async def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ + Apply tags to a prompt version. + Parameters ---------- prompt_version_id : str + ID of the prompt version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the prompt version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -252,7 +270,7 @@ async def apply_tags( Returns ------- EmptyResponse - Successful Response + Empty response indicating successful tag application Examples -------- @@ -284,7 +302,7 @@ async def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetPromptVersionResponse: """ - Get prompt version API + Get a prompt version by its ID. Parameters ---------- @@ -296,7 +314,7 @@ async def get( Returns ------- GetPromptVersionResponse - Successful Response + The prompt version data Examples -------- @@ -323,7 +341,7 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ - Delete prompt versions API + Delete a prompt version by its ID. Parameters ---------- @@ -335,7 +353,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -374,25 +392,33 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[PromptVersion, ListPromptVersionsResponse]: """ - List prompt version API + List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, name, or version. Parameters ---------- tag : typing.Optional[str] + Tag to filter prompt versions by fqn : typing.Optional[str] + Fully qualified name to filter prompt versions by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}' or 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}:{version}') prompt_id : typing.Optional[str] + ID of the prompt to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompt versions by name : typing.Optional[str] + Name of the prompt to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version offset : typing.Optional[int] + Number of prompt versions to skip for pagination limit : typing.Optional[int] + Maximum number of prompt versions to return request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -400,7 +426,7 @@ async def list( Returns ------- AsyncPager[PromptVersion, ListPromptVersionsResponse] - Successful Response + List of prompt versions matching the query with pagination information Examples -------- diff --git a/src/truefoundry_sdk/prompt_versions/raw_client.py b/src/truefoundry_sdk/prompt_versions/raw_client.py index 41606c88..d5816f5e 100644 --- a/src/truefoundry_sdk/prompt_versions/raw_client.py +++ b/src/truefoundry_sdk/prompt_versions/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.unprocessable_entity_error import UnprocessableEntityError @@ -15,6 +16,7 @@ from ..types.get_prompt_version_response import GetPromptVersionResponse from ..types.list_prompt_versions_response import ListPromptVersionsResponse from ..types.prompt_version import PromptVersion +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -29,17 +31,22 @@ def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ + Apply tags to a prompt version. + Parameters ---------- prompt_version_id : str + ID of the prompt version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the prompt version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -47,7 +54,7 @@ def apply_tags( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/prompt-versions/tags", @@ -87,13 +94,17 @@ def apply_tags( _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[GetPromptVersionResponse]: """ - Get prompt version API + Get a prompt version by its ID. Parameters ---------- @@ -105,10 +116,10 @@ def get( Returns ------- HttpResponse[GetPromptVersionResponse] - Successful Response + The prompt version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", + f"api/ml/v1/prompt-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -136,13 +147,17 @@ def get( _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[EmptyResponse]: """ - Delete prompt versions API + Delete a prompt version by its ID. Parameters ---------- @@ -154,10 +169,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", + f"api/ml/v1/prompt-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -185,6 +200,10 @@ def delete( _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 list( @@ -201,25 +220,33 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[PromptVersion, ListPromptVersionsResponse]: """ - List prompt version API + List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, name, or version. Parameters ---------- tag : typing.Optional[str] + Tag to filter prompt versions by fqn : typing.Optional[str] + Fully qualified name to filter prompt versions by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}' or 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}:{version}') prompt_id : typing.Optional[str] + ID of the prompt to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompt versions by name : typing.Optional[str] + Name of the prompt to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version offset : typing.Optional[int] + Number of prompt versions to skip for pagination limit : typing.Optional[int] + Maximum number of prompt versions to return request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -227,7 +254,7 @@ def list( Returns ------- SyncPager[PromptVersion, ListPromptVersionsResponse] - Successful Response + List of prompt versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -283,6 +310,10 @@ def list( _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) @@ -295,17 +326,22 @@ async def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = False, + force: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ + Apply tags to a prompt version. + Parameters ---------- prompt_version_id : str + ID of the prompt version to apply tags to tags : typing.Sequence[str] + List of tags to apply to the prompt version force : typing.Optional[bool] + Whether to overwrite existing tags if they conflict request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -313,7 +349,7 @@ async def apply_tags( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful tag application """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/prompt-versions/tags", @@ -353,13 +389,17 @@ async def apply_tags( _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[GetPromptVersionResponse]: """ - Get prompt version API + Get a prompt version by its ID. Parameters ---------- @@ -371,10 +411,10 @@ async def get( Returns ------- AsyncHttpResponse[GetPromptVersionResponse] - Successful Response + The prompt version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", + f"api/ml/v1/prompt-versions/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -402,13 +442,17 @@ async def get( _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[EmptyResponse]: """ - Delete prompt versions API + Delete a prompt version by its ID. Parameters ---------- @@ -420,10 +464,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", + f"api/ml/v1/prompt-versions/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -451,6 +495,10 @@ async def delete( _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 list( @@ -467,25 +515,33 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[PromptVersion, ListPromptVersionsResponse]: """ - List prompt version API + List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, name, or version. Parameters ---------- tag : typing.Optional[str] + Tag to filter prompt versions by fqn : typing.Optional[str] + Fully qualified name to filter prompt versions by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}' or 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}:{version}') prompt_id : typing.Optional[str] + ID of the prompt to filter versions by ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompt versions by name : typing.Optional[str] + Name of the prompt to filter versions by version : typing.Optional[int] + Version number (positive integer) or 'latest' to filter by specific version offset : typing.Optional[int] + Number of prompt versions to skip for pagination limit : typing.Optional[int] + Maximum number of prompt versions to return request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -493,7 +549,7 @@ async def list( Returns ------- AsyncPager[PromptVersion, ListPromptVersionsResponse] - Successful Response + List of prompt versions matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -552,4 +608,8 @@ async def _get_next(): _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/prompts/client.py b/src/truefoundry_sdk/prompts/client.py index 5df81f3e..c87ac14b 100644 --- a/src/truefoundry_sdk/prompts/client.py +++ b/src/truefoundry_sdk/prompts/client.py @@ -34,6 +34,8 @@ def with_raw_response(self) -> RawPromptsClient: def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPromptResponse: """ + Get a prompt by its ID. + Parameters ---------- id : str @@ -44,7 +46,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns ------- GetPromptResponse - Successful Response + The prompt data Examples -------- @@ -63,6 +65,8 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete a prompt by its ID. + Parameters ---------- id : str @@ -73,7 +77,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -102,19 +106,27 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Prompt, ListPromptsResponse]: """ + List prompts with optional filtering by FQN, ML Repo, or name. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter prompts by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompts by name : typing.Optional[str] + Name of the prompt to filter by offset : typing.Optional[int] + Number of prompts to skip for pagination limit : typing.Optional[int] + Maximum number of prompts to return include_empty_prompts : typing.Optional[bool] + Whether to include prompts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -122,7 +134,7 @@ def list( Returns ------- SyncPager[Prompt, ListPromptsResponse] - Successful Response + List of prompts matching the query with pagination information Examples -------- @@ -160,9 +172,12 @@ def create_or_update( self, *, manifest: ChatPromptManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetPromptVersionResponse: """ + Create or update a prompt version. + Parameters ---------- manifest : ChatPromptManifest + Manifest containing metadata for the prompt to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -170,7 +185,7 @@ def create_or_update( Returns ------- GetPromptVersionResponse - Successful Response + The created or updated prompt version Examples -------- @@ -214,6 +229,8 @@ def with_raw_response(self) -> AsyncRawPromptsClient: async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetPromptResponse: """ + Get a prompt by its ID. + Parameters ---------- id : str @@ -224,7 +241,7 @@ async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetPromptResponse - Successful Response + The prompt data Examples -------- @@ -251,6 +268,8 @@ async def main() -> None: async def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmptyResponse: """ + Delete a prompt by its ID. + Parameters ---------- id : str @@ -261,7 +280,7 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio Returns ------- EmptyResponse - Successful Response + Empty response indicating successful deletion Examples -------- @@ -298,19 +317,27 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Prompt, ListPromptsResponse]: """ + List prompts with optional filtering by FQN, ML Repo, or name. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter prompts by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompts by name : typing.Optional[str] + Name of the prompt to filter by offset : typing.Optional[int] + Number of prompts to skip for pagination limit : typing.Optional[int] + Maximum number of prompts to return include_empty_prompts : typing.Optional[bool] + Whether to include prompts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -318,7 +345,7 @@ async def list( Returns ------- AsyncPager[Prompt, ListPromptsResponse] - Successful Response + List of prompts matching the query with pagination information Examples -------- @@ -365,9 +392,12 @@ async def create_or_update( self, *, manifest: ChatPromptManifest, request_options: typing.Optional[RequestOptions] = None ) -> GetPromptVersionResponse: """ + Create or update a prompt version. + Parameters ---------- manifest : ChatPromptManifest + Manifest containing metadata for the prompt to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -375,7 +405,7 @@ async def create_or_update( Returns ------- GetPromptVersionResponse - Successful Response + The created or updated prompt version Examples -------- diff --git a/src/truefoundry_sdk/prompts/raw_client.py b/src/truefoundry_sdk/prompts/raw_client.py index eabef155..4b3a6ff9 100644 --- a/src/truefoundry_sdk/prompts/raw_client.py +++ b/src/truefoundry_sdk/prompts/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -18,6 +19,7 @@ from ..types.get_prompt_version_response import GetPromptVersionResponse from ..types.list_prompts_response import ListPromptsResponse from ..types.prompt import Prompt +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,6 +33,8 @@ def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetPromptResponse]: """ + Get a prompt by its ID. + Parameters ---------- id : str @@ -41,10 +45,10 @@ def get( Returns ------- HttpResponse[GetPromptResponse] - Successful Response + The prompt data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{jsonable_encoder(id)}", + f"api/ml/v1/prompts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -72,12 +76,18 @@ def get( _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[EmptyResponse]: """ + Delete a prompt by its ID. + Parameters ---------- id : str @@ -88,10 +98,10 @@ def delete( Returns ------- HttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{jsonable_encoder(id)}", + f"api/ml/v1/prompts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -119,6 +129,10 @@ def delete( _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 list( @@ -133,19 +147,27 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Prompt, ListPromptsResponse]: """ + List prompts with optional filtering by FQN, ML Repo, or name. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter prompts by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompts by name : typing.Optional[str] + Name of the prompt to filter by offset : typing.Optional[int] + Number of prompts to skip for pagination limit : typing.Optional[int] + Maximum number of prompts to return include_empty_prompts : typing.Optional[bool] + Whether to include prompts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -153,7 +175,7 @@ def list( Returns ------- SyncPager[Prompt, ListPromptsResponse] - Successful Response + List of prompts matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -205,15 +227,22 @@ def list( _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: ChatPromptManifest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetPromptVersionResponse]: """ + Create or update a prompt version. + Parameters ---------- manifest : ChatPromptManifest + Manifest containing metadata for the prompt to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -221,7 +250,7 @@ def create_or_update( Returns ------- HttpResponse[GetPromptVersionResponse] - Successful Response + The created or updated prompt version """ _response = self._client_wrapper.httpx_client.request( "api/ml/v1/prompt-versions", @@ -261,6 +290,10 @@ def create_or_update( _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) @@ -272,6 +305,8 @@ async def get( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetPromptResponse]: """ + Get a prompt by its ID. + Parameters ---------- id : str @@ -282,10 +317,10 @@ async def get( Returns ------- AsyncHttpResponse[GetPromptResponse] - Successful Response + The prompt data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{jsonable_encoder(id)}", + f"api/ml/v1/prompts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -313,12 +348,18 @@ async def get( _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[EmptyResponse]: """ + Delete a prompt by its ID. + Parameters ---------- id : str @@ -329,10 +370,10 @@ async def delete( Returns ------- AsyncHttpResponse[EmptyResponse] - Successful Response + Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{jsonable_encoder(id)}", + f"api/ml/v1/prompts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -360,6 +401,10 @@ async def delete( _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 list( @@ -374,19 +419,27 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Prompt, ListPromptsResponse]: """ + List prompts with optional filtering by FQN, ML Repo, or name. + Parameters ---------- fqn : typing.Optional[str] + Fully qualified name to filter prompts by (format: 'chat_prompt:{tenant_name}/{ml_repo_name}/{prompt_name}') ml_repo_id : typing.Optional[str] + ID of the ML Repo to filter prompts by name : typing.Optional[str] + Name of the prompt to filter by offset : typing.Optional[int] + Number of prompts to skip for pagination limit : typing.Optional[int] + Maximum number of prompts to return include_empty_prompts : typing.Optional[bool] + Whether to include prompts that have no versions request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -394,7 +447,7 @@ async def list( Returns ------- AsyncPager[Prompt, ListPromptsResponse] - Successful Response + List of prompts matching the query with pagination information """ offset = offset if offset is not None else 0 @@ -449,15 +502,22 @@ async def _get_next(): _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: ChatPromptManifest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetPromptVersionResponse]: """ + Create or update a prompt version. + Parameters ---------- manifest : ChatPromptManifest + Manifest containing metadata for the prompt to apply request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -465,7 +525,7 @@ async def create_or_update( Returns ------- AsyncHttpResponse[GetPromptVersionResponse] - Successful Response + The created or updated prompt version """ _response = await self._client_wrapper.httpx_client.request( "api/ml/v1/prompt-versions", @@ -505,4 +565,8 @@ async def create_or_update( _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/raw_base_client.py b/src/truefoundry_sdk/raw_base_client.py index 5247df4d..db933b65 100644 --- a/src/truefoundry_sdk/raw_base_client.py +++ b/src/truefoundry_sdk/raw_base_client.py @@ -6,12 +6,14 @@ from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .core.http_response import AsyncHttpResponse, HttpResponse +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 .types.true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest from .types.true_foundry_apply_response import TrueFoundryApplyResponse from .types.true_foundry_delete_request_manifest import TrueFoundryDeleteRequestManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -25,7 +27,7 @@ def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TrueFoundryApplyResponse]: """ @@ -75,6 +77,10 @@ def apply( _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( @@ -115,6 +121,10 @@ def delete( _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) @@ -126,7 +136,7 @@ async def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TrueFoundryApplyResponse]: """ @@ -176,6 +186,10 @@ async def apply( _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( @@ -216,4 +230,8 @@ async def delete( _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/secret_groups/client.py b/src/truefoundry_sdk/secret_groups/client.py index bcb0cb85..e69a7f3d 100644 --- a/src/truefoundry_sdk/secret_groups/client.py +++ b/src/truefoundry_sdk/secret_groups/client.py @@ -146,7 +146,11 @@ def create( return _response.data def create_or_update( - self, *, manifest: SecretGroupManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: SecretGroupManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> GetSecretGroupResponse: """ Creates a new secret group or updates an existing one based on the provided manifest. @@ -156,6 +160,9 @@ def create_or_update( manifest : SecretGroupManifest Secret Group Manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting or updating authorizations and secret groups + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -185,7 +192,9 @@ def create_or_update( ), ) """ - _response = self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + _response = self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) return _response.data def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetSecretGroupResponse: @@ -443,7 +452,11 @@ async def main() -> None: return _response.data async def create_or_update( - self, *, manifest: SecretGroupManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: SecretGroupManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> GetSecretGroupResponse: """ Creates a new secret group or updates an existing one based on the provided manifest. @@ -453,6 +466,9 @@ async def create_or_update( manifest : SecretGroupManifest Secret Group Manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting or updating authorizations and secret groups + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -490,7 +506,9 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.create_or_update(manifest=manifest, request_options=request_options) + _response = await self._raw_client.create_or_update( + manifest=manifest, dry_run=dry_run, request_options=request_options + ) return _response.data async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetSecretGroupResponse: diff --git a/src/truefoundry_sdk/secret_groups/raw_client.py b/src/truefoundry_sdk/secret_groups/raw_client.py index 6b0b2b22..2eabd01c 100644 --- a/src/truefoundry_sdk/secret_groups/raw_client.py +++ b/src/truefoundry_sdk/secret_groups/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -25,6 +26,7 @@ from ..types.secret_group_manifest import SecretGroupManifest from ..types.secret_input import SecretInput from ..types.update_secret_input import UpdateSecretInput +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -103,6 +105,10 @@ def list( _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( @@ -186,10 +192,18 @@ def create( _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: SecretGroupManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: SecretGroupManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetSecretGroupResponse]: """ Creates a new secret group or updates an existing one based on the provided manifest. @@ -199,6 +213,9 @@ def create_or_update( manifest : SecretGroupManifest Secret Group Manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting or updating authorizations and secret groups + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -214,6 +231,7 @@ def create_or_update( "manifest": convert_and_respect_annotation_metadata( object_=manifest, annotation=SecretGroupManifest, direction="write" ), + "dryRun": dry_run, }, headers={ "content-type": "application/json", @@ -289,6 +307,10 @@ def create_or_update( _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( @@ -311,7 +333,7 @@ def get( Returns the Secret Group associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -350,6 +372,10 @@ def get( _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 update( @@ -378,7 +404,7 @@ def update( Returns the updated secret group without associated secrets. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="PUT", json={ "secrets": convert_and_respect_annotation_metadata( @@ -448,6 +474,10 @@ def update( _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( @@ -470,7 +500,7 @@ def delete( Deletes Secret Group. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -509,6 +539,10 @@ def delete( _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) @@ -588,6 +622,10 @@ async def _get_next(): _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( @@ -671,10 +709,18 @@ async def create( _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: SecretGroupManifest, request_options: typing.Optional[RequestOptions] = None + self, + *, + manifest: SecretGroupManifest, + dry_run: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetSecretGroupResponse]: """ Creates a new secret group or updates an existing one based on the provided manifest. @@ -684,6 +730,9 @@ async def create_or_update( manifest : SecretGroupManifest Secret Group Manifest + dry_run : typing.Optional[bool] + Validate the manifest and collaborators without persisting or updating authorizations and secret groups + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -699,6 +748,7 @@ async def create_or_update( "manifest": convert_and_respect_annotation_metadata( object_=manifest, annotation=SecretGroupManifest, direction="write" ), + "dryRun": dry_run, }, headers={ "content-type": "application/json", @@ -774,6 +824,10 @@ async def create_or_update( _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( @@ -796,7 +850,7 @@ async def get( Returns the Secret Group associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -835,6 +889,10 @@ async def get( _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 update( @@ -863,7 +921,7 @@ async def update( Returns the updated secret group without associated secrets. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="PUT", json={ "secrets": convert_and_respect_annotation_metadata( @@ -933,6 +991,10 @@ async def update( _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( @@ -955,7 +1017,7 @@ async def delete( Deletes Secret Group. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", + f"api/svc/v1/secret-groups/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -994,4 +1056,8 @@ async def delete( _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/secrets/client.py b/src/truefoundry_sdk/secrets/client.py index 7356c92a..4f3dbed9 100644 --- a/src/truefoundry_sdk/secrets/client.py +++ b/src/truefoundry_sdk/secrets/client.py @@ -32,11 +32,11 @@ def with_raw_response(self) -> RawSecretsClient: def list( self, *, - limit: typing.Optional[int] = 100, - offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = OMIT, + offset: typing.Optional[int] = OMIT, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = False, + with_value: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Secret, ListSecretsResponse]: """ @@ -184,11 +184,11 @@ def with_raw_response(self) -> AsyncRawSecretsClient: async def list( self, *, - limit: typing.Optional[int] = 100, - offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = OMIT, + offset: typing.Optional[int] = OMIT, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = False, + with_value: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Secret, ListSecretsResponse]: """ diff --git a/src/truefoundry_sdk/secrets/raw_client.py b/src/truefoundry_sdk/secrets/raw_client.py index ff668387..95bfee11 100644 --- a/src/truefoundry_sdk/secrets/raw_client.py +++ b/src/truefoundry_sdk/secrets/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.failed_dependency_error import FailedDependencyError @@ -17,6 +18,7 @@ from ..types.http_error import HttpError from ..types.list_secrets_response import ListSecretsResponse from ..types.secret import Secret +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -29,11 +31,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list( self, *, - limit: typing.Optional[int] = 100, - offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = OMIT, + offset: typing.Optional[int] = OMIT, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = False, + with_value: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Secret, ListSecretsResponse]: """ @@ -127,6 +129,10 @@ def list( _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( @@ -149,7 +155,7 @@ def get( Returns the Secret associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{jsonable_encoder(id)}", + f"api/svc/v1/secrets/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -188,6 +194,10 @@ def get( _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( @@ -217,7 +227,7 @@ def delete( Deletes a secret and its versions along with its values and returns the count of the deleted secrets. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{jsonable_encoder(id)}", + f"api/svc/v1/secrets/{encode_path_param(id)}", method="DELETE", params={ "forceDelete": force_delete, @@ -270,6 +280,10 @@ def delete( _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) @@ -280,11 +294,11 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list( self, *, - limit: typing.Optional[int] = 100, - offset: typing.Optional[int] = 0, + limit: typing.Optional[int] = OMIT, + offset: typing.Optional[int] = OMIT, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = False, + with_value: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Secret, ListSecretsResponse]: """ @@ -381,6 +395,10 @@ async def _get_next(): _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( @@ -403,7 +421,7 @@ async def get( Returns the Secret associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{jsonable_encoder(id)}", + f"api/svc/v1/secrets/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -442,6 +460,10 @@ async def get( _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( @@ -471,7 +493,7 @@ async def delete( Deletes a secret and its versions along with its values and returns the count of the deleted secrets. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{jsonable_encoder(id)}", + f"api/svc/v1/secrets/{encode_path_param(id)}", method="DELETE", params={ "forceDelete": force_delete, @@ -524,4 +546,8 @@ async def delete( _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/teams/client.py b/src/truefoundry_sdk/teams/client.py index 62c40096..ab6335ed 100644 --- a/src/truefoundry_sdk/teams/client.py +++ b/src/truefoundry_sdk/teams/client.py @@ -6,6 +6,7 @@ from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions from ..types.delete_team_response import DeleteTeamResponse +from ..types.get_team_permissions_response import GetTeamPermissionsResponse from ..types.get_team_response import GetTeamResponse from ..types.list_teams_response import ListTeamsResponse from ..types.team import Team @@ -88,7 +89,7 @@ def create_or_update( self, *, manifest: TeamManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetTeamResponse: """ @@ -194,6 +195,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_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetTeamPermissionsResponse: + """ + Get all role bindings associated with a team. + + Parameters + ---------- + id : str + Team Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetTeamPermissionsResponse + Returns role bindings for the team. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.teams.get_permissions( + id="id", + ) + """ + _response = self._raw_client.get_permissions(id, request_options=request_options) + return _response.data + class AsyncTeamsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -275,7 +310,7 @@ async def create_or_update( self, *, manifest: TeamManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetTeamResponse: """ @@ -404,3 +439,45 @@ async def main() -> None: """ _response = await self._raw_client.delete(id, request_options=request_options) return _response.data + + async def get_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetTeamPermissionsResponse: + """ + Get all role bindings associated with a team. + + Parameters + ---------- + id : str + Team Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetTeamPermissionsResponse + Returns role bindings for the team. + + 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.teams.get_permissions( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_permissions(id, request_options=request_options) + return _response.data diff --git a/src/truefoundry_sdk/teams/raw_client.py b/src/truefoundry_sdk/teams/raw_client.py index 590549ff..c464a270 100644 --- a/src/truefoundry_sdk/teams/raw_client.py +++ b/src/truefoundry_sdk/teams/raw_client.py @@ -6,21 +6,25 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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.conflict_error import ConflictError +from ..errors.forbidden_error import ForbiddenError from ..errors.not_found_error import NotFoundError from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..types.delete_team_response import DeleteTeamResponse +from ..types.get_team_permissions_response import GetTeamPermissionsResponse from ..types.get_team_response import GetTeamResponse from ..types.http_error import HttpError from ..types.list_teams_response import ListTeamsResponse from ..types.team import Team from ..types.team_manifest import TeamManifest from .types.teams_list_request_type import TeamsListRequestType +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -93,13 +97,17 @@ def list( _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: TeamManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetTeamResponse]: """ @@ -171,6 +179,10 @@ def create_or_update( _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[GetTeamResponse]: @@ -191,7 +203,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns the Team associated with provided team id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{jsonable_encoder(id)}", + f"api/svc/v1/teams/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -219,6 +231,10 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non _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( @@ -241,7 +257,7 @@ def delete( Successfully deleted the team. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{jsonable_encoder(id)}", + f"api/svc/v1/teams/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -280,6 +296,75 @@ def delete( _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_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetTeamPermissionsResponse]: + """ + Get all role bindings associated with a team. + + Parameters + ---------- + id : str + Team Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetTeamPermissionsResponse] + Returns role bindings for the team. + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/teams/{encode_path_param(id)}/permissions", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetTeamPermissionsResponse, + parse_obj_as( + type_=GetTeamPermissionsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + 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(), + ), + ), + ) + _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) @@ -353,13 +438,17 @@ async def _get_next(): _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: TeamManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetTeamResponse]: """ @@ -431,6 +520,10 @@ async def create_or_update( _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( @@ -453,7 +546,7 @@ async def get( Returns the Team associated with provided team id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{jsonable_encoder(id)}", + f"api/svc/v1/teams/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -481,6 +574,10 @@ async def get( _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( @@ -503,7 +600,7 @@ async def delete( Successfully deleted the team. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{jsonable_encoder(id)}", + f"api/svc/v1/teams/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -542,4 +639,73 @@ async def delete( _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_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetTeamPermissionsResponse]: + """ + Get all role bindings associated with a team. + + Parameters + ---------- + id : str + Team Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetTeamPermissionsResponse] + Returns role bindings for the team. + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/teams/{encode_path_param(id)}/permissions", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetTeamPermissionsResponse, + parse_obj_as( + type_=GetTeamPermissionsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + 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(), + ), + ), + ) + _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/traces/client.py b/src/truefoundry_sdk/traces/client.py index 7ce2f88e..b793b387 100644 --- a/src/truefoundry_sdk/traces/client.py +++ b/src/truefoundry_sdk/traces/client.py @@ -48,7 +48,7 @@ def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = False, + include_feedbacks: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TraceSpan, QuerySpansResponse]: """ @@ -176,7 +176,7 @@ async def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = False, + include_feedbacks: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TraceSpan, QuerySpansResponse]: """ diff --git a/src/truefoundry_sdk/traces/raw_client.py b/src/truefoundry_sdk/traces/raw_client.py index 4ae7c14a..1ea3c7e7 100644 --- a/src/truefoundry_sdk/traces/raw_client.py +++ b/src/truefoundry_sdk/traces/raw_client.py @@ -6,6 +6,7 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.pagination import AsyncPager, SyncPager +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 @@ -14,6 +15,7 @@ from ..types.subject_type import SubjectType from ..types.trace_span import TraceSpan from .types.query_spans_request_filters_item import QuerySpansRequestFiltersItem +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -40,7 +42,7 @@ def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = False, + include_feedbacks: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TraceSpan, QuerySpansResponse]: """ @@ -164,6 +166,10 @@ def query_spans( _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) @@ -188,7 +194,7 @@ async def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = False, + include_feedbacks: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TraceSpan, QuerySpansResponse]: """ @@ -315,4 +321,8 @@ async def _get_next(): _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/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index d50bd68b..a7ffa387 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -9,6 +9,7 @@ from .resources import Resources from .resources_devices_item import ResourcesDevicesItem from .resources_node import ResourcesNode + from .a2a_framework import A2AFramework from .account import Account from .account_info import AccountInfo from .activate_user_response import ActivateUserResponse @@ -16,14 +17,23 @@ from .addon_component import AddonComponent from .addon_component_name import AddonComponentName from .addon_component_status import AddonComponentStatus + from .agent_framework import AgentFramework from .agent_manifest import AgentManifest from .agent_skill import AgentSkill + from .agent_skill_manifest import AgentSkillManifest + from .agent_skill_manifest_source import AgentSkillManifestSource + from .agent_skill_source_blob_storage import AgentSkillSourceBlobStorage + from .agent_skill_source_inline import AgentSkillSourceInline + from .agent_skill_version import AgentSkillVersion from .agent_source import AgentSource from .ai21integrations import Ai21Integrations from .ai21key_auth import Ai21KeyAuth from .ai21model import Ai21Model from .ai21provider_account import Ai21ProviderAccount from .ai_features_settings import AiFeaturesSettings + from .akto_guardrail_config import AktoGuardrailConfig + from .akto_guardrail_config_config import AktoGuardrailConfigConfig + from .akto_token_auth import AktoTokenAuth from .alert import Alert from .alert_config import AlertConfig from .alert_config_resource import AlertConfigResource @@ -40,10 +50,8 @@ from .anthropic_model import AnthropicModel from .anthropic_provider_account import AnthropicProviderAccount from .application import Application - from .application_debug_info import ApplicationDebugInfo from .application_lifecycle_stage import ApplicationLifecycleStage from .application_metadata import ApplicationMetadata - from .application_problem import ApplicationProblem from .application_set import ApplicationSet from .application_set_components_item import ApplicationSetComponentsItem from .application_type import ApplicationType @@ -116,7 +124,6 @@ from .azure_o_auth import AzureOAuth from .azure_open_ai_model import AzureOpenAiModel from .azure_open_ai_model_deployment_type import AzureOpenAiModelDeploymentType - from .azure_open_ai_model_region import AzureOpenAiModelRegion from .azure_open_ai_provider_account import AzureOpenAiProviderAccount from .azure_open_ai_provider_account_auth_data import AzureOpenAiProviderAccountAuthData from .azure_pii_category import AzurePiiCategory @@ -136,11 +143,16 @@ from .base_autoscaling import BaseAutoscaling from .base_o_auth2login import BaseOAuth2Login from .base_o_auth2login_jwt_source import BaseOAuth2LoginJwtSource + from .base_remote_agent import BaseRemoteAgent from .base_service import BaseService from .base_service_image import BaseServiceImage from .base_service_mounts_item import BaseServiceMountsItem from .base_workbench_input import BaseWorkbenchInput from .base_workbench_input_mounts_item import BaseWorkbenchInputMountsItem + from .baseten_integrations import BasetenIntegrations + from .baseten_key_auth import BasetenKeyAuth + from .baseten_model import BasetenModel + from .baseten_provider_account import BasetenProviderAccount from .basic_auth_creds import BasicAuthCreds from .bedrock_model import BedrockModel from .bitbucket_integration import BitbucketIntegration @@ -205,22 +217,28 @@ from .container_task_config_mounts_item import ContainerTaskConfigMountsItem from .core_nats_output_config import CoreNatsOutputConfig from .cpu_utilization_metric import CpuUtilizationMetric + from .create_docker_repository_response import CreateDockerRepositoryResponse from .create_multi_part_upload_request import CreateMultiPartUploadRequest from .create_personal_access_token_response import CreatePersonalAccessTokenResponse from .cron_metric import CronMetric + from .custom_agent_server_auth import CustomAgentServerAuth from .custom_basic_auth import CustomBasicAuth from .custom_bearer_auth import CustomBearerAuth from .custom_blob_storage import CustomBlobStorage + from .custom_framework import CustomFramework from .custom_guardrail_config import CustomGuardrailConfig from .custom_guardrail_config_auth_data import CustomGuardrailConfigAuthData from .custom_guardrail_config_config import CustomGuardrailConfigConfig from .custom_guardrail_config_operation import CustomGuardrailConfigOperation from .custom_guardrail_config_target import CustomGuardrailConfigTarget + from .custom_header_auth import CustomHeaderAuth from .custom_helm_repo import CustomHelmRepo from .custom_integrations import CustomIntegrations from .custom_jwt_auth_integration import CustomJwtAuthIntegration from .custom_provider_account import CustomProviderAccount from .custom_regex_pattern import CustomRegexPattern + from .custom_server_header_auth import CustomServerHeaderAuth + from .custom_server_passthrough import CustomServerPassthrough from .custom_tls_settings import CustomTlsSettings from .custom_username_password_artifacts_registry import CustomUsernamePasswordArtifactsRegistry from .data_access_rule import DataAccessRule @@ -230,6 +248,8 @@ from .data_directory_manifest_source import DataDirectoryManifestSource from .databricks_api_key_auth import DatabricksApiKeyAuth from .databricks_integrations import DatabricksIntegrations + from .databricks_job_task_config import DatabricksJobTaskConfig + from .databricks_job_task_config_image import DatabricksJobTaskConfigImage from .databricks_model import DatabricksModel from .databricks_provider_account import DatabricksProviderAccount from .databricks_provider_account_auth_data import DatabricksProviderAccountAuthData @@ -341,6 +361,7 @@ from .gateway_metadata_rule import GatewayMetadataRule from .gateway_metadata_when import GatewayMetadataWhen from .gateway_otel_config import GatewayOtelConfig + from .gateway_otel_config_otel_metrics_exporter_config import GatewayOtelConfigOtelMetricsExporterConfig from .gateway_otel_config_otel_traces_exporter_config import GatewayOtelConfigOtelTracesExporterConfig from .gateway_request_metadata_filter import GatewayRequestMetadataFilter from .gateway_request_metadata_filter_operator import GatewayRequestMetadataFilterOperator @@ -357,6 +378,9 @@ from .gcp_region import GcpRegion from .gcp_tpu import GcpTpu from .gemini_model import GeminiModel + from .generic_secret_store_integration import GenericSecretStoreIntegration + from .get_agent_skill_response import GetAgentSkillResponse + from .get_agent_skill_version_response import GetAgentSkillVersionResponse from .get_alerts_response import GetAlertsResponse from .get_application_deployment_response import GetApplicationDeploymentResponse from .get_application_response import GetApplicationResponse @@ -367,6 +391,7 @@ from .get_charts_response import GetChartsResponse from .get_cluster_response import GetClusterResponse from .get_data_directory_response import GetDataDirectoryResponse + from .get_docker_registry_credentials_response import GetDockerRegistryCredentialsResponse from .get_environment_response import GetEnvironmentResponse from .get_events_response import GetEventsResponse from .get_job_run_response import GetJobRunResponse @@ -382,8 +407,10 @@ from .get_signed_ur_ls_request import GetSignedUrLsRequest from .get_signed_ur_ls_response import GetSignedUrLsResponse from .get_suggested_deployment_endpoint_response import GetSuggestedDeploymentEndpointResponse + from .get_team_permissions_response import GetTeamPermissionsResponse from .get_team_response import GetTeamResponse from .get_token_for_virtual_account_response import GetTokenForVirtualAccountResponse + from .get_user_permissions_response import GetUserPermissionsResponse from .get_user_resources_response import GetUserResourcesResponse from .get_user_response import GetUserResponse from .get_user_teams_response import GetUserTeamsResponse @@ -403,6 +430,7 @@ from .google_model_armor_guardrail_config import GoogleModelArmorGuardrailConfig from .google_model_armor_guardrail_config_auth_data import GoogleModelArmorGuardrailConfigAuthData from .google_model_armor_guardrail_config_config import GoogleModelArmorGuardrailConfigConfig + from .google_model_armor_guardrail_config_operation import GoogleModelArmorGuardrailConfigOperation from .google_model_armor_key_file_auth import GoogleModelArmorKeyFileAuth from .google_model_armor_key_file_auth_key_file_content import GoogleModelArmorKeyFileAuthKeyFileContent from .google_vertex_provider_account import GoogleVertexProviderAccount @@ -425,12 +453,15 @@ from .guardrails_rule import GuardrailsRule from .guardrails_when import GuardrailsWhen from .h2o_framework import H2OFramework + from .hashicorp_app_role_auth import HashicorpAppRoleAuth from .hashicorp_integrations import HashicorpIntegrations from .hashicorp_provider_account import HashicorpProviderAccount from .hashicorp_token_auth import HashicorpTokenAuth from .hashicorp_vault_integration import HashicorpVaultIntegration + from .hashicorp_vault_integration_auth_data import HashicorpVaultIntegrationAuthData from .header_match import HeaderMatch from .header_routing_config import HeaderRoutingConfig + from .headers_override import HeadersOverride from .health_probe import HealthProbe from .helm import Helm from .helm_repo import HelmRepo @@ -494,8 +525,11 @@ from .latency_based_load_balance_target import LatencyBasedLoadBalanceTarget from .latency_based_load_balancing import LatencyBasedLoadBalancing from .latency_based_load_balancing_rule import LatencyBasedLoadBalancingRule + from .legacy_agent_manifest import LegacyAgentManifest from .library_name import LibraryName from .light_gbm_framework import LightGbmFramework + from .list_agent_skill_versions_response import ListAgentSkillVersionsResponse + from .list_agent_skills_response import ListAgentSkillsResponse from .list_application_deployments_response import ListApplicationDeploymentsResponse from .list_applications_response import ListApplicationsResponse from .list_artifact_versions_response import ListArtifactVersionsResponse @@ -540,13 +574,17 @@ from .logs_sorting_direction import LogsSortingDirection from .manual import Manual from .mcp_server_auth import McpServerAuth + from .mcp_server_env_auth import McpServerEnvAuth + from .mcp_server_env_auth_auth_level import McpServerEnvAuthAuthLevel from .mcp_server_header_auth import McpServerHeaderAuth + from .mcp_server_header_auth_auth_level import McpServerHeaderAuthAuthLevel from .mcp_server_header_override_auth import McpServerHeaderOverrideAuth from .mcp_server_integration import McpServerIntegration from .mcp_server_integration_transport import McpServerIntegrationTransport from .mcp_server_integrations import McpServerIntegrations from .mcp_server_manifest import McpServerManifest from .mcp_server_o_auth2 import McpServerOAuth2 + from .mcp_server_o_auth2grant_type import McpServerOAuth2GrantType from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource from .mcp_server_passthrough import McpServerPassthrough from .mcp_server_provider_account import McpServerProviderAccount @@ -556,6 +594,9 @@ from .mcp_server_with_url import McpServerWithUrl from .mcp_tool import McpTool from .mcp_tool_setting import McpToolSetting + from .mcp_tool_target import McpToolTarget + from .mcp_tools_operator import McpToolsOperator + from .mcp_tools_operator_condition import McpToolsOperatorCondition from .metadata import Metadata from .metric import Metric from .mime_type import MimeType @@ -616,12 +657,6 @@ from .open_ai_model import OpenAiModel from .open_ai_moderations_guardrail_config import OpenAiModerationsGuardrailConfig from .open_ai_moderations_guardrail_config_config import OpenAiModerationsGuardrailConfigConfig - from .open_ai_moderations_guardrail_config_config_category_thresholds_value import ( - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue, - ) - from .open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment import ( - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment, - ) from .open_api_spec_source import OpenApiSpecSource from .open_apimcp_server_manifest import OpenApimcpServerManifest from .open_apimcp_tool_setting import OpenApimcpToolSetting @@ -633,10 +668,15 @@ from .openai_api_key_auth import OpenaiApiKeyAuth from .openai_provider_account import OpenaiProviderAccount from .operation import Operation - from .otel_exporter_grpc_config import OtelExporterGrpcConfig - from .otel_exporter_http_config import OtelExporterHttpConfig - from .otel_exporter_http_config_encoding import OtelExporterHttpConfigEncoding - from .otel_exporter_span_attribute_filter import OtelExporterSpanAttributeFilter + 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_grpc_config import OtelMetricsExporterGrpcConfig + from .otel_metrics_exporter_http_config import OtelMetricsExporterHttpConfig + from .otel_traces_exporter_common_config import OtelTracesExporterCommonConfig + from .otel_traces_exporter_grpc_config import OtelTracesExporterGrpcConfig + from .otel_traces_exporter_http_config import OtelTracesExporterHttpConfig + from .otel_traces_exporter_span_attribute_filter import OtelTracesExporterSpanAttributeFilter from .own_data_access_rule import OwnDataAccessRule from .owned_by import OwnedBy from .paddle_framework import PaddleFramework @@ -711,10 +751,6 @@ from .private_pricing_tier import PrivatePricingTier from .prometheus_alert_rule import PrometheusAlertRule from .prompt import Prompt - from .prompt_foo_guard_type import PromptFooGuardType - from .prompt_foo_guardrail_config import PromptFooGuardrailConfig - from .prompt_foo_guardrail_config_config import PromptFooGuardrailConfigConfig - from .prompt_foo_guardrail_config_operation import PromptFooGuardrailConfigOperation from .prompt_source import PromptSource from .prompt_version import PromptVersion from .provider_accounts import ProviderAccounts @@ -743,16 +779,26 @@ from .regex_guardrail_config_config import RegexGuardrailConfigConfig from .regex_guardrail_config_operation import RegexGuardrailConfigOperation from .register_users_response import RegisterUsersResponse + from .remote_agent import RemoteAgent from .remote_mcp_server_manifest import RemoteMcpServerManifest from .remote_source import RemoteSource from .remote_spec_source import RemoteSpecSource + 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_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_with_resource import RoleWithResource from .role_with_resource_resource_type import RoleWithResourceResourceType from .rolling import Rolling from .rps_metric import RpsMetric + from .sagemaker_assumed_role_based_auth import SagemakerAssumedRoleBasedAuth from .sagemaker_model import SagemakerModel from .samba_nova_integrations import SambaNovaIntegrations from .samba_nova_key_auth import SambaNovaKeyAuth @@ -771,6 +817,7 @@ from .secret_mount import SecretMount from .secret_store_config import SecretStoreConfig from .secret_version import SecretVersion + from .self_hosted_agent import SelfHostedAgent from .self_hosted_model import SelfHostedModel from .self_hosted_model_auth_data import SelfHostedModelAuthData from .self_hosted_model_integrations import SelfHostedModelIntegrations @@ -844,12 +891,17 @@ from .stage_artifact_response import StageArtifactResponse from .static_volume_config import StaticVolumeConfig from .stats_models_framework import StatsModelsFramework + from .stdio_mcp_server_manifest import StdioMcpServerManifest + from .sticky_routing import StickyRouting + from .sticky_session_identifier import StickySessionIdentifier + from .sticky_session_identifier_source import StickySessionIdentifierSource from .string_data_mount import StringDataMount from .sub_agent import SubAgent from .subject import Subject from .subject_clause import SubjectClause from .subject_condition_group import SubjectConditionGroup from .subject_condition_group_operator import SubjectConditionGroupOperator + from .subject_permission import SubjectPermission from .subject_type import SubjectType from .sync_token_in_secret_store_info import SyncTokenInSecretStoreInfo from .sync_virtual_account_token_response import SyncVirtualAccountTokenResponse @@ -891,6 +943,21 @@ from .tracing_project_storage_config import TracingProjectStorageConfig from .transformers_framework import TransformersFramework from .trigger_job_run_response import TriggerJobRunResponse + from .troj_ai_client_id_auth import TrojAiClientIdAuth + from .troj_ai_guardrail_config import TrojAiGuardrailConfig + from .troj_ai_guardrail_config_config import TrojAiGuardrailConfigConfig + from .troj_ai_guardrail_config_operation import TrojAiGuardrailConfigOperation + from .true_foundry_agent_manifest import TrueFoundryAgentManifest + from .true_foundry_agent_manifest_model_params import TrueFoundryAgentManifestModelParams + from .true_foundry_agent_manifest_model_params_reasoning_effort import ( + TrueFoundryAgentManifestModelParamsReasoningEffort, + ) + from .true_foundry_agent_manifest_response_format import TrueFoundryAgentManifestResponseFormat + from .true_foundry_agent_manifest_sandbox import TrueFoundryAgentManifestSandbox + from .true_foundry_agent_mcp_server import TrueFoundryAgentMcpServer + from .true_foundry_agent_mcp_tool import TrueFoundryAgentMcpTool + 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 @@ -917,6 +984,7 @@ from .user_metadata import UserMetadata from .user_metadata_tenant_role_managed_by import UserMetadataTenantRoleManagedBy from .user_resource import UserResource + from .user_team_info import UserTeamInfo from .uv import Uv from .validation_error import ValidationError from .validation_error_loc_item import ValidationErrorLocItem @@ -961,6 +1029,7 @@ from .xg_boost_model_schema import XgBoostModelSchema from .xg_boost_serialization_format import XgBoostSerializationFormat _dynamic_imports: typing.Dict[str, str] = { + "A2AFramework": ".a2a_framework", "Account": ".account", "AccountInfo": ".account_info", "ActivateUserResponse": ".activate_user_response", @@ -968,14 +1037,23 @@ "AddonComponent": ".addon_component", "AddonComponentName": ".addon_component_name", "AddonComponentStatus": ".addon_component_status", + "AgentFramework": ".agent_framework", "AgentManifest": ".agent_manifest", "AgentSkill": ".agent_skill", + "AgentSkillManifest": ".agent_skill_manifest", + "AgentSkillManifestSource": ".agent_skill_manifest_source", + "AgentSkillSourceBlobStorage": ".agent_skill_source_blob_storage", + "AgentSkillSourceInline": ".agent_skill_source_inline", + "AgentSkillVersion": ".agent_skill_version", "AgentSource": ".agent_source", "Ai21Integrations": ".ai21integrations", "Ai21KeyAuth": ".ai21key_auth", "Ai21Model": ".ai21model", "Ai21ProviderAccount": ".ai21provider_account", "AiFeaturesSettings": ".ai_features_settings", + "AktoGuardrailConfig": ".akto_guardrail_config", + "AktoGuardrailConfigConfig": ".akto_guardrail_config_config", + "AktoTokenAuth": ".akto_token_auth", "Alert": ".alert", "AlertConfig": ".alert_config", "AlertConfigResource": ".alert_config_resource", @@ -992,10 +1070,8 @@ "AnthropicModel": ".anthropic_model", "AnthropicProviderAccount": ".anthropic_provider_account", "Application": ".application", - "ApplicationDebugInfo": ".application_debug_info", "ApplicationLifecycleStage": ".application_lifecycle_stage", "ApplicationMetadata": ".application_metadata", - "ApplicationProblem": ".application_problem", "ApplicationSet": ".application_set", "ApplicationSetComponentsItem": ".application_set_components_item", "ApplicationType": ".application_type", @@ -1068,7 +1144,6 @@ "AzureOAuth": ".azure_o_auth", "AzureOpenAiModel": ".azure_open_ai_model", "AzureOpenAiModelDeploymentType": ".azure_open_ai_model_deployment_type", - "AzureOpenAiModelRegion": ".azure_open_ai_model_region", "AzureOpenAiProviderAccount": ".azure_open_ai_provider_account", "AzureOpenAiProviderAccountAuthData": ".azure_open_ai_provider_account_auth_data", "AzurePiiCategory": ".azure_pii_category", @@ -1088,11 +1163,16 @@ "BaseAutoscaling": ".base_autoscaling", "BaseOAuth2Login": ".base_o_auth2login", "BaseOAuth2LoginJwtSource": ".base_o_auth2login_jwt_source", + "BaseRemoteAgent": ".base_remote_agent", "BaseService": ".base_service", "BaseServiceImage": ".base_service_image", "BaseServiceMountsItem": ".base_service_mounts_item", "BaseWorkbenchInput": ".base_workbench_input", "BaseWorkbenchInputMountsItem": ".base_workbench_input_mounts_item", + "BasetenIntegrations": ".baseten_integrations", + "BasetenKeyAuth": ".baseten_key_auth", + "BasetenModel": ".baseten_model", + "BasetenProviderAccount": ".baseten_provider_account", "BasicAuthCreds": ".basic_auth_creds", "BedrockModel": ".bedrock_model", "BitbucketIntegration": ".bitbucket_integration", @@ -1157,22 +1237,28 @@ "ContainerTaskConfigMountsItem": ".container_task_config_mounts_item", "CoreNatsOutputConfig": ".core_nats_output_config", "CpuUtilizationMetric": ".cpu_utilization_metric", + "CreateDockerRepositoryResponse": ".create_docker_repository_response", "CreateMultiPartUploadRequest": ".create_multi_part_upload_request", "CreatePersonalAccessTokenResponse": ".create_personal_access_token_response", "CronMetric": ".cron_metric", + "CustomAgentServerAuth": ".custom_agent_server_auth", "CustomBasicAuth": ".custom_basic_auth", "CustomBearerAuth": ".custom_bearer_auth", "CustomBlobStorage": ".custom_blob_storage", + "CustomFramework": ".custom_framework", "CustomGuardrailConfig": ".custom_guardrail_config", "CustomGuardrailConfigAuthData": ".custom_guardrail_config_auth_data", "CustomGuardrailConfigConfig": ".custom_guardrail_config_config", "CustomGuardrailConfigOperation": ".custom_guardrail_config_operation", "CustomGuardrailConfigTarget": ".custom_guardrail_config_target", + "CustomHeaderAuth": ".custom_header_auth", "CustomHelmRepo": ".custom_helm_repo", "CustomIntegrations": ".custom_integrations", "CustomJwtAuthIntegration": ".custom_jwt_auth_integration", "CustomProviderAccount": ".custom_provider_account", "CustomRegexPattern": ".custom_regex_pattern", + "CustomServerHeaderAuth": ".custom_server_header_auth", + "CustomServerPassthrough": ".custom_server_passthrough", "CustomTlsSettings": ".custom_tls_settings", "CustomUsernamePasswordArtifactsRegistry": ".custom_username_password_artifacts_registry", "DataAccessRule": ".data_access_rule", @@ -1182,6 +1268,8 @@ "DataDirectoryManifestSource": ".data_directory_manifest_source", "DatabricksApiKeyAuth": ".databricks_api_key_auth", "DatabricksIntegrations": ".databricks_integrations", + "DatabricksJobTaskConfig": ".databricks_job_task_config", + "DatabricksJobTaskConfigImage": ".databricks_job_task_config_image", "DatabricksModel": ".databricks_model", "DatabricksProviderAccount": ".databricks_provider_account", "DatabricksProviderAccountAuthData": ".databricks_provider_account_auth_data", @@ -1281,6 +1369,7 @@ "GatewayMetadataRule": ".gateway_metadata_rule", "GatewayMetadataWhen": ".gateway_metadata_when", "GatewayOtelConfig": ".gateway_otel_config", + "GatewayOtelConfigOtelMetricsExporterConfig": ".gateway_otel_config_otel_metrics_exporter_config", "GatewayOtelConfigOtelTracesExporterConfig": ".gateway_otel_config_otel_traces_exporter_config", "GatewayRequestMetadataFilter": ".gateway_request_metadata_filter", "GatewayRequestMetadataFilterOperator": ".gateway_request_metadata_filter_operator", @@ -1297,6 +1386,9 @@ "GcpRegion": ".gcp_region", "GcpTpu": ".gcp_tpu", "GeminiModel": ".gemini_model", + "GenericSecretStoreIntegration": ".generic_secret_store_integration", + "GetAgentSkillResponse": ".get_agent_skill_response", + "GetAgentSkillVersionResponse": ".get_agent_skill_version_response", "GetAlertsResponse": ".get_alerts_response", "GetApplicationDeploymentResponse": ".get_application_deployment_response", "GetApplicationResponse": ".get_application_response", @@ -1307,6 +1399,7 @@ "GetChartsResponse": ".get_charts_response", "GetClusterResponse": ".get_cluster_response", "GetDataDirectoryResponse": ".get_data_directory_response", + "GetDockerRegistryCredentialsResponse": ".get_docker_registry_credentials_response", "GetEnvironmentResponse": ".get_environment_response", "GetEventsResponse": ".get_events_response", "GetJobRunResponse": ".get_job_run_response", @@ -1322,8 +1415,10 @@ "GetSignedUrLsRequest": ".get_signed_ur_ls_request", "GetSignedUrLsResponse": ".get_signed_ur_ls_response", "GetSuggestedDeploymentEndpointResponse": ".get_suggested_deployment_endpoint_response", + "GetTeamPermissionsResponse": ".get_team_permissions_response", "GetTeamResponse": ".get_team_response", "GetTokenForVirtualAccountResponse": ".get_token_for_virtual_account_response", + "GetUserPermissionsResponse": ".get_user_permissions_response", "GetUserResourcesResponse": ".get_user_resources_response", "GetUserResponse": ".get_user_response", "GetUserTeamsResponse": ".get_user_teams_response", @@ -1343,6 +1438,7 @@ "GoogleModelArmorGuardrailConfig": ".google_model_armor_guardrail_config", "GoogleModelArmorGuardrailConfigAuthData": ".google_model_armor_guardrail_config_auth_data", "GoogleModelArmorGuardrailConfigConfig": ".google_model_armor_guardrail_config_config", + "GoogleModelArmorGuardrailConfigOperation": ".google_model_armor_guardrail_config_operation", "GoogleModelArmorKeyFileAuth": ".google_model_armor_key_file_auth", "GoogleModelArmorKeyFileAuthKeyFileContent": ".google_model_armor_key_file_auth_key_file_content", "GoogleVertexProviderAccount": ".google_vertex_provider_account", @@ -1363,12 +1459,15 @@ "GuardrailsRule": ".guardrails_rule", "GuardrailsWhen": ".guardrails_when", "H2OFramework": ".h2o_framework", + "HashicorpAppRoleAuth": ".hashicorp_app_role_auth", "HashicorpIntegrations": ".hashicorp_integrations", "HashicorpProviderAccount": ".hashicorp_provider_account", "HashicorpTokenAuth": ".hashicorp_token_auth", "HashicorpVaultIntegration": ".hashicorp_vault_integration", + "HashicorpVaultIntegrationAuthData": ".hashicorp_vault_integration_auth_data", "HeaderMatch": ".header_match", "HeaderRoutingConfig": ".header_routing_config", + "HeadersOverride": ".headers_override", "HealthProbe": ".health_probe", "Helm": ".helm", "HelmRepo": ".helm_repo", @@ -1432,8 +1531,11 @@ "LatencyBasedLoadBalanceTarget": ".latency_based_load_balance_target", "LatencyBasedLoadBalancing": ".latency_based_load_balancing", "LatencyBasedLoadBalancingRule": ".latency_based_load_balancing_rule", + "LegacyAgentManifest": ".legacy_agent_manifest", "LibraryName": ".library_name", "LightGbmFramework": ".light_gbm_framework", + "ListAgentSkillVersionsResponse": ".list_agent_skill_versions_response", + "ListAgentSkillsResponse": ".list_agent_skills_response", "ListApplicationDeploymentsResponse": ".list_application_deployments_response", "ListApplicationsResponse": ".list_applications_response", "ListArtifactVersionsResponse": ".list_artifact_versions_response", @@ -1478,13 +1580,17 @@ "LogsSortingDirection": ".logs_sorting_direction", "Manual": ".manual", "McpServerAuth": ".mcp_server_auth", + "McpServerEnvAuth": ".mcp_server_env_auth", + "McpServerEnvAuthAuthLevel": ".mcp_server_env_auth_auth_level", "McpServerHeaderAuth": ".mcp_server_header_auth", + "McpServerHeaderAuthAuthLevel": ".mcp_server_header_auth_auth_level", "McpServerHeaderOverrideAuth": ".mcp_server_header_override_auth", "McpServerIntegration": ".mcp_server_integration", "McpServerIntegrationTransport": ".mcp_server_integration_transport", "McpServerIntegrations": ".mcp_server_integrations", "McpServerManifest": ".mcp_server_manifest", "McpServerOAuth2": ".mcp_server_o_auth2", + "McpServerOAuth2GrantType": ".mcp_server_o_auth2grant_type", "McpServerOAuth2JwtSource": ".mcp_server_o_auth2jwt_source", "McpServerPassthrough": ".mcp_server_passthrough", "McpServerProviderAccount": ".mcp_server_provider_account", @@ -1494,6 +1600,9 @@ "McpServerWithUrl": ".mcp_server_with_url", "McpTool": ".mcp_tool", "McpToolSetting": ".mcp_tool_setting", + "McpToolTarget": ".mcp_tool_target", + "McpToolsOperator": ".mcp_tools_operator", + "McpToolsOperatorCondition": ".mcp_tools_operator_condition", "Metadata": ".metadata", "Metric": ".metric", "MimeType": ".mime_type", @@ -1554,8 +1663,6 @@ "OpenAiModel": ".open_ai_model", "OpenAiModerationsGuardrailConfig": ".open_ai_moderations_guardrail_config", "OpenAiModerationsGuardrailConfigConfig": ".open_ai_moderations_guardrail_config_config", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue": ".open_ai_moderations_guardrail_config_config_category_thresholds_value", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment": ".open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment", "OpenApiSpecSource": ".open_api_spec_source", "OpenApimcpServerManifest": ".open_apimcp_server_manifest", "OpenApimcpToolSetting": ".open_apimcp_tool_setting", @@ -1567,10 +1674,15 @@ "OpenaiApiKeyAuth": ".openai_api_key_auth", "OpenaiProviderAccount": ".openai_provider_account", "Operation": ".operation", - "OtelExporterGrpcConfig": ".otel_exporter_grpc_config", - "OtelExporterHttpConfig": ".otel_exporter_http_config", - "OtelExporterHttpConfigEncoding": ".otel_exporter_http_config_encoding", - "OtelExporterSpanAttributeFilter": ".otel_exporter_span_attribute_filter", + "OtelExporterGrpcConfigBase": ".otel_exporter_grpc_config_base", + "OtelExporterHttpConfigBase": ".otel_exporter_http_config_base", + "OtelExporterHttpConfigBaseEncoding": ".otel_exporter_http_config_base_encoding", + "OtelMetricsExporterGrpcConfig": ".otel_metrics_exporter_grpc_config", + "OtelMetricsExporterHttpConfig": ".otel_metrics_exporter_http_config", + "OtelTracesExporterCommonConfig": ".otel_traces_exporter_common_config", + "OtelTracesExporterGrpcConfig": ".otel_traces_exporter_grpc_config", + "OtelTracesExporterHttpConfig": ".otel_traces_exporter_http_config", + "OtelTracesExporterSpanAttributeFilter": ".otel_traces_exporter_span_attribute_filter", "OwnDataAccessRule": ".own_data_access_rule", "OwnedBy": ".owned_by", "PaddleFramework": ".paddle_framework", @@ -1645,10 +1757,6 @@ "PrivatePricingTier": ".private_pricing_tier", "PrometheusAlertRule": ".prometheus_alert_rule", "Prompt": ".prompt", - "PromptFooGuardType": ".prompt_foo_guard_type", - "PromptFooGuardrailConfig": ".prompt_foo_guardrail_config", - "PromptFooGuardrailConfigConfig": ".prompt_foo_guardrail_config_config", - "PromptFooGuardrailConfigOperation": ".prompt_foo_guardrail_config_operation", "PromptSource": ".prompt_source", "PromptVersion": ".prompt_version", "ProviderAccounts": ".provider_accounts", @@ -1677,19 +1785,29 @@ "RegexGuardrailConfigConfig": ".regex_guardrail_config_config", "RegexGuardrailConfigOperation": ".regex_guardrail_config_operation", "RegisterUsersResponse": ".register_users_response", + "RemoteAgent": ".remote_agent", "RemoteMcpServerManifest": ".remote_mcp_server_manifest", "RemoteSource": ".remote_source", "RemoteSpecSource": ".remote_spec_source", "Resources": ".resources", "ResourcesDevicesItem": ".resources_devices_item", "ResourcesNode": ".resources_node", + "ResponseFormatJsonObject": ".response_format_json_object", + "ResponseFormatJsonSchema": ".response_format_json_schema", + "ResponseFormatJsonSchemaJsonSchema": ".response_format_json_schema_json_schema", + "ResponseFormatText": ".response_format_text", "RetryConfig": ".retry_config", "RevokeAllPersonalAccessTokenResponse": ".revoke_all_personal_access_token_response", + "RoleBindingManifest": ".role_binding_manifest", + "RoleBindingPermission": ".role_binding_permission", + "RoleBindingSubject": ".role_binding_subject", + "RoleBindingSubjectType": ".role_binding_subject_type", "RoleManifest": ".role_manifest", "RoleWithResource": ".role_with_resource", "RoleWithResourceResourceType": ".role_with_resource_resource_type", "Rolling": ".rolling", "RpsMetric": ".rps_metric", + "SagemakerAssumedRoleBasedAuth": ".sagemaker_assumed_role_based_auth", "SagemakerModel": ".sagemaker_model", "SambaNovaIntegrations": ".samba_nova_integrations", "SambaNovaKeyAuth": ".samba_nova_key_auth", @@ -1708,6 +1826,7 @@ "SecretMount": ".secret_mount", "SecretStoreConfig": ".secret_store_config", "SecretVersion": ".secret_version", + "SelfHostedAgent": ".self_hosted_agent", "SelfHostedModel": ".self_hosted_model", "SelfHostedModelAuthData": ".self_hosted_model_auth_data", "SelfHostedModelIntegrations": ".self_hosted_model_integrations", @@ -1781,12 +1900,17 @@ "StageArtifactResponse": ".stage_artifact_response", "StaticVolumeConfig": ".static_volume_config", "StatsModelsFramework": ".stats_models_framework", + "StdioMcpServerManifest": ".stdio_mcp_server_manifest", + "StickyRouting": ".sticky_routing", + "StickySessionIdentifier": ".sticky_session_identifier", + "StickySessionIdentifierSource": ".sticky_session_identifier_source", "StringDataMount": ".string_data_mount", "SubAgent": ".sub_agent", "Subject": ".subject", "SubjectClause": ".subject_clause", "SubjectConditionGroup": ".subject_condition_group", "SubjectConditionGroupOperator": ".subject_condition_group_operator", + "SubjectPermission": ".subject_permission", "SubjectType": ".subject_type", "SyncTokenInSecretStoreInfo": ".sync_token_in_secret_store_info", "SyncVirtualAccountTokenResponse": ".sync_virtual_account_token_response", @@ -1828,6 +1952,19 @@ "TracingProjectStorageConfig": ".tracing_project_storage_config", "TransformersFramework": ".transformers_framework", "TriggerJobRunResponse": ".trigger_job_run_response", + "TrojAiClientIdAuth": ".troj_ai_client_id_auth", + "TrojAiGuardrailConfig": ".troj_ai_guardrail_config", + "TrojAiGuardrailConfigConfig": ".troj_ai_guardrail_config_config", + "TrojAiGuardrailConfigOperation": ".troj_ai_guardrail_config_operation", + "TrueFoundryAgentManifest": ".true_foundry_agent_manifest", + "TrueFoundryAgentManifestModelParams": ".true_foundry_agent_manifest_model_params", + "TrueFoundryAgentManifestModelParamsReasoningEffort": ".true_foundry_agent_manifest_model_params_reasoning_effort", + "TrueFoundryAgentManifestResponseFormat": ".true_foundry_agent_manifest_response_format", + "TrueFoundryAgentManifestSandbox": ".true_foundry_agent_manifest_sandbox", + "TrueFoundryAgentMcpServer": ".true_foundry_agent_mcp_server", + "TrueFoundryAgentMcpTool": ".true_foundry_agent_mcp_tool", + "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", @@ -1854,6 +1991,7 @@ "UserMetadata": ".user_metadata", "UserMetadataTenantRoleManagedBy": ".user_metadata_tenant_role_managed_by", "UserResource": ".user_resource", + "UserTeamInfo": ".user_team_info", "Uv": ".uv", "ValidationError": ".validation_error", "ValidationErrorLocItem": ".validation_error_loc_item", @@ -1922,6 +2060,7 @@ def __dir__(): __all__ = [ + "A2AFramework", "Account", "AccountInfo", "ActivateUserResponse", @@ -1929,14 +2068,23 @@ def __dir__(): "AddonComponent", "AddonComponentName", "AddonComponentStatus", + "AgentFramework", "AgentManifest", "AgentSkill", + "AgentSkillManifest", + "AgentSkillManifestSource", + "AgentSkillSourceBlobStorage", + "AgentSkillSourceInline", + "AgentSkillVersion", "AgentSource", "Ai21Integrations", "Ai21KeyAuth", "Ai21Model", "Ai21ProviderAccount", "AiFeaturesSettings", + "AktoGuardrailConfig", + "AktoGuardrailConfigConfig", + "AktoTokenAuth", "Alert", "AlertConfig", "AlertConfigResource", @@ -1953,10 +2101,8 @@ def __dir__(): "AnthropicModel", "AnthropicProviderAccount", "Application", - "ApplicationDebugInfo", "ApplicationLifecycleStage", "ApplicationMetadata", - "ApplicationProblem", "ApplicationSet", "ApplicationSetComponentsItem", "ApplicationType", @@ -2029,7 +2175,6 @@ def __dir__(): "AzureOAuth", "AzureOpenAiModel", "AzureOpenAiModelDeploymentType", - "AzureOpenAiModelRegion", "AzureOpenAiProviderAccount", "AzureOpenAiProviderAccountAuthData", "AzurePiiCategory", @@ -2049,11 +2194,16 @@ def __dir__(): "BaseAutoscaling", "BaseOAuth2Login", "BaseOAuth2LoginJwtSource", + "BaseRemoteAgent", "BaseService", "BaseServiceImage", "BaseServiceMountsItem", "BaseWorkbenchInput", "BaseWorkbenchInputMountsItem", + "BasetenIntegrations", + "BasetenKeyAuth", + "BasetenModel", + "BasetenProviderAccount", "BasicAuthCreds", "BedrockModel", "BitbucketIntegration", @@ -2118,22 +2268,28 @@ def __dir__(): "ContainerTaskConfigMountsItem", "CoreNatsOutputConfig", "CpuUtilizationMetric", + "CreateDockerRepositoryResponse", "CreateMultiPartUploadRequest", "CreatePersonalAccessTokenResponse", "CronMetric", + "CustomAgentServerAuth", "CustomBasicAuth", "CustomBearerAuth", "CustomBlobStorage", + "CustomFramework", "CustomGuardrailConfig", "CustomGuardrailConfigAuthData", "CustomGuardrailConfigConfig", "CustomGuardrailConfigOperation", "CustomGuardrailConfigTarget", + "CustomHeaderAuth", "CustomHelmRepo", "CustomIntegrations", "CustomJwtAuthIntegration", "CustomProviderAccount", "CustomRegexPattern", + "CustomServerHeaderAuth", + "CustomServerPassthrough", "CustomTlsSettings", "CustomUsernamePasswordArtifactsRegistry", "DataAccessRule", @@ -2143,6 +2299,8 @@ def __dir__(): "DataDirectoryManifestSource", "DatabricksApiKeyAuth", "DatabricksIntegrations", + "DatabricksJobTaskConfig", + "DatabricksJobTaskConfigImage", "DatabricksModel", "DatabricksProviderAccount", "DatabricksProviderAccountAuthData", @@ -2242,6 +2400,7 @@ def __dir__(): "GatewayMetadataRule", "GatewayMetadataWhen", "GatewayOtelConfig", + "GatewayOtelConfigOtelMetricsExporterConfig", "GatewayOtelConfigOtelTracesExporterConfig", "GatewayRequestMetadataFilter", "GatewayRequestMetadataFilterOperator", @@ -2258,6 +2417,9 @@ def __dir__(): "GcpRegion", "GcpTpu", "GeminiModel", + "GenericSecretStoreIntegration", + "GetAgentSkillResponse", + "GetAgentSkillVersionResponse", "GetAlertsResponse", "GetApplicationDeploymentResponse", "GetApplicationResponse", @@ -2268,6 +2430,7 @@ def __dir__(): "GetChartsResponse", "GetClusterResponse", "GetDataDirectoryResponse", + "GetDockerRegistryCredentialsResponse", "GetEnvironmentResponse", "GetEventsResponse", "GetJobRunResponse", @@ -2283,8 +2446,10 @@ def __dir__(): "GetSignedUrLsRequest", "GetSignedUrLsResponse", "GetSuggestedDeploymentEndpointResponse", + "GetTeamPermissionsResponse", "GetTeamResponse", "GetTokenForVirtualAccountResponse", + "GetUserPermissionsResponse", "GetUserResourcesResponse", "GetUserResponse", "GetUserTeamsResponse", @@ -2304,6 +2469,7 @@ def __dir__(): "GoogleModelArmorGuardrailConfig", "GoogleModelArmorGuardrailConfigAuthData", "GoogleModelArmorGuardrailConfigConfig", + "GoogleModelArmorGuardrailConfigOperation", "GoogleModelArmorKeyFileAuth", "GoogleModelArmorKeyFileAuthKeyFileContent", "GoogleVertexProviderAccount", @@ -2324,12 +2490,15 @@ def __dir__(): "GuardrailsRule", "GuardrailsWhen", "H2OFramework", + "HashicorpAppRoleAuth", "HashicorpIntegrations", "HashicorpProviderAccount", "HashicorpTokenAuth", "HashicorpVaultIntegration", + "HashicorpVaultIntegrationAuthData", "HeaderMatch", "HeaderRoutingConfig", + "HeadersOverride", "HealthProbe", "Helm", "HelmRepo", @@ -2393,8 +2562,11 @@ def __dir__(): "LatencyBasedLoadBalanceTarget", "LatencyBasedLoadBalancing", "LatencyBasedLoadBalancingRule", + "LegacyAgentManifest", "LibraryName", "LightGbmFramework", + "ListAgentSkillVersionsResponse", + "ListAgentSkillsResponse", "ListApplicationDeploymentsResponse", "ListApplicationsResponse", "ListArtifactVersionsResponse", @@ -2439,13 +2611,17 @@ def __dir__(): "LogsSortingDirection", "Manual", "McpServerAuth", + "McpServerEnvAuth", + "McpServerEnvAuthAuthLevel", "McpServerHeaderAuth", + "McpServerHeaderAuthAuthLevel", "McpServerHeaderOverrideAuth", "McpServerIntegration", "McpServerIntegrationTransport", "McpServerIntegrations", "McpServerManifest", "McpServerOAuth2", + "McpServerOAuth2GrantType", "McpServerOAuth2JwtSource", "McpServerPassthrough", "McpServerProviderAccount", @@ -2455,6 +2631,9 @@ def __dir__(): "McpServerWithUrl", "McpTool", "McpToolSetting", + "McpToolTarget", + "McpToolsOperator", + "McpToolsOperatorCondition", "Metadata", "Metric", "MimeType", @@ -2515,8 +2694,6 @@ def __dir__(): "OpenAiModel", "OpenAiModerationsGuardrailConfig", "OpenAiModerationsGuardrailConfigConfig", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue", - "OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment", "OpenApiSpecSource", "OpenApimcpServerManifest", "OpenApimcpToolSetting", @@ -2528,10 +2705,15 @@ def __dir__(): "OpenaiApiKeyAuth", "OpenaiProviderAccount", "Operation", - "OtelExporterGrpcConfig", - "OtelExporterHttpConfig", - "OtelExporterHttpConfigEncoding", - "OtelExporterSpanAttributeFilter", + "OtelExporterGrpcConfigBase", + "OtelExporterHttpConfigBase", + "OtelExporterHttpConfigBaseEncoding", + "OtelMetricsExporterGrpcConfig", + "OtelMetricsExporterHttpConfig", + "OtelTracesExporterCommonConfig", + "OtelTracesExporterGrpcConfig", + "OtelTracesExporterHttpConfig", + "OtelTracesExporterSpanAttributeFilter", "OwnDataAccessRule", "OwnedBy", "PaddleFramework", @@ -2606,10 +2788,6 @@ def __dir__(): "PrivatePricingTier", "PrometheusAlertRule", "Prompt", - "PromptFooGuardType", - "PromptFooGuardrailConfig", - "PromptFooGuardrailConfigConfig", - "PromptFooGuardrailConfigOperation", "PromptSource", "PromptVersion", "ProviderAccounts", @@ -2638,19 +2816,29 @@ def __dir__(): "RegexGuardrailConfigConfig", "RegexGuardrailConfigOperation", "RegisterUsersResponse", + "RemoteAgent", "RemoteMcpServerManifest", "RemoteSource", "RemoteSpecSource", "Resources", "ResourcesDevicesItem", "ResourcesNode", + "ResponseFormatJsonObject", + "ResponseFormatJsonSchema", + "ResponseFormatJsonSchemaJsonSchema", + "ResponseFormatText", "RetryConfig", "RevokeAllPersonalAccessTokenResponse", + "RoleBindingManifest", + "RoleBindingPermission", + "RoleBindingSubject", + "RoleBindingSubjectType", "RoleManifest", "RoleWithResource", "RoleWithResourceResourceType", "Rolling", "RpsMetric", + "SagemakerAssumedRoleBasedAuth", "SagemakerModel", "SambaNovaIntegrations", "SambaNovaKeyAuth", @@ -2669,6 +2857,7 @@ def __dir__(): "SecretMount", "SecretStoreConfig", "SecretVersion", + "SelfHostedAgent", "SelfHostedModel", "SelfHostedModelAuthData", "SelfHostedModelIntegrations", @@ -2742,12 +2931,17 @@ def __dir__(): "StageArtifactResponse", "StaticVolumeConfig", "StatsModelsFramework", + "StdioMcpServerManifest", + "StickyRouting", + "StickySessionIdentifier", + "StickySessionIdentifierSource", "StringDataMount", "SubAgent", "Subject", "SubjectClause", "SubjectConditionGroup", "SubjectConditionGroupOperator", + "SubjectPermission", "SubjectType", "SyncTokenInSecretStoreInfo", "SyncVirtualAccountTokenResponse", @@ -2789,6 +2983,19 @@ def __dir__(): "TracingProjectStorageConfig", "TransformersFramework", "TriggerJobRunResponse", + "TrojAiClientIdAuth", + "TrojAiGuardrailConfig", + "TrojAiGuardrailConfigConfig", + "TrojAiGuardrailConfigOperation", + "TrueFoundryAgentManifest", + "TrueFoundryAgentManifestModelParams", + "TrueFoundryAgentManifestModelParamsReasoningEffort", + "TrueFoundryAgentManifestResponseFormat", + "TrueFoundryAgentManifestSandbox", + "TrueFoundryAgentMcpServer", + "TrueFoundryAgentMcpTool", + "TrueFoundryAgentUserMessage", + "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", "TrueFoundryApplyResponse", "TrueFoundryApplyResponseAction", @@ -2815,6 +3022,7 @@ def __dir__(): "UserMetadata", "UserMetadataTenantRoleManagedBy", "UserResource", + "UserTeamInfo", "Uv", "ValidationError", "ValidationErrorLocItem", diff --git a/src/truefoundry_sdk/types/a2a_framework.py b/src/truefoundry_sdk/types/a2a_framework.py new file mode 100644 index 00000000..c8bfec91 --- /dev/null +++ b/src/truefoundry_sdk/types/a2a_framework.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 A2AFramework(UniversalBaseModel): + """ + A2A + """ + + type: typing.Literal["a2a"] = pydantic.Field(default="a2a") + """ + Type + """ + + agent_card_path: str = pydantic.Field() + """ + Path to the agent card JSON, relative to the base URL + """ + + 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/account.py b/src/truefoundry_sdk/types/account.py index a69069cb..a1293088 100644 --- a/src/truefoundry_sdk/types/account.py +++ b/src/truefoundry_sdk/types/account.py @@ -12,27 +12,25 @@ class Account(UniversalBaseModel): id: typing.Optional[str] = None - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] fqn: str manifest: typing.Dict[str, typing.Any] = pydantic.Field() """ Account 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", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) - is_editable: typing_extensions.Annotated[bool, FieldMetadata(alias="isEditable")] = pydantic.Field( - alias="isEditable" - ) + 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 + is_editable: typing_extensions.Annotated[ + bool, FieldMetadata(alias="isEditable"), pydantic.Field(alias="isEditable") + ] 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/account_info.py b/src/truefoundry_sdk/types/account_info.py index 3d66fb0b..1c3edd6a 100644 --- a/src/truefoundry_sdk/types/account_info.py +++ b/src/truefoundry_sdk/types/account_info.py @@ -9,7 +9,7 @@ class AccountInfo(UniversalBaseModel): - account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")] = pydantic.Field(alias="accountId") + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] name: str if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/addon_component.py b/src/truefoundry_sdk/types/addon_component.py index dbb0b9cd..d29f12c3 100644 --- a/src/truefoundry_sdk/types/addon_component.py +++ b/src/truefoundry_sdk/types/addon_component.py @@ -18,32 +18,34 @@ class AddonComponent(UniversalBaseModel): name: AddonComponentName - app_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="appName")] = pydantic.Field( - alias="appName", default=None - ) + app_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="appName"), pydantic.Field(alias="appName") + ] = None namespace: typing.Optional[str] = None - application_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="applicationId")] = ( - pydantic.Field(alias="applicationId", default=None) - ) + application_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId") + ] = None description: typing.Optional[str] = None path: typing.Optional[str] = None - addon_folder: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="addonFolder")] = ( - pydantic.Field(alias="addonFolder", default=None) - ) + addon_folder: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="addonFolder"), pydantic.Field(alias="addonFolder") + ] = None installed: typing.Optional[bool] = None status: typing.Optional[AddonComponentStatus] = None version: typing.Optional[str] = None manifest: typing.Optional[typing.Dict[str, typing.Any]] = None installation_source: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="installationSource") - ] = pydantic.Field(alias="installationSource", default=None) + typing.Optional[str], FieldMetadata(alias="installationSource"), pydantic.Field(alias="installationSource") + ] = None unsupported_cluster_types: typing_extensions.Annotated[ - typing.Optional[typing.List[ClusterType]], FieldMetadata(alias="unsupportedClusterTypes") - ] = pydantic.Field(alias="unsupportedClusterTypes", default=None) + typing.Optional[typing.List[ClusterType]], + FieldMetadata(alias="unsupportedClusterTypes"), + pydantic.Field(alias="unsupportedClusterTypes"), + ] = None required: typing.Optional[bool] = None - known_cr_ds: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="knownCRDs")] = ( - pydantic.Field(alias="knownCRDs", default=None) - ) + known_cr_ds: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="knownCRDs"), pydantic.Field(alias="knownCRDs") + ] = None source: typing.Optional[AddOnComponentSource] = None upgrades: typing.Optional[UpgradeData] = None labels: typing.Optional[typing.List[str]] = None @@ -52,9 +54,13 @@ class AddonComponent(UniversalBaseModel): Recommendations """ - workspace_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceId")] = ( - pydantic.Field(alias="workspaceId", default=None) - ) + workspace_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="workspaceId"), pydantic.Field(alias="workspaceId") + ] = None + metadata: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Addon metadata. autopilotEnabled is true when the backing addon application has autopilot enabled; otherwise false. + """ 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 ef37f79f..5361a1a3 100644 --- a/src/truefoundry_sdk/types/addon_component_status.py +++ b/src/truefoundry_sdk/types/addon_component_status.py @@ -9,20 +9,16 @@ class AddonComponentStatus(UniversalBaseModel): - health_status: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="healthStatus")] = ( - pydantic.Field(alias="healthStatus", default=None) - ) - """ - Health status of the addon - """ - - sync_status: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="syncStatus")] = pydantic.Field( - alias="syncStatus", default=None - ) - """ - Sync status of the addon - """ - + health_status: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="healthStatus"), + pydantic.Field(alias="healthStatus", description="Health status of the addon"), + ] = None + sync_status: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="syncStatus"), + pydantic.Field(alias="syncStatus", description="Sync status of the addon"), + ] = None installed: bool = pydantic.Field() """ Indicates whether the addon is installed diff --git a/src/truefoundry_sdk/types/agent_framework.py b/src/truefoundry_sdk/types/agent_framework.py new file mode 100644 index 00000000..1bfaa1df --- /dev/null +++ b/src/truefoundry_sdk/types/agent_framework.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .a2a_framework import A2AFramework +from .custom_framework import CustomFramework + +AgentFramework = typing.Union[A2AFramework, CustomFramework] diff --git a/src/truefoundry_sdk/types/agent_manifest.py b/src/truefoundry_sdk/types/agent_manifest.py index f0f32526..6ae7823f 100644 --- a/src/truefoundry_sdk/types/agent_manifest.py +++ b/src/truefoundry_sdk/types/agent_manifest.py @@ -2,51 +2,8 @@ import typing -import pydantic -import typing_extensions -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from ..core.serialization import FieldMetadata -from .agent_source import AgentSource -from .collaborator import Collaborator -from .owned_by import OwnedBy -from .sample_agent_input import SampleAgentInput +from .legacy_agent_manifest import LegacyAgentManifest +from .remote_agent import RemoteAgent +from .true_foundry_agent_manifest import TrueFoundryAgentManifest - -class AgentManifest(UniversalBaseModel): - type: typing.Literal["agent"] = pydantic.Field(default="agent") - """ - Type of the manifest - """ - - name: str = pydantic.Field() - """ - The name of the Agent - """ - - description: str = pydantic.Field() - """ - The description of the Agent - """ - - source: AgentSource - collaborators: typing.List[Collaborator] = pydantic.Field() - """ - List of users who have access to this Agent - """ - - sample_inputs: typing.Optional[typing.List[SampleAgentInput]] = pydantic.Field(default=None) - """ - Sample inputs for your agent. These inputs are shown as an example in the "Agent Chat" page. (Click on Try Now in the agent listing page) - """ - - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=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 +AgentManifest = typing.Union[TrueFoundryAgentManifest, RemoteAgent, LegacyAgentManifest] diff --git a/src/truefoundry_sdk/types/agent_skill.py b/src/truefoundry_sdk/types/agent_skill.py index bbc641d0..109e0222 100644 --- a/src/truefoundry_sdk/types/agent_skill.py +++ b/src/truefoundry_sdk/types/agent_skill.py @@ -14,12 +14,12 @@ class AgentSkill(UniversalBaseModel): description: str tags: typing.Optional[typing.List[str]] = None examples: typing.Optional[typing.List[str]] = None - input_modes: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="inputModes")] = ( - pydantic.Field(alias="inputModes", default=None) - ) - output_modes: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="outputModes")] = ( - pydantic.Field(alias="outputModes", default=None) - ) + input_modes: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="inputModes"), pydantic.Field(alias="inputModes") + ] = None + output_modes: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="outputModes"), pydantic.Field(alias="outputModes") + ] = 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/agent_skill_manifest.py b/src/truefoundry_sdk/types/agent_skill_manifest.py new file mode 100644 index 00000000..407c9479 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_skill_manifest.py @@ -0,0 +1,44 @@ +# 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_skill_manifest_source import AgentSkillManifestSource + + +class AgentSkillManifest(UniversalBaseModel): + """ + Apply/API manifest: ML Repo and versioning; ``source`` is inline (apply) or blob-storage (stored). + """ + + name: str = pydantic.Field() + """ + Name of the skill. + """ + + metadata: typing.Dict[str, typing.Any] = pydantic.Field() + """ + Key value metadata. Should be valid JSON. For e.g. `{"business-unit": "sales", "quality": "good", "rating": 4.5}` + """ + + ml_repo: str = pydantic.Field() + """ + Name of the ML Repo that this agent skill belongs to + """ + + version: typing.Optional[int] = pydantic.Field(default=None) + """ + Version of the entity + """ + + type: typing.Literal["agent_skill"] = "agent_skill" + source: AgentSkillManifestSource + + 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_skill_manifest_source.py b/src/truefoundry_sdk/types/agent_skill_manifest_source.py new file mode 100644 index 00000000..c0c0f4ce --- /dev/null +++ b/src/truefoundry_sdk/types/agent_skill_manifest_source.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .agent_skill_source_blob_storage import AgentSkillSourceBlobStorage +from .agent_skill_source_inline import AgentSkillSourceInline + +AgentSkillManifestSource = typing.Union[AgentSkillSourceInline, AgentSkillSourceBlobStorage] diff --git a/src/truefoundry_sdk/types/agent_skill_source_blob_storage.py b/src/truefoundry_sdk/types/agent_skill_source_blob_storage.py new file mode 100644 index 00000000..709bfad2 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_skill_source_blob_storage.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 AgentSkillSourceBlobStorage(UniversalBaseModel): + """ + SKILL.md content stored on blob + """ + + type: typing.Literal["blob-storage"] = "blob-storage" + description: str = pydantic.Field() + """ + 1–1024 chars. + """ + + 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_skill_source_inline.py b/src/truefoundry_sdk/types/agent_skill_source_inline.py new file mode 100644 index 00000000..c7ac30c1 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_skill_source_inline.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 AgentSkillSourceInline(UniversalBaseModel): + """ + SKILL.md for this version when using inline source. + """ + + type: typing.Literal["inline"] = "inline" + skill_md: str = pydantic.Field() + """ + Main body of SKILL.md file. + """ + + 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_skill_version.py b/src/truefoundry_sdk/types/agent_skill_version.py new file mode 100644 index 00000000..0074ea50 --- /dev/null +++ b/src/truefoundry_sdk/types/agent_skill_version.py @@ -0,0 +1,63 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .agent_skill_manifest import AgentSkillManifest +from .subject import Subject + + +class AgentSkillVersion(UniversalBaseModel): + """ + Shared artifact-version fields (identity, manifest union, ML repo). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: AgentSkillManifest = pydantic.Field() + """ + Manifest containing metadata specific to this agent skill version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + agent_skill_id: str = pydantic.Field() + """ + ID of the parent agent skill artifact that this version belongs to + """ + + 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/ai21provider_account.py b/src/truefoundry_sdk/types/ai21provider_account.py index 2ed1b09b..bc1dc89e 100644 --- a/src/truefoundry_sdk/types/ai21provider_account.py +++ b/src/truefoundry_sdk/types/ai21provider_account.py @@ -38,9 +38,9 @@ class Ai21ProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/akto_guardrail_config.py b/src/truefoundry_sdk/types/akto_guardrail_config.py new file mode 100644 index 00000000..53f51f5c --- /dev/null +++ b/src/truefoundry_sdk/types/akto_guardrail_config.py @@ -0,0 +1,54 @@ +# 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 .akto_guardrail_config_config import AktoGuardrailConfigConfig +from .akto_token_auth import AktoTokenAuth +from .enforcing_strategy import EnforcingStrategy + + +class AktoGuardrailConfig(UniversalBaseModel): + """ + Akto + """ + + name: str = pydantic.Field() + """ + The name of the Guardrail Config. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional description for this Guardrail Config. + """ + + type: typing.Literal["integration/guardrail-config/akto"] = pydantic.Field( + default="integration/guardrail-config/akto" + ) + """ + +uiType=Hidden + +value=integration/guardrail-config/akto + """ + + auth_data: AktoTokenAuth + operation: typing.Literal["validate"] = pydantic.Field(default="validate") + """ + The operation type for this guardrail. Akto guardrails can only be used for validation. + """ + + enforcing_strategy: EnforcingStrategy + config: AktoGuardrailConfigConfig = 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/prompt_foo_guardrail_config_config.py b/src/truefoundry_sdk/types/akto_guardrail_config_config.py similarity index 72% rename from src/truefoundry_sdk/types/prompt_foo_guardrail_config_config.py rename to src/truefoundry_sdk/types/akto_guardrail_config_config.py index ddb1b1e2..c837886e 100644 --- a/src/truefoundry_sdk/types/prompt_foo_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/akto_guardrail_config_config.py @@ -4,16 +4,18 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .prompt_foo_guard_type import PromptFooGuardType -class PromptFooGuardrailConfigConfig(UniversalBaseModel): +class AktoGuardrailConfigConfig(UniversalBaseModel): """ +uiType=Ignore +uiProps={"forwardJsonKey": true} """ - guard_type: PromptFooGuardType + base_url: str = pydantic.Field() + """ + The base URL of the Akto guardrails service (e.g. https://your-akto-host:port) + """ 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/akto_token_auth.py b/src/truefoundry_sdk/types/akto_token_auth.py new file mode 100644 index 00000000..dc26a503 --- /dev/null +++ b/src/truefoundry_sdk/types/akto_token_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 AktoTokenAuth(UniversalBaseModel): + """ + Authentication method using an Akto JWT token + """ + + type: typing.Literal["token"] = pydantic.Field(default="token") + """ + +value=token + """ + + token: str = pydantic.Field() + """ + JWT token for authenticating with the Akto guardrails service + """ + + 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/alert.py b/src/truefoundry_sdk/types/alert.py index 86b6133b..00f47590 100644 --- a/src/truefoundry_sdk/types/alert.py +++ b/src/truefoundry_sdk/types/alert.py @@ -13,29 +13,31 @@ class Alert(UniversalBaseModel): id: typing.Optional[str] = None name: str timestamps: typing.List[dt.datetime] - start_time: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="startTime")] = pydantic.Field( - alias="startTime" - ) - resolved_time: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="resolvedTime")] = ( - pydantic.Field(alias="resolvedTime", default=None) - ) - application_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="applicationId")] = ( - pydantic.Field(alias="applicationId", default=None) - ) - cluster_id: typing_extensions.Annotated[str, FieldMetadata(alias="clusterId")] = pydantic.Field(alias="clusterId") - tenant_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName", default=None - ) + start_time: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="startTime"), pydantic.Field(alias="startTime") + ] + resolved_time: typing_extensions.Annotated[ + typing.Optional[dt.datetime], FieldMetadata(alias="resolvedTime"), pydantic.Field(alias="resolvedTime") + ] = None + application_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId") + ] = None + cluster_id: typing_extensions.Annotated[str, FieldMetadata(alias="clusterId"), pydantic.Field(alias="clusterId")] + tenant_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName") + ] = None fingerprint: str - updated_at: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="updatedAt")] = pydantic.Field( - alias="updatedAt", default=None - ) - created_at: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdAt")] = pydantic.Field( - alias="createdAt", default=None - ) + updated_at: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="updatedAt"), pydantic.Field(alias="updatedAt") + ] = None + created_at: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt") + ] = None application_debug_info_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="applicationDebugInfoId") - ] = pydantic.Field(alias="applicationDebugInfoId", default=None) + typing.Optional[str], + FieldMetadata(alias="applicationDebugInfoId"), + pydantic.Field(alias="applicationDebugInfoId"), + ] = 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/amqp_input_config.py b/src/truefoundry_sdk/types/amqp_input_config.py index 78007103..83784e36 100644 --- a/src/truefoundry_sdk/types/amqp_input_config.py +++ b/src/truefoundry_sdk/types/amqp_input_config.py @@ -26,7 +26,7 @@ class AmqpInputConfig(UniversalBaseModel): AMQP Queue Name """ - wait_time_seconds: int = pydantic.Field(default=5) + wait_time_seconds: int = pydantic.Field() """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/anthropic_provider_account.py b/src/truefoundry_sdk/types/anthropic_provider_account.py index 79b42e84..242cda03 100644 --- a/src/truefoundry_sdk/types/anthropic_provider_account.py +++ b/src/truefoundry_sdk/types/anthropic_provider_account.py @@ -38,9 +38,9 @@ class AnthropicProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/application.py b/src/truefoundry_sdk/types/application.py index b64a7ba8..19e71b35 100644 --- a/src/truefoundry_sdk/types/application.py +++ b/src/truefoundry_sdk/types/application.py @@ -9,10 +9,8 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata -from .alert import Alert from .application_lifecycle_stage import ApplicationLifecycleStage from .application_metadata import ApplicationMetadata -from .application_problem import ApplicationProblem from .application_type import ApplicationType from .recommendation import Recommendation from .subject import Subject @@ -23,76 +21,70 @@ class Application(UniversalBaseModel): fqn: typing.Optional[str] = None name: typing.Optional[str] = None type: typing.Optional[ApplicationType] = None - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - tenant_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName", default=None - ) + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + tenant_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName") + ] = None metadata: typing.Optional[ApplicationMetadata] = None - lifecycle_stage: typing_extensions.Annotated[ApplicationLifecycleStage, FieldMetadata(alias="lifecycleStage")] = ( - pydantic.Field(alias="lifecycleStage") - ) - workspace_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceId")] = ( - pydantic.Field(alias="workspaceId", default=None) - ) - last_version: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="lastVersion")] = ( - pydantic.Field(alias="lastVersion", default=None) - ) - active_version: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="activeVersion")] = ( - pydantic.Field(alias="activeVersion", default=None) - ) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) + lifecycle_stage: typing_extensions.Annotated[ + ApplicationLifecycleStage, FieldMetadata(alias="lifecycleStage"), pydantic.Field(alias="lifecycleStage") + ] + workspace_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="workspaceId"), pydantic.Field(alias="workspaceId") + ] = None + last_version: typing_extensions.Annotated[ + typing.Optional[int], FieldMetadata(alias="lastVersion"), pydantic.Field(alias="lastVersion") + ] = None + active_version: typing_extensions.Annotated[ + typing.Optional[int], FieldMetadata(alias="activeVersion"), pydantic.Field(alias="activeVersion") + ] = 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 recommendations: typing.Optional[typing.List[Recommendation]] = pydantic.Field(default=None) """ Recommendations for this application """ - alerts: typing.Optional[typing.List[Alert]] = pydantic.Field(default=None) + alerts: typing.Optional[typing.List[typing.List[typing.Any]]] = pydantic.Field(default=None) """ Alerts for this application """ alerts_summary: typing_extensions.Annotated[ - typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="alertsSummary") - ] = pydantic.Field(alias="alertsSummary", default=None) - """ - Summary of alerts for this application - """ - + typing.Optional[typing.Dict[str, typing.Any]], + FieldMetadata(alias="alertsSummary"), + pydantic.Field(alias="alertsSummary", description="Summary of alerts for this application"), + ] = None application_debug_infos: typing_extensions.Annotated[ - typing.Optional[typing.List["ApplicationDebugInfo"]], FieldMetadata(alias="applicationDebugInfos") - ] = pydantic.Field(alias="applicationDebugInfos", default=None) - """ - Debug infos for this application - """ - + typing.Optional[typing.List[typing.List[typing.Any]]], + FieldMetadata(alias="applicationDebugInfos"), + pydantic.Field(alias="applicationDebugInfos", description="Debug infos for this application"), + ] = None potential_problems: typing_extensions.Annotated[ - typing.Optional[typing.List[ApplicationProblem]], FieldMetadata(alias="potentialProblems") - ] = pydantic.Field(alias="potentialProblems", default=None) - """ - Potential problems with the application - """ - + typing.Optional[typing.List[typing.List[typing.Any]]], + FieldMetadata(alias="potentialProblems"), + pydantic.Field(alias="potentialProblems", description="Potential problems with the application"), + ] = None autopilot: typing.Dict[str, typing.Any] - workspace_fqn: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="workspaceFqn")] = ( - pydantic.Field(alias="workspaceFqn", default=None) - ) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + workspace_fqn: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="workspaceFqn"), pydantic.Field(alias="workspaceFqn") + ] = None + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None deployment: typing.Optional["Deployment"] = None active_deployment_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="activeDeploymentId") - ] = pydantic.Field(alias="activeDeploymentId", default=None) - last_deployment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="lastDeploymentId")] = ( - pydantic.Field(alias="lastDeploymentId", default=None) - ) + typing.Optional[str], FieldMetadata(alias="activeDeploymentId"), pydantic.Field(alias="activeDeploymentId") + ] = None + last_deployment_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="lastDeploymentId"), pydantic.Field(alias="lastDeploymentId") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow") # type: ignore # Pydantic v2 @@ -103,7 +95,6 @@ class Config: extra = pydantic.Extra.allow -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment) +update_forward_refs(Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/application_debug_info.py b/src/truefoundry_sdk/types/application_debug_info.py deleted file mode 100644 index a06d81d8..00000000 --- a/src/truefoundry_sdk/types/application_debug_info.py +++ /dev/null @@ -1,42 +0,0 @@ -# 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 - - -class ApplicationDebugInfo(UniversalBaseModel): - id: typing.Optional[str] = None - application_id: typing_extensions.Annotated[str, FieldMetadata(alias="applicationId")] = pydantic.Field( - alias="applicationId" - ) - application: typing.Optional["Application"] = None - debug_info: typing_extensions.Annotated[typing.Dict[str, typing.Any], FieldMetadata(alias="debugInfo")] = ( - pydantic.Field(alias="debugInfo") - ) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=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 .application import Application # noqa: E402, I001 -from .deployment import Deployment # noqa: E402, I001 - -update_forward_refs(ApplicationDebugInfo, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/apply_ml_entity_response.py b/src/truefoundry_sdk/types/apply_ml_entity_response.py index 4197c805..33da51d7 100644 --- a/src/truefoundry_sdk/types/apply_ml_entity_response.py +++ b/src/truefoundry_sdk/types/apply_ml_entity_response.py @@ -8,7 +8,10 @@ class ApplyMlEntityResponse(UniversalBaseModel): - data: ApplyMlEntityResponseData + data: ApplyMlEntityResponseData = pydantic.Field() + """ + The created or updated ML entity (model version, prompt version, agent skill version, artifact version, or data directory) + """ 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/apply_ml_entity_response_data.py b/src/truefoundry_sdk/types/apply_ml_entity_response_data.py index a47359fa..c0ea7de3 100644 --- a/src/truefoundry_sdk/types/apply_ml_entity_response_data.py +++ b/src/truefoundry_sdk/types/apply_ml_entity_response_data.py @@ -2,9 +2,10 @@ import typing +from .agent_skill_version import AgentSkillVersion from .artifact_version import ArtifactVersion from .data_directory import DataDirectory from .model_version import ModelVersion from .prompt_version import PromptVersion -ApplyMlEntityResponseData = typing.Union[ModelVersion, PromptVersion, ArtifactVersion, DataDirectory] +ApplyMlEntityResponseData = typing.Union[ModelVersion, PromptVersion, AgentSkillVersion, ArtifactVersion, DataDirectory] diff --git a/src/truefoundry_sdk/types/artifact.py b/src/truefoundry_sdk/types/artifact.py index 71a89018..72c27053 100644 --- a/src/truefoundry_sdk/types/artifact.py +++ b/src/truefoundry_sdk/types/artifact.py @@ -11,16 +11,59 @@ class Artifact(UniversalBaseModel): - id: str - ml_repo_id: str - type: ArtifactType - name: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - latest_version: typing.Optional[BaseArtifactVersion] = None - run_steps: typing.Optional[typing.List[int]] = None + """ + Generic artifact API DTO including run-step linkage for ML runs. + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact belongs to + """ + + type: ArtifactType = pydantic.Field() + """ + Type of the artifact (e.g., 'artifact', 'model', 'chat_prompt', 'agent_skill', 'plot', 'image') + """ + + name: str = pydantic.Field() + """ + Name of the artifact (alphanumeric characters, hyphens, and underscores only, max 256 characters) + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was last updated + """ + + latest_version: typing.Optional[BaseArtifactVersion] = pydantic.Field(default=None) + """ + The most recent version of this artifact + """ + + run_steps: typing.Optional[typing.List[int]] = pydantic.Field(default=None) + """ + List of run step numbers where this artifact was created or 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/artifact_manifest.py b/src/truefoundry_sdk/types/artifact_manifest.py index 3f5cb288..88afcc2b 100644 --- a/src/truefoundry_sdk/types/artifact_manifest.py +++ b/src/truefoundry_sdk/types/artifact_manifest.py @@ -14,23 +14,17 @@ class ArtifactManifest(UniversalBaseModel): name: str = pydantic.Field() """ - Name of the entity + Name of the artifact (alphanumeric characters, hyphens, and underscores only, max 256 characters) """ - description: typing.Optional[str] = None metadata: typing.Dict[str, typing.Any] = pydantic.Field() """ Key value metadata. Should be valid JSON. For e.g. `{"business-unit": "sales", "quality": "good", "rating": 4.5}` """ - version_alias: typing.Optional[str] = pydantic.Field(default=None) - """ - Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) - """ - ml_repo: str = pydantic.Field() """ - Name of the ML Repo + Name of the ML Repo that this artifact belongs to (must start and end with alphanumeric, 2-100 characters) """ version: typing.Optional[int] = pydantic.Field(default=None) @@ -39,8 +33,14 @@ class ArtifactManifest(UniversalBaseModel): """ type: typing.Literal["artifact-version"] = "artifact-version" + description: typing.Optional[str] = None + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) + """ + source: ArtifactManifestSource - step: typing.Optional[int] = pydantic.Field(default=0) + step: typing.Optional[int] = pydantic.Field(default=None) """ Step/Epoch number in an iterative training loop the artifact version was created. Generally useful when logging a model version from a MLRepo Run """ diff --git a/src/truefoundry_sdk/types/artifact_type.py b/src/truefoundry_sdk/types/artifact_type.py index af27cec6..0c01a645 100644 --- a/src/truefoundry_sdk/types/artifact_type.py +++ b/src/truefoundry_sdk/types/artifact_type.py @@ -17,6 +17,7 @@ class ArtifactType(enum.StrEnum): PLOT = "plot" IMAGE = "image" CHAT_PROMPT = "chat_prompt" + AGENT_SKILL = "agent_skill" _UNKNOWN = "__ARTIFACTTYPE_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`. @@ -35,6 +36,7 @@ def visit( plot: typing.Callable[[], T_Result], image: typing.Callable[[], T_Result], chat_prompt: typing.Callable[[], T_Result], + agent_skill: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is ArtifactType.ARTIFACT: @@ -47,4 +49,6 @@ def visit( return image() if self is ArtifactType.CHAT_PROMPT: return chat_prompt() + if self is ArtifactType.AGENT_SKILL: + return agent_skill() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/artifact_version.py b/src/truefoundry_sdk/types/artifact_version.py index e97a2d75..140cfdc1 100644 --- a/src/truefoundry_sdk/types/artifact_version.py +++ b/src/truefoundry_sdk/types/artifact_version.py @@ -10,16 +10,64 @@ class ArtifactVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - manifest: ArtifactManifest - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None - artifact_id: str + """ + Tags, optional version alias, and SDK usage snippet (models, prompts, generic artifacts). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: ArtifactManifest = pydantic.Field() + """ + Manifest containing metadata for a generic artifact version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of tags associated with this artifact version for filtering and organization + """ + + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional human-readable version alias (e.g. v1.0.0) + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this artifact version + """ + + artifact_id: str = pydantic.Field() + """ + ID of the parent artifact that this version belongs to + """ 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/artifacts_cache_volume.py b/src/truefoundry_sdk/types/artifacts_cache_volume.py index c2dab808..d53c0166 100644 --- a/src/truefoundry_sdk/types/artifacts_cache_volume.py +++ b/src/truefoundry_sdk/types/artifacts_cache_volume.py @@ -16,7 +16,7 @@ class ArtifactsCacheVolume(UniversalBaseModel): Storage class of the Volume where artifacts will be cached """ - cache_size: int = pydantic.Field(default=200) + cache_size: int = pydantic.Field() """ Size of the Volume (in GB) where artifacts will be cached. Should be greater than twice the size of artifacts getting cached """ diff --git a/src/truefoundry_sdk/types/async_processor_sidecar.py b/src/truefoundry_sdk/types/async_processor_sidecar.py index ffac1a4f..a442c419 100644 --- a/src/truefoundry_sdk/types/async_processor_sidecar.py +++ b/src/truefoundry_sdk/types/async_processor_sidecar.py @@ -12,7 +12,7 @@ class AsyncProcessorSidecar(UniversalBaseModel): URL for the processor to invoke """ - request_timeout: typing.Optional[int] = pydantic.Field(default=10) + request_timeout: typing.Optional[int] = pydantic.Field(default=None) """ Timeout for the invoke request in seconds """ diff --git a/src/truefoundry_sdk/types/auto_rotate.py b/src/truefoundry_sdk/types/auto_rotate.py index 33d45dd8..24f75269 100644 --- a/src/truefoundry_sdk/types/auto_rotate.py +++ b/src/truefoundry_sdk/types/auto_rotate.py @@ -11,12 +11,12 @@ class AutoRotate(UniversalBaseModel): Enable Auto Rotation to automatically rotate the token """ - auto_rotate_interval: int = pydantic.Field(default=360) + auto_rotate_interval: int = pydantic.Field() """ Rotation Interval in days after which the token will be rotated. Minimum value is 30. """ - grace_period: int = pydantic.Field(default=30) + grace_period: int = pydantic.Field() """ Grace Period in days for which the token will be valid after rotation interval. Minimum value is 1. """ diff --git a/src/truefoundry_sdk/types/autoshutdown.py b/src/truefoundry_sdk/types/autoshutdown.py index cf7f2938..794e3a35 100644 --- a/src/truefoundry_sdk/types/autoshutdown.py +++ b/src/truefoundry_sdk/types/autoshutdown.py @@ -7,7 +7,7 @@ class Autoshutdown(UniversalBaseModel): - wait_time: int = pydantic.Field(default=900) + wait_time: int = pydantic.Field() """ The period to wait after the last received request before scaling the replicas to 0. This value should be high enough to allow for the replicas of the service to come up to avoid premature scaling down. """ diff --git a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py index d8f4c744..4b982012 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py +++ b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py @@ -20,9 +20,7 @@ class AwsBedrockGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="AWS Bedrock Guardrails for content filtering and safety policies" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -46,7 +44,7 @@ class AwsBedrockGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config_auth_data.py b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config_auth_data.py index 916a6513..a5433c32 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config_auth_data.py +++ b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config_auth_data.py @@ -3,6 +3,9 @@ import typing from .aws_access_key_based_auth import AwsAccessKeyBasedAuth +from .aws_bedrock_api_key_auth import AwsBedrockApiKeyAuth from .aws_bedrock_assumed_role_based_auth import AwsBedrockAssumedRoleBasedAuth -AwsBedrockGuardrailConfigAuthData = typing.Union[AwsAccessKeyBasedAuth, AwsBedrockAssumedRoleBasedAuth] +AwsBedrockGuardrailConfigAuthData = typing.Union[ + AwsAccessKeyBasedAuth, AwsBedrockAssumedRoleBasedAuth, AwsBedrockApiKeyAuth +] diff --git a/src/truefoundry_sdk/types/aws_bedrock_provider_account.py b/src/truefoundry_sdk/types/aws_bedrock_provider_account.py index d2184af6..ac400255 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_provider_account.py +++ b/src/truefoundry_sdk/types/aws_bedrock_provider_account.py @@ -44,9 +44,9 @@ class AwsBedrockProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/aws_parameter_store.py b/src/truefoundry_sdk/types/aws_parameter_store.py index 395c0768..38f62d66 100644 --- a/src/truefoundry_sdk/types/aws_parameter_store.py +++ b/src/truefoundry_sdk/types/aws_parameter_store.py @@ -36,6 +36,11 @@ class AwsParameterStore(UniversalBaseModel): List of subjects that are authorized to access this integration. List of user fqn in format :. """ + kms_arn: typing.Optional[str] = pydantic.Field(default=None) + """ + The ARN of the KMS key to use for encryption. + """ + 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_provider_account.py b/src/truefoundry_sdk/types/aws_provider_account.py index 49bcd4bb..e0e9923d 100644 --- a/src/truefoundry_sdk/types/aws_provider_account.py +++ b/src/truefoundry_sdk/types/aws_provider_account.py @@ -41,9 +41,9 @@ class AwsProviderAccount(UniversalBaseModel): List of integrations that are associated with the AWS provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/aws_sagemaker_provider_account.py b/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py index fd330ecf..5839d5b9 100644 --- a/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py +++ b/src/truefoundry_sdk/types/aws_sagemaker_provider_account.py @@ -44,9 +44,9 @@ class AwsSagemakerProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/aws_sagemaker_provider_account_auth_data.py b/src/truefoundry_sdk/types/aws_sagemaker_provider_account_auth_data.py index e28e87a8..5ef69b56 100644 --- a/src/truefoundry_sdk/types/aws_sagemaker_provider_account_auth_data.py +++ b/src/truefoundry_sdk/types/aws_sagemaker_provider_account_auth_data.py @@ -3,6 +3,6 @@ import typing from .aws_access_key_based_auth import AwsAccessKeyBasedAuth -from .aws_bedrock_assumed_role_based_auth import AwsBedrockAssumedRoleBasedAuth +from .sagemaker_assumed_role_based_auth import SagemakerAssumedRoleBasedAuth -AwsSagemakerProviderAccountAuthData = typing.Union[AwsAccessKeyBasedAuth, AwsBedrockAssumedRoleBasedAuth] +AwsSagemakerProviderAccountAuthData = typing.Union[AwsAccessKeyBasedAuth, SagemakerAssumedRoleBasedAuth] diff --git a/src/truefoundry_sdk/types/aws_secrets_manager.py b/src/truefoundry_sdk/types/aws_secrets_manager.py index 9288163d..aa9a4d61 100644 --- a/src/truefoundry_sdk/types/aws_secrets_manager.py +++ b/src/truefoundry_sdk/types/aws_secrets_manager.py @@ -36,6 +36,11 @@ class AwsSecretsManager(UniversalBaseModel): List of subjects that are authorized to access this integration. List of user fqn in format :. """ + kms_arn: typing.Optional[str] = pydantic.Field(default=None) + """ + The ARN of the KMS key to use for encryption. + """ + 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_content_safety_guardrail_config.py b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py index 924706a3..b9bb6a42 100644 --- a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py @@ -19,9 +19,7 @@ class AzureContentSafetyGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Azure Content Safety for hate, self-harm, sexual, and violence detection" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py index 6b9c9fb4..a70bb5bd 100644 --- a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py @@ -18,7 +18,7 @@ class AzureContentSafetyGuardrailConfigConfig(UniversalBaseModel): Name of your Azure Content Safety resource where the service is deployed (e.g., my-content-safety) """ - api_version: str = pydantic.Field(default="2024-09-01") + api_version: str = pydantic.Field() """ API version for the Content Safety API """ @@ -33,7 +33,7 @@ class AzureContentSafetyGuardrailConfigConfig(UniversalBaseModel): Names of custom blocklists created in Azure Content Safety to check text against. Leave empty if not using custom blocklists """ - severity_threshold: float = pydantic.Field(default=2.0) + severity_threshold: float = pydantic.Field() """ Minimum severity level (0-6) to flag content. Higher values are more restrictive. 0=Safe, 2=Low risk, 4=Medium risk, 6=High risk """ diff --git a/src/truefoundry_sdk/types/azure_foundry_provider_account.py b/src/truefoundry_sdk/types/azure_foundry_provider_account.py index 4f073dd4..7599da8e 100644 --- a/src/truefoundry_sdk/types/azure_foundry_provider_account.py +++ b/src/truefoundry_sdk/types/azure_foundry_provider_account.py @@ -36,9 +36,9 @@ class AzureFoundryProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/azure_open_ai_model.py b/src/truefoundry_sdk/types/azure_open_ai_model.py index 607d8a1a..9f5f2e16 100644 --- a/src/truefoundry_sdk/types/azure_open_ai_model.py +++ b/src/truefoundry_sdk/types/azure_open_ai_model.py @@ -5,7 +5,6 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .azure_open_ai_model_deployment_type import AzureOpenAiModelDeploymentType -from .azure_open_ai_model_region import AzureOpenAiModelRegion from .model_cost_metric import ModelCostMetric from .model_type import ModelType @@ -40,14 +39,9 @@ class AzureOpenAiModel(UniversalBaseModel): The foundation model identifier (e.g., gpt-4o-2024-11-20) """ - deployment_type: typing.Optional[AzureOpenAiModelDeploymentType] = pydantic.Field(default=None) + deployment_type: AzureOpenAiModelDeploymentType = pydantic.Field() """ - Global: worldwide processing, Data Zone: US/EU processing only - """ - - region: typing.Optional[AzureOpenAiModelRegion] = pydantic.Field(default=None) - """ - The Azure region for data-zone deployments + 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() diff --git a/src/truefoundry_sdk/types/azure_open_ai_model_deployment_type.py b/src/truefoundry_sdk/types/azure_open_ai_model_deployment_type.py index 5c67dc90..aad7b277 100644 --- a/src/truefoundry_sdk/types/azure_open_ai_model_deployment_type.py +++ b/src/truefoundry_sdk/types/azure_open_ai_model_deployment_type.py @@ -9,11 +9,13 @@ class AzureOpenAiModelDeploymentType(enum.StrEnum): """ - Global: worldwide processing, Data Zone: US/EU processing only + 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" - DATA_ZONE = "data-zone" _UNKNOWN = "__AZUREOPENAIMODELDEPLOYMENTTYPE_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`. @@ -27,12 +29,18 @@ def _missing_(cls, value: typing.Any) -> "AzureOpenAiModelDeploymentType": 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], - data_zone: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: + if self is AzureOpenAiModelDeploymentType.STANDARD: + return standard() + if self is AzureOpenAiModelDeploymentType.DATAZONE_US: + return datazone_us() + if self is AzureOpenAiModelDeploymentType.DATAZONE_EU: + return datazone_eu() if self is AzureOpenAiModelDeploymentType.GLOBAL: return global_() - if self is AzureOpenAiModelDeploymentType.DATA_ZONE: - return data_zone() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/azure_open_ai_model_region.py b/src/truefoundry_sdk/types/azure_open_ai_model_region.py deleted file mode 100644 index 91eba626..00000000 --- a/src/truefoundry_sdk/types/azure_open_ai_model_region.py +++ /dev/null @@ -1,190 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from ..core import enum - -T_Result = typing.TypeVar("T_Result") - - -class AzureOpenAiModelRegion(enum.StrEnum): - """ - The Azure region for data-zone deployments - """ - - AUSTRALIAEAST = "australiaeast" - AUSTRIAEAST = "austriaeast" - BELGIUMCENTRAL = "belgiumcentral" - BRAZILSOUTH = "brazilsouth" - CANADACENTRAL = "canadacentral" - CENTRALINDIA = "centralindia" - CENTRALUS = "centralus" - CHILECENTRAL = "chilecentral" - DENMARKEAST = "denmarkeast" - EASTASIA = "eastasia" - EASTUS = "eastus" - EASTUS2 = "eastus2" - FRANCECENTRAL = "francecentral" - GERMANYWESTCENTRAL = "germanywestcentral" - INDONESIACENTRAL = "indonesiacentral" - ISRAELCENTRAL = "israelcentral" - ITALYNORTH = "italynorth" - JAPANEAST = "japaneast" - JAPANWEST = "japanwest" - KOREACENTRAL = "koreacentral" - MALAYSIAWEST = "malaysiawest" - MEXICOCENTRAL = "mexicocentral" - NEWZEALANDNORTH = "newzealandnorth" - NORTHCENTRALUS = "northcentralus" - NORTHEUROPE = "northeurope" - NORWAYEAST = "norwayeast" - POLANDCENTRAL = "polandcentral" - QATARCENTRAL = "qatarcentral" - SOUTHAFRICANORTH = "southafricanorth" - SOUTHCENTRALUS = "southcentralus" - SOUTHEASTASIA = "southeastasia" - SPAINCENTRAL = "spaincentral" - SWEDENCENTRAL = "swedencentral" - SWITZERLANDNORTH = "switzerlandnorth" - UAENORTH = "uaenorth" - UKSOUTH = "uksouth" - WESTEUROPE = "westeurope" - WESTUS = "westus" - WESTUS2 = "westus2" - WESTUS3 = "westus3" - _UNKNOWN = "__AZUREOPENAIMODELREGION_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) -> "AzureOpenAiModelRegion": - unknown = cls._UNKNOWN - unknown._value_ = value - return unknown - - def visit( - self, - australiaeast: typing.Callable[[], T_Result], - austriaeast: typing.Callable[[], T_Result], - belgiumcentral: typing.Callable[[], T_Result], - brazilsouth: typing.Callable[[], T_Result], - canadacentral: typing.Callable[[], T_Result], - centralindia: typing.Callable[[], T_Result], - centralus: typing.Callable[[], T_Result], - chilecentral: typing.Callable[[], T_Result], - denmarkeast: typing.Callable[[], T_Result], - eastasia: typing.Callable[[], T_Result], - eastus: typing.Callable[[], T_Result], - eastus2: typing.Callable[[], T_Result], - francecentral: typing.Callable[[], T_Result], - germanywestcentral: typing.Callable[[], T_Result], - indonesiacentral: typing.Callable[[], T_Result], - israelcentral: typing.Callable[[], T_Result], - italynorth: typing.Callable[[], T_Result], - japaneast: typing.Callable[[], T_Result], - japanwest: typing.Callable[[], T_Result], - koreacentral: typing.Callable[[], T_Result], - malaysiawest: typing.Callable[[], T_Result], - mexicocentral: typing.Callable[[], T_Result], - newzealandnorth: typing.Callable[[], T_Result], - northcentralus: typing.Callable[[], T_Result], - northeurope: typing.Callable[[], T_Result], - norwayeast: typing.Callable[[], T_Result], - polandcentral: typing.Callable[[], T_Result], - qatarcentral: typing.Callable[[], T_Result], - southafricanorth: typing.Callable[[], T_Result], - southcentralus: typing.Callable[[], T_Result], - southeastasia: typing.Callable[[], T_Result], - spaincentral: typing.Callable[[], T_Result], - swedencentral: typing.Callable[[], T_Result], - switzerlandnorth: typing.Callable[[], T_Result], - uaenorth: typing.Callable[[], T_Result], - uksouth: typing.Callable[[], T_Result], - westeurope: typing.Callable[[], T_Result], - westus: typing.Callable[[], T_Result], - westus2: typing.Callable[[], T_Result], - westus3: typing.Callable[[], T_Result], - _unknown_member: typing.Callable[[str], T_Result], - ) -> T_Result: - if self is AzureOpenAiModelRegion.AUSTRALIAEAST: - return australiaeast() - if self is AzureOpenAiModelRegion.AUSTRIAEAST: - return austriaeast() - if self is AzureOpenAiModelRegion.BELGIUMCENTRAL: - return belgiumcentral() - if self is AzureOpenAiModelRegion.BRAZILSOUTH: - return brazilsouth() - if self is AzureOpenAiModelRegion.CANADACENTRAL: - return canadacentral() - if self is AzureOpenAiModelRegion.CENTRALINDIA: - return centralindia() - if self is AzureOpenAiModelRegion.CENTRALUS: - return centralus() - if self is AzureOpenAiModelRegion.CHILECENTRAL: - return chilecentral() - if self is AzureOpenAiModelRegion.DENMARKEAST: - return denmarkeast() - if self is AzureOpenAiModelRegion.EASTASIA: - return eastasia() - if self is AzureOpenAiModelRegion.EASTUS: - return eastus() - if self is AzureOpenAiModelRegion.EASTUS2: - return eastus2() - if self is AzureOpenAiModelRegion.FRANCECENTRAL: - return francecentral() - if self is AzureOpenAiModelRegion.GERMANYWESTCENTRAL: - return germanywestcentral() - if self is AzureOpenAiModelRegion.INDONESIACENTRAL: - return indonesiacentral() - if self is AzureOpenAiModelRegion.ISRAELCENTRAL: - return israelcentral() - if self is AzureOpenAiModelRegion.ITALYNORTH: - return italynorth() - if self is AzureOpenAiModelRegion.JAPANEAST: - return japaneast() - if self is AzureOpenAiModelRegion.JAPANWEST: - return japanwest() - if self is AzureOpenAiModelRegion.KOREACENTRAL: - return koreacentral() - if self is AzureOpenAiModelRegion.MALAYSIAWEST: - return malaysiawest() - if self is AzureOpenAiModelRegion.MEXICOCENTRAL: - return mexicocentral() - if self is AzureOpenAiModelRegion.NEWZEALANDNORTH: - return newzealandnorth() - if self is AzureOpenAiModelRegion.NORTHCENTRALUS: - return northcentralus() - if self is AzureOpenAiModelRegion.NORTHEUROPE: - return northeurope() - if self is AzureOpenAiModelRegion.NORWAYEAST: - return norwayeast() - if self is AzureOpenAiModelRegion.POLANDCENTRAL: - return polandcentral() - if self is AzureOpenAiModelRegion.QATARCENTRAL: - return qatarcentral() - if self is AzureOpenAiModelRegion.SOUTHAFRICANORTH: - return southafricanorth() - if self is AzureOpenAiModelRegion.SOUTHCENTRALUS: - return southcentralus() - if self is AzureOpenAiModelRegion.SOUTHEASTASIA: - return southeastasia() - if self is AzureOpenAiModelRegion.SPAINCENTRAL: - return spaincentral() - if self is AzureOpenAiModelRegion.SWEDENCENTRAL: - return swedencentral() - if self is AzureOpenAiModelRegion.SWITZERLANDNORTH: - return switzerlandnorth() - if self is AzureOpenAiModelRegion.UAENORTH: - return uaenorth() - if self is AzureOpenAiModelRegion.UKSOUTH: - return uksouth() - if self is AzureOpenAiModelRegion.WESTEUROPE: - return westeurope() - if self is AzureOpenAiModelRegion.WESTUS: - return westus() - if self is AzureOpenAiModelRegion.WESTUS2: - return westus2() - if self is AzureOpenAiModelRegion.WESTUS3: - return westus3() - return _unknown_member(self._value_) 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 9d08895c..312a4fb7 100644 --- a/src/truefoundry_sdk/types/azure_open_ai_provider_account.py +++ b/src/truefoundry_sdk/types/azure_open_ai_provider_account.py @@ -47,9 +47,9 @@ class AzureOpenAiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/azure_pii_guardrail_config.py b/src/truefoundry_sdk/types/azure_pii_guardrail_config.py index cb74e739..16072ad3 100644 --- a/src/truefoundry_sdk/types/azure_pii_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_pii_guardrail_config.py @@ -20,9 +20,7 @@ class AzurePiiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Azure AI Language PII detection and redaction for sensitive data" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -45,7 +43,7 @@ class AzurePiiGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py index 3ea0df00..796f5195 100644 --- a/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py @@ -19,7 +19,7 @@ class AzurePiiGuardrailConfigConfig(UniversalBaseModel): Name of your Azure AI Language resource where the PII detection service is deployed (e.g., my-language-resource) """ - api_version: str = pydantic.Field(default="2024-11-01") + api_version: str = pydantic.Field() """ API version for the PII detection API """ @@ -39,12 +39,12 @@ class AzurePiiGuardrailConfigConfig(UniversalBaseModel): Categories of PII to detect. """ - model_version: str = pydantic.Field(default="latest") + model_version: str = pydantic.Field() """ Version of the PII detection model to use, use latest for the newest model or specify a specific version for consistency """ - language: str = pydantic.Field(default="en") + language: str = pydantic.Field() """ Language code for PII detection (e.g., en for English) """ diff --git a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py index 4128ced1..d8b01b60 100644 --- a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py @@ -19,9 +19,7 @@ class AzurePromptShieldGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Azure Prompt Shield for jailbreak and prompt injection detection" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py index c93f55bf..35cf54e9 100644 --- a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py @@ -17,7 +17,7 @@ class AzurePromptShieldGuardrailConfigConfig(UniversalBaseModel): Name of your Azure Content Safety resource where the Prompt Shield service is deployed (e.g., my-content-safety) """ - api_version: str = pydantic.Field(default="2024-09-01") + api_version: str = pydantic.Field() """ API version for the Prompt Shield API """ diff --git a/src/truefoundry_sdk/types/azure_provider_account.py b/src/truefoundry_sdk/types/azure_provider_account.py index 28382900..760905da 100644 --- a/src/truefoundry_sdk/types/azure_provider_account.py +++ b/src/truefoundry_sdk/types/azure_provider_account.py @@ -35,9 +35,9 @@ class AzureProviderAccount(UniversalBaseModel): List of integrations that are associated with the Azure provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/base_artifact_version.py b/src/truefoundry_sdk/types/base_artifact_version.py index 2c52b5e7..534cf2ab 100644 --- a/src/truefoundry_sdk/types/base_artifact_version.py +++ b/src/truefoundry_sdk/types/base_artifact_version.py @@ -10,15 +10,40 @@ class BaseArtifactVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None + """ + Shared artifact-version fields (identity, manifest union, ML repo). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + manifest: typing.Optional[BaseArtifactVersionManifest] = None - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ 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/base_artifact_version_manifest.py b/src/truefoundry_sdk/types/base_artifact_version_manifest.py index b419d172..529fcb57 100644 --- a/src/truefoundry_sdk/types/base_artifact_version_manifest.py +++ b/src/truefoundry_sdk/types/base_artifact_version_manifest.py @@ -2,8 +2,9 @@ import typing +from .agent_skill_manifest import AgentSkillManifest from .artifact_manifest import ArtifactManifest from .chat_prompt_manifest import ChatPromptManifest from .model_manifest import ModelManifest -BaseArtifactVersionManifest = typing.Union[ModelManifest, ChatPromptManifest, ArtifactManifest] +BaseArtifactVersionManifest = typing.Union[ModelManifest, ChatPromptManifest, ArtifactManifest, AgentSkillManifest] diff --git a/src/truefoundry_sdk/types/base_autoscaling.py b/src/truefoundry_sdk/types/base_autoscaling.py index df777249..36351de4 100644 --- a/src/truefoundry_sdk/types/base_autoscaling.py +++ b/src/truefoundry_sdk/types/base_autoscaling.py @@ -7,7 +7,7 @@ class BaseAutoscaling(UniversalBaseModel): - min_replicas: int = pydantic.Field(default=1) + min_replicas: int = pydantic.Field() """ Minimum number of replicas to keep available """ @@ -17,7 +17,7 @@ class BaseAutoscaling(UniversalBaseModel): Maximum number of replicas allowed for the component. """ - polling_interval: typing.Optional[int] = pydantic.Field(default=30) + polling_interval: typing.Optional[int] = pydantic.Field(default=None) """ This is the interval to check each trigger on. """ diff --git a/src/truefoundry_sdk/types/base_remote_agent.py b/src/truefoundry_sdk/types/base_remote_agent.py new file mode 100644 index 00000000..bd34e068 --- /dev/null +++ b/src/truefoundry_sdk/types/base_remote_agent.py @@ -0,0 +1,44 @@ +# 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 .owned_by import OwnedBy + + +class BaseRemoteAgent(UniversalBaseModel): + name: str = pydantic.Field() + """ + The name of the Agent + """ + + description: str = pydantic.Field() + """ + The description of the Agent + """ + + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Tags for the Agent + """ + + collaborators: typing.List[Collaborator] = pydantic.Field() + """ + List of users who have access to this Agent + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/base_workbench_input.py b/src/truefoundry_sdk/types/base_workbench_input.py index 908053bf..550d8ee0 100644 --- a/src/truefoundry_sdk/types/base_workbench_input.py +++ b/src/truefoundry_sdk/types/base_workbench_input.py @@ -20,7 +20,7 @@ class BaseWorkbenchInput(UniversalBaseModel): > Name can only contain alphanumeric characters and '-' and can be atmost 25 characters long """ - home_directory_size: int = pydantic.Field(default=20) + home_directory_size: int = pydantic.Field() """ Size of the home directory for the workbench (Persistent Storage) """ diff --git a/src/truefoundry_sdk/types/baseten_integrations.py b/src/truefoundry_sdk/types/baseten_integrations.py new file mode 100644 index 00000000..a23916ff --- /dev/null +++ b/src/truefoundry_sdk/types/baseten_integrations.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .baseten_model import BasetenModel + +BasetenIntegrations = BasetenModel diff --git a/src/truefoundry_sdk/types/baseten_key_auth.py b/src/truefoundry_sdk/types/baseten_key_auth.py new file mode 100644 index 00000000..c789707c --- /dev/null +++ b/src/truefoundry_sdk/types/baseten_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 BasetenKeyAuth(UniversalBaseModel): + """ + Authentication method using Baseten API key + """ + + type: typing.Literal["api-key"] = pydantic.Field(default="api-key") + """ + +value=api-key + """ + + api_key: str = pydantic.Field() + """ + The API key for Baseten authentication + """ + + 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/baseten_model.py b/src/truefoundry_sdk/types/baseten_model.py new file mode 100644 index 00000000..39dc2272 --- /dev/null +++ b/src/truefoundry_sdk/types/baseten_model.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 +from .model_cost_metric import ModelCostMetric +from .model_type import ModelType + + +class BasetenModel(UniversalBaseModel): + """ + Baseten Model + """ + + type: typing.Literal["integration/model/baseten"] = pydantic.Field(default="integration/model/baseten") + """ + +value=integration/model/baseten + """ + + name: str = pydantic.Field() + """ + A descriptive name to identify this model integration in the UI + """ + + model_id: str = pydantic.Field() + """ + The Baseten model identifier. This is the model name from Baseten's model catalog. + """ + + model_types: typing.List[ModelType] = pydantic.Field() + """ + Specify the type of the Baseten model + """ + + 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/baseten_provider_account.py b/src/truefoundry_sdk/types/baseten_provider_account.py new file mode 100644 index 00000000..97a60d02 --- /dev/null +++ b/src/truefoundry_sdk/types/baseten_provider_account.py @@ -0,0 +1,51 @@ +# 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 .baseten_integrations import BasetenIntegrations +from .baseten_key_auth import BasetenKeyAuth +from .collaborator import Collaborator +from .owned_by import OwnedBy + + +class BasetenProviderAccount(UniversalBaseModel): + """ + Baseten + """ + + type: typing.Literal["provider-account/baseten"] = pydantic.Field(default="provider-account/baseten") + """ + +value=provider-account/baseten + """ + + name: str = pydantic.Field() + """ + The name of the Baseten provider 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 + """ + + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) + """ + List of users who have access to this provider account + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/bitbucket_provider_account.py b/src/truefoundry_sdk/types/bitbucket_provider_account.py index 3bf62bc2..cdedf78a 100644 --- a/src/truefoundry_sdk/types/bitbucket_provider_account.py +++ b/src/truefoundry_sdk/types/bitbucket_provider_account.py @@ -30,9 +30,9 @@ class BitbucketProviderAccount(UniversalBaseModel): +uiType=IntegrationsGroup """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/blue_green.py b/src/truefoundry_sdk/types/blue_green.py index 9fc217bb..23e7d6ec 100644 --- a/src/truefoundry_sdk/types/blue_green.py +++ b/src/truefoundry_sdk/types/blue_green.py @@ -17,12 +17,12 @@ class BlueGreen(UniversalBaseModel): +value=blue_green """ - enable_auto_promotion: typing.Optional[bool] = pydantic.Field(default=False) + enable_auto_promotion: typing.Optional[bool] = pydantic.Field(default=None) """ Promote the new release to handle the complete traffic. A manual promotion would be needed if this is disabled """ - auto_promotion_seconds: typing.Optional[int] = pydantic.Field(default=30) + auto_promotion_seconds: typing.Optional[int] = pydantic.Field(default=None) """ Promote the new release to handle the complete traffic after waiting for these many seconds """ diff --git a/src/truefoundry_sdk/types/budget_rule.py b/src/truefoundry_sdk/types/budget_rule.py index 26d37c5b..9ad1e509 100644 --- a/src/truefoundry_sdk/types/budget_rule.py +++ b/src/truefoundry_sdk/types/budget_rule.py @@ -32,7 +32,7 @@ class BudgetRule(UniversalBaseModel): """ alerts: typing.Optional[BudgetAlert] = None - audit_mode: typing.Optional[bool] = pydantic.Field(default=False) + audit_mode: typing.Optional[bool] = pydantic.Field(default=None) """ When enabled, requests exceeding the budget are tracked but not blocked """ diff --git a/src/truefoundry_sdk/types/cartesia_provider_account.py b/src/truefoundry_sdk/types/cartesia_provider_account.py index f81e62c7..d7cd509a 100644 --- a/src/truefoundry_sdk/types/cartesia_provider_account.py +++ b/src/truefoundry_sdk/types/cartesia_provider_account.py @@ -49,9 +49,9 @@ class CartesiaProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/cedar_guardrail_config.py b/src/truefoundry_sdk/types/cedar_guardrail_config.py index e4816096..429afd2b 100644 --- a/src/truefoundry_sdk/types/cedar_guardrail_config.py +++ b/src/truefoundry_sdk/types/cedar_guardrail_config.py @@ -18,9 +18,7 @@ class CedarGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Enforces access control policies using Cedar policy language" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/cerebras_provider_account.py b/src/truefoundry_sdk/types/cerebras_provider_account.py index abae3cd9..4a89401d 100644 --- a/src/truefoundry_sdk/types/cerebras_provider_account.py +++ b/src/truefoundry_sdk/types/cerebras_provider_account.py @@ -38,9 +38,9 @@ class CerebrasProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/chat_prompt_manifest.py b/src/truefoundry_sdk/types/chat_prompt_manifest.py index f2e02d21..a4190516 100644 --- a/src/truefoundry_sdk/types/chat_prompt_manifest.py +++ b/src/truefoundry_sdk/types/chat_prompt_manifest.py @@ -24,23 +24,17 @@ class ChatPromptManifest(UniversalBaseModel): name: str = pydantic.Field() """ - Name of the entity + Name of the prompt (alphanumeric characters, hyphens, and underscores only, max 256 characters) """ - description: typing.Optional[str] = None metadata: typing.Dict[str, typing.Any] = pydantic.Field() """ Key value metadata. Should be valid JSON. For e.g. `{"business-unit": "sales", "quality": "good", "rating": 4.5}` """ - version_alias: typing.Optional[str] = pydantic.Field(default=None) - """ - Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) - """ - ml_repo: str = pydantic.Field() """ - Name of the ML Repo + Name of the ML Repo that this prompt belongs to (must start and end with alphanumeric, 2-100 characters) """ version: typing.Optional[int] = pydantic.Field(default=None) @@ -49,6 +43,12 @@ class ChatPromptManifest(UniversalBaseModel): """ type: typing.Literal["chat_prompt"] = "chat_prompt" + description: typing.Optional[str] = None + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) + """ + messages: typing.List[ChatPromptManifestMessagesItem] = pydantic.Field() """ List of messages in the chat conversation, must be non-empty diff --git a/src/truefoundry_sdk/types/cloudera_provider_account.py b/src/truefoundry_sdk/types/cloudera_provider_account.py index 740b53b8..b5eab788 100644 --- a/src/truefoundry_sdk/types/cloudera_provider_account.py +++ b/src/truefoundry_sdk/types/cloudera_provider_account.py @@ -42,9 +42,9 @@ class ClouderaProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/cluster.py b/src/truefoundry_sdk/types/cluster.py index 82045743..b7e850b6 100644 --- a/src/truefoundry_sdk/types/cluster.py +++ b/src/truefoundry_sdk/types/cluster.py @@ -15,22 +15,20 @@ class Cluster(UniversalBaseModel): id: str fqn: str manifest: ClusterManifest - 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") + 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")] created_by_subject: typing_extensions.Annotated[ - typing.Optional[Subject], FieldMetadata(alias="createdBySubject") - ] = pydantic.Field(alias="createdBySubject", default=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" - ) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + 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") + ] + 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 diff --git a/src/truefoundry_sdk/types/cluster_gateway.py b/src/truefoundry_sdk/types/cluster_gateway.py index 34fa6819..355c1d13 100644 --- a/src/truefoundry_sdk/types/cluster_gateway.py +++ b/src/truefoundry_sdk/types/cluster_gateway.py @@ -12,13 +12,11 @@ class ClusterGateway(UniversalBaseModel): uid: typing.Optional[str] = None name: str hosts: typing.List[str] - is_tie_breaker: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isTieBreaker")] = ( - pydantic.Field(alias="isTieBreaker", default=None) - ) - """ - Used when there are 2 gateways with same host - """ - + is_tie_breaker: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="isTieBreaker"), + pydantic.Field(alias="isTieBreaker", description="Used when there are 2 gateways with same host"), + ] = None selector: typing.Dict[str, str] if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/cluster_manifest.py b/src/truefoundry_sdk/types/cluster_manifest.py index b85d96db..d396ed85 100644 --- a/src/truefoundry_sdk/types/cluster_manifest.py +++ b/src/truefoundry_sdk/types/cluster_manifest.py @@ -89,9 +89,9 @@ class ClusterManifest(UniversalBaseModel): Collaborators who can access this cluster """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/code_safety_linter_guardrail_config.py b/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py index de72cce1..d95126c4 100644 --- a/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py +++ b/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py @@ -17,9 +17,7 @@ class CodeSafetyLinterGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Detects unsafe code patterns in tool outputs (eval, exec, os.system, subprocess, rm -rf)" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/cohere_provider_account.py b/src/truefoundry_sdk/types/cohere_provider_account.py index fd51ceb8..947c9e0f 100644 --- a/src/truefoundry_sdk/types/cohere_provider_account.py +++ b/src/truefoundry_sdk/types/cohere_provider_account.py @@ -38,9 +38,9 @@ class CohereProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/common_tools_settings.py b/src/truefoundry_sdk/types/common_tools_settings.py index a9810265..e1845171 100644 --- a/src/truefoundry_sdk/types/common_tools_settings.py +++ b/src/truefoundry_sdk/types/common_tools_settings.py @@ -16,31 +16,31 @@ class CommonToolsSettings(UniversalBaseModel): +value=settings/common-tools """ - web_search: bool = pydantic.Field(default=True) + web_search: bool = pydantic.Field() """ Enable web search tool Allows model to search the web for information. """ - code_executor: bool = pydantic.Field(default=True) + code_executor: bool = pydantic.Field() """ Enable code executor tool Allows model to execute code and return the results. """ - sandbox_exec: bool = pydantic.Field(default=True) + sandbox_exec: bool = pydantic.Field() """ Enable sandbox executor tool Allows model to execute shell command in an isolated stateful sandbox environment. """ - sequential_thinking: bool = pydantic.Field(default=True) + sequential_thinking: bool = pydantic.Field() """ Enable sequential thinking tool Allows model to reason step-by-step to solve complex problems. """ - web_scrape: bool = pydantic.Field(default=True) + web_scrape: bool = pydantic.Field() """ Enable web scraping tool. Allows model to scrape content from web pages with intelligent format selection for structured or unstructured data. diff --git a/src/truefoundry_sdk/internal/docker_registries/types/docker_registries_create_repository_response.py b/src/truefoundry_sdk/types/create_docker_repository_response.py similarity index 50% rename from src/truefoundry_sdk/internal/docker_registries/types/docker_registries_create_repository_response.py rename to src/truefoundry_sdk/types/create_docker_repository_response.py index 68e866dc..7cbe2b32 100644 --- a/src/truefoundry_sdk/internal/docker_registries/types/docker_registries_create_repository_response.py +++ b/src/truefoundry_sdk/types/create_docker_repository_response.py @@ -4,14 +4,16 @@ import pydantic import typing_extensions -from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from ....core.serialization import FieldMetadata +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ..core.serialization import FieldMetadata -class DockerRegistriesCreateRepositoryResponse(UniversalBaseModel): - repo_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="repoName")] = pydantic.Field( - alias="repoName", default=None - ) +class CreateDockerRepositoryResponse(UniversalBaseModel): + repo_name: typing_extensions.Annotated[ + str, + FieldMetadata(alias="repoName"), + pydantic.Field(alias="repoName", description="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/create_multi_part_upload_request.py b/src/truefoundry_sdk/types/create_multi_part_upload_request.py index d82746fb..d9f227a2 100644 --- a/src/truefoundry_sdk/types/create_multi_part_upload_request.py +++ b/src/truefoundry_sdk/types/create_multi_part_upload_request.py @@ -7,9 +7,20 @@ class CreateMultiPartUploadRequest(UniversalBaseModel): - id: str - path: str - num_parts: int + id: str = pydantic.Field() + """ + ID of the artifact version to upload files to + """ + + path: str = pydantic.Field() + """ + Relative path within the artifact version where the file should be uploaded + """ + + num_parts: int = pydantic.Field() + """ + Number of parts to split the upload into for multipart upload + """ 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/cron_metric.py b/src/truefoundry_sdk/types/cron_metric.py index f342d102..86d361c4 100644 --- a/src/truefoundry_sdk/types/cron_metric.py +++ b/src/truefoundry_sdk/types/cron_metric.py @@ -45,7 +45,7 @@ class CronMetric(UniversalBaseModel): ``` """ - timezone: str = pydantic.Field(default="UTC") + timezone: str = pydantic.Field() """ Timezone against which the cron schedule will be calculated, e.g. "Asia/Tokyo". Default is machine's local time. https://docs.truefoundry.com/docs/list-of-supported-timezones diff --git a/src/truefoundry_sdk/types/custom_agent_server_auth.py b/src/truefoundry_sdk/types/custom_agent_server_auth.py new file mode 100644 index 00000000..fd3dfcba --- /dev/null +++ b/src/truefoundry_sdk/types/custom_agent_server_auth.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .custom_server_header_auth import CustomServerHeaderAuth +from .custom_server_passthrough import CustomServerPassthrough + +CustomAgentServerAuth = typing.Union[CustomServerHeaderAuth, CustomServerPassthrough] diff --git a/src/truefoundry_sdk/types/custom_framework.py b/src/truefoundry_sdk/types/custom_framework.py new file mode 100644 index 00000000..939cc1d1 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_framework.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 CustomFramework(UniversalBaseModel): + """ + Custom + """ + + type: typing.Literal["custom"] = pydantic.Field(default="custom") + """ + 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/custom_guardrail_config.py b/src/truefoundry_sdk/types/custom_guardrail_config.py index 652d0b05..9d85b93f 100644 --- a/src/truefoundry_sdk/types/custom_guardrail_config.py +++ b/src/truefoundry_sdk/types/custom_guardrail_config.py @@ -21,9 +21,7 @@ class CustomGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Custom guardrail server for validate or mutate via HTTP endpoint" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -47,7 +45,7 @@ class CustomGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/custom_header_auth.py b/src/truefoundry_sdk/types/custom_header_auth.py new file mode 100644 index 00000000..53cbcb00 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_header_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 CustomHeaderAuth(UniversalBaseModel): + """ + Static API key or token authentication via request headers. All users share the same credentials. + """ + + type: typing.Literal["header"] = pydantic.Field(default="header") + """ + +value=header + """ + + headers: typing.Dict[str, str] = pydantic.Field() + """ + Headers passed to the generic secret server with every request. + """ + + 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_integrations.py b/src/truefoundry_sdk/types/custom_integrations.py index d3afe875..63a35ed4 100644 --- a/src/truefoundry_sdk/types/custom_integrations.py +++ b/src/truefoundry_sdk/types/custom_integrations.py @@ -7,6 +7,7 @@ from .custom_jwt_auth_integration import CustomJwtAuthIntegration from .custom_username_password_artifacts_registry import CustomUsernamePasswordArtifactsRegistry from .email_notification_channel import EmailNotificationChannel +from .generic_secret_store_integration import GenericSecretStoreIntegration CustomIntegrations = typing.Union[ CustomUsernamePasswordArtifactsRegistry, @@ -14,4 +15,5 @@ CustomHelmRepo, CustomBlobStorage, CustomJwtAuthIntegration, + GenericSecretStoreIntegration, ] diff --git a/src/truefoundry_sdk/types/custom_provider_account.py b/src/truefoundry_sdk/types/custom_provider_account.py index 70c8f882..5b27d859 100644 --- a/src/truefoundry_sdk/types/custom_provider_account.py +++ b/src/truefoundry_sdk/types/custom_provider_account.py @@ -32,9 +32,9 @@ class CustomProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/custom_regex_pattern.py b/src/truefoundry_sdk/types/custom_regex_pattern.py index 2670d73a..dd42d4dc 100644 --- a/src/truefoundry_sdk/types/custom_regex_pattern.py +++ b/src/truefoundry_sdk/types/custom_regex_pattern.py @@ -16,7 +16,7 @@ class CustomRegexPattern(UniversalBaseModel): A custom regex pattern to match against content (e.g., "\\\\b\\\\d{3}-\\\\d{2}-\\\\d{4}\\\\b" for SSN) """ - redaction_text: typing.Optional[str] = pydantic.Field(default="[REDACTED]") + redaction_text: typing.Optional[str] = pydantic.Field(default=None) """ Text to use when redacting matched content (only applicable in mutate mode). Defaults to '[REDACTED]'. """ diff --git a/src/truefoundry_sdk/types/custom_server_header_auth.py b/src/truefoundry_sdk/types/custom_server_header_auth.py new file mode 100644 index 00000000..1a17e868 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_header_auth.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 + + +class CustomServerHeaderAuth(UniversalBaseModel): + """ + Static API key or token authentication via request headers. + """ + + type: typing.Literal["header"] = pydantic.Field(default="header") + """ + +value=header + """ + + headers: typing.Dict[str, 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/custom_server_passthrough.py b/src/truefoundry_sdk/types/custom_server_passthrough.py new file mode 100644 index 00000000..60c795a2 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_server_passthrough.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 CustomServerPassthrough(UniversalBaseModel): + """ + Authenticate using your existing TrueFoundry account (PAT or Virtual Accounts). Your credentials are automatically passed to the server. + """ + + type: typing.Literal["passthrough"] = pydantic.Field(default="passthrough") + """ + +value=passthrough + """ + + 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_tls_settings.py b/src/truefoundry_sdk/types/custom_tls_settings.py index e62aa26e..8b5229a5 100644 --- a/src/truefoundry_sdk/types/custom_tls_settings.py +++ b/src/truefoundry_sdk/types/custom_tls_settings.py @@ -11,7 +11,7 @@ class CustomTlsSettings(UniversalBaseModel): Configure TLS settings for secure connections with custom CA certificates. """ - reject_unauthorized: bool = pydantic.Field(default=True) + reject_unauthorized: bool = pydantic.Field() """ When set to true, it will reject any connection which is not authorized with the list of supplied CAs. """ diff --git a/src/truefoundry_sdk/types/data_access_rule_base.py b/src/truefoundry_sdk/types/data_access_rule_base.py index ff01e08b..e0d68429 100644 --- a/src/truefoundry_sdk/types/data_access_rule_base.py +++ b/src/truefoundry_sdk/types/data_access_rule_base.py @@ -22,7 +22,7 @@ class DataAccessRuleBase(UniversalBaseModel): Description of the rule """ - enabled: typing.Optional[bool] = pydantic.Field(default=True) + enabled: typing.Optional[bool] = pydantic.Field(default=None) """ Whether this rule is enabled """ diff --git a/src/truefoundry_sdk/types/data_directory.py b/src/truefoundry_sdk/types/data_directory.py index f9d2d4c8..e2094d64 100644 --- a/src/truefoundry_sdk/types/data_directory.py +++ b/src/truefoundry_sdk/types/data_directory.py @@ -10,15 +10,50 @@ class DataDirectory(UniversalBaseModel): - id: str - ml_repo_id: str - name: str - fqn: str - created_by_subject: Subject - created_at: dt.datetime - updated_at: dt.datetime - manifest: DataDirectoryManifest - usage_code_snippet: typing.Optional[str] = None + id: str = pydantic.Field() + """ + Unique identifier for the data directory + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this data directory belongs to + """ + + name: str = pydantic.Field() + """ + Name of the data directory + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the data directory + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this data directory + """ + + created_at: dt.datetime = pydantic.Field() + """ + Timestamp when the data directory was created + """ + + updated_at: dt.datetime = pydantic.Field() + """ + Timestamp when the data directory was last updated + """ + + manifest: DataDirectoryManifest = pydantic.Field() + """ + Manifest containing metadata for the data directory + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this data directory + """ 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/databricks_job_task_config.py b/src/truefoundry_sdk/types/databricks_job_task_config.py new file mode 100644 index 00000000..020ba5ed --- /dev/null +++ b/src/truefoundry_sdk/types/databricks_job_task_config.py @@ -0,0 +1,69 @@ +# 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 .databricks_job_task_config_image import DatabricksJobTaskConfigImage +from .resources import Resources + + +class DatabricksJobTaskConfig(UniversalBaseModel): + """ + Task that triggers a Databricks job via API and polls until completion. Uses image and optional resources; no env or mounts. Execution is handled by the CLI (trigger + poll). + """ + + type: typing.Literal["databricks-job-task-config"] = pydantic.Field(default="databricks-job-task-config") + """ + +value=databricks-job-task-config + """ + + image: DatabricksJobTaskConfigImage = pydantic.Field() + """ + Specify the image spec for the task + """ + + workspace_host: str = pydantic.Field() + """ + Databricks workspace URL, e.g. https://.cloud.databricks.com + """ + + job_id: str = pydantic.Field() + """ + The Databricks job ID to run (from Databricks workspace Jobs). + """ + + service_account: typing.Optional[str] = pydantic.Field(default=None) + """ + Service Account + """ + + job_parameters: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) + """ + Optional parameters to pass to the job run (e.g. notebook params, jar params). + """ + + timeout_seconds: typing.Optional[float] = pydantic.Field(default=None) + """ + Maximum seconds to wait for the job run to complete. Used by CLI when polling. + """ + + skip_wait_for_completion: typing.Optional[bool] = pydantic.Field(default=None) + """ + If false, the task waits for the Databricks job run to complete (trigger and poll). If true, only triggers the job and returns. Default false. + """ + + env: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) + """ + Configure environment variables to be injected in the task either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables) + """ + + resources: typing.Optional[Resources] = 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/databricks_job_task_config_image.py b/src/truefoundry_sdk/types/databricks_job_task_config_image.py new file mode 100644 index 00000000..f232b8cd --- /dev/null +++ b/src/truefoundry_sdk/types/databricks_job_task_config_image.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .task_docker_file_build import TaskDockerFileBuild +from .task_python_build import TaskPythonBuild + +DatabricksJobTaskConfigImage = typing.Union[TaskPythonBuild, TaskDockerFileBuild] diff --git a/src/truefoundry_sdk/types/databricks_provider_account.py b/src/truefoundry_sdk/types/databricks_provider_account.py index 39360106..5923c6c8 100644 --- a/src/truefoundry_sdk/types/databricks_provider_account.py +++ b/src/truefoundry_sdk/types/databricks_provider_account.py @@ -47,9 +47,9 @@ class DatabricksProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/deepgram_provider_account.py b/src/truefoundry_sdk/types/deepgram_provider_account.py index f3217b41..13105341 100644 --- a/src/truefoundry_sdk/types/deepgram_provider_account.py +++ b/src/truefoundry_sdk/types/deepgram_provider_account.py @@ -43,9 +43,9 @@ class DeepgramProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/deepinfra_provider_account.py b/src/truefoundry_sdk/types/deepinfra_provider_account.py index 6d072006..cf4ffb6d 100644 --- a/src/truefoundry_sdk/types/deepinfra_provider_account.py +++ b/src/truefoundry_sdk/types/deepinfra_provider_account.py @@ -38,9 +38,9 @@ class DeepinfraProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/deployment.py b/src/truefoundry_sdk/types/deployment.py index 15d20522..3b606e85 100644 --- a/src/truefoundry_sdk/types/deployment.py +++ b/src/truefoundry_sdk/types/deployment.py @@ -20,42 +20,44 @@ class Deployment(UniversalBaseModel): id: typing.Optional[str] = None version: typing.Optional[float] = None fqn: typing.Optional[str] = None - application_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="applicationId")] = ( - pydantic.Field(alias="applicationId", default=None) - ) + application_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId") + ] = None manifest: DeploymentManifest application: typing.Optional["Application"] = 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", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=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 deployment_builds: typing_extensions.Annotated[ - typing.Optional[typing.List[BuildInfo]], FieldMetadata(alias="deploymentBuilds") - ] = pydantic.Field(alias="deploymentBuilds", default=None) + typing.Optional[typing.List[BuildInfo]], + FieldMetadata(alias="deploymentBuilds"), + pydantic.Field(alias="deploymentBuilds"), + ] = None deployment_statuses: typing_extensions.Annotated[ - typing.Optional[typing.List[DeploymentStatus]], FieldMetadata(alias="deploymentStatuses") - ] = pydantic.Field(alias="deploymentStatuses", default=None) - current_status_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="currentStatusId")] = ( - pydantic.Field(alias="currentStatusId", default=None) - ) + typing.Optional[typing.List[DeploymentStatus]], + FieldMetadata(alias="deploymentStatuses"), + pydantic.Field(alias="deploymentStatuses"), + ] = None + current_status_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="currentStatusId"), pydantic.Field(alias="currentStatusId") + ] = None current_status: typing_extensions.Annotated[ - typing.Optional[DeploymentStatus], FieldMetadata(alias="currentStatus") - ] = pydantic.Field(alias="currentStatus", default=None) + typing.Optional[DeploymentStatus], FieldMetadata(alias="currentStatus"), pydantic.Field(alias="currentStatus") + ] = None applied_recommendations: typing_extensions.Annotated[ - typing.Optional[typing.List[Recommendation]], FieldMetadata(alias="appliedRecommendations") - ] = pydantic.Field(alias="appliedRecommendations", default=None) - """ - Applied recommendations for this deployment - """ - - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + typing.Optional[typing.List[Recommendation]], + FieldMetadata(alias="appliedRecommendations"), + pydantic.Field(alias="appliedRecommendations", description="Applied recommendations for this deployment"), + ] = 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 @@ -67,6 +69,5 @@ class Config: from .application import Application # noqa: E402, I001 -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 -update_forward_refs(Deployment, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo) +update_forward_refs(Deployment, Application=Application) diff --git a/src/truefoundry_sdk/types/deployment_build.py b/src/truefoundry_sdk/types/deployment_build.py index 8ee5600a..629b8486 100644 --- a/src/truefoundry_sdk/types/deployment_build.py +++ b/src/truefoundry_sdk/types/deployment_build.py @@ -13,37 +13,37 @@ class DeploymentBuild(UniversalBaseModel): id: typing.Optional[str] = None - deployment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="deploymentId")] = ( - pydantic.Field(alias="deploymentId", default=None) - ) - component_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="componentName")] = ( - pydantic.Field(alias="componentName", default=None) - ) + deployment_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="deploymentId"), pydantic.Field(alias="deploymentId") + ] = None + component_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="componentName"), pydantic.Field(alias="componentName") + ] = None build: typing.Optional[BuildInfo] = None - build_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="buildId")] = pydantic.Field( - alias="buildId", default=None - ) - image_uri: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="imageUri")] = pydantic.Field( - alias="imageUri", default=None - ) + build_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="buildId"), pydantic.Field(alias="buildId") + ] = None + image_uri: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="imageUri"), pydantic.Field(alias="imageUri") + ] = None name: typing.Optional[str] = None status: typing.Optional[BuildStatus] = None - get_logs_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="getLogsUrl")] = pydantic.Field( - alias="getLogsUrl", default=None - ) - tail_logs_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="tailLogsUrl")] = ( - pydantic.Field(alias="tailLogsUrl", default=None) - ) - logs_start_ts: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="logsStartTs")] = ( - pydantic.Field(alias="logsStartTs", default=None) - ) + get_logs_url: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="getLogsUrl"), pydantic.Field(alias="getLogsUrl") + ] = None + tail_logs_url: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="tailLogsUrl"), pydantic.Field(alias="tailLogsUrl") + ] = None + logs_start_ts: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="logsStartTs"), pydantic.Field(alias="logsStartTs") + ] = None metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=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 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_status.py b/src/truefoundry_sdk/types/deployment_status.py index c06fe004..27191c35 100644 --- a/src/truefoundry_sdk/types/deployment_status.py +++ b/src/truefoundry_sdk/types/deployment_status.py @@ -13,22 +13,22 @@ class DeploymentStatus(UniversalBaseModel): id: typing.Optional[str] = None - deployment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="deploymentId")] = ( - pydantic.Field(alias="deploymentId", default=None) - ) + deployment_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="deploymentId"), pydantic.Field(alias="deploymentId") + ] = None status: typing.Optional[DeploymentStatusValue] = None state: typing.Optional[typing.Dict[str, typing.Any]] = None transition: typing.Optional[DeploymentTransition] = None message: typing.Optional[str] = None - retry_count: typing_extensions.Annotated[typing.Optional[float], FieldMetadata(alias="retryCount")] = ( - pydantic.Field(alias="retryCount", default=None) - ) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) + retry_count: typing_extensions.Annotated[ + typing.Optional[float], FieldMetadata(alias="retryCount"), pydantic.Field(alias="retryCount") + ] = 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 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/docker_file_build.py b/src/truefoundry_sdk/types/docker_file_build.py index d4de4824..3a7192e3 100644 --- a/src/truefoundry_sdk/types/docker_file_build.py +++ b/src/truefoundry_sdk/types/docker_file_build.py @@ -18,12 +18,12 @@ class DockerFileBuild(UniversalBaseModel): +value=dockerfile """ - dockerfile_path: str = pydantic.Field(default="./Dockerfile") + dockerfile_path: str = pydantic.Field() """ The file path of the Dockerfile relative to project root path. """ - build_context_path: str = pydantic.Field(default="./") + build_context_path: str = pydantic.Field() """ Build context path for the Dockerfile relative to project root path. """ diff --git a/src/truefoundry_sdk/types/dockerhub_provider_account.py b/src/truefoundry_sdk/types/dockerhub_provider_account.py index ee292391..ae4be579 100644 --- a/src/truefoundry_sdk/types/dockerhub_provider_account.py +++ b/src/truefoundry_sdk/types/dockerhub_provider_account.py @@ -37,9 +37,9 @@ class DockerhubProviderAccount(UniversalBaseModel): +uiType=IntegrationsGroup """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/eleven_labs_provider_account.py b/src/truefoundry_sdk/types/eleven_labs_provider_account.py index 86d11667..677492d0 100644 --- a/src/truefoundry_sdk/types/eleven_labs_provider_account.py +++ b/src/truefoundry_sdk/types/eleven_labs_provider_account.py @@ -43,9 +43,9 @@ class ElevenLabsProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/enkrypt_ai_guardrail_config.py b/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py index c68bc092..2cee7ec3 100644 --- a/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py +++ b/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py @@ -20,9 +20,7 @@ class EnkryptAiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Enkrypt AI guardrails for content safety and policy enforcement" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -42,7 +40,7 @@ class EnkryptAiGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/environment.py b/src/truefoundry_sdk/types/environment.py index 5dc16a84..38623630 100644 --- a/src/truefoundry_sdk/types/environment.py +++ b/src/truefoundry_sdk/types/environment.py @@ -16,22 +16,20 @@ class Environment(UniversalBaseModel): id: typing.Optional[str] = None priority: float color: EnvironmentColor - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - is_production: typing_extensions.Annotated[bool, FieldMetadata(alias="isProduction")] = pydantic.Field( - alias="isProduction" - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + is_production: typing_extensions.Annotated[ + bool, FieldMetadata(alias="isProduction"), pydantic.Field(alias="isProduction") + ] optimize_for: typing_extensions.Annotated[ - typing.Optional[EnvironmentOptimizeFor], FieldMetadata(alias="optimizeFor") - ] = pydantic.Field(alias="optimizeFor", default=None) + typing.Optional[EnvironmentOptimizeFor], FieldMetadata(alias="optimizeFor"), pydantic.Field(alias="optimizeFor") + ] = None manifest: EnvironmentManifest - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=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 diff --git a/src/truefoundry_sdk/types/environment_color.py b/src/truefoundry_sdk/types/environment_color.py index 04de9f59..d453ddc0 100644 --- a/src/truefoundry_sdk/types/environment_color.py +++ b/src/truefoundry_sdk/types/environment_color.py @@ -9,16 +9,16 @@ class EnvironmentColor(UniversalBaseModel): - color_hex: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="colorHex")] = pydantic.Field( - alias="colorHex", default=None - ) + color_hex: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="colorHex"), pydantic.Field(alias="colorHex") + ] = None background_color_hex: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="backgroundColorHex") - ] = pydantic.Field(alias="backgroundColorHex", default=None) + typing.Optional[str], FieldMetadata(alias="backgroundColorHex"), pydantic.Field(alias="backgroundColorHex") + ] = None color: typing.Optional[str] = None - background_color: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="backgroundColor")] = ( - pydantic.Field(alias="backgroundColor", default=None) - ) + background_color: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="backgroundColor"), pydantic.Field(alias="backgroundColor") + ] = 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/environment_manifest.py b/src/truefoundry_sdk/types/environment_manifest.py index 29965c62..583795ea 100644 --- a/src/truefoundry_sdk/types/environment_manifest.py +++ b/src/truefoundry_sdk/types/environment_manifest.py @@ -22,16 +22,16 @@ class EnvironmentManifest(UniversalBaseModel): """ color: EnvironmentColor - is_production: typing_extensions.Annotated[bool, FieldMetadata(alias="isProduction")] = pydantic.Field( - alias="isProduction" - ) - """ - Environment Type - Indicates if the environment is for production use - """ - - optimize_for: typing_extensions.Annotated[EnvironmentOptimizeFor, FieldMetadata(alias="optimizeFor")] = ( - pydantic.Field(alias="optimizeFor") - ) + is_production: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="isProduction"), + pydantic.Field( + alias="isProduction", description="Environment Type - Indicates if the environment is for production use" + ), + ] + optimize_for: typing_extensions.Annotated[ + EnvironmentOptimizeFor, FieldMetadata(alias="optimizeFor"), pydantic.Field(alias="optimizeFor") + ] 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/event.py b/src/truefoundry_sdk/types/event.py index 675ae1a0..48e54e8c 100644 --- a/src/truefoundry_sdk/types/event.py +++ b/src/truefoundry_sdk/types/event.py @@ -16,27 +16,21 @@ class Event(UniversalBaseModel): Name of the event """ - first_timestamp: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="firstTimestamp")] = ( - pydantic.Field(alias="firstTimestamp", default=None) - ) - """ - Timestamp when the event was first observed - """ - - last_timestamp: typing_extensions.Annotated[str, FieldMetadata(alias="lastTimestamp")] = pydantic.Field( - alias="lastTimestamp" - ) - """ - Timestamp when the event was last observed - """ - - involved_object: typing_extensions.Annotated[EventInvolvedObject, FieldMetadata(alias="involvedObject")] = ( - pydantic.Field(alias="involvedObject") - ) - """ - Details of the involved object - """ - + first_timestamp: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="firstTimestamp"), + pydantic.Field(alias="firstTimestamp", description="Timestamp when the event was first observed"), + ] = None + last_timestamp: typing_extensions.Annotated[ + str, + FieldMetadata(alias="lastTimestamp"), + pydantic.Field(alias="lastTimestamp", description="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"), + ] type: str = pydantic.Field() """ Type of the event diff --git a/src/truefoundry_sdk/types/event_involved_object.py b/src/truefoundry_sdk/types/event_involved_object.py index fdf0f1e7..1d56d624 100644 --- a/src/truefoundry_sdk/types/event_involved_object.py +++ b/src/truefoundry_sdk/types/event_involved_object.py @@ -11,13 +11,13 @@ class EventInvolvedObject(UniversalBaseModel): kind: str name: str - api_version: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="apiVersion")] = pydantic.Field( - alias="apiVersion", default=None - ) + api_version: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="apiVersion"), pydantic.Field(alias="apiVersion") + ] = None namespace: typing.Optional[str] = None - container_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="containerName")] = ( - pydantic.Field(alias="containerName", default=None) - ) + container_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="containerName"), pydantic.Field(alias="containerName") + ] = 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/exact_match_cache_config.py b/src/truefoundry_sdk/types/exact_match_cache_config.py index 469459a4..1ef70372 100644 --- a/src/truefoundry_sdk/types/exact_match_cache_config.py +++ b/src/truefoundry_sdk/types/exact_match_cache_config.py @@ -17,7 +17,7 @@ class ExactMatchCacheConfig(UniversalBaseModel): Cache namespace (defaults to 'default' if not provided) """ - ttl: float = pydantic.Field(default=3600.0) + ttl: float = pydantic.Field() """ Time-to-live for cached entries in seconds (max 3 days) """ diff --git a/src/truefoundry_sdk/types/fiddler_guardrail_config.py b/src/truefoundry_sdk/types/fiddler_guardrail_config.py index 8abd8593..b23aa2cb 100644 --- a/src/truefoundry_sdk/types/fiddler_guardrail_config.py +++ b/src/truefoundry_sdk/types/fiddler_guardrail_config.py @@ -19,9 +19,7 @@ class FiddlerGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Fiddler for harmful content detection or response faithfulness checks" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/file_info.py b/src/truefoundry_sdk/types/file_info.py index 50f5e7fe..15b3e3d7 100644 --- a/src/truefoundry_sdk/types/file_info.py +++ b/src/truefoundry_sdk/types/file_info.py @@ -8,11 +8,30 @@ class FileInfo(UniversalBaseModel): - path: str - is_dir: bool - file_size: typing.Optional[int] = None - signed_url: typing.Optional[str] = None - last_modified: typing.Optional[dt.datetime] = None + path: str = pydantic.Field() + """ + Relative path of the file or directory within the artifact version + """ + + is_dir: bool = pydantic.Field() + """ + Whether this path represents a directory (true) or a file (false) + """ + + file_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Size of the file in bytes (only present for files, not directories) + """ + + signed_url: typing.Optional[str] = pydantic.Field(default=None) + """ + Pre-signed URL to download the file directly (only present for files) + """ + + last_modified: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the file was last modified + """ 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/flyte_launch_plan_id.py b/src/truefoundry_sdk/types/flyte_launch_plan_id.py index 45cdd4a5..38c87779 100644 --- a/src/truefoundry_sdk/types/flyte_launch_plan_id.py +++ b/src/truefoundry_sdk/types/flyte_launch_plan_id.py @@ -9,9 +9,9 @@ class FlyteLaunchPlanId(UniversalBaseModel): - resource_type: typing_extensions.Annotated[typing.Literal["LAUNCH_PLAN"], FieldMetadata(alias="resourceType")] = ( - pydantic.Field(alias="resourceType", default="LAUNCH_PLAN") - ) + resource_type: typing_extensions.Annotated[ + typing.Literal["LAUNCH_PLAN"], FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType") + ] = "LAUNCH_PLAN" name: str if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/flyte_launch_plan_spec.py b/src/truefoundry_sdk/types/flyte_launch_plan_spec.py index 0137d92b..4f23fc95 100644 --- a/src/truefoundry_sdk/types/flyte_launch_plan_spec.py +++ b/src/truefoundry_sdk/types/flyte_launch_plan_spec.py @@ -10,9 +10,9 @@ class FlyteLaunchPlanSpec(UniversalBaseModel): - workflow_id: typing_extensions.Annotated[FlyteWorkflowId, FieldMetadata(alias="workflowId")] = pydantic.Field( - alias="workflowId" - ) + workflow_id: typing_extensions.Annotated[ + FlyteWorkflowId, FieldMetadata(alias="workflowId"), pydantic.Field(alias="workflowId") + ] 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/flyte_task_custom_truefoundry.py b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py index 2828febe..c34cdf9e 100644 --- a/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py +++ b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py @@ -3,7 +3,10 @@ import typing from .container_task_config import ContainerTaskConfig +from .databricks_job_task_config import DatabricksJobTaskConfig from .py_spark_task_config import PySparkTaskConfig from .python_task_config import PythonTaskConfig -FlyteTaskCustomTruefoundry = typing.Union[PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig] +FlyteTaskCustomTruefoundry = typing.Union[ + PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig, DatabricksJobTaskConfig +] diff --git a/src/truefoundry_sdk/types/flyte_task_id.py b/src/truefoundry_sdk/types/flyte_task_id.py index 48526eb7..c988df09 100644 --- a/src/truefoundry_sdk/types/flyte_task_id.py +++ b/src/truefoundry_sdk/types/flyte_task_id.py @@ -9,9 +9,9 @@ class FlyteTaskId(UniversalBaseModel): - resource_type: typing_extensions.Annotated[typing.Literal["TASK"], FieldMetadata(alias="resourceType")] = ( - pydantic.Field(alias="resourceType", default="TASK") - ) + resource_type: typing_extensions.Annotated[ + typing.Literal["TASK"], FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType") + ] = "TASK" name: str if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/flyte_workflow_id.py b/src/truefoundry_sdk/types/flyte_workflow_id.py index 73aaeeb5..5590da8c 100644 --- a/src/truefoundry_sdk/types/flyte_workflow_id.py +++ b/src/truefoundry_sdk/types/flyte_workflow_id.py @@ -9,9 +9,9 @@ class FlyteWorkflowId(UniversalBaseModel): - resource_type: typing_extensions.Annotated[typing.Literal["WORKFLOW"], FieldMetadata(alias="resourceType")] = ( - pydantic.Field(alias="resourceType", default="WORKFLOW") - ) + resource_type: typing_extensions.Annotated[ + typing.Literal["WORKFLOW"], FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType") + ] = "WORKFLOW" name: str if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/function_schema.py b/src/truefoundry_sdk/types/function_schema.py index fdc8bb2e..7824d6de 100644 --- a/src/truefoundry_sdk/types/function_schema.py +++ b/src/truefoundry_sdk/types/function_schema.py @@ -26,7 +26,7 @@ class FunctionSchema(UniversalBaseModel): Parameters schema for the function """ - strict: typing.Optional[bool] = pydantic.Field(default=False) + strict: typing.Optional[bool] = pydantic.Field(default=None) """ Indicates if the function should be called strictly """ diff --git a/src/truefoundry_sdk/types/gateway_configuration.py b/src/truefoundry_sdk/types/gateway_configuration.py index c97385e3..524e0480 100644 --- a/src/truefoundry_sdk/types/gateway_configuration.py +++ b/src/truefoundry_sdk/types/gateway_configuration.py @@ -13,20 +13,18 @@ class GatewayConfiguration(UniversalBaseModel): id: typing.Optional[str] = None - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] type: str manifest: types_config_Config - 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", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=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 diff --git a/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py b/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py index 91f1a601..e56eb065 100644 --- a/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py +++ b/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py @@ -18,7 +18,7 @@ class GatewayDataRoutingConfigDestination(GatewayDataRoutingConfigDestinationSto Name for the destination """ - enabled: bool = pydantic.Field(default=True) + enabled: bool = pydantic.Field() """ Whether this destination is enabled """ diff --git a/src/truefoundry_sdk/types/gateway_otel_config.py b/src/truefoundry_sdk/types/gateway_otel_config.py index 34ed263a..3670b08e 100644 --- a/src/truefoundry_sdk/types/gateway_otel_config.py +++ b/src/truefoundry_sdk/types/gateway_otel_config.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .gateway_otel_config_otel_metrics_exporter_config import GatewayOtelConfigOtelMetricsExporterConfig from .gateway_otel_config_otel_traces_exporter_config import GatewayOtelConfigOtelTracesExporterConfig @@ -18,7 +19,14 @@ class GatewayOtelConfig(UniversalBaseModel): default=None ) """ - Set this configuration to export LLM gateway OTEL traces to an external platform. Note that we only export OTEL traces via this configuration, this does not include OTEL metrics. + Set this configuration to export LLM gateway OTEL traces to an external platform. Note that we only export OTEL traces via this configuration. + """ + + otel_metrics_exporter_config: typing.Optional[GatewayOtelConfigOtelMetricsExporterConfig] = pydantic.Field( + default=None + ) + """ + Set this configuration to export LLM gateway OTEL metrics to an external platform. Note that we only export OTEL metrics via this configuration. """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/gateway_otel_config_otel_metrics_exporter_config.py b/src/truefoundry_sdk/types/gateway_otel_config_otel_metrics_exporter_config.py new file mode 100644 index 00000000..76a32ab6 --- /dev/null +++ b/src/truefoundry_sdk/types/gateway_otel_config_otel_metrics_exporter_config.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .otel_metrics_exporter_grpc_config import OtelMetricsExporterGrpcConfig +from .otel_metrics_exporter_http_config import OtelMetricsExporterHttpConfig + +GatewayOtelConfigOtelMetricsExporterConfig = typing.Union[OtelMetricsExporterHttpConfig, OtelMetricsExporterGrpcConfig] diff --git a/src/truefoundry_sdk/types/gateway_otel_config_otel_traces_exporter_config.py b/src/truefoundry_sdk/types/gateway_otel_config_otel_traces_exporter_config.py index b2baf905..e1b95ff4 100644 --- a/src/truefoundry_sdk/types/gateway_otel_config_otel_traces_exporter_config.py +++ b/src/truefoundry_sdk/types/gateway_otel_config_otel_traces_exporter_config.py @@ -2,7 +2,7 @@ import typing -from .otel_exporter_grpc_config import OtelExporterGrpcConfig -from .otel_exporter_http_config import OtelExporterHttpConfig +from .otel_traces_exporter_grpc_config import OtelTracesExporterGrpcConfig +from .otel_traces_exporter_http_config import OtelTracesExporterHttpConfig -GatewayOtelConfigOtelTracesExporterConfig = typing.Union[OtelExporterHttpConfig, OtelExporterGrpcConfig] +GatewayOtelConfigOtelTracesExporterConfig = typing.Union[OtelTracesExporterHttpConfig, OtelTracesExporterGrpcConfig] diff --git a/src/truefoundry_sdk/types/gateway_request_metadata_filter.py b/src/truefoundry_sdk/types/gateway_request_metadata_filter.py index 4d6adbf4..7748bf11 100644 --- a/src/truefoundry_sdk/types/gateway_request_metadata_filter.py +++ b/src/truefoundry_sdk/types/gateway_request_metadata_filter.py @@ -11,9 +11,9 @@ class GatewayRequestMetadataFilter(UniversalBaseModel): - gateway_request_metadata_key: typing_extensions.Annotated[str, FieldMetadata(alias="gatewayRequestMetadataKey")] = ( - pydantic.Field(alias="gatewayRequestMetadataKey") - ) + gateway_request_metadata_key: typing_extensions.Annotated[ + str, FieldMetadata(alias="gatewayRequestMetadataKey"), pydantic.Field(alias="gatewayRequestMetadataKey") + ] operator: GatewayRequestMetadataFilterOperator value: GatewayRequestMetadataFilterValue diff --git a/src/truefoundry_sdk/types/gcp_api_key_auth.py b/src/truefoundry_sdk/types/gcp_api_key_auth.py index 3df7039f..a588d968 100644 --- a/src/truefoundry_sdk/types/gcp_api_key_auth.py +++ b/src/truefoundry_sdk/types/gcp_api_key_auth.py @@ -18,10 +18,11 @@ class GcpApiKeyAuth(UniversalBaseModel): +value=api-key """ - api_key: typing_extensions.Annotated[str, FieldMetadata(alias="apiKey")] = pydantic.Field(alias="apiKey") - """ - The API key for Google Cloud authentication - """ + api_key: typing_extensions.Annotated[ + str, + FieldMetadata(alias="apiKey"), + pydantic.Field(alias="apiKey", description="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/gcp_provider_account.py b/src/truefoundry_sdk/types/gcp_provider_account.py index 4774f6e4..a8f6e840 100644 --- a/src/truefoundry_sdk/types/gcp_provider_account.py +++ b/src/truefoundry_sdk/types/gcp_provider_account.py @@ -37,9 +37,9 @@ class GcpProviderAccount(UniversalBaseModel): List of integrations that are associated with the GCP provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/generic_secret_store_integration.py b/src/truefoundry_sdk/types/generic_secret_store_integration.py new file mode 100644 index 00000000..eef2e916 --- /dev/null +++ b/src/truefoundry_sdk/types/generic_secret_store_integration.py @@ -0,0 +1,44 @@ +# 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_header_auth import CustomHeaderAuth + + +class GenericSecretStoreIntegration(UniversalBaseModel): + """ + Generic Secret Store + """ + + type: typing.Literal["integration/secret-store/custom/generic"] = pydantic.Field( + default="integration/secret-store/custom/generic" + ) + """ + +value=integration/secret-store/custom/generic + """ + + name: str = pydantic.Field() + """ + The name of the integration that will be displayed in the TrueFoundry UI. + """ + + base_url: str = pydantic.Field() + """ + Base URL of the generic secret server. + """ + + auth_data: CustomHeaderAuth + 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/get_agent_skill_response.py b/src/truefoundry_sdk/types/get_agent_skill_response.py new file mode 100644 index 00000000..c0f9150c --- /dev/null +++ b/src/truefoundry_sdk/types/get_agent_skill_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 .agent_skill import AgentSkill + + +class GetAgentSkillResponse(UniversalBaseModel): + data: AgentSkill = pydantic.Field() + """ + The agent skill data + """ + + 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/get_agent_skill_version_response.py b/src/truefoundry_sdk/types/get_agent_skill_version_response.py new file mode 100644 index 00000000..306fabd6 --- /dev/null +++ b/src/truefoundry_sdk/types/get_agent_skill_version_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 .agent_skill_version import AgentSkillVersion + + +class GetAgentSkillVersionResponse(UniversalBaseModel): + data: AgentSkillVersion = pydantic.Field() + """ + The agent skill version data + """ + + 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/get_application_deployment_response.py b/src/truefoundry_sdk/types/get_application_deployment_response.py index bd90c13c..8e20d7b4 100644 --- a/src/truefoundry_sdk/types/get_application_deployment_response.py +++ b/src/truefoundry_sdk/types/get_application_deployment_response.py @@ -24,12 +24,6 @@ class Config: from .application import Application # noqa: E402, I001 -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs( - GetApplicationDeploymentResponse, - Application=Application, - ApplicationDebugInfo=ApplicationDebugInfo, - Deployment=Deployment, -) +update_forward_refs(GetApplicationDeploymentResponse, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/get_application_response.py b/src/truefoundry_sdk/types/get_application_response.py index 0b776fda..e3bfeb41 100644 --- a/src/truefoundry_sdk/types/get_application_response.py +++ b/src/truefoundry_sdk/types/get_application_response.py @@ -24,9 +24,6 @@ class Config: from .application import Application # noqa: E402, I001 -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs( - GetApplicationResponse, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment -) +update_forward_refs(GetApplicationResponse, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/get_artifact_response.py b/src/truefoundry_sdk/types/get_artifact_response.py index 99b4c81a..a398f9fd 100644 --- a/src/truefoundry_sdk/types/get_artifact_response.py +++ b/src/truefoundry_sdk/types/get_artifact_response.py @@ -8,7 +8,10 @@ class GetArtifactResponse(UniversalBaseModel): - data: Artifact + data: Artifact = pydantic.Field() + """ + The artifact data + """ 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_artifact_version_response.py b/src/truefoundry_sdk/types/get_artifact_version_response.py index e75f03e0..81ae4f2d 100644 --- a/src/truefoundry_sdk/types/get_artifact_version_response.py +++ b/src/truefoundry_sdk/types/get_artifact_version_response.py @@ -8,7 +8,10 @@ class GetArtifactVersionResponse(UniversalBaseModel): - data: ArtifactVersion + data: ArtifactVersion = pydantic.Field() + """ + The artifact version data + """ 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 1f1e47b8..4f1d9f0d 100644 --- a/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py +++ b/src/truefoundry_sdk/types/get_authenticated_vcsurl_response.py @@ -9,12 +9,11 @@ class GetAuthenticatedVcsurlResponse(UniversalBaseModel): - authenticated_url: typing_extensions.Annotated[str, FieldMetadata(alias="authenticatedURL")] = pydantic.Field( - alias="authenticatedURL" - ) - """ - Authenticated URL to access the repository - """ + authenticated_url: typing_extensions.Annotated[ + str, + FieldMetadata(alias="authenticatedURL"), + pydantic.Field(alias="authenticatedURL", description="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_data_directory_response.py b/src/truefoundry_sdk/types/get_data_directory_response.py index 83e8b454..d0fd68bd 100644 --- a/src/truefoundry_sdk/types/get_data_directory_response.py +++ b/src/truefoundry_sdk/types/get_data_directory_response.py @@ -8,7 +8,10 @@ class GetDataDirectoryResponse(UniversalBaseModel): - data: DataDirectory + data: DataDirectory = pydantic.Field() + """ + The data directory data + """ 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 new file mode 100644 index 00000000..a1860cb0 --- /dev/null +++ b/src/truefoundry_sdk/types/get_docker_registry_credentials_response.py @@ -0,0 +1,36 @@ +# 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 GetDockerRegistryCredentialsResponse(UniversalBaseModel): + fqn: str = pydantic.Field() + """ + Docker registry FQN + """ + + registry_url: typing_extensions.Annotated[ + str, FieldMetadata(alias="registryUrl"), pydantic.Field(alias="registryUrl", description="Docker registry URL") + ] + username: str = pydantic.Field() + """ + Docker registry username + """ + + password: str = pydantic.Field() + """ + Docker registry password + """ + + 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/get_model_response.py b/src/truefoundry_sdk/types/get_model_response.py index 115585c1..e4a43d80 100644 --- a/src/truefoundry_sdk/types/get_model_response.py +++ b/src/truefoundry_sdk/types/get_model_response.py @@ -8,7 +8,10 @@ class GetModelResponse(UniversalBaseModel): - data: Model + data: Model = pydantic.Field() + """ + The model data + """ 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_model_version_response.py b/src/truefoundry_sdk/types/get_model_version_response.py index a2d5037b..291c5bda 100644 --- a/src/truefoundry_sdk/types/get_model_version_response.py +++ b/src/truefoundry_sdk/types/get_model_version_response.py @@ -8,7 +8,10 @@ class GetModelVersionResponse(UniversalBaseModel): - data: ModelVersion + data: ModelVersion = pydantic.Field() + """ + The model version data + """ 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_prompt_response.py b/src/truefoundry_sdk/types/get_prompt_response.py index 5ed20277..52f8d1bd 100644 --- a/src/truefoundry_sdk/types/get_prompt_response.py +++ b/src/truefoundry_sdk/types/get_prompt_response.py @@ -8,7 +8,10 @@ class GetPromptResponse(UniversalBaseModel): - data: Prompt + data: Prompt = pydantic.Field() + """ + The prompt data + """ 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_prompt_version_response.py b/src/truefoundry_sdk/types/get_prompt_version_response.py index 7bbf08d7..2ceaaa32 100644 --- a/src/truefoundry_sdk/types/get_prompt_version_response.py +++ b/src/truefoundry_sdk/types/get_prompt_version_response.py @@ -8,7 +8,10 @@ class GetPromptVersionResponse(UniversalBaseModel): - data: PromptVersion + data: PromptVersion = pydantic.Field() + """ + The prompt version data + """ 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_signed_ur_ls_request.py b/src/truefoundry_sdk/types/get_signed_ur_ls_request.py index a0735190..be5dbd0e 100644 --- a/src/truefoundry_sdk/types/get_signed_ur_ls_request.py +++ b/src/truefoundry_sdk/types/get_signed_ur_ls_request.py @@ -8,9 +8,20 @@ class GetSignedUrLsRequest(UniversalBaseModel): - id: str - paths: typing.List[str] - operation: Operation + id: str = pydantic.Field() + """ + ID of the artifact version to get signed URLs for + """ + + paths: typing.List[str] = pydantic.Field() + """ + List of relative file paths within the artifact version to get signed URLs for + """ + + operation: Operation = pydantic.Field() + """ + Operation type for the signed URL (e.g., 'READ' or 'WRITE') + """ 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_signed_ur_ls_response.py b/src/truefoundry_sdk/types/get_signed_ur_ls_response.py index 1d9419b1..7451eaae 100644 --- a/src/truefoundry_sdk/types/get_signed_ur_ls_response.py +++ b/src/truefoundry_sdk/types/get_signed_ur_ls_response.py @@ -8,7 +8,10 @@ class GetSignedUrLsResponse(UniversalBaseModel): - data: typing.List[SignedUrl] + data: typing.List[SignedUrl] = pydantic.Field() + """ + List of signed URLs for the requested file paths + """ 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_team_permissions_response.py b/src/truefoundry_sdk/types/get_team_permissions_response.py new file mode 100644 index 00000000..bb2101c1 --- /dev/null +++ b/src/truefoundry_sdk/types/get_team_permissions_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 .subject_permission import SubjectPermission + + +class GetTeamPermissionsResponse(UniversalBaseModel): + data: typing.List[SubjectPermission] = pydantic.Field() + """ + Role bindings for 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/get_user_permissions_response.py b/src/truefoundry_sdk/types/get_user_permissions_response.py new file mode 100644 index 00000000..c7c54d3f --- /dev/null +++ b/src/truefoundry_sdk/types/get_user_permissions_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 .subject_permission import SubjectPermission + + +class GetUserPermissionsResponse(UniversalBaseModel): + data: typing.List[SubjectPermission] = pydantic.Field() + """ + Role bindings for the user (including team-inherited) + """ + + 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/get_user_teams_response.py b/src/truefoundry_sdk/types/get_user_teams_response.py index 7e91370d..c2df74b7 100644 --- a/src/truefoundry_sdk/types/get_user_teams_response.py +++ b/src/truefoundry_sdk/types/get_user_teams_response.py @@ -4,13 +4,13 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .team import Team +from .user_team_info import UserTeamInfo class GetUserTeamsResponse(UniversalBaseModel): - data: typing.List[Team] = pydantic.Field() + data: typing.List[UserTeamInfo] = pydantic.Field() """ - Teams where user is a member + Teams where user is a member, with their role """ if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/github_provider_account.py b/src/truefoundry_sdk/types/github_provider_account.py index 6bf4bef2..0f0bd1db 100644 --- a/src/truefoundry_sdk/types/github_provider_account.py +++ b/src/truefoundry_sdk/types/github_provider_account.py @@ -30,9 +30,9 @@ class GithubProviderAccount(UniversalBaseModel): +uiType=IntegrationsGroup """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/gitlab_provider_account.py b/src/truefoundry_sdk/types/gitlab_provider_account.py index b007da8f..7a895b58 100644 --- a/src/truefoundry_sdk/types/gitlab_provider_account.py +++ b/src/truefoundry_sdk/types/gitlab_provider_account.py @@ -30,9 +30,9 @@ class GitlabProviderAccount(UniversalBaseModel): +uiType=IntegrationsGroup """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/google_gemini_provider_account.py b/src/truefoundry_sdk/types/google_gemini_provider_account.py index 04f99568..c6dab5a5 100644 --- a/src/truefoundry_sdk/types/google_gemini_provider_account.py +++ b/src/truefoundry_sdk/types/google_gemini_provider_account.py @@ -38,9 +38,9 @@ class GoogleGeminiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/google_model_armor_guardrail_config.py b/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py index 55c3ab29..4c396983 100644 --- a/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py +++ b/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py @@ -7,6 +7,7 @@ from .enforcing_strategy import EnforcingStrategy from .google_model_armor_guardrail_config_auth_data import GoogleModelArmorGuardrailConfigAuthData from .google_model_armor_guardrail_config_config import GoogleModelArmorGuardrailConfigConfig +from .google_model_armor_guardrail_config_operation import GoogleModelArmorGuardrailConfigOperation class GoogleModelArmorGuardrailConfig(UniversalBaseModel): @@ -19,9 +20,7 @@ class GoogleModelArmorGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Google Cloud Model Armor for prompt injection, harmful content, PII, and malicious URI detection" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -39,9 +38,14 @@ class GoogleModelArmorGuardrailConfig(UniversalBaseModel): Authentication credentials for Google Cloud Model Armor """ - operation: typing.Literal["validate"] = pydantic.Field(default="validate") + operation: GoogleModelArmorGuardrailConfigOperation = 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. + """ + + priority: typing.Optional[int] = pydantic.Field(default=None) """ - The operation type for this guardrail. Google Model Armor guardrails can only be used for validation. + 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/prompt_foo_guardrail_config_operation.py b/src/truefoundry_sdk/types/google_model_armor_guardrail_config_operation.py similarity index 72% rename from src/truefoundry_sdk/types/prompt_foo_guardrail_config_operation.py rename to src/truefoundry_sdk/types/google_model_armor_guardrail_config_operation.py index c0e48d5c..1ac90017 100644 --- a/src/truefoundry_sdk/types/prompt_foo_guardrail_config_operation.py +++ b/src/truefoundry_sdk/types/google_model_armor_guardrail_config_operation.py @@ -7,20 +7,20 @@ T_Result = typing.TypeVar("T_Result") -class PromptFooGuardrailConfigOperation(enum.StrEnum): +class GoogleModelArmorGuardrailConfigOperation(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. """ VALIDATE = "validate" MUTATE = "mutate" - _UNKNOWN = "__PROMPTFOOGUARDRAILCONFIGOPERATION_UNKNOWN__" + _UNKNOWN = "__GOOGLEMODELARMORGUARDRAILCONFIGOPERATION_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) -> "PromptFooGuardrailConfigOperation": + def _missing_(cls, value: typing.Any) -> "GoogleModelArmorGuardrailConfigOperation": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -31,8 +31,8 @@ def visit( mutate: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is PromptFooGuardrailConfigOperation.VALIDATE: + if self is GoogleModelArmorGuardrailConfigOperation.VALIDATE: return validate() - if self is PromptFooGuardrailConfigOperation.MUTATE: + if self is GoogleModelArmorGuardrailConfigOperation.MUTATE: return mutate() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/google_vertex_provider_account.py b/src/truefoundry_sdk/types/google_vertex_provider_account.py index eecb302f..568e2d83 100644 --- a/src/truefoundry_sdk/types/google_vertex_provider_account.py +++ b/src/truefoundry_sdk/types/google_vertex_provider_account.py @@ -45,9 +45,9 @@ class GoogleVertexProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/graph.py b/src/truefoundry_sdk/types/graph.py index f6f4e0d5..a2dafb01 100644 --- a/src/truefoundry_sdk/types/graph.py +++ b/src/truefoundry_sdk/types/graph.py @@ -25,13 +25,9 @@ class Graph(UniversalBaseModel): Chart name """ - chart_type: typing_extensions.Annotated[GraphChartType, FieldMetadata(alias="chartType")] = pydantic.Field( - alias="chartType" - ) - """ - Chart type - """ - + chart_type: typing_extensions.Annotated[ + GraphChartType, FieldMetadata(alias="chartType"), pydantic.Field(alias="chartType", description="Chart type") + ] params: str = pydantic.Field() """ Chart params diff --git a/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py b/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py index 9232d4e2..e4ee0ca6 100644 --- a/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py +++ b/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py @@ -19,9 +19,7 @@ class GraySwanCygnalGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="GraySwan Cygnal for policy violation and content safety monitoring" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/groq_provider_account.py b/src/truefoundry_sdk/types/groq_provider_account.py index 88c726a4..187262ef 100644 --- a/src/truefoundry_sdk/types/groq_provider_account.py +++ b/src/truefoundry_sdk/types/groq_provider_account.py @@ -38,9 +38,9 @@ class GroqProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/guardrail_config_group.py b/src/truefoundry_sdk/types/guardrail_config_group.py index 0c8083de..1f178721 100644 --- a/src/truefoundry_sdk/types/guardrail_config_group.py +++ b/src/truefoundry_sdk/types/guardrail_config_group.py @@ -39,9 +39,9 @@ class GuardrailConfigGroup(UniversalBaseModel): List of Guardrail Configs, which are part of this Guardrail Config Group. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/guardrail_config_integrations.py b/src/truefoundry_sdk/types/guardrail_config_integrations.py index f85b1f16..ee475406 100644 --- a/src/truefoundry_sdk/types/guardrail_config_integrations.py +++ b/src/truefoundry_sdk/types/guardrail_config_integrations.py @@ -2,6 +2,7 @@ import typing +from .akto_guardrail_config import AktoGuardrailConfig from .aws_bedrock_guardrail_config import AwsBedrockGuardrailConfig from .azure_content_safety_guardrail_config import AzureContentSafetyGuardrailConfig from .azure_pii_guardrail_config import AzurePiiGuardrailConfig @@ -18,13 +19,13 @@ from .palo_alto_prisma_airs_guardrail_config import PaloAltoPrismaAirsGuardrailConfig from .pangea_guardrail_config import PangeaGuardrailConfig from .patronus_guardrail_config import PatronusGuardrailConfig -from .prompt_foo_guardrail_config import PromptFooGuardrailConfig from .regex_guardrail_config import RegexGuardrailConfig from .secret_detection_guardrail_config import SecretDetectionGuardrailConfig from .sql_sanitizer_guardrail_config import SqlSanitizerGuardrailConfig from .tfy_content_moderation_guardrail_config import TfyContentModerationGuardrailConfig from .tfy_pii_guardrail_config import TfyPiiGuardrailConfig from .tfy_prompt_injection_guardrail_config import TfyPromptInjectionGuardrailConfig +from .troj_ai_guardrail_config import TrojAiGuardrailConfig GuardrailConfigIntegrations = typing.Union[ OpenAiModerationsGuardrailConfig, @@ -35,7 +36,6 @@ AzurePromptShieldGuardrailConfig, EnkryptAiGuardrailConfig, PaloAltoPrismaAirsGuardrailConfig, - PromptFooGuardrailConfig, FiddlerGuardrailConfig, PangeaGuardrailConfig, PatronusGuardrailConfig, @@ -50,4 +50,6 @@ OpaGuardrailConfig, GoogleModelArmorGuardrailConfig, GraySwanCygnalGuardrailConfig, + AktoGuardrailConfig, + TrojAiGuardrailConfig, ] diff --git a/src/truefoundry_sdk/types/hashicorp_app_role_auth.py b/src/truefoundry_sdk/types/hashicorp_app_role_auth.py new file mode 100644 index 00000000..1f233987 --- /dev/null +++ b/src/truefoundry_sdk/types/hashicorp_app_role_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 HashicorpAppRoleAuth(UniversalBaseModel): + """ + Role ID and secret ID from your AppRole. Token policies must allow KV v2 data and metadata on this mount for your root path, secret paths, and the connection check. + """ + + type: typing.Literal["approle"] = pydantic.Field(default="approle") + """ + +value=approle + """ + + role_id: str = pydantic.Field() + """ + AppRole role ID for Vault authentication. + """ + + secret_id: str = pydantic.Field() + """ + AppRole secret ID for Vault authentication. + """ + + 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/hashicorp_provider_account.py b/src/truefoundry_sdk/types/hashicorp_provider_account.py index 106495b7..54f3b3ec 100644 --- a/src/truefoundry_sdk/types/hashicorp_provider_account.py +++ b/src/truefoundry_sdk/types/hashicorp_provider_account.py @@ -30,9 +30,9 @@ class HashicorpProviderAccount(UniversalBaseModel): List of integrations that are associated with the HashiCorp Vault provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/hashicorp_token_auth.py b/src/truefoundry_sdk/types/hashicorp_token_auth.py index f225c954..614cae84 100644 --- a/src/truefoundry_sdk/types/hashicorp_token_auth.py +++ b/src/truefoundry_sdk/types/hashicorp_token_auth.py @@ -8,7 +8,7 @@ class HashicorpTokenAuth(UniversalBaseModel): """ - Auth Data + Vault Token Auth """ type: typing.Literal["token"] = pydantic.Field(default="token") diff --git a/src/truefoundry_sdk/types/hashicorp_vault_integration.py b/src/truefoundry_sdk/types/hashicorp_vault_integration.py index 4bb1fb8d..2c895a67 100644 --- a/src/truefoundry_sdk/types/hashicorp_vault_integration.py +++ b/src/truefoundry_sdk/types/hashicorp_vault_integration.py @@ -4,7 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .hashicorp_token_auth import HashicorpTokenAuth +from .hashicorp_vault_integration_auth_data import HashicorpVaultIntegrationAuthData class HashicorpVaultIntegration(UniversalBaseModel): @@ -29,12 +29,17 @@ class HashicorpVaultIntegration(UniversalBaseModel): The URL of the HashiCorp Vault server (e.g., https://vault.example.com:8200). """ - kv_mount_path: typing.Optional[str] = pydantic.Field(default=None) + kv_mount_path: str = pydantic.Field() """ - Mount path of the KV v2 engine vault to use for secrets. The default value is tfy-secrets + Mount path of the KV v2 engine vault to use for secrets. + """ + + root_path: typing.Optional[str] = None + auth_data: HashicorpVaultIntegrationAuthData = pydantic.Field() + """ + Authentication data for the Vault integration. """ - auth_data: HashicorpTokenAuth 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 :. diff --git a/src/truefoundry_sdk/types/hashicorp_vault_integration_auth_data.py b/src/truefoundry_sdk/types/hashicorp_vault_integration_auth_data.py new file mode 100644 index 00000000..770facba --- /dev/null +++ b/src/truefoundry_sdk/types/hashicorp_vault_integration_auth_data.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .hashicorp_app_role_auth import HashicorpAppRoleAuth +from .hashicorp_token_auth import HashicorpTokenAuth + +HashicorpVaultIntegrationAuthData = typing.Union[HashicorpTokenAuth, HashicorpAppRoleAuth] diff --git a/src/truefoundry_sdk/types/header_match.py b/src/truefoundry_sdk/types/header_match.py index 8bcdee22..cdfcce5c 100644 --- a/src/truefoundry_sdk/types/header_match.py +++ b/src/truefoundry_sdk/types/header_match.py @@ -17,7 +17,7 @@ class HeaderMatch(UniversalBaseModel): Header name to match on """ - exact_match: str = pydantic.Field(default="") + exact_match: str = pydantic.Field() """ Header value to match on """ diff --git a/src/truefoundry_sdk/types/headers_override.py b/src/truefoundry_sdk/types/headers_override.py new file mode 100644 index 00000000..63b3f548 --- /dev/null +++ b/src/truefoundry_sdk/types/headers_override.py @@ -0,0 +1,33 @@ +# 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 HeadersOverride(UniversalBaseModel): + """ + Headers Override + """ + + remove: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of headers to remove from upstream request + """ + + set_: typing_extensions.Annotated[ + typing.Optional[typing.Dict[str, str]], + FieldMetadata(alias="set"), + pydantic.Field(alias="set", description="Headers to add or overwrite in upstream request"), + ] = 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/health_probe.py b/src/truefoundry_sdk/types/health_probe.py index aa838560..fd06da28 100644 --- a/src/truefoundry_sdk/types/health_probe.py +++ b/src/truefoundry_sdk/types/health_probe.py @@ -14,27 +14,27 @@ class HealthProbe(UniversalBaseModel): """ config: HttpProbe - initial_delay_seconds: typing.Optional[int] = pydantic.Field(default=0) + initial_delay_seconds: typing.Optional[int] = pydantic.Field(default=None) """ Time to wait after container has started before checking the endpoint """ - period_seconds: typing.Optional[int] = pydantic.Field(default=10) + period_seconds: typing.Optional[int] = pydantic.Field(default=None) """ How often to check the endpoint """ - timeout_seconds: typing.Optional[int] = pydantic.Field(default=1) + timeout_seconds: typing.Optional[int] = pydantic.Field(default=None) """ Time to wait for a response from the endpoint before considering it down """ - success_threshold: typing.Optional[int] = pydantic.Field(default=1) + success_threshold: typing.Optional[int] = pydantic.Field(default=None) """ Number of successful responses from the endpoint before container is considered healthy """ - failure_threshold: typing.Optional[int] = pydantic.Field(default=3) + failure_threshold: typing.Optional[int] = pydantic.Field(default=None) """ Number of consecutive failures before the container is considered down """ diff --git a/src/truefoundry_sdk/types/helm.py b/src/truefoundry_sdk/types/helm.py index b4b11802..ac70553f 100644 --- a/src/truefoundry_sdk/types/helm.py +++ b/src/truefoundry_sdk/types/helm.py @@ -38,8 +38,10 @@ class Helm(UniversalBaseModel): kustomize: typing.Optional[Kustomize] = None ignore_differences: typing_extensions.Annotated[ - typing.Optional[typing.List[typing.Dict[str, typing.Any]]], FieldMetadata(alias="ignoreDifferences") - ] = pydantic.Field(alias="ignoreDifferences", default=None) + typing.Optional[typing.List[typing.Dict[str, typing.Any]]], + FieldMetadata(alias="ignoreDifferences"), + pydantic.Field(alias="ignoreDifferences"), + ] = None workspace_fqn: typing.Optional[str] = pydantic.Field(default=None) """ Fully qualified name of the workspace diff --git a/src/truefoundry_sdk/types/http_error.py b/src/truefoundry_sdk/types/http_error.py index ab62b042..5f9fbe76 100644 --- a/src/truefoundry_sdk/types/http_error.py +++ b/src/truefoundry_sdk/types/http_error.py @@ -10,13 +10,9 @@ class HttpError(UniversalBaseModel): - status_code: typing_extensions.Annotated[int, FieldMetadata(alias="statusCode")] = pydantic.Field( - alias="statusCode" - ) - """ - HTTP Status Code - """ - + status_code: typing_extensions.Annotated[ + int, FieldMetadata(alias="statusCode"), pydantic.Field(alias="statusCode", description="HTTP Status Code") + ] message: str = pydantic.Field() """ Error Message diff --git a/src/truefoundry_sdk/types/http_probe.py b/src/truefoundry_sdk/types/http_probe.py index d81d0a92..d7fbcfbf 100644 --- a/src/truefoundry_sdk/types/http_probe.py +++ b/src/truefoundry_sdk/types/http_probe.py @@ -32,7 +32,7 @@ class HttpProbe(UniversalBaseModel): Host name to connect to, defaults to the pod IP """ - scheme: typing.Optional[str] = pydantic.Field(default="HTTP") + scheme: typing.Optional[str] = pydantic.Field(default=None) """ Scheme to use for connecting to the host """ diff --git a/src/truefoundry_sdk/types/i_change.py b/src/truefoundry_sdk/types/i_change.py index f65921f0..97ec6c12 100644 --- a/src/truefoundry_sdk/types/i_change.py +++ b/src/truefoundry_sdk/types/i_change.py @@ -16,8 +16,8 @@ class IChange(UniversalBaseModel): key: str value: typing.Optional[typing.Dict[str, typing.Any]] = None old_value: typing_extensions.Annotated[ - typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="oldValue") - ] = pydantic.Field(alias="oldValue", default=None) + typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="oldValue"), pydantic.Field(alias="oldValue") + ] = None changes: typing.Optional[typing.List["IChange"]] = None if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/ingress_controller_config.py b/src/truefoundry_sdk/types/ingress_controller_config.py index 92744e6e..1ad2a533 100644 --- a/src/truefoundry_sdk/types/ingress_controller_config.py +++ b/src/truefoundry_sdk/types/ingress_controller_config.py @@ -7,12 +7,12 @@ class IngressControllerConfig(UniversalBaseModel): - ingress_class_name: str = pydantic.Field(default="nginx") + ingress_class_name: str = pydantic.Field() """ Ingress Class Name """ - tls_enabled: typing.Optional[bool] = pydantic.Field(default=False) + tls_enabled: typing.Optional[bool] = pydantic.Field(default=None) """ Whether TLS is managed by the ingress controller. If enabled, the ingress object will have TLS configuration. """ diff --git a/src/truefoundry_sdk/types/internal_artifact_version.py b/src/truefoundry_sdk/types/internal_artifact_version.py index 4770e41d..2d1dd46f 100644 --- a/src/truefoundry_sdk/types/internal_artifact_version.py +++ b/src/truefoundry_sdk/types/internal_artifact_version.py @@ -10,18 +10,74 @@ class InternalArtifactVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - manifest: ArtifactManifest - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None - artifact_id: str - artifact_fqn: str - artifact_size: typing.Optional[int] = None + """ + Tags, optional version alias, and SDK usage snippet (models, prompts, generic artifacts). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: ArtifactManifest = pydantic.Field() + """ + Manifest containing metadata for a generic artifact version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of tags associated with this artifact version for filtering and organization + """ + + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional human-readable version alias (e.g. v1.0.0) + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this artifact version + """ + + artifact_id: str = pydantic.Field() + """ + ID of the parent artifact that this version belongs to + """ + + artifact_fqn: str = pydantic.Field() + """ + Fully qualified name of the parent artifact (internal use only) + """ + + artifact_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Total size of the artifact version in bytes (internal use only) + """ 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/internal_list_artifact_versions_response.py b/src/truefoundry_sdk/types/internal_list_artifact_versions_response.py index f0ad0d1a..2fd66186 100644 --- a/src/truefoundry_sdk/types/internal_list_artifact_versions_response.py +++ b/src/truefoundry_sdk/types/internal_list_artifact_versions_response.py @@ -9,8 +9,15 @@ class InternalListArtifactVersionsResponse(UniversalBaseModel): - data: typing.List[InternalListArtifactVersionsResponseDataItem] - pagination: Pagination + data: typing.List[InternalListArtifactVersionsResponseDataItem] = pydantic.Field() + """ + List of artifact versions and model versions with internal metadata + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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/internal_model_version.py b/src/truefoundry_sdk/types/internal_model_version.py index 626a6ddd..7ab3aa51 100644 --- a/src/truefoundry_sdk/types/internal_model_version.py +++ b/src/truefoundry_sdk/types/internal_model_version.py @@ -11,20 +11,84 @@ class InternalModelVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - manifest: ModelManifest - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None - model_id: str - metrics: typing.Optional[typing.List[Metric]] = None - deployable: typing.Optional[bool] = False - artifact_fqn: str - artifact_size: typing.Optional[int] = None + """ + Tags, optional version alias, and SDK usage snippet (models, prompts, generic artifacts). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: ModelManifest = pydantic.Field() + """ + Manifest containing metadata specific to the model version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of tags associated with this artifact version for filtering and organization + """ + + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional human-readable version alias (e.g. v1.0.0) + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this artifact version + """ + + model_id: str = pydantic.Field() + """ + ID of the parent model that this version belongs to + """ + + metrics: typing.Optional[typing.List[Metric]] = pydantic.Field(default=None) + """ + List of metrics associated with this model version + """ + + deployable: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this model version is ready for deployment + """ + + artifact_fqn: str = pydantic.Field() + """ + Fully qualified name of the parent model (internal use only) + """ + + artifact_size: typing.Optional[int] = pydantic.Field(default=None) + """ + Total size of the model version in bytes (internal use only) + """ 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/is_cluster_connected_response.py b/src/truefoundry_sdk/types/is_cluster_connected_response.py index 965b09bc..00caba99 100644 --- a/src/truefoundry_sdk/types/is_cluster_connected_response.py +++ b/src/truefoundry_sdk/types/is_cluster_connected_response.py @@ -9,12 +9,11 @@ class IsClusterConnectedResponse(UniversalBaseModel): - is_connected: typing_extensions.Annotated[bool, FieldMetadata(alias="isConnected")] = pydantic.Field( - alias="isConnected" - ) - """ - Whether the cluster is connected - """ + is_connected: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="isConnected"), + pydantic.Field(alias="isConnected", description="Whether the cluster is connected"), + ] 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/jfrog_provider_account.py b/src/truefoundry_sdk/types/jfrog_provider_account.py index 81a76b9f..eda2ca18 100644 --- a/src/truefoundry_sdk/types/jfrog_provider_account.py +++ b/src/truefoundry_sdk/types/jfrog_provider_account.py @@ -37,9 +37,9 @@ class JfrogProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/job.py b/src/truefoundry_sdk/types/job.py index 7ea23b9f..ee6158f4 100644 --- a/src/truefoundry_sdk/types/job.py +++ b/src/truefoundry_sdk/types/job.py @@ -59,7 +59,7 @@ class Job(UniversalBaseModel): Configure alerts to be sent when the job starts/fails/completes """ - retries: typing.Optional[int] = pydantic.Field(default=0) + retries: typing.Optional[int] = pydantic.Field(default=None) """ Specify the maximum number of attempts to retry a job before it is marked as failed. """ diff --git a/src/truefoundry_sdk/types/job_alert.py b/src/truefoundry_sdk/types/job_alert.py index ad681930..aafef422 100644 --- a/src/truefoundry_sdk/types/job_alert.py +++ b/src/truefoundry_sdk/types/job_alert.py @@ -23,13 +23,13 @@ class JobAlert(UniversalBaseModel): """ notification_target: typing.Optional[NotificationTarget] = None - on_start: typing.Optional[bool] = pydantic.Field(default=False) + on_start: typing.Optional[bool] = pydantic.Field(default=None) """ Send an alert when the job starts """ - on_completion: typing.Optional[bool] = False - on_failure: typing.Optional[bool] = pydantic.Field(default=True) + on_completion: typing.Optional[bool] = None + on_failure: typing.Optional[bool] = pydantic.Field(default=None) """ Send an alert when the job fails """ diff --git a/src/truefoundry_sdk/types/job_run.py b/src/truefoundry_sdk/types/job_run.py index 25c7a0f5..0d939b53 100644 --- a/src/truefoundry_sdk/types/job_run.py +++ b/src/truefoundry_sdk/types/job_run.py @@ -21,32 +21,24 @@ class JobRun(UniversalBaseModel): JobRun Name """ - application_name: typing_extensions.Annotated[str, FieldMetadata(alias="applicationName")] = pydantic.Field( - alias="applicationName" - ) - """ - Application Name - """ - - deployment_version: typing_extensions.Annotated[str, FieldMetadata(alias="deploymentVersion")] = pydantic.Field( - alias="deploymentVersion" - ) - """ - Deployment Version - """ - - created_at: typing_extensions.Annotated[float, FieldMetadata(alias="createdAt")] = pydantic.Field(alias="createdAt") - """ - Created At - """ - - end_time: typing_extensions.Annotated[typing.Optional[float], FieldMetadata(alias="endTime")] = pydantic.Field( - alias="endTime", default=None - ) - """ - End Time of JobRun - """ - + application_name: typing_extensions.Annotated[ + str, + FieldMetadata(alias="applicationName"), + pydantic.Field(alias="applicationName", description="Application Name"), + ] + deployment_version: typing_extensions.Annotated[ + str, + FieldMetadata(alias="deploymentVersion"), + pydantic.Field(alias="deploymentVersion", description="Deployment Version"), + ] + created_at: typing_extensions.Annotated[ + float, FieldMetadata(alias="createdAt"), pydantic.Field(alias="createdAt", description="Created At") + ] + end_time: typing_extensions.Annotated[ + typing.Optional[float], + FieldMetadata(alias="endTime"), + pydantic.Field(alias="endTime", description="End Time of JobRun"), + ] = None duration: typing.Optional[int] = pydantic.Field(default=None) """ Duration of JobRun @@ -57,13 +49,9 @@ class JobRun(UniversalBaseModel): Command """ - total_retries: typing_extensions.Annotated[int, FieldMetadata(alias="totalRetries")] = pydantic.Field( - alias="totalRetries" - ) - """ - Total Retries - """ - + total_retries: typing_extensions.Annotated[ + int, FieldMetadata(alias="totalRetries"), pydantic.Field(alias="totalRetries", description="Total Retries") + ] error: typing.Optional[str] = pydantic.Field(default=None) """ Error @@ -74,54 +62,39 @@ class JobRun(UniversalBaseModel): Status of JobRun """ - triggered_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="triggeredBy")] = ( - pydantic.Field(alias="triggeredBy", default=None) - ) - """ - Triggered By - """ - + triggered_by: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="triggeredBy"), + pydantic.Field(alias="triggeredBy", description="Triggered By"), + ] = None triggered_by_subject: typing_extensions.Annotated[ - typing.Optional[Subject], FieldMetadata(alias="triggeredBySubject") - ] = pydantic.Field(alias="triggeredBySubject", default=None) - """ - Triggered By Subject - """ - - exit_code: typing_extensions.Annotated[typing.Optional[int], FieldMetadata(alias="exitCode")] = pydantic.Field( - alias="exitCode", default=None - ) - """ - Exit Code - """ - - spark_ui: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="sparkUi")] = pydantic.Field( - alias="sparkUi", default=None - ) - """ - Spark UI Url - """ - - application_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="applicationId")] = ( - pydantic.Field(alias="applicationId", default=None) - ) - """ - Application ID - """ - - deployment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="deploymentId")] = ( - pydantic.Field(alias="deploymentId", default=None) - ) - """ - Deployment ID - """ - - tenant_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName", default=None - ) - """ - Tenant Name - """ + typing.Optional[Subject], + FieldMetadata(alias="triggeredBySubject"), + pydantic.Field(alias="triggeredBySubject", description="Triggered By Subject"), + ] = None + exit_code: typing_extensions.Annotated[ + typing.Optional[int], FieldMetadata(alias="exitCode"), pydantic.Field(alias="exitCode", description="Exit Code") + ] = None + spark_ui: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="sparkUi"), + pydantic.Field(alias="sparkUi", description="Spark UI Url"), + ] = None + application_id: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="applicationId"), + pydantic.Field(alias="applicationId", description="Application ID"), + ] = None + deployment_id: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="deploymentId"), + pydantic.Field(alias="deploymentId", description="Deployment ID"), + ] = None + tenant_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="tenantName"), + pydantic.Field(alias="tenantName", description="Tenant Name"), + ] = 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/json_schema.py b/src/truefoundry_sdk/types/json_schema.py index 5c6fce32..831dfb32 100644 --- a/src/truefoundry_sdk/types/json_schema.py +++ b/src/truefoundry_sdk/types/json_schema.py @@ -18,12 +18,11 @@ class JsonSchema(UniversalBaseModel): Name of the schema """ - schema_: typing_extensions.Annotated[typing.Dict[str, typing.Any], FieldMetadata(alias="schema")] = pydantic.Field( - alias="schema" - ) - """ - JSON schema object defining the expected structure - """ + schema_: typing_extensions.Annotated[ + typing.Dict[str, typing.Any], + FieldMetadata(alias="schema"), + pydantic.Field(alias="schema", description="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/jwt.py b/src/truefoundry_sdk/types/jwt.py index 9074fb3f..225d4e88 100644 --- a/src/truefoundry_sdk/types/jwt.py +++ b/src/truefoundry_sdk/types/jwt.py @@ -11,18 +11,18 @@ class Jwt(UniversalBaseModel): id: str - subject_type: typing_extensions.Annotated[str, FieldMetadata(alias="subjectType")] = pydantic.Field( - alias="subjectType" - ) - subject_id: typing_extensions.Annotated[str, FieldMetadata(alias="subjectId")] = pydantic.Field(alias="subjectId") + subject_type: typing_extensions.Annotated[ + str, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType") + ] + subject_id: typing_extensions.Annotated[str, FieldMetadata(alias="subjectId"), pydantic.Field(alias="subjectId")] metadata: typing.Optional[typing.Dict[str, typing.Any]] = None expiry: dt.datetime - 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" - ) + 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 diff --git a/src/truefoundry_sdk/types/kafka_input_config.py b/src/truefoundry_sdk/types/kafka_input_config.py index 7a7da58f..0a3ad185 100644 --- a/src/truefoundry_sdk/types/kafka_input_config.py +++ b/src/truefoundry_sdk/types/kafka_input_config.py @@ -32,12 +32,12 @@ class KafkaInputConfig(UniversalBaseModel): The name of the consumer group to join for dynamic partition assignment """ - tls: bool = pydantic.Field(default=True) + tls: bool = pydantic.Field() """ TLS configuration for SASL authentication """ - wait_time_seconds: typing.Optional[int] = pydantic.Field(default=10) + wait_time_seconds: typing.Optional[int] = pydantic.Field(default=None) """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/kafka_output_config.py b/src/truefoundry_sdk/types/kafka_output_config.py index c148379e..37460632 100644 --- a/src/truefoundry_sdk/types/kafka_output_config.py +++ b/src/truefoundry_sdk/types/kafka_output_config.py @@ -27,7 +27,7 @@ class KafkaOutputConfig(UniversalBaseModel): Kafka topic to publish to """ - tls: bool = pydantic.Field(default=True) + tls: bool = pydantic.Field() """ TLS configuration for SASL authentication """ diff --git a/src/truefoundry_sdk/types/latency_based_load_balance_target.py b/src/truefoundry_sdk/types/latency_based_load_balance_target.py index abf58d70..1d4840b9 100644 --- a/src/truefoundry_sdk/types/latency_based_load_balance_target.py +++ b/src/truefoundry_sdk/types/latency_based_load_balance_target.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .headers_override import HeadersOverride from .retry_config import RetryConfig @@ -23,7 +24,7 @@ class LatencyBasedLoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=True) + fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) """ Whether this target is a fallback candidate. If set to false, this model will not be considered as a fallback option for targets of this load-balance-rule """ @@ -33,6 +34,12 @@ class LatencyBasedLoadBalanceTarget(UniversalBaseModel): 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: diff --git a/src/truefoundry_sdk/types/legacy_agent_manifest.py b/src/truefoundry_sdk/types/legacy_agent_manifest.py new file mode 100644 index 00000000..60f8ede5 --- /dev/null +++ b/src/truefoundry_sdk/types/legacy_agent_manifest.py @@ -0,0 +1,52 @@ +# 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 .agent_source import AgentSource +from .collaborator import Collaborator +from .owned_by import OwnedBy +from .sample_agent_input import SampleAgentInput + + +class LegacyAgentManifest(UniversalBaseModel): + type: typing.Literal["agent"] = pydantic.Field(default="agent") + """ + Type of the manifest + """ + + name: str = pydantic.Field() + """ + The name of the Agent + """ + + description: str = pydantic.Field() + """ + The description of the Agent + """ + + source: AgentSource + collaborators: typing.List[Collaborator] = pydantic.Field() + """ + List of users who have access to this Agent + """ + + sample_inputs: typing.Optional[typing.List[SampleAgentInput]] = pydantic.Field(default=None) + """ + Sample inputs for your agent. These inputs are shown as an example in the "Agent Chat" page. (Click on Try Now in the agent listing page) + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/list_agent_skill_versions_response.py b/src/truefoundry_sdk/types/list_agent_skill_versions_response.py new file mode 100644 index 00000000..a0d44eb7 --- /dev/null +++ b/src/truefoundry_sdk/types/list_agent_skill_versions_response.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 .agent_skill_version import AgentSkillVersion +from .pagination import Pagination + + +class ListAgentSkillVersionsResponse(UniversalBaseModel): + data: typing.List[AgentSkillVersion] = pydantic.Field() + """ + List of agent skill versions + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information + """ + + 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/list_agent_skills_response.py b/src/truefoundry_sdk/types/list_agent_skills_response.py new file mode 100644 index 00000000..b8e55066 --- /dev/null +++ b/src/truefoundry_sdk/types/list_agent_skills_response.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 .agent_skill import AgentSkill +from .pagination import Pagination + + +class ListAgentSkillsResponse(UniversalBaseModel): + data: typing.List[AgentSkill] = pydantic.Field() + """ + List of agent skills matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information + """ + + 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/list_application_deployments_response.py b/src/truefoundry_sdk/types/list_application_deployments_response.py index a470172a..71f5aa1e 100644 --- a/src/truefoundry_sdk/types/list_application_deployments_response.py +++ b/src/truefoundry_sdk/types/list_application_deployments_response.py @@ -30,12 +30,6 @@ class Config: from .application import Application # noqa: E402, I001 -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs( - ListApplicationDeploymentsResponse, - Application=Application, - ApplicationDebugInfo=ApplicationDebugInfo, - Deployment=Deployment, -) +update_forward_refs(ListApplicationDeploymentsResponse, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/list_applications_response.py b/src/truefoundry_sdk/types/list_applications_response.py index a7ab2d12..4a9a46f1 100644 --- a/src/truefoundry_sdk/types/list_applications_response.py +++ b/src/truefoundry_sdk/types/list_applications_response.py @@ -30,9 +30,6 @@ class Config: from .application import Application # noqa: E402, I001 -from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs( - ListApplicationsResponse, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment -) +update_forward_refs(ListApplicationsResponse, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/list_artifact_versions_response.py b/src/truefoundry_sdk/types/list_artifact_versions_response.py index caaa91c1..6f167801 100644 --- a/src/truefoundry_sdk/types/list_artifact_versions_response.py +++ b/src/truefoundry_sdk/types/list_artifact_versions_response.py @@ -9,8 +9,15 @@ class ListArtifactVersionsResponse(UniversalBaseModel): - data: typing.List[ArtifactVersion] - pagination: Pagination + data: typing.List[ArtifactVersion] = pydantic.Field() + """ + List of artifact versions matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_artifacts_response.py b/src/truefoundry_sdk/types/list_artifacts_response.py index f6b2654f..84c9eb8c 100644 --- a/src/truefoundry_sdk/types/list_artifacts_response.py +++ b/src/truefoundry_sdk/types/list_artifacts_response.py @@ -9,8 +9,15 @@ class ListArtifactsResponse(UniversalBaseModel): - data: typing.List[Artifact] - pagination: Pagination + data: typing.List[Artifact] = pydantic.Field() + """ + List of artifacts matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_data_directories_response.py b/src/truefoundry_sdk/types/list_data_directories_response.py index 7bc08ac3..56946acb 100644 --- a/src/truefoundry_sdk/types/list_data_directories_response.py +++ b/src/truefoundry_sdk/types/list_data_directories_response.py @@ -9,8 +9,15 @@ class ListDataDirectoriesResponse(UniversalBaseModel): - data: typing.List[DataDirectory] - pagination: Pagination + data: typing.List[DataDirectory] = pydantic.Field() + """ + List of data directories matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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 6eb7e4a7..6f29882f 100644 --- a/src/truefoundry_sdk/types/list_files_request.py +++ b/src/truefoundry_sdk/types/list_files_request.py @@ -9,12 +9,26 @@ class ListFilesRequest(UniversalBaseModel): - id: str - path: typing.Optional[str] = None - limit: typing.Optional[int] = None - page_token: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="pageToken")] = pydantic.Field( - alias="pageToken", default=None - ) + id: str = pydantic.Field() + """ + ID of the artifact version to list files from + """ + + path: typing.Optional[str] = pydantic.Field(default=None) + """ + Relative path within the artifact version to list files from (defaults to root) + """ + + limit: typing.Optional[int] = pydantic.Field(default=None) + """ + Maximum number of files/directories to return + """ + + page_token: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="pageToken"), + pydantic.Field(alias="pageToken", description="Token to retrieve the next page of results"), + ] = 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/list_files_response.py b/src/truefoundry_sdk/types/list_files_response.py index 5bae2987..83320f09 100644 --- a/src/truefoundry_sdk/types/list_files_response.py +++ b/src/truefoundry_sdk/types/list_files_response.py @@ -9,8 +9,15 @@ class ListFilesResponse(UniversalBaseModel): - data: typing.List[FileInfo] - pagination: TokenPagination + data: typing.List[FileInfo] = pydantic.Field() + """ + List of files and directories in the artifact version + """ + + pagination: TokenPagination = pydantic.Field() + """ + Pagination information including page tokens for navigation + """ 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_ml_repos_response.py b/src/truefoundry_sdk/types/list_ml_repos_response.py index 9f570dae..da42f063 100644 --- a/src/truefoundry_sdk/types/list_ml_repos_response.py +++ b/src/truefoundry_sdk/types/list_ml_repos_response.py @@ -9,8 +9,15 @@ class ListMlReposResponse(UniversalBaseModel): - data: typing.List[MlRepo] - pagination: Pagination + data: typing.List[MlRepo] = pydantic.Field() + """ + List of ML Repos matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_model_versions_response.py b/src/truefoundry_sdk/types/list_model_versions_response.py index fdb7f8af..273f1e19 100644 --- a/src/truefoundry_sdk/types/list_model_versions_response.py +++ b/src/truefoundry_sdk/types/list_model_versions_response.py @@ -9,8 +9,15 @@ class ListModelVersionsResponse(UniversalBaseModel): - data: typing.List[ModelVersion] - pagination: Pagination + data: typing.List[ModelVersion] = pydantic.Field() + """ + List of model versions matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_models_response.py b/src/truefoundry_sdk/types/list_models_response.py index c9bc0715..513e4914 100644 --- a/src/truefoundry_sdk/types/list_models_response.py +++ b/src/truefoundry_sdk/types/list_models_response.py @@ -9,8 +9,15 @@ class ListModelsResponse(UniversalBaseModel): - data: typing.List[Model] - pagination: Pagination + data: typing.List[Model] = pydantic.Field() + """ + List of models matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_prompt_versions_response.py b/src/truefoundry_sdk/types/list_prompt_versions_response.py index 991f8155..3db5a1ef 100644 --- a/src/truefoundry_sdk/types/list_prompt_versions_response.py +++ b/src/truefoundry_sdk/types/list_prompt_versions_response.py @@ -9,8 +9,15 @@ class ListPromptVersionsResponse(UniversalBaseModel): - data: typing.List[PromptVersion] - pagination: Pagination + data: typing.List[PromptVersion] = pydantic.Field() + """ + List of prompt versions matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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_prompts_response.py b/src/truefoundry_sdk/types/list_prompts_response.py index bcb62329..af97d14f 100644 --- a/src/truefoundry_sdk/types/list_prompts_response.py +++ b/src/truefoundry_sdk/types/list_prompts_response.py @@ -9,8 +9,15 @@ class ListPromptsResponse(UniversalBaseModel): - data: typing.List[Prompt] - pagination: Pagination + data: typing.List[Prompt] = pydantic.Field() + """ + List of prompts matching the query + """ + + pagination: Pagination = pydantic.Field() + """ + Pagination information including total count, offset, and limit + """ 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/load_balance_target.py b/src/truefoundry_sdk/types/load_balance_target.py index 872ca1d9..de2df3d9 100644 --- a/src/truefoundry_sdk/types/load_balance_target.py +++ b/src/truefoundry_sdk/types/load_balance_target.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .headers_override import HeadersOverride from .retry_config import RetryConfig @@ -28,7 +29,7 @@ class LoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=True) + fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) """ Whether this target is a fallback candidate. If set to false, this model will not be considered as a fallback option for targets of this load-balance-rule """ @@ -38,6 +39,12 @@ class LoadBalanceTarget(UniversalBaseModel): 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: diff --git a/src/truefoundry_sdk/types/local_source.py b/src/truefoundry_sdk/types/local_source.py index c922bcb2..bc3fd008 100644 --- a/src/truefoundry_sdk/types/local_source.py +++ b/src/truefoundry_sdk/types/local_source.py @@ -16,12 +16,12 @@ class LocalSource(UniversalBaseModel): +value=local """ - project_root_path: str = pydantic.Field(default="./") + project_root_path: str = pydantic.Field() """ Local project root path. """ - local_build: bool = pydantic.Field(default=True) + local_build: bool = pydantic.Field() """ run docker build locally """ diff --git a/src/truefoundry_sdk/types/log.py b/src/truefoundry_sdk/types/log.py index 6e4cca73..19b41732 100644 --- a/src/truefoundry_sdk/types/log.py +++ b/src/truefoundry_sdk/types/log.py @@ -29,12 +29,11 @@ class Log(UniversalBaseModel): Log Time """ - container_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="containerName")] = ( - pydantic.Field(alias="containerName", default=None) - ) - """ - Container Name - """ + container_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="containerName"), + pydantic.Field(alias="containerName", description="Container Name"), + ] = 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/logging_config.py b/src/truefoundry_sdk/types/logging_config.py index a21afc1e..3956e12c 100644 --- a/src/truefoundry_sdk/types/logging_config.py +++ b/src/truefoundry_sdk/types/logging_config.py @@ -11,7 +11,7 @@ class LoggingConfig(UniversalBaseModel): Logging configuration for the chat prompt """ - enabled: bool = pydantic.Field(default=True) + enabled: bool = pydantic.Field() """ Whether logging is enabled for the chat prompt """ diff --git a/src/truefoundry_sdk/types/logs_filter_query.py b/src/truefoundry_sdk/types/logs_filter_query.py index 2e60bb2e..4dfc9d7d 100644 --- a/src/truefoundry_sdk/types/logs_filter_query.py +++ b/src/truefoundry_sdk/types/logs_filter_query.py @@ -11,13 +11,11 @@ class LogsFilterQuery(UniversalBaseModel): - match_string: typing_extensions.Annotated[str, FieldMetadata(alias="matchString")] = pydantic.Field( - alias="matchString" - ) - """ - String that needs to be matched - """ - + match_string: typing_extensions.Annotated[ + str, + FieldMetadata(alias="matchString"), + pydantic.Field(alias="matchString", description="String that needs to be matched"), + ] type: LogsFilterQueryType = pydantic.Field() """ query filter type, `regex` or `substring` diff --git a/src/truefoundry_sdk/types/mcp_server_env_auth.py b/src/truefoundry_sdk/types/mcp_server_env_auth.py new file mode 100644 index 00000000..c19c0d63 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_env_auth.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 +from .mcp_server_env_auth_auth_level import McpServerEnvAuthAuthLevel + + +class McpServerEnvAuth(UniversalBaseModel): + """ + Environment variable authentication for stdio MCP. For individual credentials, use a single {{placeholder}} name in values (same rules as header auth). + """ + + type: typing.Literal["env"] = pydantic.Field(default="env") + """ + +value=env + """ + + env: typing.Dict[str, str] = pydantic.Field() + """ + Map each env variable to its value. For shared, enter the actual value. For individual, use a placeholder that will be filled in by each user (e.g. API_KEY {{API_KEY}}). + """ + + auth_level: typing.Optional[McpServerEnvAuthAuthLevel] = pydantic.Field(default=None) + """ + Level at which this authentication will be applied. Values: global (default), per_user + """ + + 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_env_auth_auth_level.py b/src/truefoundry_sdk/types/mcp_server_env_auth_auth_level.py new file mode 100644 index 00000000..670c6036 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_env_auth_auth_level.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 McpServerEnvAuthAuthLevel(enum.StrEnum): + """ + Level at which this authentication will be applied. Values: global (default), per_user + """ + + GLOBAL = "global" + PER_USER = "per_user" + _UNKNOWN = "__MCPSERVERENVAUTHAUTHLEVEL_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) -> "McpServerEnvAuthAuthLevel": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + global_: typing.Callable[[], T_Result], + per_user: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is McpServerEnvAuthAuthLevel.GLOBAL: + return global_() + if self is McpServerEnvAuthAuthLevel.PER_USER: + return per_user() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_header_auth.py b/src/truefoundry_sdk/types/mcp_server_header_auth.py index 01c87939..e0c563ca 100644 --- a/src/truefoundry_sdk/types/mcp_server_header_auth.py +++ b/src/truefoundry_sdk/types/mcp_server_header_auth.py @@ -4,11 +4,12 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .mcp_server_header_auth_auth_level import McpServerHeaderAuthAuthLevel class McpServerHeaderAuth(UniversalBaseModel): """ - Static API key or token authentication via request headers. All users share the same credentials. + Authenticate using a static key or token sent as a request header. Choose shared vs individual credentials below. """ type: typing.Literal["header"] = pydantic.Field(default="header") @@ -16,7 +17,15 @@ class McpServerHeaderAuth(UniversalBaseModel): +value=header """ - headers: typing.Dict[str, str] + headers: typing.Dict[str, str] = pydantic.Field() + """ + Map each header name to its value. For shared, enter the actual value. For individual, use a placeholder that will be filled in by each user (e.g. Bearer {{API_KEY}}). + """ + + auth_level: McpServerHeaderAuthAuthLevel = pydantic.Field() + """ + Level at which this authentication will be applied. Values: global (default), per_user + """ 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_server_header_auth_auth_level.py b/src/truefoundry_sdk/types/mcp_server_header_auth_auth_level.py new file mode 100644 index 00000000..bf3f2e43 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_header_auth_auth_level.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 McpServerHeaderAuthAuthLevel(enum.StrEnum): + """ + Level at which this authentication will be applied. Values: global (default), per_user + """ + + GLOBAL = "global" + PER_USER = "per_user" + _UNKNOWN = "__MCPSERVERHEADERAUTHAUTHLEVEL_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) -> "McpServerHeaderAuthAuthLevel": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + global_: typing.Callable[[], T_Result], + per_user: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is McpServerHeaderAuthAuthLevel.GLOBAL: + return global_() + if self is McpServerHeaderAuthAuthLevel.PER_USER: + return per_user() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/mcp_server_manifest.py b/src/truefoundry_sdk/types/mcp_server_manifest.py index 842ef09e..b76d9ba2 100644 --- a/src/truefoundry_sdk/types/mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/mcp_server_manifest.py @@ -4,6 +4,9 @@ from .open_apimcp_server_manifest import OpenApimcpServerManifest from .remote_mcp_server_manifest import RemoteMcpServerManifest +from .stdio_mcp_server_manifest import StdioMcpServerManifest from .virtual_mcp_server_manifest import VirtualMcpServerManifest -McpServerManifest = typing.Union[RemoteMcpServerManifest, VirtualMcpServerManifest, OpenApimcpServerManifest] +McpServerManifest = typing.Union[ + RemoteMcpServerManifest, VirtualMcpServerManifest, OpenApimcpServerManifest, StdioMcpServerManifest +] diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2.py b/src/truefoundry_sdk/types/mcp_server_o_auth2.py index 0b4688b4..ea267eef 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, UniversalBaseModel +from .mcp_server_o_auth2grant_type import McpServerOAuth2GrantType from .mcp_server_o_auth2jwt_source import McpServerOAuth2JwtSource @@ -17,7 +18,12 @@ class McpServerOAuth2(UniversalBaseModel): OAuth2 authentication """ - authorization_url: str = pydantic.Field() + grant_type: McpServerOAuth2GrantType = pydantic.Field() + """ + The OAuth2 grant type to use for authentication. + """ + + authorization_url: typing.Optional[str] = pydantic.Field(default=None) """ URL for the authorization request """ diff --git a/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_type.py new file mode 100644 index 00000000..184eccd6 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_server_o_auth2grant_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 McpServerOAuth2GrantType(enum.StrEnum): + """ + The OAuth2 grant type to use for authentication. + """ + + AUTHORIZATION_CODE = "authorization_code" + CLIENT_CREDENTIALS = "client_credentials" + _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`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "McpServerOAuth2GrantType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + authorization_code: typing.Callable[[], T_Result], + client_credentials: 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() + 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 1fe9283a..38283a98 100644 --- a/src/truefoundry_sdk/types/mcp_server_provider_account.py +++ b/src/truefoundry_sdk/types/mcp_server_provider_account.py @@ -38,9 +38,9 @@ class McpServerProviderAccount(UniversalBaseModel): List of MCP Servers, which are part of this MCP Server Group. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/mcp_server_with_fqn.py b/src/truefoundry_sdk/types/mcp_server_with_fqn.py index 6dae4cd0..a552af22 100644 --- a/src/truefoundry_sdk/types/mcp_server_with_fqn.py +++ b/src/truefoundry_sdk/types/mcp_server_with_fqn.py @@ -22,7 +22,7 @@ class McpServerWithFqn(UniversalBaseModel): The FQN of the MCP server """ - enable_all_tools: bool = pydantic.Field(default=False) + enable_all_tools: bool = pydantic.Field() """ Whether to enable all tools from the MCP server """ diff --git a/src/truefoundry_sdk/types/mcp_server_with_url.py b/src/truefoundry_sdk/types/mcp_server_with_url.py index 39cc7d04..d24d690e 100644 --- a/src/truefoundry_sdk/types/mcp_server_with_url.py +++ b/src/truefoundry_sdk/types/mcp_server_with_url.py @@ -27,7 +27,7 @@ class McpServerWithUrl(UniversalBaseModel): The headers to send to the MCP server """ - enable_all_tools: bool = pydantic.Field(default=False) + enable_all_tools: bool = pydantic.Field() """ Whether to enable all tools from the MCP server """ diff --git a/src/truefoundry_sdk/types/mcp_tool_target.py b/src/truefoundry_sdk/types/mcp_tool_target.py new file mode 100644 index 00000000..297a0187 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_tool_target.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 McpToolTarget(UniversalBaseModel): + name: str = pydantic.Field() + """ + Name of the MCP server + """ + + enable_all_tools: bool = pydantic.Field() + """ + When enabled, all tools from this MCP server are targeted. Disable to select specific tools. + """ + + enabled_tools: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of specific tools to target from this MCP server. + """ + + 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_tools_operator.py b/src/truefoundry_sdk/types/mcp_tools_operator.py new file mode 100644 index 00000000..dbc559ad --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_tools_operator.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 +from .mcp_tool_target import McpToolTarget +from .mcp_tools_operator_condition import McpToolsOperatorCondition + + +class McpToolsOperator(UniversalBaseModel): + condition: McpToolsOperatorCondition + values: typing.List[McpToolTarget] + + 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_tools_operator_condition.py b/src/truefoundry_sdk/types/mcp_tools_operator_condition.py new file mode 100644 index 00000000..b5098e81 --- /dev/null +++ b/src/truefoundry_sdk/types/mcp_tools_operator_condition.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 McpToolsOperatorCondition(enum.StrEnum): + IN = "in" + NOT_IN = "not_in" + _UNKNOWN = "__MCPTOOLSOPERATORCONDITION_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) -> "McpToolsOperatorCondition": + 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 McpToolsOperatorCondition.IN: + return in_() + if self is McpToolsOperatorCondition.NOT_IN: + return not_in() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/metric.py b/src/truefoundry_sdk/types/metric.py index 90f0b0ba..8586c477 100644 --- a/src/truefoundry_sdk/types/metric.py +++ b/src/truefoundry_sdk/types/metric.py @@ -7,10 +7,25 @@ class Metric(UniversalBaseModel): - key: str - value: typing.Optional[float] = None - timestamp: typing.Optional[int] = None - step: typing.Optional[int] = 0 + key: str = pydantic.Field() + """ + Name of the metric + """ + + value: typing.Optional[float] = pydantic.Field(default=None) + """ + Value of the metric + """ + + timestamp: typing.Optional[int] = pydantic.Field(default=None) + """ + Timestamp when the metric was recorded (epoch milliseconds) + """ + + step: typing.Optional[int] = pydantic.Field(default=None) + """ + Training step number when the metric was recorded + """ 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/mistral_ai_provider_account.py b/src/truefoundry_sdk/types/mistral_ai_provider_account.py index d1c6040a..a8744b7e 100644 --- a/src/truefoundry_sdk/types/mistral_ai_provider_account.py +++ b/src/truefoundry_sdk/types/mistral_ai_provider_account.py @@ -38,9 +38,9 @@ class MistralAiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/ml_repo_manifest.py b/src/truefoundry_sdk/types/ml_repo_manifest.py index d683374b..0e91d18d 100644 --- a/src/truefoundry_sdk/types/ml_repo_manifest.py +++ b/src/truefoundry_sdk/types/ml_repo_manifest.py @@ -36,9 +36,9 @@ class MlRepoManifest(UniversalBaseModel): Users and Teams that have access to MLRepo """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/model.py b/src/truefoundry_sdk/types/model.py index 8f6d4e27..b9c4e73e 100644 --- a/src/truefoundry_sdk/types/model.py +++ b/src/truefoundry_sdk/types/model.py @@ -10,16 +10,59 @@ class Model(UniversalBaseModel): - id: str - ml_repo_id: str - type: typing.Optional[typing.Literal["model"]] = None - name: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - latest_version: typing.Optional[ModelVersion] = None - run_steps: typing.Optional[typing.List[int]] = None + """ + Generic artifact API DTO including run-step linkage for ML runs. + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact belongs to + """ + + type: typing.Optional[typing.Literal["model"]] = pydantic.Field(default=None) + """ + Type of the artifact, always 'model' for Model entities + """ + + name: str = pydantic.Field() + """ + Name of the artifact (alphanumeric characters, hyphens, and underscores only, max 256 characters) + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was last updated + """ + + latest_version: typing.Optional[ModelVersion] = pydantic.Field(default=None) + """ + The most recent version of this model + """ + + run_steps: typing.Optional[typing.List[int]] = pydantic.Field(default=None) + """ + List of run step numbers where this artifact was created or 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/model_manifest.py b/src/truefoundry_sdk/types/model_manifest.py index 304cdc1a..8083a419 100644 --- a/src/truefoundry_sdk/types/model_manifest.py +++ b/src/truefoundry_sdk/types/model_manifest.py @@ -16,23 +16,17 @@ class ModelManifest(UniversalBaseModel): name: str = pydantic.Field() """ - Name of the entity + Name of the model (alphanumeric characters, hyphens, and underscores only, max 256 characters) """ - description: typing.Optional[str] = None metadata: typing.Dict[str, typing.Any] = pydantic.Field() """ Key value metadata. Should be valid JSON. For e.g. `{"business-unit": "sales", "quality": "good", "rating": 4.5}` """ - version_alias: typing.Optional[str] = pydantic.Field(default=None) - """ - Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) - """ - ml_repo: str = pydantic.Field() """ - Name of the ML Repo + Name of the ML Repo that this model belongs to (must start and end with alphanumeric, 2-100 characters) """ version: typing.Optional[int] = pydantic.Field(default=None) @@ -41,6 +35,12 @@ class ModelManifest(UniversalBaseModel): """ type: typing.Literal["model-version"] = "model-version" + description: typing.Optional[str] = None + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Version alias is alternate, ideally human readable, version string to reference an artifact version. It should start with `v` followed by alphanumeric and it can include `.` and `-` in between (e.g. `v1.0.0`, `v1-prod`, `v3-dev`, etc) + """ + source: ModelManifestSource framework: typing.Optional[ModelManifestFramework] = pydantic.Field(default=None) """ @@ -48,7 +48,7 @@ class ModelManifest(UniversalBaseModel): """ environment: typing.Optional[ModelVersionEnvironment] = None - step: typing.Optional[int] = pydantic.Field(default=0) + step: typing.Optional[int] = pydantic.Field(default=None) """ Step/Epoch number in an iterative training loop the model version was created. Generally useful when logging a model version from a MLRepo Run """ diff --git a/src/truefoundry_sdk/types/model_provider_account.py b/src/truefoundry_sdk/types/model_provider_account.py index fc6d8c18..b9a4b58d 100644 --- a/src/truefoundry_sdk/types/model_provider_account.py +++ b/src/truefoundry_sdk/types/model_provider_account.py @@ -8,6 +8,7 @@ from .aws_sagemaker_provider_account import AwsSagemakerProviderAccount from .azure_foundry_provider_account import AzureFoundryProviderAccount from .azure_open_ai_provider_account import AzureOpenAiProviderAccount +from .baseten_provider_account import BasetenProviderAccount from .cartesia_provider_account import CartesiaProviderAccount from .cerebras_provider_account import CerebrasProviderAccount from .cloudera_provider_account import ClouderaProviderAccount @@ -57,6 +58,7 @@ OpenRouterProviderAccount, SambaNovaProviderAccount, XaiProviderAccount, + BasetenProviderAccount, AwsSagemakerProviderAccount, CerebrasProviderAccount, SnowflakeCortexProviderAccount, diff --git a/src/truefoundry_sdk/types/model_type.py b/src/truefoundry_sdk/types/model_type.py index 8cff4f5c..9b1e5aa6 100644 --- a/src/truefoundry_sdk/types/model_type.py +++ b/src/truefoundry_sdk/types/model_type.py @@ -22,6 +22,7 @@ class ModelType(enum.StrEnum): TEXT_TO_SPEECH = "text_to_speech" MODERATION = "moderation" IMAGE = "image" + RESPONSES = "responses" _UNKNOWN = "__MODELTYPE_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`. @@ -45,6 +46,7 @@ def visit( text_to_speech: typing.Callable[[], T_Result], moderation: 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 ModelType.CHAT: @@ -67,4 +69,6 @@ def visit( return moderation() if self is ModelType.IMAGE: return image() + if self is ModelType.RESPONSES: + return responses() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/model_version.py b/src/truefoundry_sdk/types/model_version.py index cdc09ed8..4a3c0216 100644 --- a/src/truefoundry_sdk/types/model_version.py +++ b/src/truefoundry_sdk/types/model_version.py @@ -11,18 +11,74 @@ class ModelVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - manifest: ModelManifest - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None - model_id: str - metrics: typing.Optional[typing.List[Metric]] = None - deployable: typing.Optional[bool] = False + """ + Tags, optional version alias, and SDK usage snippet (models, prompts, generic artifacts). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: ModelManifest = pydantic.Field() + """ + Manifest containing metadata specific to the model version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of tags associated with this artifact version for filtering and organization + """ + + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional human-readable version alias (e.g. v1.0.0) + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this artifact version + """ + + model_id: str = pydantic.Field() + """ + ID of the parent model that this version belongs to + """ + + metrics: typing.Optional[typing.List[Metric]] = pydantic.Field(default=None) + """ + List of metrics associated with this model version + """ + + deployable: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this model version is ready for 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/multi_part_upload.py b/src/truefoundry_sdk/types/multi_part_upload.py index 3cb7e554..47646652 100644 --- a/src/truefoundry_sdk/types/multi_part_upload.py +++ b/src/truefoundry_sdk/types/multi_part_upload.py @@ -11,13 +11,30 @@ class MultiPartUpload(UniversalBaseModel): - storage_provider: MultiPartUploadStorageProvider - part_signed_urls: typing.List[SignedUrl] + storage_provider: MultiPartUploadStorageProvider = pydantic.Field() + """ + Storage provider being used for the multipart upload (e.g., 'S3_COMPATIBLE' or 'AZURE_BLOB') + """ + + part_signed_urls: typing.List[SignedUrl] = pydantic.Field() + """ + List of signed URLs for each part of the multipart upload + """ + s3compatible_upload_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="s3_compatible_upload_id") - ] = pydantic.Field(alias="s3_compatible_upload_id", default=None) - azure_blob_block_ids: typing.Optional[typing.List[str]] = None - finalize_signed_url: SignedUrl + typing.Optional[str], + FieldMetadata(alias="s3_compatible_upload_id"), + pydantic.Field(alias="s3_compatible_upload_id", description="Upload ID for S3-compatible storage providers"), + ] = None + azure_blob_block_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of block IDs for Azure Blob Storage multipart upload + """ + + finalize_signed_url: SignedUrl = pydantic.Field() + """ + Signed URL to call after all parts are uploaded to finalize the multipart upload + """ 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_response.py b/src/truefoundry_sdk/types/multi_part_upload_response.py index 42c58094..8b50e292 100644 --- a/src/truefoundry_sdk/types/multi_part_upload_response.py +++ b/src/truefoundry_sdk/types/multi_part_upload_response.py @@ -8,7 +8,10 @@ class MultiPartUploadResponse(UniversalBaseModel): - data: MultiPartUpload + data: MultiPartUpload = pydantic.Field() + """ + Multipart upload information including signed URLs for each part + """ 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/nats_input_config.py b/src/truefoundry_sdk/types/nats_input_config.py index efaf9cd9..5f1ec645 100644 --- a/src/truefoundry_sdk/types/nats_input_config.py +++ b/src/truefoundry_sdk/types/nats_input_config.py @@ -37,7 +37,7 @@ class NatsInputConfig(UniversalBaseModel): Consumer name of input NATS """ - wait_time_seconds: int = pydantic.Field(default=19) + wait_time_seconds: int = pydantic.Field() """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/nats_user_password_auth.py b/src/truefoundry_sdk/types/nats_user_password_auth.py index d882ee25..331c0fe6 100644 --- a/src/truefoundry_sdk/types/nats_user_password_auth.py +++ b/src/truefoundry_sdk/types/nats_user_password_auth.py @@ -11,7 +11,7 @@ class NatsUserPasswordAuth(UniversalBaseModel): NATS User Password Authentication """ - account_name: str = pydantic.Field(default="$G") + account_name: str = pydantic.Field() """ Name of the NATS account """ diff --git a/src/truefoundry_sdk/types/nomic_provider_account.py b/src/truefoundry_sdk/types/nomic_provider_account.py index 13f7a77f..e2beadb4 100644 --- a/src/truefoundry_sdk/types/nomic_provider_account.py +++ b/src/truefoundry_sdk/types/nomic_provider_account.py @@ -38,9 +38,9 @@ class NomicProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/non_negative_float.py b/src/truefoundry_sdk/types/non_negative_float.py index da8968da..940f6df3 100644 --- a/src/truefoundry_sdk/types/non_negative_float.py +++ b/src/truefoundry_sdk/types/non_negative_float.py @@ -1,3 +1,6 @@ # This file was auto-generated by Fern from our API Definition. NonNegativeFloat = float +""" ++uiProps={"allowDecimal":true, "allowNegative":false} +""" diff --git a/src/truefoundry_sdk/types/notebook.py b/src/truefoundry_sdk/types/notebook.py index 77d15c6c..84dbee10 100644 --- a/src/truefoundry_sdk/types/notebook.py +++ b/src/truefoundry_sdk/types/notebook.py @@ -19,7 +19,7 @@ class Notebook(BaseWorkbenchInput): """ image: WorkbenchImage - cull_timeout: typing.Optional[int] = pydantic.Field(default=30) + cull_timeout: typing.Optional[int] = pydantic.Field(default=None) """ Stop the notebook instance after this much time in minutes of inactivity. The notebook instance will be stopped even if the notebook is open in your browser, but nothing is running on the notebook. diff --git a/src/truefoundry_sdk/types/notification_target.py b/src/truefoundry_sdk/types/notification_target.py index 8be24ee7..4b7e46ff 100644 --- a/src/truefoundry_sdk/types/notification_target.py +++ b/src/truefoundry_sdk/types/notification_target.py @@ -3,7 +3,8 @@ import typing from .email import Email +from .pager_duty import PagerDuty from .slack_bot import SlackBot from .slack_webhook import SlackWebhook -NotificationTarget = typing.Union[Email, SlackWebhook, SlackBot] +NotificationTarget = typing.Union[Email, SlackWebhook, SlackBot, PagerDuty] diff --git a/src/truefoundry_sdk/types/notification_target_for_alert_rule.py b/src/truefoundry_sdk/types/notification_target_for_alert_rule.py index 08427567..4adfce43 100644 --- a/src/truefoundry_sdk/types/notification_target_for_alert_rule.py +++ b/src/truefoundry_sdk/types/notification_target_for_alert_rule.py @@ -5,5 +5,6 @@ from .email import Email from .pager_duty import PagerDuty from .slack_bot import SlackBot +from .slack_webhook import SlackWebhook -NotificationTargetForAlertRule = typing.Union[Email, SlackBot, PagerDuty] +NotificationTargetForAlertRule = typing.Union[Email, SlackWebhook, SlackBot, PagerDuty] diff --git a/src/truefoundry_sdk/types/ollama_provider_account.py b/src/truefoundry_sdk/types/ollama_provider_account.py index 7e36a568..71ff800c 100644 --- a/src/truefoundry_sdk/types/ollama_provider_account.py +++ b/src/truefoundry_sdk/types/ollama_provider_account.py @@ -38,9 +38,9 @@ class OllamaProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/opa_guardrail_config.py b/src/truefoundry_sdk/types/opa_guardrail_config.py index 77325ed8..3675712e 100644 --- a/src/truefoundry_sdk/types/opa_guardrail_config.py +++ b/src/truefoundry_sdk/types/opa_guardrail_config.py @@ -19,9 +19,7 @@ class OpaGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Open Policy Agent (OPA) for policy-based access control and validation" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py index 04041bfc..6a47496f 100644 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py +++ b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py @@ -19,9 +19,7 @@ class OpenAiModerationsGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="OpenAI content moderation for hate, harassment, self-harm, sexual, violence, and illicit content" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py index 26b20a77..a8081a29 100644 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py @@ -4,9 +4,6 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .open_ai_moderations_guardrail_config_config_category_thresholds_value import ( - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue, -) class OpenAiModerationsGuardrailConfigConfig(UniversalBaseModel): @@ -15,7 +12,7 @@ class OpenAiModerationsGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - model: str = pydantic.Field(default="omni-moderation-latest") + model: str = pydantic.Field() """ The model to use for the OpenAI Moderation API. """ @@ -25,9 +22,7 @@ class OpenAiModerationsGuardrailConfigConfig(UniversalBaseModel): Optional custom base URL for OpenAI API. If not provided, the default base URL will be used. """ - category_thresholds: typing.Optional[ - typing.Dict[str, OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue] - ] = None + category_thresholds: typing.Optional[typing.Dict[str, float]] = 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/open_ai_moderations_guardrail_config_config_category_thresholds_value.py b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value.py deleted file mode 100644 index 6178edee..00000000 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value.py +++ /dev/null @@ -1,11 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment import ( - OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment, -) - -OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValue = typing.Union[ - float, OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment -] diff --git a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py index 0c3d1821..18cc9095 100644 --- a/src/truefoundry_sdk/types/open_apimcp_server_manifest.py +++ b/src/truefoundry_sdk/types/open_apimcp_server_manifest.py @@ -57,9 +57,9 @@ class OpenApimcpServerManifest(UniversalBaseModel): Users and Teams that have access to this OpenAPI Server """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ Key-value pairs to categorize this OpenAPI MCP Server (e.g., by owner or environment). diff --git a/src/truefoundry_sdk/types/open_router_provider_account.py b/src/truefoundry_sdk/types/open_router_provider_account.py index 58ada1c5..f5139124 100644 --- a/src/truefoundry_sdk/types/open_router_provider_account.py +++ b/src/truefoundry_sdk/types/open_router_provider_account.py @@ -38,9 +38,9 @@ class OpenRouterProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/openai_provider_account.py b/src/truefoundry_sdk/types/openai_provider_account.py index 2da6abe4..3cbaa2c2 100644 --- a/src/truefoundry_sdk/types/openai_provider_account.py +++ b/src/truefoundry_sdk/types/openai_provider_account.py @@ -43,9 +43,9 @@ class OpenaiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/otel_exporter_grpc_config_base.py b/src/truefoundry_sdk/types/otel_exporter_grpc_config_base.py new file mode 100644 index 00000000..f0fbe9f5 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_exporter_grpc_config_base.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 OtelExporterGrpcConfigBase(UniversalBaseModel): + """ + Base gRPC exporter fields (without type discriminator) + """ + + endpoint: str = pydantic.Field() + """ + Endpoint URL where OpenTelemetry data will be sent + """ + + headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + gRPC metadata to include in OpenTelemetry export 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/otel_exporter_http_config.py b/src/truefoundry_sdk/types/otel_exporter_http_config.py deleted file mode 100644 index dd6f2f97..00000000 --- a/src/truefoundry_sdk/types/otel_exporter_http_config.py +++ /dev/null @@ -1,57 +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 .otel_exporter_http_config_encoding import OtelExporterHttpConfigEncoding -from .otel_exporter_span_attribute_filter import OtelExporterSpanAttributeFilter - - -class OtelExporterHttpConfig(UniversalBaseModel): - """ - HTTP Configuration - """ - - type: typing.Literal["http"] = pydantic.Field(default="http") - """ - Configuration type - """ - - endpoint: str = pydantic.Field() - """ - Traces endpoint URL where OpenTelemetry data will be sent (typical format: https://://v1/traces) - """ - - encoding: OtelExporterHttpConfigEncoding = pydantic.Field() - """ - Encoding for OpenTelemetry data - """ - - headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) - """ - HTTP headers to include in OpenTelemetry export requests - """ - - additional_resource_attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) - """ - Set additional attributes to append them to existing resource attributes of every exported trace - """ - - exclude_request_data: typing.Optional[bool] = pydantic.Field(default=None) - """ - Enable to prevent forwarding the LLM or MCP request and response body in exported traces. The following span attributes are dropped: tfy.input, tfy.output, tfy.input_short_hand - """ - - when: typing.Optional[typing.List[OtelExporterSpanAttributeFilter]] = pydantic.Field(default=None) - """ - Export spans only when they match all of the following filters. Only matching on spanAttributes with string values in supported. - """ - - 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_exporter_http_config_base.py b/src/truefoundry_sdk/types/otel_exporter_http_config_base.py new file mode 100644 index 00000000..29ad8d28 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_exporter_http_config_base.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 +from .otel_exporter_http_config_base_encoding import OtelExporterHttpConfigBaseEncoding + + +class OtelExporterHttpConfigBase(UniversalBaseModel): + """ + Base HTTP exporter fields (without type discriminator) + """ + + endpoint: str = pydantic.Field() + """ + Endpoint URL where OpenTelemetry data will be sent + """ + + encoding: OtelExporterHttpConfigBaseEncoding = pydantic.Field() + """ + Encoding for OpenTelemetry data + """ + + headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + HTTP headers to include in OpenTelemetry export 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/otel_exporter_http_config_encoding.py b/src/truefoundry_sdk/types/otel_exporter_http_config_base_encoding.py similarity index 77% rename from src/truefoundry_sdk/types/otel_exporter_http_config_encoding.py rename to src/truefoundry_sdk/types/otel_exporter_http_config_base_encoding.py index 692e9728..ef2363d1 100644 --- a/src/truefoundry_sdk/types/otel_exporter_http_config_encoding.py +++ b/src/truefoundry_sdk/types/otel_exporter_http_config_base_encoding.py @@ -7,20 +7,20 @@ T_Result = typing.TypeVar("T_Result") -class OtelExporterHttpConfigEncoding(enum.StrEnum): +class OtelExporterHttpConfigBaseEncoding(enum.StrEnum): """ Encoding for OpenTelemetry data """ PROTO = "proto" JSON = "json" - _UNKNOWN = "__OTELEXPORTERHTTPCONFIGENCODING_UNKNOWN__" + _UNKNOWN = "__OTELEXPORTERHTTPCONFIGBASEENCODING_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) -> "OtelExporterHttpConfigEncoding": + def _missing_(cls, value: typing.Any) -> "OtelExporterHttpConfigBaseEncoding": unknown = cls._UNKNOWN unknown._value_ = value return unknown @@ -31,8 +31,8 @@ def visit( json: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: - if self is OtelExporterHttpConfigEncoding.PROTO: + if self is OtelExporterHttpConfigBaseEncoding.PROTO: return proto() - if self is OtelExporterHttpConfigEncoding.JSON: + if self is OtelExporterHttpConfigBaseEncoding.JSON: return json() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py b/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_config.py new file mode 100644 index 00000000..b6278902 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_metrics_exporter_grpc_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 .otel_exporter_grpc_config_base import OtelExporterGrpcConfigBase + + +class OtelMetricsExporterGrpcConfig(OtelExporterGrpcConfigBase): + """ + gRPC Configuration + """ + + type: typing.Literal["grpc"] = pydantic.Field(default="grpc") + """ + Configuration 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/otel_metrics_exporter_http_config.py b/src/truefoundry_sdk/types/otel_metrics_exporter_http_config.py new file mode 100644 index 00000000..a1660a10 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_metrics_exporter_http_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 .otel_exporter_http_config_base import OtelExporterHttpConfigBase + + +class OtelMetricsExporterHttpConfig(OtelExporterHttpConfigBase): + """ + HTTP Configuration + """ + + type: typing.Literal["http"] = pydantic.Field(default="http") + """ + Configuration 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/otel_exporter_grpc_config.py b/src/truefoundry_sdk/types/otel_traces_exporter_common_config.py similarity index 61% rename from src/truefoundry_sdk/types/otel_exporter_grpc_config.py rename to src/truefoundry_sdk/types/otel_traces_exporter_common_config.py index e9309604..d5146eda 100644 --- a/src/truefoundry_sdk/types/otel_exporter_grpc_config.py +++ b/src/truefoundry_sdk/types/otel_traces_exporter_common_config.py @@ -4,27 +4,12 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .otel_exporter_span_attribute_filter import OtelExporterSpanAttributeFilter +from .otel_traces_exporter_span_attribute_filter import OtelTracesExporterSpanAttributeFilter -class OtelExporterGrpcConfig(UniversalBaseModel): +class OtelTracesExporterCommonConfig(UniversalBaseModel): """ - gRPC Configuration - """ - - type: typing.Literal["grpc"] = pydantic.Field(default="grpc") - """ - Configuration type - """ - - endpoint: str = pydantic.Field() - """ - Traces endpoint URL where OpenTelemetry data will be sent (format: https://:) - """ - - headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) - """ - gRPC metadata to include in OpenTelemetry export requests + Common fields shared by HTTP and gRPC exporter configs """ additional_resource_attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) @@ -37,7 +22,7 @@ class OtelExporterGrpcConfig(UniversalBaseModel): Enable to prevent forwarding the LLM or MCP request and response body in exported traces. The following span attributes are dropped: tfy.input, tfy.output, tfy.input_short_hand """ - when: typing.Optional[typing.List[OtelExporterSpanAttributeFilter]] = pydantic.Field(default=None) + when: typing.Optional[typing.List[OtelTracesExporterSpanAttributeFilter]] = pydantic.Field(default=None) """ Export spans only when they match all of the following filters. Only matching on spanAttributes with string values in supported. """ diff --git a/src/truefoundry_sdk/types/otel_traces_exporter_grpc_config.py b/src/truefoundry_sdk/types/otel_traces_exporter_grpc_config.py new file mode 100644 index 00000000..d2d69e85 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_traces_exporter_grpc_config.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 +from .otel_exporter_grpc_config_base import OtelExporterGrpcConfigBase +from .otel_traces_exporter_common_config import OtelTracesExporterCommonConfig + + +class OtelTracesExporterGrpcConfig(OtelExporterGrpcConfigBase, OtelTracesExporterCommonConfig): + """ + gRPC Configuration + """ + + type: typing.Literal["grpc"] = pydantic.Field(default="grpc") + """ + Configuration 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/otel_traces_exporter_http_config.py b/src/truefoundry_sdk/types/otel_traces_exporter_http_config.py new file mode 100644 index 00000000..a817b267 --- /dev/null +++ b/src/truefoundry_sdk/types/otel_traces_exporter_http_config.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 +from .otel_exporter_http_config_base import OtelExporterHttpConfigBase +from .otel_traces_exporter_common_config import OtelTracesExporterCommonConfig + + +class OtelTracesExporterHttpConfig(OtelExporterHttpConfigBase, OtelTracesExporterCommonConfig): + """ + HTTP Configuration + """ + + type: typing.Literal["http"] = pydantic.Field(default="http") + """ + Configuration 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/otel_exporter_span_attribute_filter.py b/src/truefoundry_sdk/types/otel_traces_exporter_span_attribute_filter.py similarity index 93% rename from src/truefoundry_sdk/types/otel_exporter_span_attribute_filter.py rename to src/truefoundry_sdk/types/otel_traces_exporter_span_attribute_filter.py index f0fb4127..ba1e3317 100644 --- a/src/truefoundry_sdk/types/otel_exporter_span_attribute_filter.py +++ b/src/truefoundry_sdk/types/otel_traces_exporter_span_attribute_filter.py @@ -6,7 +6,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class OtelExporterSpanAttributeFilter(UniversalBaseModel): +class OtelTracesExporterSpanAttributeFilter(UniversalBaseModel): """ Filter configuration for filtering spans by attributes before exporting """ diff --git a/src/truefoundry_sdk/types/pager_duty_provider_account.py b/src/truefoundry_sdk/types/pager_duty_provider_account.py index 9e4c54a9..53202738 100644 --- a/src/truefoundry_sdk/types/pager_duty_provider_account.py +++ b/src/truefoundry_sdk/types/pager_duty_provider_account.py @@ -30,9 +30,9 @@ class PagerDutyProviderAccount(UniversalBaseModel): List of integrations that are associated with the PagerDuty provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/palm_provider_account.py b/src/truefoundry_sdk/types/palm_provider_account.py index 8cb316a0..413cc183 100644 --- a/src/truefoundry_sdk/types/palm_provider_account.py +++ b/src/truefoundry_sdk/types/palm_provider_account.py @@ -38,9 +38,9 @@ class PalmProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/palo_alto_prisma_airs_guardrail_config.py b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py index db1b996f..efee0680 100644 --- a/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py +++ b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py @@ -19,9 +19,7 @@ class PaloAltoPrismaAirsGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Palo Alto Prisma AIRS for AI security and content validation" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config_config.py b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config_config.py index 56d852a7..4f2fb220 100644 --- a/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config_config.py @@ -28,6 +28,11 @@ class PaloAltoPrismaAirsGuardrailConfigConfig(UniversalBaseModel): Execution mode for the guardrail. Sync waits for the guardrail check to complete before proceeding. Async triggers the check without waiting. Defaults to sync. """ + metadata_key_mapping: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Map Palo Alto AIRS metadata fields to TrueFoundry request metadata keys. Key is the Palo Alto AIRS metadata field name, value is the corresponding key from X-TFY-METADATA header on the TrueFoundry side. Example: {"app_user": "user_email", "ai_model": "model_name"}. Reserved AIRS keys: ai_model, app_user, app_name. [Docs](https://www.truefoundry.com/docs/ai-gateway/palo-alto-airs) + """ + 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/pangea_guardrail_config.py b/src/truefoundry_sdk/types/pangea_guardrail_config.py index 0e66c54f..81a8928e 100644 --- a/src/truefoundry_sdk/types/pangea_guardrail_config.py +++ b/src/truefoundry_sdk/types/pangea_guardrail_config.py @@ -20,9 +20,7 @@ class PangeaGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Pangea textGuard for text security or PII detection and redaction" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -41,7 +39,7 @@ class PangeaGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/patronus_guardrail_config.py b/src/truefoundry_sdk/types/patronus_guardrail_config.py index 49f230ad..4fab554d 100644 --- a/src/truefoundry_sdk/types/patronus_guardrail_config.py +++ b/src/truefoundry_sdk/types/patronus_guardrail_config.py @@ -19,9 +19,7 @@ class PatronusGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Patronus evaluators for relevance, safety, PII, PHI, toxicity, and more" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/perplexity_ai_provider_account.py b/src/truefoundry_sdk/types/perplexity_ai_provider_account.py index 648745ae..f32ff3f1 100644 --- a/src/truefoundry_sdk/types/perplexity_ai_provider_account.py +++ b/src/truefoundry_sdk/types/perplexity_ai_provider_account.py @@ -38,9 +38,9 @@ class PerplexityAiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/personal_access_token_manifest.py b/src/truefoundry_sdk/types/personal_access_token_manifest.py index 071630e0..ee80ff22 100644 --- a/src/truefoundry_sdk/types/personal_access_token_manifest.py +++ b/src/truefoundry_sdk/types/personal_access_token_manifest.py @@ -30,9 +30,9 @@ class PersonalAccessTokenManifest(UniversalBaseModel): The fully qualified name of the user """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/poetry.py b/src/truefoundry_sdk/types/poetry.py index b7762ab1..6a4f16ed 100644 --- a/src/truefoundry_sdk/types/poetry.py +++ b/src/truefoundry_sdk/types/poetry.py @@ -17,7 +17,7 @@ class Poetry(UniversalBaseModel): +value=poetry """ - poetry_version: typing.Optional[str] = pydantic.Field(default="latest") + poetry_version: typing.Optional[str] = pydantic.Field(default=None) """ Poetry version to use """ diff --git a/src/truefoundry_sdk/types/policy_entity_types.py b/src/truefoundry_sdk/types/policy_entity_types.py index 362a13b0..9c7f7607 100644 --- a/src/truefoundry_sdk/types/policy_entity_types.py +++ b/src/truefoundry_sdk/types/policy_entity_types.py @@ -15,6 +15,7 @@ class PolicyEntityTypes(enum.StrEnum): SSH_SERVER = "ssh-server" WORKFLOW = "workflow" HELM = "helm" + VOLUME = "volume" _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`. @@ -35,6 +36,7 @@ def visit( ssh_server: typing.Callable[[], T_Result], workflow: typing.Callable[[], T_Result], helm: typing.Callable[[], T_Result], + volume: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is PolicyEntityTypes.SERVICE: @@ -51,4 +53,6 @@ def visit( return workflow() if self is PolicyEntityTypes.HELM: return helm() + if self is PolicyEntityTypes.VOLUME: + return volume() return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/port.py b/src/truefoundry_sdk/types/port.py index 9f038c06..3bc7db57 100644 --- a/src/truefoundry_sdk/types/port.py +++ b/src/truefoundry_sdk/types/port.py @@ -14,7 +14,7 @@ class Port(UniversalBaseModel): Describes the ports the service should be exposed to. """ - port: int = pydantic.Field(default=80) + port: int = pydantic.Field() """ Port number to expose. """ @@ -24,7 +24,7 @@ class Port(UniversalBaseModel): Protocol for the port. """ - expose: bool = pydantic.Field(default=True) + expose: bool = pydantic.Field() """ Expose the port """ diff --git a/src/truefoundry_sdk/types/priority_based_load_balance_target.py b/src/truefoundry_sdk/types/priority_based_load_balance_target.py index bbc42a76..ee5e68a9 100644 --- a/src/truefoundry_sdk/types/priority_based_load_balance_target.py +++ b/src/truefoundry_sdk/types/priority_based_load_balance_target.py @@ -4,6 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .headers_override import HeadersOverride from .retry_config import RetryConfig from .sla_cutoff import SlaCutoff @@ -14,7 +15,7 @@ class PriorityBasedLoadBalanceTarget(UniversalBaseModel): Target model or provider FQN """ - priority: int = pydantic.Field(default=0) + priority: int = pydantic.Field() """ Priority for the target, Lower the number, higher the priority (0 is the highest priority) """ @@ -26,7 +27,7 @@ class PriorityBasedLoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=True) + fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) """ Whether this target is a fallback candidate. If set to false, this model will not be considered as a fallback option for targets of this load-balance-rule """ @@ -36,6 +37,12 @@ class PriorityBasedLoadBalanceTarget(UniversalBaseModel): 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: diff --git a/src/truefoundry_sdk/types/private_pricing_tier.py b/src/truefoundry_sdk/types/private_pricing_tier.py index 74fff83a..0e051964 100644 --- a/src/truefoundry_sdk/types/private_pricing_tier.py +++ b/src/truefoundry_sdk/types/private_pricing_tier.py @@ -14,11 +14,14 @@ class PrivatePricingTier(UniversalBaseModel): Pricing tier for volume-based pricing (per 1000 tokens) """ - from_: typing_extensions.Annotated[int, FieldMetadata(alias="from")] = pydantic.Field(alias="from") - """ - Token count threshold where this pricing tier begins (e.g., 200000 for 200k tokens) - """ - + from_: typing_extensions.Annotated[ + int, + FieldMetadata(alias="from"), + pydantic.Field( + alias="from", + description="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 f9d47e25..12dbb6e5 100644 --- a/src/truefoundry_sdk/types/prometheus_alert_rule.py +++ b/src/truefoundry_sdk/types/prometheus_alert_rule.py @@ -29,18 +29,21 @@ class PrometheusAlertRule(UniversalBaseModel): Enter a valid PromQL expression that defines the condition for triggering this alert. The alert will fire when this expression evaluates to true for the duration specified in the duration to trigger alert field. """ - for_: typing_extensions.Annotated[float, FieldMetadata(alias="for")] = pydantic.Field(alias="for") - """ - 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. - """ - + for_: typing_extensions.Annotated[ + float, + FieldMetadata(alias="for"), + pydantic.Field( + alias="for", + 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.", + ), + ] severity: AlertSeverity description: typing.Optional[str] = pydantic.Field(default=None) """ Description of the alert rule which will be displayed in the alert rule list. This can be used to provide more context about the alert rule. """ - notification_enabled: bool = pydantic.Field(default=True) + notification_enabled: bool = pydantic.Field() """ When enabled, notifications will be sent to all configured target channels when the alert conditions are met. """ diff --git a/src/truefoundry_sdk/types/prompt.py b/src/truefoundry_sdk/types/prompt.py index 870b2e1e..e770af8a 100644 --- a/src/truefoundry_sdk/types/prompt.py +++ b/src/truefoundry_sdk/types/prompt.py @@ -10,16 +10,59 @@ class Prompt(UniversalBaseModel): - id: str - ml_repo_id: str - type: typing.Optional[typing.Literal["chat_prompt"]] = None - name: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - latest_version: typing.Optional[PromptVersion] = None - run_steps: typing.Optional[typing.List[int]] = None + """ + Generic artifact API DTO including run-step linkage for ML runs. + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact belongs to + """ + + type: typing.Optional[typing.Literal["chat_prompt"]] = pydantic.Field(default=None) + """ + Type of the artifact, always 'chat_prompt' for Prompt entities + """ + + name: str = pydantic.Field() + """ + Name of the artifact (alphanumeric characters, hyphens, and underscores only, max 256 characters) + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact was last updated + """ + + latest_version: typing.Optional[PromptVersion] = pydantic.Field(default=None) + """ + The most recent version of this prompt + """ + + run_steps: typing.Optional[typing.List[int]] = pydantic.Field(default=None) + """ + List of run step numbers where this artifact was created or 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/prompt_foo_guard_type.py b/src/truefoundry_sdk/types/prompt_foo_guard_type.py deleted file mode 100644 index 6ff24582..00000000 --- a/src/truefoundry_sdk/types/prompt_foo_guard_type.py +++ /dev/null @@ -1,38 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from ..core import enum - -T_Result = typing.TypeVar("T_Result") - - -class PromptFooGuardType(enum.StrEnum): - GUARD_CHECK = "guard_check" - PII_REDACTION = "pii_redaction" - HARMFUL_DETECTION = "harmful_detection" - _UNKNOWN = "__PROMPTFOOGUARDTYPE_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) -> "PromptFooGuardType": - unknown = cls._UNKNOWN - unknown._value_ = value - return unknown - - def visit( - self, - guard_check: typing.Callable[[], T_Result], - pii_redaction: typing.Callable[[], T_Result], - harmful_detection: typing.Callable[[], T_Result], - _unknown_member: typing.Callable[[str], T_Result], - ) -> T_Result: - if self is PromptFooGuardType.GUARD_CHECK: - return guard_check() - if self is PromptFooGuardType.PII_REDACTION: - return pii_redaction() - if self is PromptFooGuardType.HARMFUL_DETECTION: - return harmful_detection() - return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/prompt_version.py b/src/truefoundry_sdk/types/prompt_version.py index f5a90605..5a81084e 100644 --- a/src/truefoundry_sdk/types/prompt_version.py +++ b/src/truefoundry_sdk/types/prompt_version.py @@ -11,17 +11,69 @@ class PromptVersion(UniversalBaseModel): - id: str - fqn: str - created_by_subject: Subject - created_at: typing.Optional[dt.datetime] = None - updated_at: typing.Optional[dt.datetime] = None - manifest: ChatPromptManifest - usage_code_snippet: typing.Optional[str] = None - ml_repo_id: str - tags: typing.Optional[typing.List[str]] = None - usage_code_snippets: typing.Optional[typing.List[UsageCodeSnippet]] = None - prompt_id: str + """ + Tags, optional version alias, and SDK usage snippet (models, prompts, generic artifacts). + """ + + id: str = pydantic.Field() + """ + Unique identifier for the artifact version + """ + + fqn: str = pydantic.Field() + """ + Fully qualified name of the artifact version in the format '{artifact_type}:{tenant_name}/{ml_repo_name}/{artifact_name}:{version}' + """ + + created_by_subject: Subject = pydantic.Field() + """ + Subject (user, team, or service account) that created this artifact version + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was created + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + Timestamp when the artifact version was last updated + """ + + manifest: ChatPromptManifest = pydantic.Field() + """ + Manifest containing metadata specific to the chat prompt version + """ + + ml_repo_id: str = pydantic.Field() + """ + ID of the ML Repo that this artifact version belongs to + """ + + tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of tags associated with this artifact version for filtering and organization + """ + + version_alias: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional human-readable version alias (e.g. v1.0.0) + """ + + usage_code_snippet: typing.Optional[str] = pydantic.Field(default=None) + """ + Code snippet demonstrating how to use this artifact version + """ + + usage_code_snippets: typing.Optional[typing.List[UsageCodeSnippet]] = pydantic.Field(default=None) + """ + List of code snippets demonstrating how to use this prompt version in different languages + """ + + prompt_id: str = pydantic.Field() + """ + ID of the parent prompt that this version belongs to + """ 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/py_spark_task_config.py b/src/truefoundry_sdk/types/py_spark_task_config.py index 9ca67345..d38e3344 100644 --- a/src/truefoundry_sdk/types/py_spark_task_config.py +++ b/src/truefoundry_sdk/types/py_spark_task_config.py @@ -19,7 +19,7 @@ class PySparkTaskConfig(UniversalBaseModel): image: TaskPySparkBuild driver_config: SparkDriverConfig executor_config: SparkExecutorConfig - spark_conf: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + spark_conf: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) """ Extra configuration properties to be passed to the spark job. [Docs](https://spark.apache.org/docs/latest/configuration.html) """ diff --git a/src/truefoundry_sdk/types/python_build.py b/src/truefoundry_sdk/types/python_build.py index a372ae26..a4bb5d14 100644 --- a/src/truefoundry_sdk/types/python_build.py +++ b/src/truefoundry_sdk/types/python_build.py @@ -23,7 +23,7 @@ class PythonBuild(UniversalBaseModel): Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python) """ - build_context_path: str = pydantic.Field(default="./") + build_context_path: str = pydantic.Field() """ Build path relative to project root path. """ diff --git a/src/truefoundry_sdk/types/quay_provider_account.py b/src/truefoundry_sdk/types/quay_provider_account.py index 80737060..5b091d95 100644 --- a/src/truefoundry_sdk/types/quay_provider_account.py +++ b/src/truefoundry_sdk/types/quay_provider_account.py @@ -37,9 +37,9 @@ class QuayProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/recommendation.py b/src/truefoundry_sdk/types/recommendation.py index c6f01d76..1efdf721 100644 --- a/src/truefoundry_sdk/types/recommendation.py +++ b/src/truefoundry_sdk/types/recommendation.py @@ -11,36 +11,38 @@ class Recommendation(UniversalBaseModel): id: typing.Optional[str] = None - cluster_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="clusterId")] = pydantic.Field( - alias="clusterId", default=None - ) - application_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="applicationId")] = ( - pydantic.Field(alias="applicationId", default=None) - ) - deployment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="deploymentId")] = ( - pydantic.Field(alias="deploymentId", default=None) - ) + cluster_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="clusterId"), pydantic.Field(alias="clusterId") + ] = None + application_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId") + ] = None + deployment_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="deploymentId"), pydantic.Field(alias="deploymentId") + ] = None application_version: typing_extensions.Annotated[ - typing.Optional[int], FieldMetadata(alias="applicationVersion") - ] = pydantic.Field(alias="applicationVersion", default=None) + typing.Optional[int], FieldMetadata(alias="applicationVersion"), pydantic.Field(alias="applicationVersion") + ] = None recommendation_data: typing_extensions.Annotated[ - typing.Dict[str, typing.Any], FieldMetadata(alias="recommendationData") - ] = pydantic.Field(alias="recommendationData") - recommendation_type: typing_extensions.Annotated[str, FieldMetadata(alias="recommendationType")] = pydantic.Field( - alias="recommendationType" - ) + typing.Dict[str, typing.Any], + FieldMetadata(alias="recommendationData"), + pydantic.Field(alias="recommendationData"), + ] + recommendation_type: typing_extensions.Annotated[ + str, FieldMetadata(alias="recommendationType"), pydantic.Field(alias="recommendationType") + ] applied_deployment_id: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="appliedDeploymentId") - ] = pydantic.Field(alias="appliedDeploymentId", default=None) - expiry_timestamp: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="expiryTimestamp")] = pydantic.Field( - alias="expiryTimestamp" - ) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) + typing.Optional[str], FieldMetadata(alias="appliedDeploymentId"), pydantic.Field(alias="appliedDeploymentId") + ] = None + expiry_timestamp: typing_extensions.Annotated[ + dt.datetime, FieldMetadata(alias="expiryTimestamp"), pydantic.Field(alias="expiryTimestamp") + ] + 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 diff --git a/src/truefoundry_sdk/types/regex_guardrail_config.py b/src/truefoundry_sdk/types/regex_guardrail_config.py index 18acf1c7..d6449234 100644 --- a/src/truefoundry_sdk/types/regex_guardrail_config.py +++ b/src/truefoundry_sdk/types/regex_guardrail_config.py @@ -19,9 +19,7 @@ class RegexGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Regex pattern matching for content filtering or redaction" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -39,7 +37,7 @@ class RegexGuardrailConfig(UniversalBaseModel): Validate blocks when pattern matches. Mutate replaces matched text and continues. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/remote_agent.py b/src/truefoundry_sdk/types/remote_agent.py new file mode 100644 index 00000000..4b20c506 --- /dev/null +++ b/src/truefoundry_sdk/types/remote_agent.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .self_hosted_agent import SelfHostedAgent + +RemoteAgent = SelfHostedAgent diff --git a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py index 549758ad..b58aa230 100644 --- a/src/truefoundry_sdk/types/remote_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/remote_mcp_server_manifest.py @@ -50,9 +50,9 @@ class RemoteMcpServerManifest(UniversalBaseModel): Users and Teams that have access to this MCP Server """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ Key-value pairs to categorize this MCP Server (e.g., by owner or environment). diff --git a/src/truefoundry_sdk/types/resources.py b/src/truefoundry_sdk/types/resources.py index 44d6b261..f1ebca90 100644 --- a/src/truefoundry_sdk/types/resources.py +++ b/src/truefoundry_sdk/types/resources.py @@ -13,38 +13,38 @@ class Resources(UniversalBaseModel): Configure resource allocations, specify node constraints and capacity types to improve performance and reduce expenses. [Docs](https://www.truefoundry.com/docs/resources-cpu-memory-storage) """ - cpu_request: float = pydantic.Field(default=0.2) + cpu_request: float = pydantic.Field() """ Requested CPU which determines the minimum cost incurred. The CPU usage can exceed the requested amount, but not the value specified in the limit. 1 CPU means 1 CPU core. Fractional CPU can be requested like `0.5` or `0.05` """ - cpu_limit: float = pydantic.Field(default=0.5) + cpu_limit: float = pydantic.Field() """ CPU limit beyond which the usage cannot be exceeded. 1 CPU means 1 CPU core. Fractional CPU can be requested like `0.5`. CPU limit should be >= cpu request. """ - memory_request: int = pydantic.Field(default=200) + memory_request: int = pydantic.Field() """ Requested memory which determines the minimum cost incurred. The unit of memory is in megabytes(MB). So 1 means 1 MB and 2000 means 2GB. """ - memory_limit: int = pydantic.Field(default=500) + memory_limit: int = pydantic.Field() """ Memory limit after which the application will be killed with an OOM error. The unit of memory is in megabytes(MB). So 1 means 1 MB and 2000 means 2GB. MemoryLimit should be greater than memory request. """ - ephemeral_storage_request: int = pydantic.Field(default=1000) + ephemeral_storage_request: int = pydantic.Field() """ Requested disk storage. The unit of memory is in megabytes(MB). This is ephemeral storage and will be wiped out on pod restarts or eviction """ - ephemeral_storage_limit: int = pydantic.Field(default=2000) + ephemeral_storage_limit: int = pydantic.Field() """ Disk storage limit. The unit of memory is in megabytes(MB). Exceeding this limit will result in eviction. It should be greater than the request. This is ephemeral storage and will be wiped out on pod restarts or eviction diff --git a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment.py b/src/truefoundry_sdk/types/response_format_json_object.py similarity index 72% rename from src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment.py rename to src/truefoundry_sdk/types/response_format_json_object.py index 60986964..f697db89 100644 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config_category_thresholds_value_harassment.py +++ b/src/truefoundry_sdk/types/response_format_json_object.py @@ -6,10 +6,8 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class OpenAiModerationsGuardrailConfigConfigCategoryThresholdsValueHarassment(UniversalBaseModel): - harassment: float - sexual: float - violence: float +class ResponseFormatJsonObject(UniversalBaseModel): + type: typing.Literal["json_object"] = "json_object" 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/response_format_json_schema.py b/src/truefoundry_sdk/types/response_format_json_schema.py new file mode 100644 index 00000000..cb481a59 --- /dev/null +++ b/src/truefoundry_sdk/types/response_format_json_schema.py @@ -0,0 +1,20 @@ +# 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 .response_format_json_schema_json_schema import ResponseFormatJsonSchemaJsonSchema + + +class ResponseFormatJsonSchema(UniversalBaseModel): + type: typing.Literal["json_schema"] = "json_schema" + json_schema: ResponseFormatJsonSchemaJsonSchema + + 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/response_format_json_schema_json_schema.py b/src/truefoundry_sdk/types/response_format_json_schema_json_schema.py new file mode 100644 index 00000000..2b92dd23 --- /dev/null +++ b/src/truefoundry_sdk/types/response_format_json_schema_json_schema.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 + + +class ResponseFormatJsonSchemaJsonSchema(UniversalBaseModel): + name: str + description: typing.Optional[str] = None + schema_: typing_extensions.Annotated[ + typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="schema"), pydantic.Field(alias="schema") + ] = None + strict: typing.Optional[bool] = 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/response_format_text.py b/src/truefoundry_sdk/types/response_format_text.py new file mode 100644 index 00000000..1bb49798 --- /dev/null +++ b/src/truefoundry_sdk/types/response_format_text.py @@ -0,0 +1,18 @@ +# 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 ResponseFormatText(UniversalBaseModel): + type: typing.Literal["text"] = "text" + + 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/retry_config.py b/src/truefoundry_sdk/types/retry_config.py index 8dfc105f..6abc6397 100644 --- a/src/truefoundry_sdk/types/retry_config.py +++ b/src/truefoundry_sdk/types/retry_config.py @@ -12,7 +12,7 @@ class RetryConfig(UniversalBaseModel): Number of attempts to retry the request """ - delay: typing.Optional[int] = pydantic.Field(default=100) + delay: typing.Optional[int] = pydantic.Field(default=None) """ Delay between retries in milliseconds """ diff --git a/src/truefoundry_sdk/types/role_binding_manifest.py b/src/truefoundry_sdk/types/role_binding_manifest.py new file mode 100644 index 00000000..e6ae232e --- /dev/null +++ b/src/truefoundry_sdk/types/role_binding_manifest.py @@ -0,0 +1,38 @@ +# 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 .role_binding_permission import RoleBindingPermission +from .role_binding_subject import RoleBindingSubject + + +class RoleBindingManifest(UniversalBaseModel): + type: typing.Literal["role-binding"] = pydantic.Field(default="role-binding") + """ + +value=role-binding + """ + + name: str = pydantic.Field() + """ + Unique name for this role binding. + """ + + subjects: typing.List[RoleBindingSubject] = pydantic.Field() + """ + One row per principal; set type and name (email, team name, virtual account name, or external identity name). + """ + + permissions: typing.List[RoleBindingPermission] = pydantic.Field() + """ + Resource-scoped role grants (resource type, FQN, and role name). + """ + + 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_permission.py b/src/truefoundry_sdk/types/role_binding_permission.py new file mode 100644 index 00000000..2be7a42d --- /dev/null +++ b/src/truefoundry_sdk/types/role_binding_permission.py @@ -0,0 +1,37 @@ +# 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 RoleBindingPermission(UniversalBaseModel): + """ + Grants a named account role on a specific resource identified by FQN. + """ + + resource_type: typing_extensions.Annotated[ + str, + FieldMetadata(alias="resourceType"), + pydantic.Field(alias="resourceType", description="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."), + ] + role: str = pydantic.Field() + """ + Name of the role to bind (e.g. workspace-editor, model-user). + """ + + 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 new file mode 100644 index 00000000..46c1827e --- /dev/null +++ b/src/truefoundry_sdk/types/role_binding_subject.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 .role_binding_subject_type import RoleBindingSubjectType + + +class RoleBindingSubject(UniversalBaseModel): + """ + Single row per principal: type selects how to interpret name (email vs names). + Field names mirror the manifest root (type + name) for consistency in the UI and YAML. + """ + + type: RoleBindingSubjectType = pydantic.Field() + """ + Whether this row identifies a user (email), a team (name), a virtual account (name), or an external identity (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. + """ + + 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_type.py b/src/truefoundry_sdk/types/role_binding_subject_type.py new file mode 100644 index 00000000..66561e9a --- /dev/null +++ b/src/truefoundry_sdk/types/role_binding_subject_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 RoleBindingSubjectType(enum.StrEnum): + """ + Whether this row identifies a user (email), a team (name), a virtual account (name), or an external identity (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`. + """ + + @classmethod + def _missing_(cls, value: typing.Any) -> "RoleBindingSubjectType": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + 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: + return user() + if self is RoleBindingSubjectType.TEAM: + 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/role_manifest.py b/src/truefoundry_sdk/types/role_manifest.py index d842d280..be75e241 100644 --- a/src/truefoundry_sdk/types/role_manifest.py +++ b/src/truefoundry_sdk/types/role_manifest.py @@ -19,25 +19,21 @@ class RoleManifest(UniversalBaseModel): Unique identifier of the role across the organization """ - display_name: typing_extensions.Annotated[str, FieldMetadata(alias="displayName")] = pydantic.Field( - alias="displayName" - ) - """ - Human-readable name for the role - """ - + display_name: typing_extensions.Annotated[ + str, + FieldMetadata(alias="displayName"), + pydantic.Field(alias="displayName", description="Human-readable name for the role"), + ] description: str = pydantic.Field() """ Description of the role that explains its purpose and permissions """ - resource_type: typing_extensions.Annotated[str, FieldMetadata(alias="resourceType")] = pydantic.Field( - alias="resourceType" - ) - """ - Type of resource this role applies to - """ - + resource_type: typing_extensions.Annotated[ + str, + FieldMetadata(alias="resourceType"), + pydantic.Field(alias="resourceType", description="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/role_with_resource.py b/src/truefoundry_sdk/types/role_with_resource.py index 4b81d251..6bde6343 100644 --- a/src/truefoundry_sdk/types/role_with_resource.py +++ b/src/truefoundry_sdk/types/role_with_resource.py @@ -10,13 +10,11 @@ class RoleWithResource(UniversalBaseModel): - role_id: typing_extensions.Annotated[str, FieldMetadata(alias="roleId")] = pydantic.Field(alias="roleId") - resource_type: typing_extensions.Annotated[RoleWithResourceResourceType, FieldMetadata(alias="resourceType")] = ( - pydantic.Field(alias="resourceType") - ) - resource_id: typing_extensions.Annotated[str, FieldMetadata(alias="resourceId")] = pydantic.Field( - alias="resourceId" - ) + role_id: typing_extensions.Annotated[str, FieldMetadata(alias="roleId"), pydantic.Field(alias="roleId")] + resource_type: typing_extensions.Annotated[ + RoleWithResourceResourceType, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType") + ] + resource_id: typing_extensions.Annotated[str, FieldMetadata(alias="resourceId"), pydantic.Field(alias="resourceId")] 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/role_with_resource_resource_type.py b/src/truefoundry_sdk/types/role_with_resource_resource_type.py index e8e8bbd8..6a7ab07d 100644 --- a/src/truefoundry_sdk/types/role_with_resource_resource_type.py +++ b/src/truefoundry_sdk/types/role_with_resource_resource_type.py @@ -27,6 +27,7 @@ class RoleWithResourceResourceType(enum.StrEnum): SERVICE_ACCOUNT = "service-account" LLM_GATEWAY = "llm-gateway" POLICY = "policy" + ROLE_BINDING = "role-binding" SETTINGS = "settings" PROVIDER_ACCOUNT = "provider-account" USER = "user" @@ -76,6 +77,7 @@ def visit( 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], @@ -133,6 +135,8 @@ def visit( return llm_gateway() if self is RoleWithResourceResourceType.POLICY: return policy() + if self is RoleWithResourceResourceType.ROLE_BINDING: + return role_binding() if self is RoleWithResourceResourceType.SETTINGS: return settings() if self is RoleWithResourceResourceType.PROVIDER_ACCOUNT: diff --git a/src/truefoundry_sdk/types/rolling.py b/src/truefoundry_sdk/types/rolling.py index 87ec321c..b1925f33 100644 --- a/src/truefoundry_sdk/types/rolling.py +++ b/src/truefoundry_sdk/types/rolling.py @@ -22,14 +22,14 @@ class Rolling(UniversalBaseModel): +value=rolling_update """ - max_unavailable_percentage: int = pydantic.Field(default=25) + max_unavailable_percentage: int = pydantic.Field() """ Percentage of total replicas that can be brought down at one time. For a value of 25 when replicas are set to 12 this would mean minimum (25% of 12) = 3 pods might be unavailable during the deployment. Setting this to a higher value can help in speeding up the deployment process. """ - max_surge_percentage: int = pydantic.Field(default=25) + max_surge_percentage: int = pydantic.Field() """ Percentage of total replicas of updated image that can be brought up over the total replicas count. For a value of 25 when replicas are set to 12 this would mean (12+(25% of 12) = 15) pods might be running at one time. diff --git a/src/truefoundry_sdk/types/sagemaker_assumed_role_based_auth.py b/src/truefoundry_sdk/types/sagemaker_assumed_role_based_auth.py new file mode 100644 index 00000000..ca0803f7 --- /dev/null +++ b/src/truefoundry_sdk/types/sagemaker_assumed_role_based_auth.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .aws_bedrock_assumed_role_based_auth import AwsBedrockAssumedRoleBasedAuth + +SagemakerAssumedRoleBasedAuth = AwsBedrockAssumedRoleBasedAuth diff --git a/src/truefoundry_sdk/types/samba_nova_provider_account.py b/src/truefoundry_sdk/types/samba_nova_provider_account.py index 8e27b74d..f2e5f46e 100644 --- a/src/truefoundry_sdk/types/samba_nova_provider_account.py +++ b/src/truefoundry_sdk/types/samba_nova_provider_account.py @@ -38,9 +38,9 @@ class SambaNovaProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/secret.py b/src/truefoundry_sdk/types/secret.py index 029a74c5..814ec15c 100644 --- a/src/truefoundry_sdk/types/secret.py +++ b/src/truefoundry_sdk/types/secret.py @@ -16,28 +16,32 @@ class Secret(UniversalBaseModel): id: str fqn: str name: str - secret_group_id: typing_extensions.Annotated[str, FieldMetadata(alias="secretGroupId")] = pydantic.Field( - alias="secretGroupId" - ) + secret_group_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="secretGroupId"), pydantic.Field(alias="secretGroupId") + ] value: typing.Optional[str] = None created_by_subject: typing_extensions.Annotated[ - typing.Optional[Subject], FieldMetadata(alias="createdBySubject") - ] = pydantic.Field(alias="createdBySubject", default=None) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) + typing.Optional[Subject], FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] = 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 secret_versions: typing_extensions.Annotated[ - typing.Optional[typing.List["SecretVersion"]], FieldMetadata(alias="secretVersions") - ] = pydantic.Field(alias="secretVersions", default=None) + typing.Optional[typing.List["SecretVersion"]], + FieldMetadata(alias="secretVersions"), + pydantic.Field(alias="secretVersions"), + ] = None active_deployments_count: typing_extensions.Annotated[ - typing.Optional[int], FieldMetadata(alias="activeDeploymentsCount") - ] = pydantic.Field(alias="activeDeploymentsCount", default=None) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + typing.Optional[int], + FieldMetadata(alias="activeDeploymentsCount"), + pydantic.Field(alias="activeDeploymentsCount"), + ] = 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 diff --git a/src/truefoundry_sdk/types/secret_detection_guardrail_config.py b/src/truefoundry_sdk/types/secret_detection_guardrail_config.py index 72918e89..fa606d2e 100644 --- a/src/truefoundry_sdk/types/secret_detection_guardrail_config.py +++ b/src/truefoundry_sdk/types/secret_detection_guardrail_config.py @@ -19,9 +19,7 @@ class SecretDetectionGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Detects likely credentials/secrets (AWS keys, API keys, JWT tokens, private keys)" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -39,13 +37,13 @@ class SecretDetectionGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ enforcing_strategy: EnforcingStrategy - config: SecretDetectionGuardrailConfigConfig = pydantic.Field() + config: typing.Optional[SecretDetectionGuardrailConfigConfig] = pydantic.Field(default=None) """ +uiType=Ignore +uiProps={"forwardJsonKey": true} diff --git a/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py b/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py index 3ee0cad5..9661df3d 100644 --- a/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py @@ -12,7 +12,7 @@ class SecretDetectionGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - redaction_text: typing.Optional[str] = pydantic.Field(default="[REDACTED]") + redaction_text: typing.Optional[str] = pydantic.Field(default=None) """ Text to use when redacting detected secrets in logs and error messages. Defaults to '[REDACTED]'.Only applicable in mutate mode. """ diff --git a/src/truefoundry_sdk/types/secret_group.py b/src/truefoundry_sdk/types/secret_group.py index 29f69239..dcf4c6b3 100644 --- a/src/truefoundry_sdk/types/secret_group.py +++ b/src/truefoundry_sdk/types/secret_group.py @@ -15,29 +15,27 @@ class SecretGroup(UniversalBaseModel): id: typing.Optional[str] = None fqn: typing.Optional[str] = None - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - associated_secrets: typing_extensions.Annotated[typing.List["Secret"], FieldMetadata(alias="associatedSecrets")] = ( - pydantic.Field(alias="associatedSecrets") - ) - integration_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="integrationId")] = ( - pydantic.Field(alias="integrationId", default=None) - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + associated_secrets: typing_extensions.Annotated[ + typing.List["Secret"], FieldMetadata(alias="associatedSecrets"), pydantic.Field(alias="associatedSecrets") + ] + integration_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="integrationId"), pydantic.Field(alias="integrationId") + ] = None manifest: typing.Optional[typing.Dict[str, typing.Any]] = None - 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" - ) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + 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") + ] + 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 diff --git a/src/truefoundry_sdk/types/secret_group_manifest.py b/src/truefoundry_sdk/types/secret_group_manifest.py index d144013f..d26636c5 100644 --- a/src/truefoundry_sdk/types/secret_group_manifest.py +++ b/src/truefoundry_sdk/types/secret_group_manifest.py @@ -31,9 +31,9 @@ class SecretGroupManifest(UniversalBaseModel): Users and Teams that have access to Secret Group """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/secret_version.py b/src/truefoundry_sdk/types/secret_version.py index 9e91c225..11ca0d25 100644 --- a/src/truefoundry_sdk/types/secret_version.py +++ b/src/truefoundry_sdk/types/secret_version.py @@ -17,15 +17,15 @@ class SecretVersion(UniversalBaseModel): value: typing.Optional[str] = None version: typing.Optional[float] = None secret: typing.Optional["Secret"] = None - secret_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="secretId")] = pydantic.Field( - alias="secretId", default=None - ) - created_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="createdAt")] = ( - pydantic.Field(alias="createdAt", default=None) - ) - updated_at: typing_extensions.Annotated[typing.Optional[dt.datetime], FieldMetadata(alias="updatedAt")] = ( - pydantic.Field(alias="updatedAt", default=None) - ) + secret_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="secretId"), pydantic.Field(alias="secretId") + ] = 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 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/self_hosted_agent.py b/src/truefoundry_sdk/types/self_hosted_agent.py new file mode 100644 index 00000000..adba6365 --- /dev/null +++ b/src/truefoundry_sdk/types/self_hosted_agent.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 +from .agent_framework import AgentFramework +from .base_remote_agent import BaseRemoteAgent +from .custom_agent_server_auth import CustomAgentServerAuth + + +class SelfHostedAgent(BaseRemoteAgent): + """ + Self Hosted + """ + + type: typing.Literal["remote-agent/self-hosted"] = pydantic.Field(default="remote-agent/self-hosted") + """ + Type of the manifest + """ + + url: str = pydantic.Field() + """ + The URL of the server + """ + + auth_data: typing.Optional[CustomAgentServerAuth] = None + framework: AgentFramework + + 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/self_hosted_model_provider_account.py b/src/truefoundry_sdk/types/self_hosted_model_provider_account.py index caf9aa1a..be6a1601 100644 --- a/src/truefoundry_sdk/types/self_hosted_model_provider_account.py +++ b/src/truefoundry_sdk/types/self_hosted_model_provider_account.py @@ -38,9 +38,9 @@ class SelfHostedModelProviderAccount(UniversalBaseModel): Collaborators """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/semantic_cache_config.py b/src/truefoundry_sdk/types/semantic_cache_config.py index 053ae287..80d3d515 100644 --- a/src/truefoundry_sdk/types/semantic_cache_config.py +++ b/src/truefoundry_sdk/types/semantic_cache_config.py @@ -22,7 +22,7 @@ class SemanticCacheConfig(UniversalBaseModel): Cache namespace (defaults to 'default' if not provided) """ - ttl: float = pydantic.Field(default=3600.0) + ttl: float = pydantic.Field() """ Time-to-live for cached entries in seconds (max 3 days) """ diff --git a/src/truefoundry_sdk/types/service.py b/src/truefoundry_sdk/types/service.py index 180ab206..567d02d5 100644 --- a/src/truefoundry_sdk/types/service.py +++ b/src/truefoundry_sdk/types/service.py @@ -26,7 +26,7 @@ class Service(BaseService): """ auto_shutdown: typing.Optional[Autoshutdown] = None - allow_interception: typing.Optional[bool] = pydantic.Field(default=False) + allow_interception: typing.Optional[bool] = pydantic.Field(default=None) """ Whether to allow intercepts to be applied for this service. This would inject an additional sidecar in each pod of the service. Not recommended on production diff --git a/src/truefoundry_sdk/types/session.py b/src/truefoundry_sdk/types/session.py index 7903bca8..b51f0de9 100644 --- a/src/truefoundry_sdk/types/session.py +++ b/src/truefoundry_sdk/types/session.py @@ -15,42 +15,46 @@ class Session(UniversalBaseModel): id: str - user_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="userName")] = pydantic.Field( - alias="userName", default=None - ) - subject_slug: typing_extensions.Annotated[str, FieldMetadata(alias="subjectSlug")] = pydantic.Field( - alias="subjectSlug" - ) + user_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="userName"), pydantic.Field(alias="userName") + ] = None + subject_slug: typing_extensions.Annotated[ + str, FieldMetadata(alias="subjectSlug"), pydantic.Field(alias="subjectSlug") + ] subject_controller_name: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="subjectControllerName") - ] = pydantic.Field(alias="subjectControllerName", default=None) - subject_pat_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="subjectPatName")] = ( - pydantic.Field(alias="subjectPatName", default=None) - ) + typing.Optional[str], + FieldMetadata(alias="subjectControllerName"), + pydantic.Field(alias="subjectControllerName"), + ] = None + subject_pat_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="subjectPatName"), pydantic.Field(alias="subjectPatName") + ] = None email: typing.Optional[str] = None - subject_type: typing_extensions.Annotated[SubjectType, FieldMetadata(alias="subjectType")] = pydantic.Field( - alias="subjectType" - ) - tenant_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName", default=None - ) + subject_type: typing_extensions.Annotated[ + SubjectType, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType") + ] + tenant_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName") + ] = None roles: typing.List[str] teams: typing.List[SessionTeam] accounts: typing.List[SessionAccount] metadata: typing.Optional[UserMetadata] = None - is_billing_enabled: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isBillingEnabled")] = ( - pydantic.Field(alias="isBillingEnabled", default=None) - ) + is_billing_enabled: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="isBillingEnabled"), pydantic.Field(alias="isBillingEnabled") + ] = None service_account_metadata: typing_extensions.Annotated[ - typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="serviceAccountMetadata") - ] = pydantic.Field(alias="serviceAccountMetadata", default=None) + typing.Optional[typing.Dict[str, typing.Any]], + FieldMetadata(alias="serviceAccountMetadata"), + pydantic.Field(alias="serviceAccountMetadata"), + ] = None account: typing.Optional[Account] = None - root_account: typing_extensions.Annotated[typing.Optional[Account], FieldMetadata(alias="rootAccount")] = ( - pydantic.Field(alias="rootAccount", default=None) - ) - effective_user_id: typing_extensions.Annotated[str, FieldMetadata(alias="effectiveUserId")] = pydantic.Field( - alias="effectiveUserId" - ) + root_account: typing_extensions.Annotated[ + typing.Optional[Account], FieldMetadata(alias="rootAccount"), pydantic.Field(alias="rootAccount") + ] = None + effective_user_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="effectiveUserId"), pydantic.Field(alias="effectiveUserId") + ] 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/signed_url.py b/src/truefoundry_sdk/types/signed_url.py index 728c0519..fab76ab5 100644 --- a/src/truefoundry_sdk/types/signed_url.py +++ b/src/truefoundry_sdk/types/signed_url.py @@ -7,8 +7,15 @@ class SignedUrl(UniversalBaseModel): - path: str - signed_url: str + path: str = pydantic.Field() + """ + Relative path of the file within the artifact storage + """ + + signed_url: str = pydantic.Field() + """ + Pre-signed URL that can be used to access the file directly + """ 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/slack_provider_account.py b/src/truefoundry_sdk/types/slack_provider_account.py index c52f1a8d..67eb61dc 100644 --- a/src/truefoundry_sdk/types/slack_provider_account.py +++ b/src/truefoundry_sdk/types/slack_provider_account.py @@ -30,9 +30,9 @@ class SlackProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/smtp_credentials.py b/src/truefoundry_sdk/types/smtp_credentials.py index ea40574d..f44594be 100644 --- a/src/truefoundry_sdk/types/smtp_credentials.py +++ b/src/truefoundry_sdk/types/smtp_credentials.py @@ -32,12 +32,12 @@ class SmtpCredentials(UniversalBaseModel): The password for the SMTP server. """ - port: int = pydantic.Field(default=587) + port: int = pydantic.Field() """ The port of the SMTP server. """ - tls: bool = pydantic.Field(default=True) + tls: bool = pydantic.Field() """ Whether to use TLS for the SMTP server. """ diff --git a/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py b/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py index 7a3df225..0ee4c7c0 100644 --- a/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py +++ b/src/truefoundry_sdk/types/snowflake_cortex_provider_account.py @@ -45,9 +45,9 @@ class SnowflakeCortexProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/span_attribute_filter.py b/src/truefoundry_sdk/types/span_attribute_filter.py index 11edeaa2..e3df424d 100644 --- a/src/truefoundry_sdk/types/span_attribute_filter.py +++ b/src/truefoundry_sdk/types/span_attribute_filter.py @@ -11,9 +11,9 @@ class SpanAttributeFilter(UniversalBaseModel): - span_attribute_key: typing_extensions.Annotated[str, FieldMetadata(alias="spanAttributeKey")] = pydantic.Field( - alias="spanAttributeKey" - ) + span_attribute_key: typing_extensions.Annotated[ + str, FieldMetadata(alias="spanAttributeKey"), pydantic.Field(alias="spanAttributeKey") + ] operator: SpanAttributeFilterOperator value: SpanAttributeFilterValue diff --git a/src/truefoundry_sdk/types/span_field_filter.py b/src/truefoundry_sdk/types/span_field_filter.py index a4eebee7..b29e5632 100644 --- a/src/truefoundry_sdk/types/span_field_filter.py +++ b/src/truefoundry_sdk/types/span_field_filter.py @@ -12,9 +12,9 @@ class SpanFieldFilter(UniversalBaseModel): - span_field_name: typing_extensions.Annotated[SpanFieldFilterSpanFieldName, FieldMetadata(alias="spanFieldName")] = ( - pydantic.Field(alias="spanFieldName") - ) + span_field_name: typing_extensions.Annotated[ + SpanFieldFilterSpanFieldName, FieldMetadata(alias="spanFieldName"), pydantic.Field(alias="spanFieldName") + ] operator: SpanFieldFilterOperator value: SpanFieldFilterValue diff --git a/src/truefoundry_sdk/types/spark_build.py b/src/truefoundry_sdk/types/spark_build.py index 0be18066..64f0ba8a 100644 --- a/src/truefoundry_sdk/types/spark_build.py +++ b/src/truefoundry_sdk/types/spark_build.py @@ -16,12 +16,12 @@ class SparkBuild(UniversalBaseModel): +value=tfy-spark-buildpack """ - spark_version: str = pydantic.Field(default="3.5.2") + spark_version: str = pydantic.Field() """ Spark version should match the spark version installed in the image. """ - build_context_path: str = pydantic.Field(default="./") + build_context_path: str = pydantic.Field() """ Build path relative to project root path. """ diff --git a/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py b/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py index a706bacc..1ac9e1e8 100644 --- a/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py +++ b/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py @@ -16,12 +16,12 @@ class SparkExecutorDynamicScaling(UniversalBaseModel): +value=dynamic """ - min: int = pydantic.Field(default=1) + min: int = pydantic.Field() """ Minimum number of instances to start / scale down to """ - max: int = pydantic.Field(default=1) + max: int = pydantic.Field() """ Maximum number of instances to scale up to """ diff --git a/src/truefoundry_sdk/types/spark_executor_fixed_instances.py b/src/truefoundry_sdk/types/spark_executor_fixed_instances.py index 18f31b80..7800d49f 100644 --- a/src/truefoundry_sdk/types/spark_executor_fixed_instances.py +++ b/src/truefoundry_sdk/types/spark_executor_fixed_instances.py @@ -16,7 +16,7 @@ class SparkExecutorFixedInstances(UniversalBaseModel): +value=fixed """ - count: int = pydantic.Field(default=1) + count: int = pydantic.Field() """ Number of instances to start """ diff --git a/src/truefoundry_sdk/types/spark_image.py b/src/truefoundry_sdk/types/spark_image.py index bf4baa60..3c121190 100644 --- a/src/truefoundry_sdk/types/spark_image.py +++ b/src/truefoundry_sdk/types/spark_image.py @@ -16,7 +16,7 @@ class SparkImage(UniversalBaseModel): +value=spark-image """ - spark_version: str = pydantic.Field(default="3.5.2") + spark_version: str = pydantic.Field() """ Spark version should match the spark version installed in the image. """ diff --git a/src/truefoundry_sdk/types/spark_job.py b/src/truefoundry_sdk/types/spark_job.py index 5b99107a..e6a70a1f 100644 --- a/src/truefoundry_sdk/types/spark_job.py +++ b/src/truefoundry_sdk/types/spark_job.py @@ -40,7 +40,7 @@ class SparkJob(UniversalBaseModel): Configure environment variables to be injected in the service either as plain text. [Docs](https://docs.truefoundry.com/docs/env-variables) """ - spark_conf: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + spark_conf: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) """ Extra configuration properties to be passed to the spark job. [Docs](https://spark.apache.org/docs/latest/configuration.html) """ @@ -50,7 +50,7 @@ class SparkJob(UniversalBaseModel): Configure volumes to be mounted to driver and executors. [Docs](https://docs.truefoundry.com/docs/mounting-volumes-job) """ - retries: typing.Optional[int] = pydantic.Field(default=0) + retries: typing.Optional[int] = pydantic.Field(default=None) """ Specify the maximum number of attempts to retry a job before it is marked as failed. """ diff --git a/src/truefoundry_sdk/types/spark_job_trigger_input.py b/src/truefoundry_sdk/types/spark_job_trigger_input.py index 57c3fc89..964ba8c4 100644 --- a/src/truefoundry_sdk/types/spark_job_trigger_input.py +++ b/src/truefoundry_sdk/types/spark_job_trigger_input.py @@ -9,20 +9,16 @@ class SparkJobTriggerInput(UniversalBaseModel): - main_class: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="mainClass")] = pydantic.Field( - alias="mainClass", default=None - ) - """ - Main Class for Spark Job - """ - + main_class: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="mainClass"), + pydantic.Field(alias="mainClass", description="Main Class for Spark Job"), + ] = None main_application_file: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="mainApplicationFile") - ] = pydantic.Field(alias="mainApplicationFile", default=None) - """ - Main Application File for Spark Job - """ - + typing.Optional[str], + FieldMetadata(alias="mainApplicationFile"), + pydantic.Field(alias="mainApplicationFile", description="Main Application File for Spark Job"), + ] = None arguments: typing.Optional[str] = pydantic.Field(default=None) """ Arguments to pass to the main application file diff --git a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py index d2a2c5a2..018cbb16 100644 --- a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py +++ b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py @@ -19,9 +19,7 @@ class SqlSanitizerGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="Detects and sanitizes risky SQL patterns (DROP, TRUNCATE, DELETE/UPDATE without WHERE, string interpolation)" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -39,7 +37,7 @@ class SqlSanitizerGuardrailConfig(UniversalBaseModel): Validate (detect and block) or Mutate (detect, sanitize comments, and continue). """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py index 6d3dfcd4..4f4cd874 100644 --- a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py @@ -7,47 +7,47 @@ class SqlSanitizerGuardrailConfigConfig(UniversalBaseModel): - block_drop: typing.Optional[bool] = pydantic.Field(default=True) + block_drop: typing.Optional[bool] = pydantic.Field(default=None) """ Block SQL DROP statements as dangerous operations. """ - block_truncate: typing.Optional[bool] = pydantic.Field(default=True) + block_truncate: typing.Optional[bool] = pydantic.Field(default=None) """ Block SQL TRUNCATE statements as dangerous operations. """ - block_alter: typing.Optional[bool] = pydantic.Field(default=True) + block_alter: typing.Optional[bool] = pydantic.Field(default=None) """ Block SQL ALTER statements as dangerous operations. """ - block_grant: typing.Optional[bool] = pydantic.Field(default=True) + block_grant: typing.Optional[bool] = pydantic.Field(default=None) """ Block SQL GRANT statements as dangerous operations. """ - block_revoke: typing.Optional[bool] = pydantic.Field(default=True) + block_revoke: typing.Optional[bool] = pydantic.Field(default=None) """ Block SQL REVOKE statements as dangerous operations. """ - strip_comments: typing.Optional[bool] = pydantic.Field(default=True) + strip_comments: typing.Optional[bool] = pydantic.Field(default=None) """ Remove SQL comments (-- and block comments) from queries. In mutate mode, comments are stripped from the output. """ - block_delete_without_where: typing.Optional[bool] = pydantic.Field(default=True) + block_delete_without_where: typing.Optional[bool] = pydantic.Field(default=None) """ Flag DELETE FROM statements that lack a WHERE clause as potentially dangerous. """ - block_update_without_where: typing.Optional[bool] = pydantic.Field(default=True) + block_update_without_where: typing.Optional[bool] = pydantic.Field(default=None) """ Flag UPDATE statements that lack a WHERE clause as potentially dangerous. """ - require_parameterization: typing.Optional[bool] = pydantic.Field(default=False) + require_parameterization: typing.Optional[bool] = pydantic.Field(default=None) """ Detect naive string interpolation patterns (+, %., {}) that may indicate SQL injection vulnerabilities. """ diff --git a/src/truefoundry_sdk/types/sqs_input_config.py b/src/truefoundry_sdk/types/sqs_input_config.py index f571e9d9..4c5f9854 100644 --- a/src/truefoundry_sdk/types/sqs_input_config.py +++ b/src/truefoundry_sdk/types/sqs_input_config.py @@ -32,7 +32,7 @@ class SqsInputConfig(UniversalBaseModel): A period during which Amazon SQS prevents all consumers from receiving and processing the message. If one message takes 5 seconds to process, you can set this number to 7 or any number higher than 5. This will ensure that while the message is being processed, it will not be available to other replicas. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) """ - wait_time_seconds: int = pydantic.Field(default=19) + wait_time_seconds: int = pydantic.Field() """ Wait timeout for long polling. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html) """ diff --git a/src/truefoundry_sdk/types/stage_artifact_response.py b/src/truefoundry_sdk/types/stage_artifact_response.py index a0e807e5..c62bcdba 100644 --- a/src/truefoundry_sdk/types/stage_artifact_response.py +++ b/src/truefoundry_sdk/types/stage_artifact_response.py @@ -7,9 +7,20 @@ class StageArtifactResponse(UniversalBaseModel): - id: str - storage_root: str - artifact_id: str + id: str = pydantic.Field() + """ + ID of the staged artifact version + """ + + storage_root: str = pydantic.Field() + """ + Root storage path where the artifact version files should be uploaded + """ + + artifact_id: str = pydantic.Field() + """ + ID of the artifact that the staged version belongs to + """ 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/stdio_mcp_server_manifest.py b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py new file mode 100644 index 00000000..c0bcf054 --- /dev/null +++ b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py @@ -0,0 +1,65 @@ +# 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 .mcp_server_env_auth import McpServerEnvAuth +from .owned_by import OwnedBy + + +class StdioMcpServerManifest(UniversalBaseModel): + """ + Stdio MCP server configuration. + """ + + name: str = pydantic.Field() + """ + The name of the MCP Server. + """ + + description: str = pydantic.Field() + """ + Provide a brief description of the purpose of this MCP Server. + """ + + collaborators: typing.List[Collaborator] = pydantic.Field() + """ + Users and Teams that have access to this MCP Server + """ + + type: typing.Literal["mcp-server/stdio"] = pydantic.Field(default="mcp-server/stdio") + """ + +value=mcp-server/stdio + +sort=400 + """ + + command: str = pydantic.Field() + """ + Executable to run for the stdio MCP server process. + """ + + args: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + Arguments passed to the stdio MCP server command. + """ + + auth_data: typing.Optional[McpServerEnvAuth] = None + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Key-value pairs to categorize this MCP Server (e.g., by owner or environment). + """ + + 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/sticky_routing.py b/src/truefoundry_sdk/types/sticky_routing.py new file mode 100644 index 00000000..e1668a1d --- /dev/null +++ b/src/truefoundry_sdk/types/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 StickyRouting(UniversalBaseModel): + """ + Sticky Routing + """ + + ttl_seconds: int = pydantic.Field() + """ + Sticky mapping TTL in seconds + """ + + 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/sticky_session_identifier.py b/src/truefoundry_sdk/types/sticky_session_identifier.py new file mode 100644 index 00000000..32b762dc --- /dev/null +++ b/src/truefoundry_sdk/types/sticky_session_identifier.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_source import StickySessionIdentifierSource + + +class StickySessionIdentifier(UniversalBaseModel): + """ + Sticky Session Identifier + """ + + source: StickySessionIdentifierSource = pydantic.Field() + """ + Source from which session identifier value will be extracted + """ + + key: str = pydantic.Field() + """ + Key to read from selected source + """ + + 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/sticky_session_identifier_source.py b/src/truefoundry_sdk/types/sticky_session_identifier_source.py new file mode 100644 index 00000000..948ad24e --- /dev/null +++ b/src/truefoundry_sdk/types/sticky_session_identifier_source.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 StickySessionIdentifierSource(enum.StrEnum): + """ + Source from which session identifier value will be extracted + """ + + HEADERS = "headers" + METADATA = "metadata" + _UNKNOWN = "__STICKYSESSIONIDENTIFIERSOURCE_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) -> "StickySessionIdentifierSource": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + headers: typing.Callable[[], T_Result], + metadata: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is StickySessionIdentifierSource.HEADERS: + return headers() + if self is StickySessionIdentifierSource.METADATA: + return metadata() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/subject.py b/src/truefoundry_sdk/types/subject.py index 2418a409..96152430 100644 --- a/src/truefoundry_sdk/types/subject.py +++ b/src/truefoundry_sdk/types/subject.py @@ -10,31 +10,39 @@ class Subject(UniversalBaseModel): - subject_id: typing_extensions.Annotated[str, FieldMetadata(alias="subjectId")] = pydantic.Field(alias="subjectId") - """ - Subject ID - """ - - subject_type: typing_extensions.Annotated[SubjectType, FieldMetadata(alias="subjectType")] = pydantic.Field( - alias="subjectType" - ) - """ - Subject type - """ - - subject_slug: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="subjectSlug")] = ( - pydantic.Field(alias="subjectSlug", default=None) - ) - """ - Subject slug - """ - + subject_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="subjectId"), pydantic.Field(alias="subjectId", description="Subject ID") + ] + subject_type: typing_extensions.Annotated[ + SubjectType, FieldMetadata(alias="subjectType"), pydantic.Field(alias="subjectType", description="Subject type") + ] + subject_slug: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="subjectSlug"), + pydantic.Field(alias="subjectSlug", description="Subject slug"), + ] = None subject_display_name: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="subjectDisplayName") - ] = pydantic.Field(alias="subjectDisplayName", default=None) - """ - Subject display name - """ + typing.Optional[str], + FieldMetadata(alias="subjectDisplayName"), + pydantic.Field(alias="subjectDisplayName", description="Subject display name"), + ] = None + subject_pat_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="subjectPatName"), + pydantic.Field(alias="subjectPatName", description="Subject PAT name"), + ] = None + subject_controller_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="subjectControllerName"), + pydantic.Field(alias="subjectControllerName"), + ] = None + subject_external_identity_slug: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="subjectExternalIdentitySlug"), + pydantic.Field( + alias="subjectExternalIdentitySlug", description="External identity slug (external_identity_id:sub:email)" + ), + ] = 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/subject_clause.py b/src/truefoundry_sdk/types/subject_clause.py index 51804360..2ae55ec2 100644 --- a/src/truefoundry_sdk/types/subject_clause.py +++ b/src/truefoundry_sdk/types/subject_clause.py @@ -9,9 +9,9 @@ class SubjectClause(UniversalBaseModel): - in_: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="in")] = pydantic.Field( - alias="in", default=None - ) + in_: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="in"), pydantic.Field(alias="in") + ] = None not_in: typing.Optional[typing.List[str]] = None if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/subject_permission.py b/src/truefoundry_sdk/types/subject_permission.py new file mode 100644 index 00000000..df851765 --- /dev/null +++ b/src/truefoundry_sdk/types/subject_permission.py @@ -0,0 +1,51 @@ +# 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 SubjectPermission(UniversalBaseModel): + resource_type: typing_extensions.Annotated[ + str, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Resource Type") + ] + resource_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="resourceId"), pydantic.Field(alias="resourceId", description="Resource ID") + ] + resource_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="resourceName"), + pydantic.Field(alias="resourceName", description="Resource Name (if available)"), + ] = None + resource_fqn: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="resourceFqn"), + pydantic.Field(alias="resourceFqn", description="Resource FQN (if available)"), + ] = None + role_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="roleId"), pydantic.Field(alias="roleId", description="Role ID") + ] + role_name: typing_extensions.Annotated[ + str, FieldMetadata(alias="roleName"), pydantic.Field(alias="roleName", description="Role Name") + ] + subject_id: typing_extensions.Annotated[ + str, + FieldMetadata(alias="subjectId"), + pydantic.Field(alias="subjectId", description="Subject ID (user or team)"), + ] + subject_type: typing_extensions.Annotated[ + str, + FieldMetadata(alias="subjectType"), + pydantic.Field(alias="subjectType", description="Subject Type (user or 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/subject_type.py b/src/truefoundry_sdk/types/subject_type.py index 54113263..722f739e 100644 --- a/src/truefoundry_sdk/types/subject_type.py +++ b/src/truefoundry_sdk/types/subject_type.py @@ -13,6 +13,7 @@ class SubjectType(enum.StrEnum): SERVICEACCOUNT = "serviceaccount" VIRTUALACCOUNT = "virtualaccount" EXTERNAL_IDENTITY = "external-identity" + ROLE = "role" _UNKNOWN = "__SUBJECTTYPE_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( serviceaccount: typing.Callable[[], T_Result], virtualaccount: typing.Callable[[], T_Result], external_identity: typing.Callable[[], T_Result], + role: typing.Callable[[], T_Result], _unknown_member: typing.Callable[[str], T_Result], ) -> T_Result: if self is SubjectType.USER: @@ -43,4 +45,6 @@ def visit( return virtualaccount() if self is SubjectType.EXTERNAL_IDENTITY: return external_identity() + if self is SubjectType.ROLE: + return role() return _unknown_member(self._value_) 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 96bfb467..bb2ded51 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 @@ -9,11 +9,11 @@ class SyncTokenInSecretStoreInfo(UniversalBaseModel): - updated_at: typing_extensions.Annotated[str, FieldMetadata(alias="updatedAt")] = pydantic.Field(alias="updatedAt") - """ - ISO timestamp of when the token was synced - """ - + updated_at: typing_extensions.Annotated[ + str, + FieldMetadata(alias="updatedAt"), + pydantic.Field(alias="updatedAt", description="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 ce2caa38..f59eeccd 100644 --- a/src/truefoundry_sdk/types/sync_virtual_account_token_response.py +++ b/src/truefoundry_sdk/types/sync_virtual_account_token_response.py @@ -11,11 +11,12 @@ class SyncVirtualAccountTokenResponse(UniversalBaseModel): sync_token_in_secret_store_info: typing_extensions.Annotated[ - SyncTokenInSecretStoreInfo, FieldMetadata(alias="syncTokenInSecretStoreInfo") - ] = pydantic.Field(alias="syncTokenInSecretStoreInfo") - """ - Sync status including timestamp and error (if any) - """ + SyncTokenInSecretStoreInfo, + FieldMetadata(alias="syncTokenInSecretStoreInfo"), + pydantic.Field( + alias="syncTokenInSecretStoreInfo", description="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/target_clause.py b/src/truefoundry_sdk/types/target_clause.py index fa9d16e6..faff21f5 100644 --- a/src/truefoundry_sdk/types/target_clause.py +++ b/src/truefoundry_sdk/types/target_clause.py @@ -7,15 +7,16 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata from .in_not_in_operator import InNotInOperator +from .mcp_tools_operator import McpToolsOperator class TargetClause(UniversalBaseModel): - mcp_servers: typing_extensions.Annotated[typing.Optional[InNotInOperator], FieldMetadata(alias="mcpServers")] = ( - pydantic.Field(alias="mcpServers", default=None) - ) - mcp_tools: typing_extensions.Annotated[typing.Optional[InNotInOperator], FieldMetadata(alias="mcpTools")] = ( - pydantic.Field(alias="mcpTools", default=None) - ) + mcp_servers: typing_extensions.Annotated[ + typing.Optional[InNotInOperator], FieldMetadata(alias="mcpServers"), pydantic.Field(alias="mcpServers") + ] = None + mcp_tools: typing_extensions.Annotated[ + typing.Optional[McpToolsOperator], FieldMetadata(alias="mcpTools"), pydantic.Field(alias="mcpTools") + ] = None model: typing.Optional[InNotInOperator] = None if IS_PYDANTIC_V2: diff --git a/src/truefoundry_sdk/types/task_docker_file_build.py b/src/truefoundry_sdk/types/task_docker_file_build.py index 796fbdef..7ca12137 100644 --- a/src/truefoundry_sdk/types/task_docker_file_build.py +++ b/src/truefoundry_sdk/types/task_docker_file_build.py @@ -13,6 +13,7 @@ class TaskDockerFileBuild(UniversalBaseModel): type: typing.Literal["task-dockerfile-build"] = pydantic.Field(default="task-dockerfile-build") """ + +uiType=Hidden +value=dockerfile """ @@ -22,7 +23,7 @@ class TaskDockerFileBuild(UniversalBaseModel): add it through the [Integrations](/integrations?tab=docker-registry) page """ - dockerfile_path: str = pydantic.Field(default="./Dockerfile") + dockerfile_path: str = pydantic.Field() """ The file path of the Dockerfile relative to project root path. """ diff --git a/src/truefoundry_sdk/types/task_py_spark_build.py b/src/truefoundry_sdk/types/task_py_spark_build.py index 53657fd7..360fe68f 100644 --- a/src/truefoundry_sdk/types/task_py_spark_build.py +++ b/src/truefoundry_sdk/types/task_py_spark_build.py @@ -13,14 +13,22 @@ class TaskPySparkBuild(UniversalBaseModel): type: typing.Literal["task-pyspark-build"] = pydantic.Field(default="task-pyspark-build") """ + +uiType=Hidden +value=task-pyspark-build """ - spark_version: str = pydantic.Field(default="3.5.2") + spark_version: str = pydantic.Field() """ Spark version should match the spark version installed in the image. """ + container_image: typing.Optional[str] = pydantic.Field(default=None) + """ + Custom container image URI. If provided, this image is used instead of the + default Spark base image (public.ecr.aws/bitnami/spark). The image must be + Debian-based and have Python and Spark pre-installed. + """ + docker_registry: typing.Optional[str] = pydantic.Field(default=None) """ FQN of the container registry. If you can't find your registry here, diff --git a/src/truefoundry_sdk/types/task_python_build.py b/src/truefoundry_sdk/types/task_python_build.py index 732cf131..b1d599d3 100644 --- a/src/truefoundry_sdk/types/task_python_build.py +++ b/src/truefoundry_sdk/types/task_python_build.py @@ -13,6 +13,7 @@ class TaskPythonBuild(UniversalBaseModel): type: typing.Literal["task-python-build"] = pydantic.Field(default="task-python-build") """ + +uiType=Hidden +value=task-python-build """ diff --git a/src/truefoundry_sdk/types/team.py b/src/truefoundry_sdk/types/team.py index 93702685..4c32ca0d 100644 --- a/src/truefoundry_sdk/types/team.py +++ b/src/truefoundry_sdk/types/team.py @@ -15,25 +15,23 @@ class Team(UniversalBaseModel): id: str description: str - 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") - 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")] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] members: typing.Optional[typing.List[str]] = 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" - ) + 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") + ] manifest: TeamManifest metadata: typing.Optional[TeamMetadata] = None - is_editable: typing_extensions.Annotated[bool, FieldMetadata(alias="isEditable")] = pydantic.Field( - alias="isEditable" - ) + is_editable: typing_extensions.Annotated[ + bool, FieldMetadata(alias="isEditable"), pydantic.Field(alias="isEditable") + ] 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 210ad43b..76b5419d 100644 --- a/src/truefoundry_sdk/types/team_manifest.py +++ b/src/truefoundry_sdk/types/team_manifest.py @@ -30,9 +30,13 @@ class TeamManifest(UniversalBaseModel): Enter email of each of the user you want to add in the team. """ - owned_by: typing_extensions.Annotated[typing.Optional[TeamOwnedBy], FieldMetadata(alias="ownedBy")] = ( - pydantic.Field(alias="ownedBy", default=None) - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[TeamOwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Key-value pairs to categorize this Team (e.g., by owner or environment). + """ 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_metadata.py b/src/truefoundry_sdk/types/team_metadata.py index d373e195..dc267166 100644 --- a/src/truefoundry_sdk/types/team_metadata.py +++ b/src/truefoundry_sdk/types/team_metadata.py @@ -9,9 +9,9 @@ class TeamMetadata(UniversalBaseModel): - created_by_scim: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="createdByScim")] = ( - pydantic.Field(alias="createdByScim", default=None) - ) + created_by_scim: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="createdByScim"), pydantic.Field(alias="createdByScim") + ] = 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/terminate_job_response.py b/src/truefoundry_sdk/types/terminate_job_response.py index e7d4ed90..32fde267 100644 --- a/src/truefoundry_sdk/types/terminate_job_response.py +++ b/src/truefoundry_sdk/types/terminate_job_response.py @@ -15,12 +15,11 @@ class TerminateJobResponse(UniversalBaseModel): Terminate Job Message """ - job_run_status: typing_extensions.Annotated[JobRunStatus, FieldMetadata(alias="jobRunStatus")] = pydantic.Field( - alias="jobRunStatus" - ) - """ - Job run status - """ + job_run_status: typing_extensions.Annotated[ + JobRunStatus, + FieldMetadata(alias="jobRunStatus"), + pydantic.Field(alias="jobRunStatus", description="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/tfy_content_moderation_guardrail_config.py b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py index 64da5c2c..a470fb51 100644 --- a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py @@ -18,7 +18,7 @@ class TfyContentModerationGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default="Content moderation guardrail, managed by TrueFoundry") + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py index 927a74a0..38acf7bb 100644 --- a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py @@ -13,7 +13,7 @@ class TfyContentModerationGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - severity_threshold: float = pydantic.Field(default=2.0) + severity_threshold: float = pydantic.Field() """ Minimum severity level (0-6) to flag content. 0=Safe, 2=Low risk, 4=Medium risk, 6=High risk """ diff --git a/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py b/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py index 9a2b1bd1..f2110996 100644 --- a/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py @@ -19,9 +19,7 @@ class TfyPiiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="PII detection and redaction guardrail, managed by TrueFoundry" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ @@ -39,7 +37,7 @@ class TfyPiiGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. """ diff --git a/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py b/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py index 8f00b885..d2231e7e 100644 --- a/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py @@ -17,7 +17,7 @@ class TfyPromptInjectionGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default="Prompt injection guardrail, managed by TrueFoundry") + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/together_ai_provider_account.py b/src/truefoundry_sdk/types/together_ai_provider_account.py index bd3332eb..656d5593 100644 --- a/src/truefoundry_sdk/types/together_ai_provider_account.py +++ b/src/truefoundry_sdk/types/together_ai_provider_account.py @@ -38,9 +38,9 @@ class TogetherAiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/token_pagination.py b/src/truefoundry_sdk/types/token_pagination.py index ccb08a2b..cdfc5286 100644 --- a/src/truefoundry_sdk/types/token_pagination.py +++ b/src/truefoundry_sdk/types/token_pagination.py @@ -14,19 +14,16 @@ class TokenPagination(UniversalBaseModel): Number of items per page """ - next_page_token: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="nextPageToken")] = ( - pydantic.Field(alias="nextPageToken", default=None) - ) - """ - Base64 encoded token for the next page - """ - - previous_page_token: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="previousPageToken")] = ( - pydantic.Field(alias="previousPageToken", default=None) - ) - """ - Base64 encoded token for the previous page - """ + next_page_token: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="nextPageToken"), + pydantic.Field(alias="nextPageToken", description="Base64 encoded token for the next page"), + ] = None + 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 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 dc287c4d..020a6b53 100644 --- a/src/truefoundry_sdk/types/trace_span.py +++ b/src/truefoundry_sdk/types/trace_span.py @@ -10,97 +10,87 @@ class TraceSpan(UniversalBaseModel): - span_id: typing_extensions.Annotated[str, FieldMetadata(alias="spanId")] = pydantic.Field(alias="spanId") - """ - Unique identifier for the span within the trace. - """ - - trace_id: typing_extensions.Annotated[str, FieldMetadata(alias="traceId")] = pydantic.Field(alias="traceId") - """ - Unique identifier for the trace that contains this span. - """ - - parent_span_id: typing_extensions.Annotated[str, FieldMetadata(alias="parentSpanId")] = pydantic.Field( - alias="parentSpanId" - ) - """ - Identifier of the parent span in the trace hierarchy. - """ - - service_name: typing_extensions.Annotated[str, FieldMetadata(alias="serviceName")] = pydantic.Field( - alias="serviceName" - ) - """ - Name of the service that generated this span. - """ - - span_name: typing_extensions.Annotated[str, FieldMetadata(alias="spanName")] = pydantic.Field(alias="spanName") - """ - Name of the span - """ - - span_kind: typing_extensions.Annotated[str, FieldMetadata(alias="spanKind")] = pydantic.Field(alias="spanKind") - """ - Type of span (e.g., CLIENT, SERVER, INTERNAL, PRODUCER, CONSUMER). - """ - - scope_name: typing_extensions.Annotated[str, FieldMetadata(alias="scopeName")] = pydantic.Field(alias="scopeName") - """ - Name of the instrumentation scope that created this span. - """ - - scope_version: typing_extensions.Annotated[str, FieldMetadata(alias="scopeVersion")] = pydantic.Field( - alias="scopeVersion" - ) - """ - Version of the instrumentation scope that created this span. - """ - + span_id: typing_extensions.Annotated[ + str, + FieldMetadata(alias="spanId"), + pydantic.Field(alias="spanId", description="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."), + ] + parent_span_id: typing_extensions.Annotated[ + str, + FieldMetadata(alias="parentSpanId"), + pydantic.Field(alias="parentSpanId", description="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."), + ] + span_name: typing_extensions.Annotated[ + str, FieldMetadata(alias="spanName"), pydantic.Field(alias="spanName", description="Name of the span") + ] + span_kind: typing_extensions.Annotated[ + str, + FieldMetadata(alias="spanKind"), + pydantic.Field( + alias="spanKind", description="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."), + ] + scope_version: typing_extensions.Annotated[ + str, + FieldMetadata(alias="scopeVersion"), + pydantic.Field( + alias="scopeVersion", description="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). """ - duration_ns: typing_extensions.Annotated[float, FieldMetadata(alias="durationNs")] = pydantic.Field( - alias="durationNs" - ) - """ - Duration of the span in nanoseconds. - """ - - status_code: typing_extensions.Annotated[str, FieldMetadata(alias="statusCode")] = pydantic.Field( - alias="statusCode" - ) - """ - Status code of the span (e.g., OK, ERROR, UNSET). - """ - - status_message: typing_extensions.Annotated[str, FieldMetadata(alias="statusMessage")] = pydantic.Field( - alias="statusMessage" - ) - """ - Human-readable status message describing the span result. - """ - + duration_ns: typing_extensions.Annotated[ + float, + FieldMetadata(alias="durationNs"), + pydantic.Field(alias="durationNs", description="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_message: typing_extensions.Annotated[ + str, + FieldMetadata(alias="statusMessage"), + pydantic.Field(alias="statusMessage", description="Human-readable status message describing the span result."), + ] span_attributes: typing_extensions.Annotated[ - typing.Dict[str, typing.Any], FieldMetadata(alias="spanAttributes") - ] = pydantic.Field(alias="spanAttributes") - """ - Key-value pairs containing additional metadata about the span. - """ - + typing.Dict[str, typing.Any], + FieldMetadata(alias="spanAttributes"), + pydantic.Field( + alias="spanAttributes", description="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. """ - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - """ - Subject (user or virtualaccount) that created this span. - """ - + created_by_subject: typing_extensions.Annotated[ + Subject, + FieldMetadata(alias="createdBySubject"), + pydantic.Field( + alias="createdBySubject", description="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/tracing_project_manifest.py b/src/truefoundry_sdk/types/tracing_project_manifest.py index 821956ed..fe440331 100644 --- a/src/truefoundry_sdk/types/tracing_project_manifest.py +++ b/src/truefoundry_sdk/types/tracing_project_manifest.py @@ -45,9 +45,9 @@ class TracingProjectManifest(UniversalBaseModel): Note: Metrics will be retained regardless of this setting. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/trigger_job_run_response.py b/src/truefoundry_sdk/types/trigger_job_run_response.py index 89ddd003..df313aac 100644 --- a/src/truefoundry_sdk/types/trigger_job_run_response.py +++ b/src/truefoundry_sdk/types/trigger_job_run_response.py @@ -15,13 +15,9 @@ class TriggerJobRunResponse(UniversalBaseModel): Job triggered """ - job_run_name: typing_extensions.Annotated[str, FieldMetadata(alias="jobRunName")] = pydantic.Field( - alias="jobRunName" - ) - """ - Name of the job run - """ - + job_run_name: typing_extensions.Annotated[ + str, FieldMetadata(alias="jobRunName"), pydantic.Field(alias="jobRunName", description="Name of the job run") + ] data: JobRun = pydantic.Field() """ Details of the triggered job run diff --git a/src/truefoundry_sdk/types/troj_ai_client_id_auth.py b/src/truefoundry_sdk/types/troj_ai_client_id_auth.py new file mode 100644 index 00000000..58c875a6 --- /dev/null +++ b/src/truefoundry_sdk/types/troj_ai_client_id_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 TrojAiClientIdAuth(UniversalBaseModel): + """ + Authentication using a TrojAI firewall client ID (x-eag-clientid) + """ + + type: typing.Literal["client-id"] = pydantic.Field(default="client-id") + """ + +value=client-id + """ + + client_id: str = pydantic.Field() + """ + The client ID that identifies your TrojAI firewall policy (sent as x-eag-clientid header) + """ + + 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/prompt_foo_guardrail_config.py b/src/truefoundry_sdk/types/troj_ai_guardrail_config.py similarity index 56% rename from src/truefoundry_sdk/types/prompt_foo_guardrail_config.py rename to src/truefoundry_sdk/types/troj_ai_guardrail_config.py index 4b9f297f..0ebcb68a 100644 --- a/src/truefoundry_sdk/types/prompt_foo_guardrail_config.py +++ b/src/truefoundry_sdk/types/troj_ai_guardrail_config.py @@ -5,13 +5,14 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .enforcing_strategy import EnforcingStrategy -from .prompt_foo_guardrail_config_config import PromptFooGuardrailConfigConfig -from .prompt_foo_guardrail_config_operation import PromptFooGuardrailConfigOperation +from .troj_ai_client_id_auth import TrojAiClientIdAuth +from .troj_ai_guardrail_config_config import TrojAiGuardrailConfigConfig +from .troj_ai_guardrail_config_operation import TrojAiGuardrailConfigOperation -class PromptFooGuardrailConfig(UniversalBaseModel): +class TrojAiGuardrailConfig(UniversalBaseModel): """ - PromptFoo + TrojAI """ name: str = pydantic.Field() @@ -19,33 +20,33 @@ class PromptFooGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field( - default="PromptFoo guardrails: guard check, PII redaction, or harmful content detection" - ) + description: typing.Optional[str] = pydantic.Field(default=None) """ Optional description for this Guardrail Config. """ - type: typing.Literal["integration/guardrail-config/promptfoo"] = pydantic.Field( - default="integration/guardrail-config/promptfoo" + type: typing.Literal["integration/guardrail-config/trojai"] = pydantic.Field( + default="integration/guardrail-config/trojai" ) """ +uiType=Hidden - +value=integration/guardrail-config/promptfoo + +value=integration/guardrail-config/trojai """ - operation: PromptFooGuardrailConfigOperation = pydantic.Field() + auth_data: TrojAiClientIdAuth + operation: TrojAiGuardrailConfigOperation = 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. + Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=1) + priority: typing.Optional[int] = pydantic.Field(default=None) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ enforcing_strategy: EnforcingStrategy - config: PromptFooGuardrailConfigConfig = pydantic.Field() + config: TrojAiGuardrailConfigConfig = pydantic.Field() """ +uiType=Ignore +uiProps={"forwardJsonKey": true} diff --git a/src/truefoundry_sdk/types/troj_ai_guardrail_config_config.py b/src/truefoundry_sdk/types/troj_ai_guardrail_config_config.py new file mode 100644 index 00000000..c9662ab2 --- /dev/null +++ b/src/truefoundry_sdk/types/troj_ai_guardrail_config_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, UniversalBaseModel + + +class TrojAiGuardrailConfigConfig(UniversalBaseModel): + """ + +uiType=Ignore + +uiProps={"forwardJsonKey": true} + """ + + base_url: str = pydantic.Field() + """ + The base URL of the TrojAI firewall (e.g. https://your-trojai-firewall-host) + """ + + 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/troj_ai_guardrail_config_operation.py b/src/truefoundry_sdk/types/troj_ai_guardrail_config_operation.py new file mode 100644 index 00000000..fa52dc38 --- /dev/null +++ b/src/truefoundry_sdk/types/troj_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 TrojAiGuardrailConfigOperation(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. + Validate guardrails are run in parallel while mutate guardrails are run sequentially. + """ + + VALIDATE = "validate" + MUTATE = "mutate" + _UNKNOWN = "__TROJAIGUARDRAILCONFIGOPERATION_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) -> "TrojAiGuardrailConfigOperation": + 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 TrojAiGuardrailConfigOperation.VALIDATE: + return validate() + if self is TrojAiGuardrailConfigOperation.MUTATE: + return mutate() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py new file mode 100644 index 00000000..dd54d9dd --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py @@ -0,0 +1,100 @@ +# 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 .owned_by import OwnedBy +from .true_foundry_agent_manifest_model_params import TrueFoundryAgentManifestModelParams +from .true_foundry_agent_manifest_response_format import TrueFoundryAgentManifestResponseFormat +from .true_foundry_agent_manifest_sandbox import TrueFoundryAgentManifestSandbox +from .true_foundry_agent_mcp_server import TrueFoundryAgentMcpServer +from .true_foundry_agent_user_message import TrueFoundryAgentUserMessage +from .true_foundry_agent_variable import TrueFoundryAgentVariable + + +class TrueFoundryAgentManifest(UniversalBaseModel): + type: typing.Literal["truefoundry-agent"] = pydantic.Field(default="truefoundry-agent") + """ + Type of the manifest + """ + + name: str = pydantic.Field() + """ + The name of the Agent + """ + + description: str = pydantic.Field() + """ + The description of the Agent + """ + + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Tags for the Agent + """ + + model: str = pydantic.Field() + """ + Model for the Agent + """ + + model_params: typing.Optional[TrueFoundryAgentManifestModelParams] = pydantic.Field(default=None) + """ + Model parameters (default and extra). Keys are param names, values are float, int, bool, or string. + """ + + mcp_servers: typing.Optional[typing.List[TrueFoundryAgentMcpServer]] = pydantic.Field(default=None) + """ + List of MCP servers with name, enable_all_tools, and optional tools filter + """ + + instruction: typing.Optional[str] = pydantic.Field(default=None) + """ + System instruction or prompt for the agent + """ + + messages: typing.Optional[typing.List[TrueFoundryAgentUserMessage]] = pydantic.Field(default=None) + """ + Pre-defined initial messages for the agent. Supports template variable replacement. + """ + + variables: typing.Optional[typing.Dict[str, TrueFoundryAgentVariable]] = pydantic.Field(default=None) + """ + Variables keyed by name. Each has optional default_value and optional description. + """ + + response_format: typing.Optional[TrueFoundryAgentManifestResponseFormat] = pydantic.Field(default=None) + """ + JSON schema or structure for the agent response format + """ + + sandbox: typing.Optional[TrueFoundryAgentManifestSandbox] = pydantic.Field(default=None) + """ + Sandbox execution settings + """ + + iteration_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + Maximum number of iterations for the agent + """ + + collaborators: typing.List[Collaborator] = pydantic.Field() + """ + List of users who have access to this Agent + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params.py new file mode 100644 index 00000000..8655b888 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params.py @@ -0,0 +1,43 @@ +# 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_manifest_model_params_reasoning_effort import ( + TrueFoundryAgentManifestModelParamsReasoningEffort, +) + + +class TrueFoundryAgentManifestModelParams(UniversalBaseModel): + """ + Model parameters (default and extra). Keys are param names, values are float, int, bool, or string. + """ + + max_tokens: typing.Optional[int] = pydantic.Field(default=None) + """ + Maximum number of tokens to generate. + """ + + reasoning_effort: typing.Optional[TrueFoundryAgentManifestModelParamsReasoningEffort] = pydantic.Field(default=None) + """ + Reasoning depth when the model and provider support this parameter. + """ + + temperature: typing.Optional[float] = pydantic.Field(default=None) + """ + Sampling temperature (0–2). Higher values increase randomness. + """ + + top_p: typing.Optional[float] = pydantic.Field(default=None) + """ + Nucleus sampling threshold (0–1). Alternative to temperature. + """ + + 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_manifest_model_params_reasoning_effort.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params_reasoning_effort.py new file mode 100644 index 00000000..f291f296 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest_model_params_reasoning_effort.py @@ -0,0 +1,50 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core import enum + +T_Result = typing.TypeVar("T_Result") + + +class TrueFoundryAgentManifestModelParamsReasoningEffort(enum.StrEnum): + """ + Reasoning depth when the model and provider support this parameter. + """ + + NONE = "none" + MINIMAL = "minimal" + LOW = "low" + MEDIUM = "medium" + HIGH = "high" + _UNKNOWN = "__TRUEFOUNDRYAGENTMANIFESTMODELPARAMSREASONINGEFFORT_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) -> "TrueFoundryAgentManifestModelParamsReasoningEffort": + unknown = cls._UNKNOWN + unknown._value_ = value + return unknown + + def visit( + self, + none: typing.Callable[[], T_Result], + minimal: typing.Callable[[], T_Result], + low: typing.Callable[[], T_Result], + medium: typing.Callable[[], T_Result], + high: typing.Callable[[], T_Result], + _unknown_member: typing.Callable[[str], T_Result], + ) -> T_Result: + if self is TrueFoundryAgentManifestModelParamsReasoningEffort.NONE: + return none() + if self is TrueFoundryAgentManifestModelParamsReasoningEffort.MINIMAL: + return minimal() + if self is TrueFoundryAgentManifestModelParamsReasoningEffort.LOW: + return low() + if self is TrueFoundryAgentManifestModelParamsReasoningEffort.MEDIUM: + return medium() + if self is TrueFoundryAgentManifestModelParamsReasoningEffort.HIGH: + return high() + return _unknown_member(self._value_) diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest_response_format.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest_response_format.py new file mode 100644 index 00000000..7051e044 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest_response_format.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .response_format_json_object import ResponseFormatJsonObject +from .response_format_json_schema import ResponseFormatJsonSchema +from .response_format_text import ResponseFormatText + +TrueFoundryAgentManifestResponseFormat = typing.Union[ + ResponseFormatText, ResponseFormatJsonSchema, ResponseFormatJsonObject +] diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest_sandbox.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest_sandbox.py new file mode 100644 index 00000000..d2bfef38 --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest_sandbox.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 + + +class TrueFoundryAgentManifestSandbox(UniversalBaseModel): + """ + Sandbox execution settings + """ + + enabled: bool + + 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 new file mode 100644 index 00000000..e0b9e27b --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.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 .true_foundry_agent_mcp_tool import TrueFoundryAgentMcpTool + + +class TrueFoundryAgentMcpServer(UniversalBaseModel): + name: str = pydantic.Field() + """ + MCP server name + """ + + deferred: typing.Optional[bool] = pydantic.Field(default=None) + """ + When true, tools from this server are loaded lazily (deferred loading). + """ + + tools: typing.Optional[typing.List[TrueFoundryAgentMcpTool]] = pydantic.Field(default=None) + """ + List of tools to enable from this server + """ + + 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/application_problem.py b/src/truefoundry_sdk/types/true_foundry_agent_mcp_tool.py similarity index 86% rename from src/truefoundry_sdk/types/application_problem.py rename to src/truefoundry_sdk/types/true_foundry_agent_mcp_tool.py index 26d2afcd..d46efa3c 100644 --- a/src/truefoundry_sdk/types/application_problem.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_tool.py @@ -6,9 +6,8 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class ApplicationProblem(UniversalBaseModel): +class TrueFoundryAgentMcpTool(UniversalBaseModel): name: str - description: str 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_user_message.py b/src/truefoundry_sdk/types/true_foundry_agent_user_message.py new file mode 100644 index 00000000..f97a130d --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_user_message.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 TrueFoundryAgentUserMessage(UniversalBaseModel): + role: typing.Literal["user"] = pydantic.Field(default="user") + """ + Role of the message sender. + """ + + content: str = pydantic.Field() + """ + Content of the user message. Supports template variables like {{variable_name}}. + """ + + 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_variable.py b/src/truefoundry_sdk/types/true_foundry_agent_variable.py new file mode 100644 index 00000000..454bf3fe --- /dev/null +++ b/src/truefoundry_sdk/types/true_foundry_agent_variable.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 TrueFoundryAgentVariable(UniversalBaseModel): + default_value: typing.Optional[str] = pydantic.Field(default=None) + """ + Default value for the variable + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + Description of the variable + """ + + 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_apply_request_manifest.py b/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py index a4463808..60d6ba7d 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_request_manifest.py @@ -23,6 +23,7 @@ from .policy_manifest import PolicyManifest from .provider_accounts import ProviderAccounts from .r_studio import RStudio +from .role_binding_manifest import RoleBindingManifest from .role_manifest import RoleManifest from .secret_group_manifest import SecretGroupManifest from .service import Service @@ -68,4 +69,5 @@ EnvironmentManifest, TracingProjectManifest, McpServerManifest, + RoleBindingManifest, ] diff --git a/src/truefoundry_sdk/types/true_foundry_apply_response.py b/src/truefoundry_sdk/types/true_foundry_apply_response.py index 9b553de8..715cce78 100644 --- a/src/truefoundry_sdk/types/true_foundry_apply_response.py +++ b/src/truefoundry_sdk/types/true_foundry_apply_response.py @@ -12,12 +12,10 @@ class TrueFoundryApplyResponse(UniversalBaseModel): existing_manifest: typing_extensions.Annotated[ - typing.Optional[TrueFoundryApplyResponseExistingManifest], FieldMetadata(alias="existingManifest") - ] = pydantic.Field(alias="existingManifest", default=None) - """ - The existing manifest of the resource - """ - + typing.Optional[TrueFoundryApplyResponseExistingManifest], + FieldMetadata(alias="existingManifest"), + pydantic.Field(alias="existingManifest", description="The existing manifest of the resource"), + ] = None action: typing.Optional[TrueFoundryApplyResponseAction] = pydantic.Field(default=None) """ The action performed: CREATE or UPDATE 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 8074d876..a5643db2 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 @@ -23,6 +23,7 @@ from .policy_manifest import PolicyManifest from .provider_accounts import ProviderAccounts from .r_studio import RStudio +from .role_binding_manifest import RoleBindingManifest from .role_manifest import RoleManifest from .secret_group_manifest import SecretGroupManifest from .service import Service @@ -68,4 +69,5 @@ EnvironmentManifest, TracingProjectManifest, McpServerManifest, + RoleBindingManifest, ] 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 58af7fbc..c81282a6 100644 --- a/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_delete_request_manifest.py @@ -23,6 +23,7 @@ from .policy_manifest import PolicyManifest from .provider_accounts import ProviderAccounts from .r_studio import RStudio +from .role_binding_manifest import RoleBindingManifest from .role_manifest import RoleManifest from .secret_group_manifest import SecretGroupManifest from .service import Service @@ -68,4 +69,5 @@ EnvironmentManifest, TracingProjectManifest, McpServerManifest, + RoleBindingManifest, ] diff --git a/src/truefoundry_sdk/types/true_foundry_provider_account.py b/src/truefoundry_sdk/types/true_foundry_provider_account.py index 609677d8..2a58759b 100644 --- a/src/truefoundry_sdk/types/true_foundry_provider_account.py +++ b/src/truefoundry_sdk/types/true_foundry_provider_account.py @@ -30,9 +30,9 @@ class TrueFoundryProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/ttl_provider_account.py b/src/truefoundry_sdk/types/ttl_provider_account.py index 23eb6fdf..ce41cb6b 100644 --- a/src/truefoundry_sdk/types/ttl_provider_account.py +++ b/src/truefoundry_sdk/types/ttl_provider_account.py @@ -30,9 +30,9 @@ class TtlProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/ttl_registry.py b/src/truefoundry_sdk/types/ttl_registry.py index 98eb9279..e46e4706 100644 --- a/src/truefoundry_sdk/types/ttl_registry.py +++ b/src/truefoundry_sdk/types/ttl_registry.py @@ -21,7 +21,7 @@ class TtlRegistry(UniversalBaseModel): The name of the integration that will be displayed in the TrueFoundry UI. """ - registry_url: str = pydantic.Field(default="https://ttl.sh") + registry_url: str = pydantic.Field() """ The URL of the registry. """ diff --git a/src/truefoundry_sdk/types/upgrade_data.py b/src/truefoundry_sdk/types/upgrade_data.py index 0a7a1f8a..9819736a 100644 --- a/src/truefoundry_sdk/types/upgrade_data.py +++ b/src/truefoundry_sdk/types/upgrade_data.py @@ -13,21 +13,21 @@ class UpgradeData(UniversalBaseModel): diff: typing.Optional[typing.List["IChange"]] = None - current_manifest: typing_extensions.Annotated[typing.Optional[Helm], FieldMetadata(alias="currentManifest")] = ( - pydantic.Field(alias="currentManifest", default=None) - ) - desired_manifest: typing_extensions.Annotated[typing.Optional[Helm], FieldMetadata(alias="desiredManifest")] = ( - pydantic.Field(alias="desiredManifest", default=None) - ) - upgrade_possible: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="upgradePossible")] = ( - pydantic.Field(alias="upgradePossible", default=None) - ) + current_manifest: typing_extensions.Annotated[ + typing.Optional[Helm], FieldMetadata(alias="currentManifest"), pydantic.Field(alias="currentManifest") + ] = None + desired_manifest: typing_extensions.Annotated[ + typing.Optional[Helm], FieldMetadata(alias="desiredManifest"), pydantic.Field(alias="desiredManifest") + ] = None + upgrade_possible: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="upgradePossible"), pydantic.Field(alias="upgradePossible") + ] = None conflict_fields: typing_extensions.Annotated[ - typing.Optional[typing.List[str]], FieldMetadata(alias="conflictFields") - ] = pydantic.Field(alias="conflictFields", default=None) - has_conflict: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="hasConflict")] = ( - pydantic.Field(alias="hasConflict", default=None) - ) + typing.Optional[typing.List[str]], FieldMetadata(alias="conflictFields"), pydantic.Field(alias="conflictFields") + ] = None + has_conflict: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="hasConflict"), pydantic.Field(alias="hasConflict") + ] = 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/usage_code_snippet.py b/src/truefoundry_sdk/types/usage_code_snippet.py index 33f697f6..0464e6ab 100644 --- a/src/truefoundry_sdk/types/usage_code_snippet.py +++ b/src/truefoundry_sdk/types/usage_code_snippet.py @@ -7,14 +7,25 @@ class UsageCodeSnippet(UniversalBaseModel): - display_name: str - language: str + display_name: str = pydantic.Field() + """ + Display name for the code snippet (e.g., 'Python', 'JavaScript') + """ + + language: str = pydantic.Field() + """ + Programming language of the code snippet (e.g., 'python', 'javascript') + """ + libraries: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ - Libraries used in the code snippet + List of libraries/frameworks used in the code snippet """ - code: str + code: str = pydantic.Field() + """ + Code snippet demonstrating how to use the prompt version + """ 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.py b/src/truefoundry_sdk/types/user.py index 42283a15..586b396a 100644 --- a/src/truefoundry_sdk/types/user.py +++ b/src/truefoundry_sdk/types/user.py @@ -15,25 +15,25 @@ class User(UniversalBaseModel): id: str email: str - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] metadata: UserMetadata roles: typing.Optional[typing.List[str]] = None roles_with_resource: typing_extensions.Annotated[ - typing.Optional[typing.List[RoleWithResource]], FieldMetadata(alias="rolesWithResource") - ] = pydantic.Field(alias="rolesWithResource", default=None) + typing.Optional[typing.List[RoleWithResource]], + FieldMetadata(alias="rolesWithResource"), + pydantic.Field(alias="rolesWithResource"), + ] = None accounts: typing.Optional[typing.List[AccountInfo]] = None active: bool - is_editable: typing_extensions.Annotated[bool, FieldMetadata(alias="isEditable")] = pydantic.Field( - alias="isEditable" - ) - 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_editable: typing_extensions.Annotated[ + bool, FieldMetadata(alias="isEditable"), pydantic.Field(alias="isEditable") + ] + 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 diff --git a/src/truefoundry_sdk/types/user_metadata.py b/src/truefoundry_sdk/types/user_metadata.py index 6981bb38..d6f65df1 100644 --- a/src/truefoundry_sdk/types/user_metadata.py +++ b/src/truefoundry_sdk/types/user_metadata.py @@ -11,41 +11,47 @@ class UserMetadata(UniversalBaseModel): sub: typing.Optional[str] = None - image_url: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="imageURL")] = pydantic.Field( - alias="imageURL", default=None - ) + image_url: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="imageURL"), pydantic.Field(alias="imageURL") + ] = None picture_download_path: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="pictureDownloadPath") - ] = pydantic.Field(alias="pictureDownloadPath", default=None) - display_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="displayName")] = ( - pydantic.Field(alias="displayName", default=None) - ) + typing.Optional[str], FieldMetadata(alias="pictureDownloadPath"), pydantic.Field(alias="pictureDownloadPath") + ] = None + display_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="displayName"), pydantic.Field(alias="displayName") + ] = None user_object: typing_extensions.Annotated[ - typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="userObject") - ] = pydantic.Field(alias="userObject", default=None) - invite_accepted: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="inviteAccepted")] = ( - pydantic.Field(alias="inviteAccepted", default=None) - ) - registered_in_idp: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="registeredInIdp")] = ( - pydantic.Field(alias="registeredInIdp", default=None) - ) + typing.Optional[typing.Dict[str, typing.Any]], + FieldMetadata(alias="userObject"), + pydantic.Field(alias="userObject"), + ] = None + invite_accepted: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="inviteAccepted"), pydantic.Field(alias="inviteAccepted") + ] = None + registered_in_idp: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="registeredInIdp"), pydantic.Field(alias="registeredInIdp") + ] = None preference: typing.Optional[typing.Dict[str, typing.Any]] = None groups: typing.Optional[typing.List[str]] = None tenant_role_managed_by: typing_extensions.Annotated[ - typing.Optional[UserMetadataTenantRoleManagedBy], FieldMetadata(alias="tenantRoleManagedBy") - ] = pydantic.Field(alias="tenantRoleManagedBy", default=None) - sso_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="ssoName")] = pydantic.Field( - alias="ssoName", default=None - ) - is_primary_sso: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isPrimarySSO")] = ( - pydantic.Field(alias="isPrimarySSO", default=None) - ) + typing.Optional[UserMetadataTenantRoleManagedBy], + FieldMetadata(alias="tenantRoleManagedBy"), + pydantic.Field(alias="tenantRoleManagedBy"), + ] = None + sso_name: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="ssoName"), pydantic.Field(alias="ssoName") + ] = None + is_primary_sso: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="isPrimarySSO"), pydantic.Field(alias="isPrimarySSO") + ] = None scim_user_object: typing_extensions.Annotated[ - typing.Optional[typing.Dict[str, typing.Any]], FieldMetadata(alias="scimUserObject") - ] = pydantic.Field(alias="scimUserObject", default=None) - created_by_scim: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="createdByScim")] = ( - pydantic.Field(alias="createdByScim", default=None) - ) + typing.Optional[typing.Dict[str, typing.Any]], + FieldMetadata(alias="scimUserObject"), + pydantic.Field(alias="scimUserObject"), + ] = None + created_by_scim: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="createdByScim"), pydantic.Field(alias="createdByScim") + ] = 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/user_resource.py b/src/truefoundry_sdk/types/user_resource.py index b801485f..d597ab5e 100644 --- a/src/truefoundry_sdk/types/user_resource.py +++ b/src/truefoundry_sdk/types/user_resource.py @@ -9,31 +9,20 @@ class UserResource(UniversalBaseModel): - resource_type: typing_extensions.Annotated[str, FieldMetadata(alias="resourceType")] = pydantic.Field( - alias="resourceType" - ) - """ - Resource Type - """ - - resource_id: typing_extensions.Annotated[str, FieldMetadata(alias="resourceId")] = pydantic.Field( - alias="resourceId" - ) - """ - Resource ID - """ - - role_id: typing_extensions.Annotated[str, FieldMetadata(alias="roleId")] = pydantic.Field(alias="roleId") - """ - Role ID - """ - - resource_name: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="resourceName")] = ( - pydantic.Field(alias="resourceName", default=None) - ) - """ - Resource Name (if available) - """ + resource_type: typing_extensions.Annotated[ + str, FieldMetadata(alias="resourceType"), pydantic.Field(alias="resourceType", description="Resource Type") + ] + resource_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="resourceId"), pydantic.Field(alias="resourceId", description="Resource ID") + ] + role_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="roleId"), pydantic.Field(alias="roleId", description="Role ID") + ] + resource_name: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="resourceName"), + pydantic.Field(alias="resourceName", description="Resource Name (if available)"), + ] = 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/user_team_info.py b/src/truefoundry_sdk/types/user_team_info.py new file mode 100644 index 00000000..00dccddc --- /dev/null +++ b/src/truefoundry_sdk/types/user_team_info.py @@ -0,0 +1,26 @@ +# 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 UserTeamInfo(UniversalBaseModel): + team_name: typing_extensions.Annotated[ + str, FieldMetadata(alias="teamName"), pydantic.Field(alias="teamName", description="Name of the team") + ] + roles: typing.List[str] = pydantic.Field() + """ + Roles of the user in 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/uv.py b/src/truefoundry_sdk/types/uv.py index dfefdbee..b07e7a6a 100644 --- a/src/truefoundry_sdk/types/uv.py +++ b/src/truefoundry_sdk/types/uv.py @@ -17,7 +17,7 @@ class Uv(UniversalBaseModel): +value=uv """ - uv_version: typing.Optional[str] = pydantic.Field(default="latest") + uv_version: typing.Optional[str] = pydantic.Field(default=None) """ UV version to use """ diff --git a/src/truefoundry_sdk/types/virtual_account.py b/src/truefoundry_sdk/types/virtual_account.py index 8305f642..fc527a82 100644 --- a/src/truefoundry_sdk/types/virtual_account.py +++ b/src/truefoundry_sdk/types/virtual_account.py @@ -16,40 +16,42 @@ class VirtualAccount(UniversalBaseModel): id: str type: str - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] manifest: typing.Optional[VirtualAccountManifest] = None - jwt_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="jwtId")] = pydantic.Field( - alias="jwtId", default=None - ) - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - 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_expired: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isExpired")] = pydantic.Field( - alias="isExpired", default=None - ) + jwt_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="jwtId"), pydantic.Field(alias="jwtId") + ] = None + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + 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_expired: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="isExpired"), pydantic.Field(alias="isExpired") + ] = None jwts: typing.Optional[typing.List[Jwt]] = None - account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")] = pydantic.Field(alias="accountId") + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] metadata: typing.Optional[typing.Dict[str, typing.Any]] = None - role_ids: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="roleIds")] = ( - pydantic.Field(alias="roleIds", default=None) - ) + role_ids: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="roleIds"), pydantic.Field(alias="roleIds") + ] = None roles_with_resource: typing_extensions.Annotated[ - typing.Optional[typing.List[RoleWithResource]], FieldMetadata(alias="rolesWithResource") - ] = pydantic.Field(alias="rolesWithResource", default=None) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + typing.Optional[typing.List[RoleWithResource]], + FieldMetadata(alias="rolesWithResource"), + pydantic.Field(alias="rolesWithResource"), + ] = None + created_by: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="createdBy"), pydantic.Field(alias="createdBy") + ] = None next_scheduled_rotation: typing_extensions.Annotated[ - typing.Optional[str], FieldMetadata(alias="nextScheduledRotation") - ] = pydantic.Field(alias="nextScheduledRotation", default=None) + typing.Optional[str], + FieldMetadata(alias="nextScheduledRotation"), + pydantic.Field(alias="nextScheduledRotation"), + ] = 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/virtual_account_manifest.py b/src/truefoundry_sdk/types/virtual_account_manifest.py index 3e9ec523..f09e7368 100644 --- a/src/truefoundry_sdk/types/virtual_account_manifest.py +++ b/src/truefoundry_sdk/types/virtual_account_manifest.py @@ -37,9 +37,13 @@ class VirtualAccountManifest(UniversalBaseModel): auto_rotate: typing.Optional[AutoRotate] = None notification_target: typing.Optional[NotificationTarget] = None secret_store_config: typing.Optional[SecretStoreConfig] = None - owned_by: typing_extensions.Annotated[typing.Optional[VirtualAccountOwnedBy], FieldMetadata(alias="ownedBy")] = ( - pydantic.Field(alias="ownedBy", default=None) - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[VirtualAccountOwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None + tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) + """ + Key-value pairs to categorize this Virtual Account (e.g., by owner or environment). + """ 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/virtual_mcp_server_manifest.py b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py index 96932cef..a0c2c3e8 100644 --- a/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/virtual_mcp_server_manifest.py @@ -41,9 +41,9 @@ class VirtualMcpServerManifest(UniversalBaseModel): Users and Teams that have access to this Virtual MCP Server """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy"), pydantic.Field(alias="ownedBy") + ] = None tags: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ Key-value pairs to categorize this Virtual MCP Server (e.g., by owner or environment). diff --git a/src/truefoundry_sdk/types/virtual_model_provider_account.py b/src/truefoundry_sdk/types/virtual_model_provider_account.py index a34824c2..0fb457a5 100644 --- a/src/truefoundry_sdk/types/virtual_model_provider_account.py +++ b/src/truefoundry_sdk/types/virtual_model_provider_account.py @@ -36,9 +36,9 @@ class VirtualModelProviderAccount(UniversalBaseModel): List of users who have access to this Virtual Model Provider Group """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/webhook_bearer_auth.py b/src/truefoundry_sdk/types/webhook_bearer_auth.py index 3caa261a..2f49b11d 100644 --- a/src/truefoundry_sdk/types/webhook_bearer_auth.py +++ b/src/truefoundry_sdk/types/webhook_bearer_auth.py @@ -17,7 +17,7 @@ class WebhookBearerAuth(UniversalBaseModel): Bearer token for authentication """ - prefix: str = pydantic.Field(default="Bearer") + prefix: str = pydantic.Field() """ Prefix for the token """ diff --git a/src/truefoundry_sdk/types/webhook_provider_account.py b/src/truefoundry_sdk/types/webhook_provider_account.py index 206972b1..a8eeca87 100644 --- a/src/truefoundry_sdk/types/webhook_provider_account.py +++ b/src/truefoundry_sdk/types/webhook_provider_account.py @@ -30,9 +30,9 @@ class WebhookProviderAccount(UniversalBaseModel): List of integrations that are associated with the provider account. """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/weight_based_load_balancing.py b/src/truefoundry_sdk/types/weight_based_load_balancing.py index 114edc9f..69313ea0 100644 --- a/src/truefoundry_sdk/types/weight_based_load_balancing.py +++ b/src/truefoundry_sdk/types/weight_based_load_balancing.py @@ -5,6 +5,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .load_balance_target import LoadBalanceTarget +from .sticky_routing import StickyRouting class WeightBasedLoadBalancing(UniversalBaseModel): @@ -18,6 +19,8 @@ class WeightBasedLoadBalancing(UniversalBaseModel): List of targets for load balancing with weights """ + sticky_routing: typing.Optional[StickyRouting] = 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/worker_config.py b/src/truefoundry_sdk/types/worker_config.py index 3aca0c51..844e1169 100644 --- a/src/truefoundry_sdk/types/worker_config.py +++ b/src/truefoundry_sdk/types/worker_config.py @@ -19,7 +19,7 @@ class WorkerConfig(UniversalBaseModel): Output Config """ - num_concurrent_workers: int = pydantic.Field(default=1) + num_concurrent_workers: int = pydantic.Field() """ Number of concurrent workers to spawn for the processor """ diff --git a/src/truefoundry_sdk/types/workflow_alert.py b/src/truefoundry_sdk/types/workflow_alert.py index f3e3b4fa..a19d866e 100644 --- a/src/truefoundry_sdk/types/workflow_alert.py +++ b/src/truefoundry_sdk/types/workflow_alert.py @@ -13,12 +13,12 @@ class WorkflowAlert(UniversalBaseModel): """ notification_target: typing.Optional[NotificationTarget] = None - on_completion: typing.Optional[bool] = pydantic.Field(default=False) + on_completion: typing.Optional[bool] = pydantic.Field(default=None) """ Send an alert when the job completes """ - on_failure: typing.Optional[bool] = pydantic.Field(default=True) + on_failure: typing.Optional[bool] = pydantic.Field(default=None) """ Send an alert when the job fails """ diff --git a/src/truefoundry_sdk/types/workspace.py b/src/truefoundry_sdk/types/workspace.py index 0f95e604..9b7f7127 100644 --- a/src/truefoundry_sdk/types/workspace.py +++ b/src/truefoundry_sdk/types/workspace.py @@ -14,30 +14,28 @@ class Workspace(UniversalBaseModel): id: str fqn: str - tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName")] = pydantic.Field( - alias="tenantName" - ) - cluster_id: typing_extensions.Annotated[str, FieldMetadata(alias="clusterId")] = pydantic.Field(alias="clusterId") - created_by_subject: typing_extensions.Annotated[Subject, FieldMetadata(alias="createdBySubject")] = pydantic.Field( - alias="createdBySubject" - ) - 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" - ) - environment_id: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="environmentId")] = ( - pydantic.Field(alias="environmentId", default=None) - ) + tenant_name: typing_extensions.Annotated[str, FieldMetadata(alias="tenantName"), pydantic.Field(alias="tenantName")] + cluster_id: typing_extensions.Annotated[str, FieldMetadata(alias="clusterId"), pydantic.Field(alias="clusterId")] + created_by_subject: typing_extensions.Annotated[ + Subject, FieldMetadata(alias="createdBySubject"), pydantic.Field(alias="createdBySubject") + ] + 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") + ] + environment_id: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="environmentId"), pydantic.Field(alias="environmentId") + ] = None manifest: WorkspaceManifest - account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId")] = pydantic.Field(alias="accountId") - is_system_ws: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="isSystemWs")] = ( - pydantic.Field(alias="isSystemWs", default=None) - ) - created_by: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="createdBy")] = pydantic.Field( - alias="createdBy", default=None - ) + account_id: typing_extensions.Annotated[str, FieldMetadata(alias="accountId"), pydantic.Field(alias="accountId")] + is_system_ws: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="isSystemWs"), pydantic.Field(alias="isSystemWs") + ] = 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 diff --git a/src/truefoundry_sdk/types/workspace_manifest.py b/src/truefoundry_sdk/types/workspace_manifest.py index c113410e..48360ce4 100644 --- a/src/truefoundry_sdk/types/workspace_manifest.py +++ b/src/truefoundry_sdk/types/workspace_manifest.py @@ -52,9 +52,9 @@ class WorkspaceManifest(UniversalBaseModel): Permissions """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/xai_provider_account.py b/src/truefoundry_sdk/types/xai_provider_account.py index e067ef27..771c80d3 100644 --- a/src/truefoundry_sdk/types/xai_provider_account.py +++ b/src/truefoundry_sdk/types/xai_provider_account.py @@ -38,9 +38,9 @@ class XaiProviderAccount(UniversalBaseModel): List of users who have access to this provider account """ - owned_by: typing_extensions.Annotated[typing.Optional[OwnedBy], FieldMetadata(alias="ownedBy")] = pydantic.Field( - alias="ownedBy", default=None - ) + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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/users/client.py b/src/truefoundry_sdk/users/client.py index 6c50a90a..a8fe9ff4 100644 --- a/src/truefoundry_sdk/users/client.py +++ b/src/truefoundry_sdk/users/client.py @@ -9,6 +9,7 @@ from ..types.change_password_response import ChangePasswordResponse from ..types.deactivate_user_response import DeactivateUserResponse from ..types.delete_user_response import DeleteUserResponse +from ..types.get_user_permissions_response import GetUserPermissionsResponse from ..types.get_user_resources_response import GetUserResourcesResponse from ..types.get_user_response import GetUserResponse from ..types.get_user_teams_response import GetUserTeamsResponse @@ -103,9 +104,9 @@ def pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = False, - skip_if_user_exists: typing.Optional[bool] = False, - dry_run: typing.Optional[bool] = False, + send_invite_email: typing.Optional[bool] = OMIT, + skip_if_user_exists: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = OMIT, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> RegisterUsersResponse: @@ -239,7 +240,13 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non _response = self._raw_client.get(id, request_options=request_options) return _response.data - def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeleteUserResponse: + def delete( + self, + id: str, + *, + tenant_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeleteUserResponse: """ Delete user if they are not a collaborator in any resource and not part of any team other than everyone. @@ -248,6 +255,9 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = id : str User Id + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -266,9 +276,10 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = ) client.users.delete( id="id", + tenant_name="tenantName", ) """ - _response = self._raw_client.delete(id, request_options=request_options) + _response = self._raw_client.delete(id, tenant_name=tenant_name, request_options=request_options) return _response.data def invite_user( @@ -312,7 +323,11 @@ def invite_user( return _response.data def deactivate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> DeactivateUserResponse: """ Deactivate user associated with the provided email within the tenant. @@ -322,6 +337,9 @@ def deactivate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -342,10 +360,16 @@ def deactivate( email="email", ) """ - _response = self._raw_client.deactivate(email=email, request_options=request_options) + _response = self._raw_client.deactivate(email=email, tenant_name=tenant_name, request_options=request_options) return _response.data - def activate(self, *, email: str, request_options: typing.Optional[RequestOptions] = None) -> ActivateUserResponse: + def activate( + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ActivateUserResponse: """ Activate user associated with the provided email within the tenant. @@ -354,6 +378,9 @@ def activate(self, *, email: str, request_options: typing.Optional[RequestOption email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -374,7 +401,7 @@ def activate(self, *, email: str, request_options: typing.Optional[RequestOption email="email", ) """ - _response = self._raw_client.activate(email=email, request_options=request_options) + _response = self._raw_client.activate(email=email, tenant_name=tenant_name, request_options=request_options) return _response.data def change_password( @@ -460,9 +487,43 @@ def get_resources( _response = self._raw_client.get_resources(id, request_options=request_options) return _response.data + def get_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetUserPermissionsResponse: + """ + Get all role bindings associated with a user, including team-inherited bindings. + + Parameters + ---------- + id : str + User Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetUserPermissionsResponse + Returns role bindings for the user (including team-inherited). + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + client.users.get_permissions( + id="id", + ) + """ + _response = self._raw_client.get_permissions(id, request_options=request_options) + return _response.data + def get_teams(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetUserTeamsResponse: """ - Get all manual teams associated with a user. + Get all teams associated with a user, including their role in each team. Parameters ---------- @@ -475,7 +536,7 @@ def get_teams(self, id: str, *, request_options: typing.Optional[RequestOptions] Returns ------- GetUserTeamsResponse - Returns all manual teams for the user. + Returns all teams for the user with their roles. Examples -------- @@ -582,9 +643,9 @@ async def pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = False, - skip_if_user_exists: typing.Optional[bool] = False, - dry_run: typing.Optional[bool] = False, + send_invite_email: typing.Optional[bool] = OMIT, + skip_if_user_exists: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = OMIT, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> RegisterUsersResponse: @@ -742,7 +803,13 @@ async def main() -> None: _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) -> DeleteUserResponse: + async def delete( + self, + id: str, + *, + tenant_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeleteUserResponse: """ Delete user if they are not a collaborator in any resource and not part of any team other than everyone. @@ -751,6 +818,9 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio id : str User Id + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -774,12 +844,13 @@ async def delete(self, id: str, *, request_options: typing.Optional[RequestOptio async def main() -> None: await client.users.delete( id="id", + tenant_name="tenantName", ) asyncio.run(main()) """ - _response = await self._raw_client.delete(id, request_options=request_options) + _response = await self._raw_client.delete(id, tenant_name=tenant_name, request_options=request_options) return _response.data async def invite_user( @@ -831,7 +902,11 @@ async def main() -> None: return _response.data async def deactivate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> DeactivateUserResponse: """ Deactivate user associated with the provided email within the tenant. @@ -841,6 +916,9 @@ async def deactivate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -869,11 +947,17 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.deactivate(email=email, request_options=request_options) + _response = await self._raw_client.deactivate( + email=email, tenant_name=tenant_name, request_options=request_options + ) return _response.data async def activate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> ActivateUserResponse: """ Activate user associated with the provided email within the tenant. @@ -883,6 +967,9 @@ async def activate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -911,7 +998,9 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.activate(email=email, request_options=request_options) + _response = await self._raw_client.activate( + email=email, tenant_name=tenant_name, request_options=request_options + ) return _response.data async def change_password( @@ -1013,11 +1102,53 @@ async def main() -> None: _response = await self._raw_client.get_resources(id, request_options=request_options) return _response.data + async def get_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetUserPermissionsResponse: + """ + Get all role bindings associated with a user, including team-inherited bindings. + + Parameters + ---------- + id : str + User Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetUserPermissionsResponse + Returns role bindings for the user (including team-inherited). + + 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.users.get_permissions( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_permissions(id, request_options=request_options) + return _response.data + async def get_teams( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> GetUserTeamsResponse: """ - Get all manual teams associated with a user. + Get all teams associated with a user, including their role in each team. Parameters ---------- @@ -1030,7 +1161,7 @@ async def get_teams( Returns ------- GetUserTeamsResponse - Returns all manual teams for the user. + Returns all teams for the user with their roles. Examples -------- diff --git a/src/truefoundry_sdk/users/raw_client.py b/src/truefoundry_sdk/users/raw_client.py index 4d4a94d3..ee7ba751 100644 --- a/src/truefoundry_sdk/users/raw_client.py +++ b/src/truefoundry_sdk/users/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -20,6 +21,7 @@ from ..types.change_password_response import ChangePasswordResponse from ..types.deactivate_user_response import DeactivateUserResponse from ..types.delete_user_response import DeleteUserResponse +from ..types.get_user_permissions_response import GetUserPermissionsResponse from ..types.get_user_resources_response import GetUserResourcesResponse from ..types.get_user_response import GetUserResponse from ..types.get_user_teams_response import GetUserTeamsResponse @@ -29,6 +31,7 @@ from ..types.register_users_response import RegisterUsersResponse from ..types.update_user_roles_response import UpdateUserRolesResponse from ..types.user import User +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -106,15 +109,19 @@ def list( _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 pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = False, - skip_if_user_exists: typing.Optional[bool] = False, - dry_run: typing.Optional[bool] = False, + send_invite_email: typing.Optional[bool] = OMIT, + skip_if_user_exists: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = OMIT, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[RegisterUsersResponse]: @@ -208,6 +215,10 @@ def pre_register_users( _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 update_roles( @@ -300,6 +311,10 @@ def update_roles( _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[GetUserResponse]: @@ -320,7 +335,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns the User associated with provided User id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}", + f"api/svc/v1/users/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -348,10 +363,18 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non _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 + self, + id: str, + *, + tenant_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[DeleteUserResponse]: """ Delete user if they are not a collaborator in any resource and not part of any team other than everyone. @@ -361,6 +384,9 @@ def delete( id : str User Id + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -370,8 +396,11 @@ def delete( User has been successfully deleted. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}", + f"api/svc/v1/users/{encode_path_param(id)}", method="DELETE", + params={ + "tenantName": tenant_name, + }, request_options=request_options, ) try: @@ -420,6 +449,10 @@ def delete( _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 invite_user( @@ -503,10 +536,18 @@ def invite_user( _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 deactivate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[DeactivateUserResponse]: """ Deactivate user associated with the provided email within the tenant. @@ -516,6 +557,9 @@ def deactivate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -529,6 +573,7 @@ def deactivate( method="PATCH", json={ "email": email, + "tenantName": tenant_name, }, headers={ "content-type": "application/json", @@ -571,10 +616,18 @@ def deactivate( _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 activate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ActivateUserResponse]: """ Activate user associated with the provided email within the tenant. @@ -584,6 +637,9 @@ def activate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -597,6 +653,7 @@ def activate( method="PATCH", json={ "email": email, + "tenantName": tenant_name, }, headers={ "content-type": "application/json", @@ -639,6 +696,10 @@ def activate( _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 change_password( @@ -698,6 +759,10 @@ def change_password( _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_resources( @@ -720,7 +785,7 @@ def get_resources( Returns all resources for the user. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}/resources", + f"api/svc/v1/users/{encode_path_param(id)}/resources", method="GET", request_options=request_options, ) @@ -759,13 +824,82 @@ def get_resources( _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_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetUserPermissionsResponse]: + """ + Get all role bindings associated with a user, including team-inherited bindings. + + Parameters + ---------- + id : str + User Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetUserPermissionsResponse] + Returns role bindings for the user (including team-inherited). + """ + _response = self._client_wrapper.httpx_client.request( + f"api/svc/v1/users/{encode_path_param(id)}/permissions", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetUserPermissionsResponse, + parse_obj_as( + type_=GetUserPermissionsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + 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(), + ), + ), + ) + _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_teams( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[GetUserTeamsResponse]: """ - Get all manual teams associated with a user. + Get all teams associated with a user, including their role in each team. Parameters ---------- @@ -778,10 +912,10 @@ def get_teams( Returns ------- HttpResponse[GetUserTeamsResponse] - Returns all manual teams for the user. + Returns all teams for the user with their roles. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}/teams", + f"api/svc/v1/users/{encode_path_param(id)}/teams", method="GET", request_options=request_options, ) @@ -820,6 +954,10 @@ def get_teams( _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) @@ -898,15 +1036,19 @@ async def _get_next(): _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 pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = False, - skip_if_user_exists: typing.Optional[bool] = False, - dry_run: typing.Optional[bool] = False, + send_invite_email: typing.Optional[bool] = OMIT, + skip_if_user_exists: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = OMIT, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[RegisterUsersResponse]: @@ -1000,6 +1142,10 @@ async def pre_register_users( _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 update_roles( @@ -1092,6 +1238,10 @@ async def update_roles( _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( @@ -1114,7 +1264,7 @@ async def get( Returns the User associated with provided User id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}", + f"api/svc/v1/users/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -1142,10 +1292,18 @@ async def get( _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 + self, + id: str, + *, + tenant_name: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[DeleteUserResponse]: """ Delete user if they are not a collaborator in any resource and not part of any team other than everyone. @@ -1155,6 +1313,9 @@ async def delete( id : str User Id + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1164,8 +1325,11 @@ async def delete( User has been successfully deleted. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}", + f"api/svc/v1/users/{encode_path_param(id)}", method="DELETE", + params={ + "tenantName": tenant_name, + }, request_options=request_options, ) try: @@ -1214,6 +1378,10 @@ async def delete( _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 invite_user( @@ -1297,10 +1465,18 @@ async def invite_user( _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 deactivate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[DeactivateUserResponse]: """ Deactivate user associated with the provided email within the tenant. @@ -1310,6 +1486,9 @@ async def deactivate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1323,6 +1502,7 @@ async def deactivate( method="PATCH", json={ "email": email, + "tenantName": tenant_name, }, headers={ "content-type": "application/json", @@ -1365,10 +1545,18 @@ async def deactivate( _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 activate( - self, *, email: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + email: str, + tenant_name: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ActivateUserResponse]: """ Activate user associated with the provided email within the tenant. @@ -1378,6 +1566,9 @@ async def activate( email : str Email of the user + tenant_name : typing.Optional[str] + Tenant name + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1391,6 +1582,7 @@ async def activate( method="PATCH", json={ "email": email, + "tenantName": tenant_name, }, headers={ "content-type": "application/json", @@ -1433,6 +1625,10 @@ async def activate( _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 change_password( @@ -1492,6 +1688,10 @@ async def change_password( _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_resources( @@ -1514,7 +1714,7 @@ async def get_resources( Returns all resources for the user. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}/resources", + f"api/svc/v1/users/{encode_path_param(id)}/resources", method="GET", request_options=request_options, ) @@ -1553,13 +1753,82 @@ async def get_resources( _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_permissions( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetUserPermissionsResponse]: + """ + Get all role bindings associated with a user, including team-inherited bindings. + + Parameters + ---------- + id : str + User Id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetUserPermissionsResponse] + Returns role bindings for the user (including team-inherited). + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/svc/v1/users/{encode_path_param(id)}/permissions", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetUserPermissionsResponse, + parse_obj_as( + type_=GetUserPermissionsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + 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(), + ), + ), + ) + _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_teams( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[GetUserTeamsResponse]: """ - Get all manual teams associated with a user. + Get all teams associated with a user, including their role in each team. Parameters ---------- @@ -1572,10 +1841,10 @@ async def get_teams( Returns ------- AsyncHttpResponse[GetUserTeamsResponse] - Returns all manual teams for the user. + Returns all teams for the user with their roles. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{jsonable_encoder(id)}/teams", + f"api/svc/v1/users/{encode_path_param(id)}/teams", method="GET", request_options=request_options, ) @@ -1614,4 +1883,8 @@ async def get_teams( _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/virtual_accounts/client.py b/src/truefoundry_sdk/virtual_accounts/client.py index 93cf7b24..16ab8794 100644 --- a/src/truefoundry_sdk/virtual_accounts/client.py +++ b/src/truefoundry_sdk/virtual_accounts/client.py @@ -39,6 +39,9 @@ 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, + is_expired: typing.Optional[bool] = None, + filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[VirtualAccount, ListVirtualAccountResponse]: """ @@ -55,6 +58,15 @@ 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]]] + Return virtual accounts owned by these teams + + is_expired : typing.Optional[bool] + Filter virtual accounts by expiration status. true = expired, false = not expired + + filter : typing.Optional[str] + JSON string: structured filter tree (AND/OR groups, column leaves on `name`, json_map leaves on manifest.tags). + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -75,6 +87,8 @@ def list( limit=10, offset=0, name_search_query="nameSearchQuery", + is_expired=True, + filter="filter", ) for item in response: yield item @@ -83,14 +97,20 @@ def list( yield page """ return self._raw_client.list( - limit=limit, offset=offset, name_search_query=name_search_query, request_options=request_options + limit=limit, + offset=offset, + name_search_query=name_search_query, + owned_by_teams=owned_by_teams, + is_expired=is_expired, + filter=filter, + request_options=request_options, ) def create_or_update( self, *, manifest: VirtualAccountManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ @@ -369,6 +389,9 @@ 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, + is_expired: typing.Optional[bool] = None, + filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[VirtualAccount, ListVirtualAccountResponse]: """ @@ -385,6 +408,15 @@ 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]]] + Return virtual accounts owned by these teams + + is_expired : typing.Optional[bool] + Filter virtual accounts by expiration status. true = expired, false = not expired + + filter : typing.Optional[str] + JSON string: structured filter tree (AND/OR groups, column leaves on `name`, json_map leaves on manifest.tags). + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -410,6 +442,8 @@ async def main() -> None: limit=10, offset=0, name_search_query="nameSearchQuery", + is_expired=True, + filter="filter", ) async for item in response: yield item @@ -422,14 +456,20 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - limit=limit, offset=offset, name_search_query=name_search_query, request_options=request_options + limit=limit, + offset=offset, + name_search_query=name_search_query, + owned_by_teams=owned_by_teams, + is_expired=is_expired, + filter=filter, + request_options=request_options, ) async def create_or_update( self, *, manifest: VirtualAccountManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ diff --git a/src/truefoundry_sdk/virtual_accounts/raw_client.py b/src/truefoundry_sdk/virtual_accounts/raw_client.py index 0e509576..afbd0de2 100644 --- a/src/truefoundry_sdk/virtual_accounts/raw_client.py +++ b/src/truefoundry_sdk/virtual_accounts/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -21,6 +22,7 @@ from ..types.sync_virtual_account_token_response import SyncVirtualAccountTokenResponse from ..types.virtual_account import VirtualAccount from ..types.virtual_account_manifest import VirtualAccountManifest +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -36,6 +38,9 @@ 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, + is_expired: typing.Optional[bool] = None, + filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[VirtualAccount, ListVirtualAccountResponse]: """ @@ -52,6 +57,15 @@ 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]]] + Return virtual accounts owned by these teams + + is_expired : typing.Optional[bool] + Filter virtual accounts by expiration status. true = expired, false = not expired + + filter : typing.Optional[str] + JSON string: structured filter tree (AND/OR groups, column leaves on `name`, json_map leaves on manifest.tags). + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -69,6 +83,9 @@ def list( "limit": limit, "offset": offset, "nameSearchQuery": name_search_query, + "ownedByTeams": owned_by_teams, + "isExpired": is_expired, + "filter": filter, }, request_options=request_options, ) @@ -87,19 +104,26 @@ def list( limit=limit, offset=offset + len(_items or []), name_search_query=name_search_query, + owned_by_teams=owned_by_teams, + is_expired=is_expired, + filter=filter, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) _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: VirtualAccountManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetVirtualAccountResponse]: """ @@ -171,6 +195,10 @@ def create_or_update( _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( @@ -193,7 +221,7 @@ def get( Returns the virtual account associated with the provided virtual account id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -221,6 +249,10 @@ def get( _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( @@ -243,7 +275,7 @@ def delete( Virtual account deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -271,6 +303,10 @@ def delete( _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_token( @@ -293,7 +329,7 @@ def get_token( Token for the virtual account """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/token", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/token", method="GET", request_options=request_options, ) @@ -310,6 +346,10 @@ def get_token( _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 sync_to_secret_store( @@ -332,7 +372,7 @@ def sync_to_secret_store( Token synced successfully to secret store """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/sync-to-secret-store", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/sync-to-secret-store", method="POST", request_options=request_options, ) @@ -371,6 +411,10 @@ def sync_to_secret_store( _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( @@ -396,7 +440,7 @@ def regenerate_token( Token for the virtual account """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/regenerate-token", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", method="POST", json={ "gracePeriodInDays": grace_period_in_days, @@ -420,6 +464,10 @@ def regenerate_token( _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_jwt( @@ -444,7 +492,7 @@ def delete_jwt( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/jwt/{jsonable_encoder(jwt_id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/jwt/{encode_path_param(jwt_id)}", method="DELETE", request_options=request_options, ) @@ -454,6 +502,10 @@ def delete_jwt( _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) @@ -467,6 +519,9 @@ 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, + is_expired: typing.Optional[bool] = None, + filter: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[VirtualAccount, ListVirtualAccountResponse]: """ @@ -483,6 +538,15 @@ 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]]] + Return virtual accounts owned by these teams + + is_expired : typing.Optional[bool] + Filter virtual accounts by expiration status. true = expired, false = not expired + + filter : typing.Optional[str] + JSON string: structured filter tree (AND/OR groups, column leaves on `name`, json_map leaves on manifest.tags). + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -500,6 +564,9 @@ async def list( "limit": limit, "offset": offset, "nameSearchQuery": name_search_query, + "ownedByTeams": owned_by_teams, + "isExpired": is_expired, + "filter": filter, }, request_options=request_options, ) @@ -520,6 +587,9 @@ async def _get_next(): limit=limit, offset=offset + len(_items or []), name_search_query=name_search_query, + owned_by_teams=owned_by_teams, + is_expired=is_expired, + filter=filter, request_options=request_options, ) @@ -527,13 +597,17 @@ async def _get_next(): _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: VirtualAccountManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetVirtualAccountResponse]: """ @@ -605,6 +679,10 @@ async def create_or_update( _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( @@ -627,7 +705,7 @@ async def get( Returns the virtual account associated with the provided virtual account id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -655,6 +733,10 @@ async def get( _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( @@ -677,7 +759,7 @@ async def delete( Virtual account deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -705,6 +787,10 @@ async def delete( _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_token( @@ -727,7 +813,7 @@ async def get_token( Token for the virtual account """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/token", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/token", method="GET", request_options=request_options, ) @@ -744,6 +830,10 @@ async def get_token( _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 sync_to_secret_store( @@ -766,7 +856,7 @@ async def sync_to_secret_store( Token synced successfully to secret store """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/sync-to-secret-store", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/sync-to-secret-store", method="POST", request_options=request_options, ) @@ -805,6 +895,10 @@ async def sync_to_secret_store( _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( @@ -830,7 +924,7 @@ async def regenerate_token( Token for the virtual account """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/regenerate-token", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", method="POST", json={ "gracePeriodInDays": grace_period_in_days, @@ -854,6 +948,10 @@ async def regenerate_token( _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_jwt( @@ -878,7 +976,7 @@ async def delete_jwt( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/jwt/{jsonable_encoder(jwt_id)}", + f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/jwt/{encode_path_param(jwt_id)}", method="DELETE", request_options=request_options, ) @@ -888,4 +986,8 @@ async def delete_jwt( _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/workspaces/client.py b/src/truefoundry_sdk/workspaces/client.py index 64ef2604..66e46d7c 100644 --- a/src/truefoundry_sdk/workspaces/client.py +++ b/src/truefoundry_sdk/workspaces/client.py @@ -39,10 +39,11 @@ def list( cluster_id: typing.Optional[str] = None, name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Workspace, ListWorkspacesResponse]: """ - List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Pagination is available based on query parameters. + List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Parameters ---------- @@ -61,6 +62,9 @@ def list( fqn : typing.Optional[str] Workspace FQN + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -83,6 +87,7 @@ def list( cluster_id="clusterId", name="name", fqn="fqn", + include_cluster=True, ) for item in response: yield item @@ -91,14 +96,20 @@ def list( yield page """ return self._raw_client.list( - limit=limit, offset=offset, cluster_id=cluster_id, name=name, fqn=fqn, request_options=request_options + limit=limit, + offset=offset, + cluster_id=cluster_id, + name=name, + fqn=fqn, + include_cluster=include_cluster, + request_options=request_options, ) def create_or_update( self, *, manifest: WorkspaceManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetWorkspaceResponse: """ @@ -142,6 +153,64 @@ def create_or_update( ) return _response.data + def search( + self, + *, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, + filter: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Workspace, ListWorkspacesResponse]: + """ + List workspaces the user can read with optional structured `filter` (name, id, environmentId, cluster_fqn) and pagination. + + Parameters + ---------- + limit : typing.Optional[int] + Number of items per page + + offset : typing.Optional[int] + Number of items to skip + + filter : typing.Optional[str] + JSON string containing array of search filters with string, type and operator + + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Workspace, ListWorkspacesResponse] + Paginated workspaces matching the filter. + + Examples + -------- + from truefoundry_sdk import TrueFoundry + + client = TrueFoundry( + api_key="YOUR_API_KEY", + base_url="https://yourhost.com/path/to/api", + ) + response = client.workspaces.search( + limit=10, + offset=0, + filter="filter", + include_cluster=True, + ) + for item in response: + yield item + # alternatively, you can paginate page-by-page + for page in response.iter_pages(): + yield page + """ + return self._raw_client.search( + limit=limit, offset=offset, filter=filter, include_cluster=include_cluster, request_options=request_options + ) + def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetWorkspaceResponse: """ Get workspace associated with provided workspace id @@ -232,10 +301,11 @@ async def list( cluster_id: typing.Optional[str] = None, name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Workspace, ListWorkspacesResponse]: """ - List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Pagination is available based on query parameters. + List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Parameters ---------- @@ -254,6 +324,9 @@ async def list( fqn : typing.Optional[str] Workspace FQN + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -281,6 +354,7 @@ async def main() -> None: cluster_id="clusterId", name="name", fqn="fqn", + include_cluster=True, ) async for item in response: yield item @@ -293,14 +367,20 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - limit=limit, offset=offset, cluster_id=cluster_id, name=name, fqn=fqn, request_options=request_options + limit=limit, + offset=offset, + cluster_id=cluster_id, + name=name, + fqn=fqn, + include_cluster=include_cluster, + request_options=request_options, ) async def create_or_update( self, *, manifest: WorkspaceManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> GetWorkspaceResponse: """ @@ -352,6 +432,73 @@ async def main() -> None: ) return _response.data + async def search( + self, + *, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, + filter: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Workspace, ListWorkspacesResponse]: + """ + List workspaces the user can read with optional structured `filter` (name, id, environmentId, cluster_fqn) and pagination. + + Parameters + ---------- + limit : typing.Optional[int] + Number of items per page + + offset : typing.Optional[int] + Number of items to skip + + filter : typing.Optional[str] + JSON string containing array of search filters with string, type and operator + + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Workspace, ListWorkspacesResponse] + Paginated workspaces matching the filter. + + 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: + response = await client.workspaces.search( + limit=10, + offset=0, + filter="filter", + include_cluster=True, + ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page + + + asyncio.run(main()) + """ + return await self._raw_client.search( + limit=limit, offset=offset, filter=filter, include_cluster=include_cluster, request_options=request_options + ) + async def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> GetWorkspaceResponse: """ Get workspace associated with provided workspace id diff --git a/src/truefoundry_sdk/workspaces/raw_client.py b/src/truefoundry_sdk/workspaces/raw_client.py index cbcdf8ac..45069b3b 100644 --- a/src/truefoundry_sdk/workspaces/raw_client.py +++ b/src/truefoundry_sdk/workspaces/raw_client.py @@ -6,8 +6,9 @@ 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 jsonable_encoder +from ..core.jsonable_encoder import encode_path_param from ..core.pagination import AsyncPager, SyncPager +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 @@ -22,6 +23,7 @@ from ..types.workspace import Workspace from ..types.workspace_manifest import WorkspaceManifest from .types.workspaces_delete_response import WorkspacesDeleteResponse +from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -39,10 +41,11 @@ def list( cluster_id: typing.Optional[str] = None, name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Workspace, ListWorkspacesResponse]: """ - List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Pagination is available based on query parameters. + List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Parameters ---------- @@ -61,6 +64,9 @@ def list( fqn : typing.Optional[str] Workspace FQN + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -80,6 +86,7 @@ def list( "clusterId": cluster_id, "name": name, "fqn": fqn, + "includeCluster": include_cluster, }, request_options=request_options, ) @@ -100,19 +107,24 @@ def list( cluster_id=cluster_id, name=name, fqn=fqn, + include_cluster=include_cluster, request_options=request_options, ) return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) _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: WorkspaceManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetWorkspaceResponse]: """ @@ -208,6 +220,85 @@ def create_or_update( _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 search( + self, + *, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, + filter: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> SyncPager[Workspace, ListWorkspacesResponse]: + """ + List workspaces the user can read with optional structured `filter` (name, id, environmentId, cluster_fqn) and pagination. + + Parameters + ---------- + limit : typing.Optional[int] + Number of items per page + + offset : typing.Optional[int] + Number of items to skip + + filter : typing.Optional[str] + JSON string containing array of search filters with string, type and operator + + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SyncPager[Workspace, ListWorkspacesResponse] + Paginated workspaces matching the filter. + """ + offset = offset if offset is not None else 0 + + _response = self._client_wrapper.httpx_client.request( + "api/svc/v1/workspaces/search", + method="GET", + params={ + "limit": limit, + "offset": offset, + "filter": filter, + "includeCluster": include_cluster, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListWorkspacesResponse, + parse_obj_as( + type_=ListWorkspacesResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + _get_next = lambda: self.search( + limit=limit, + offset=offset + len(_items or []), + filter=filter, + include_cluster=include_cluster, + request_options=request_options, + ) + return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + _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( @@ -230,7 +321,7 @@ def get( Returns the workspaces associated with provided workspace id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{jsonable_encoder(id)}", + f"api/svc/v1/workspaces/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -258,6 +349,10 @@ def get( _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( @@ -282,7 +377,7 @@ def delete( Successfully deletes the workspace and returns the workspace details along with a confirmation message. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{jsonable_encoder(id)}", + f"api/svc/v1/workspaces/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -321,6 +416,10 @@ def delete( _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) @@ -336,10 +435,11 @@ async def list( cluster_id: typing.Optional[str] = None, name: typing.Optional[str] = None, fqn: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Workspace, ListWorkspacesResponse]: """ - List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Pagination is available based on query parameters. + List workspaces associated with the user. Optional filters include clusterId, fqn, and workspace name. Parameters ---------- @@ -358,6 +458,9 @@ async def list( fqn : typing.Optional[str] Workspace FQN + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -377,6 +480,7 @@ async def list( "clusterId": cluster_id, "name": name, "fqn": fqn, + "includeCluster": include_cluster, }, request_options=request_options, ) @@ -399,6 +503,7 @@ async def _get_next(): cluster_id=cluster_id, name=name, fqn=fqn, + include_cluster=include_cluster, request_options=request_options, ) @@ -406,13 +511,17 @@ async def _get_next(): _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: WorkspaceManifest, - dry_run: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetWorkspaceResponse]: """ @@ -508,6 +617,88 @@ async def create_or_update( _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 search( + self, + *, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, + filter: typing.Optional[str] = None, + include_cluster: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncPager[Workspace, ListWorkspacesResponse]: + """ + List workspaces the user can read with optional structured `filter` (name, id, environmentId, cluster_fqn) and pagination. + + Parameters + ---------- + limit : typing.Optional[int] + Number of items per page + + offset : typing.Optional[int] + Number of items to skip + + filter : typing.Optional[str] + JSON string containing array of search filters with string, type and operator + + include_cluster : typing.Optional[bool] + When true, each workspace includes cluster information + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncPager[Workspace, ListWorkspacesResponse] + Paginated workspaces matching the filter. + """ + offset = offset if offset is not None else 0 + + _response = await self._client_wrapper.httpx_client.request( + "api/svc/v1/workspaces/search", + method="GET", + params={ + "limit": limit, + "offset": offset, + "filter": filter, + "includeCluster": include_cluster, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _parsed_response = typing.cast( + ListWorkspacesResponse, + parse_obj_as( + type_=ListWorkspacesResponse, # type: ignore + object_=_response.json(), + ), + ) + _items = _parsed_response.data + _has_next = True + + async def _get_next(): + return await self.search( + limit=limit, + offset=offset + len(_items or []), + filter=filter, + include_cluster=include_cluster, + request_options=request_options, + ) + + return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response) + _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( @@ -530,7 +721,7 @@ async def get( Returns the workspaces associated with provided workspace id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{jsonable_encoder(id)}", + f"api/svc/v1/workspaces/{encode_path_param(id)}", method="GET", request_options=request_options, ) @@ -558,6 +749,10 @@ async def get( _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( @@ -582,7 +777,7 @@ async def delete( Successfully deletes the workspace and returns the workspace details along with a confirmation message. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{jsonable_encoder(id)}", + f"api/svc/v1/workspaces/{encode_path_param(id)}", method="DELETE", request_options=request_options, ) @@ -621,4 +816,8 @@ async def delete( _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/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..25710dbe --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,21 @@ +import pytest + + +def _has_httpx_aiohttp() -> bool: + """Check if httpx_aiohttp is importable.""" + try: + import httpx_aiohttp # type: ignore[import-not-found] # noqa: F401 + + return True + except ImportError: + return False + + +def pytest_collection_modifyitems(config: pytest.Config, items: list) -> None: + """Auto-skip @pytest.mark.aiohttp tests when httpx_aiohttp is not installed.""" + if _has_httpx_aiohttp(): + return + skip_aiohttp = pytest.mark.skip(reason="httpx_aiohttp not installed") + for item in items: + if "aiohttp" in item.keywords: + item.add_marker(skip_aiohttp) diff --git a/tests/test_aiohttp_autodetect.py b/tests/test_aiohttp_autodetect.py new file mode 100644 index 00000000..69daf0bd --- /dev/null +++ b/tests/test_aiohttp_autodetect.py @@ -0,0 +1,116 @@ +import importlib +import sys +import unittest +from unittest import mock + +import httpx +import pytest + + +class TestMakeDefaultAsyncClientWithoutAiohttp(unittest.TestCase): + """Tests for _make_default_async_client when httpx_aiohttp is NOT installed.""" + + def test_returns_httpx_async_client(self) -> None: + """When httpx_aiohttp is not installed, returns plain httpx.AsyncClient.""" + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + from truefoundry_sdk.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=True) + self.assertIsInstance(client, httpx.AsyncClient) + self.assertEqual(client.timeout.read, 60) + self.assertTrue(client.follow_redirects) + + def test_follow_redirects_none(self) -> None: + """When follow_redirects is None, omits it from httpx.AsyncClient.""" + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + from truefoundry_sdk.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=None) + self.assertIsInstance(client, httpx.AsyncClient) + self.assertFalse(client.follow_redirects) + + def test_explicit_httpx_client_bypasses_autodetect(self) -> None: + """When user passes httpx_client explicitly, _make_default_async_client is not called.""" + + explicit_client = httpx.AsyncClient(timeout=120) + with mock.patch("truefoundry_sdk.base_client._make_default_async_client") as mock_make: + # Replicate the generated conditional: httpx_client if httpx_client is not None else _make_default_async_client(...) + result = explicit_client if explicit_client is not None else mock_make(timeout=60, follow_redirects=True) + mock_make.assert_not_called() + self.assertIs(result, explicit_client) + + +@pytest.mark.aiohttp +class TestMakeDefaultAsyncClientWithAiohttp(unittest.TestCase): + """Tests for _make_default_async_client when httpx_aiohttp IS installed.""" + + def test_returns_aiohttp_client(self) -> None: + """When httpx_aiohttp is installed, returns HttpxAiohttpClient.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from truefoundry_sdk.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=True) + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertEqual(client.timeout.read, 60) + self.assertTrue(client.follow_redirects) + + def test_follow_redirects_none(self) -> None: + """When httpx_aiohttp is installed and follow_redirects is None, omits it.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from truefoundry_sdk.base_client import _make_default_async_client + + client = _make_default_async_client(timeout=60, follow_redirects=None) + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertFalse(client.follow_redirects) + + +class TestDefaultClientsWithoutAiohttp(unittest.TestCase): + """Tests for _default_clients.py convenience classes (no aiohttp).""" + + def test_default_async_httpx_client_defaults(self) -> None: + """DefaultAsyncHttpxClient applies SDK defaults.""" + from truefoundry_sdk._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAsyncHttpxClient + + client = DefaultAsyncHttpxClient() + self.assertIsInstance(client, httpx.AsyncClient) + self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) + self.assertTrue(client.follow_redirects) + + def test_default_async_httpx_client_overrides(self) -> None: + """DefaultAsyncHttpxClient allows overriding defaults.""" + from truefoundry_sdk._default_clients import DefaultAsyncHttpxClient + + client = DefaultAsyncHttpxClient(timeout=30, follow_redirects=False) + self.assertEqual(client.timeout.read, 30) + self.assertFalse(client.follow_redirects) + + def test_default_aiohttp_client_raises_without_package(self) -> None: + """DefaultAioHttpClient raises RuntimeError when httpx_aiohttp not installed.""" + import truefoundry_sdk._default_clients + + with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): + importlib.reload(truefoundry_sdk._default_clients) + + with self.assertRaises(RuntimeError) as ctx: + truefoundry_sdk._default_clients.DefaultAioHttpClient() + self.assertIn("pip install truefoundry-sdk[aiohttp]", str(ctx.exception)) + + importlib.reload(truefoundry_sdk._default_clients) + + +@pytest.mark.aiohttp +class TestDefaultClientsWithAiohttp(unittest.TestCase): + """Tests for _default_clients.py when httpx_aiohttp IS installed.""" + + def test_default_aiohttp_client_defaults(self) -> None: + """DefaultAioHttpClient works when httpx_aiohttp is installed.""" + import httpx_aiohttp # type: ignore[import-not-found] + + from truefoundry_sdk._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAioHttpClient + + client = DefaultAioHttpClient() + self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) + self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) + self.assertTrue(client.follow_redirects) diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index e2083580..bf0dbcc7 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -1,7 +1,9 @@ # This file was auto-generated by Fern from our API Definition. from typing import Any, Dict +from unittest.mock import AsyncMock, MagicMock, patch +import httpx import pytest from truefoundry_sdk.core.http_client import ( @@ -298,3 +300,363 @@ def test_preserves_base_url_path_prefix_trailing_slash() -> None: """Test that path prefixes in base URL are preserved.""" result = _build_url("https://cloud.example.com/org/tenant/api/", "/users") assert result == "https://cloud.example.com/org/tenant/api/users" + + +# --------------------------------------------------------------------------- +# Connection error retry tests +# --------------------------------------------------------------------------- + + +def _make_sync_http_client(mock_client: Any) -> HttpClient: + return HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + ) + + +def _make_async_http_client(mock_client: Any) -> AsyncHttpClient: + return AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + async_base_headers=None, + ) + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_retries_on_connect_error(mock_sleep: MagicMock) -> None: + """Sync: connection error retries on httpx.ConnectError.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + http_client = _make_sync_http_client(mock_client) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_retries_on_remote_protocol_error(mock_sleep: MagicMock) -> None: + """Sync: connection error retries on httpx.RemoteProtocolError.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.RemoteProtocolError("Remote end closed connection without response"), + _DummyResponse(), + ] + http_client = _make_sync_http_client(mock_client) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_connection_error_exhausts_retries(mock_sleep: MagicMock) -> None: + """Sync: connection error exhausts retries then raises.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = _make_sync_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + assert mock_sleep.call_count == 2 + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_connection_error_respects_max_retries_zero(mock_sleep: MagicMock) -> None: + """Sync: connection error respects max_retries=0.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = _make_sync_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 0}, + ) + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_retries_on_connect_error(mock_sleep: AsyncMock) -> None: + """Async: connection error retries on httpx.ConnectError.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + ) + http_client = _make_async_http_client(mock_client) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_retries_on_remote_protocol_error(mock_sleep: AsyncMock) -> None: + """Async: connection error retries on httpx.RemoteProtocolError.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.RemoteProtocolError("Remote end closed connection without response"), + _DummyResponse(), + ] + ) + http_client = _make_async_http_client(mock_client) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + assert mock_client.request.call_count == 2 + mock_sleep.assert_called_once() + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_connection_error_exhausts_retries(mock_sleep: AsyncMock) -> None: + """Async: connection error exhausts retries then raises.""" + mock_client = MagicMock() + mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) + http_client = _make_async_http_client(mock_client) + + with pytest.raises(httpx.ConnectError): + await http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + assert mock_sleep.call_count == 2 + + +# --------------------------------------------------------------------------- +# base_max_retries constructor parameter tests +# --------------------------------------------------------------------------- + + +def test_sync_http_client_default_base_max_retries() -> None: + """HttpClient defaults to base_max_retries=2.""" + http_client = HttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + ) + assert http_client.base_max_retries == 2 + + +def test_async_http_client_default_base_max_retries() -> None: + """AsyncHttpClient defaults to base_max_retries=2.""" + http_client = AsyncHttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + ) + assert http_client.base_max_retries == 2 + + +def test_sync_http_client_custom_base_max_retries() -> None: + """HttpClient accepts a custom base_max_retries value.""" + http_client = HttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_max_retries=5, + ) + assert http_client.base_max_retries == 5 + + +def test_async_http_client_custom_base_max_retries() -> None: + """AsyncHttpClient accepts a custom base_max_retries value.""" + http_client = AsyncHttpClient( + httpx_client=MagicMock(), # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_max_retries=5, + ) + assert http_client.base_max_retries == 5 + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_base_max_retries_zero_disables_retries(mock_sleep: MagicMock) -> None: + """Sync: base_max_retries=0 disables retries when no request_options override.""" + mock_client = MagicMock() + mock_client.request.side_effect = httpx.ConnectError("connection failed") + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, + ) + + with pytest.raises(httpx.ConnectError): + http_client.request(path="/test", method="GET") + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_base_max_retries_zero_disables_retries(mock_sleep: AsyncMock) -> None: + """Async: base_max_retries=0 disables retries when no request_options override.""" + mock_client = MagicMock() + mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, + ) + + with pytest.raises(httpx.ConnectError): + await http_client.request(path="/test", method="GET") + + # No retries, just the initial attempt + assert mock_client.request.call_count == 1 + mock_sleep.assert_not_called() + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_request_options_override_base_max_retries(mock_sleep: MagicMock) -> None: + """Sync: request_options max_retries overrides base_max_retries.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("connection failed"), + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, # base says no retries + ) + + # But request_options overrides to allow 2 retries + response = http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + assert response.status_code == 200 + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_request_options_override_base_max_retries(mock_sleep: AsyncMock) -> None: + """Async: request_options max_retries overrides base_max_retries.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("connection failed"), + httpx.ConnectError("connection failed"), + _DummyResponse(), + ] + ) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=0, # base says no retries + ) + + # But request_options overrides to allow 2 retries + response = await http_client.request( + path="/test", + method="GET", + request_options={"max_retries": 2}, + ) + + assert response.status_code == 200 + # 1 initial + 2 retries = 3 total attempts + assert mock_client.request.call_count == 3 + + +@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) +def test_sync_base_max_retries_used_as_default(mock_sleep: MagicMock) -> None: + """Sync: base_max_retries is used when request_options has no max_retries.""" + mock_client = MagicMock() + mock_client.request.side_effect = [ + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + _DummyResponse(), + ] + http_client = HttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=3, + ) + + response = http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + # 1 initial + 3 retries = 4 total attempts + assert mock_client.request.call_count == 4 + + +@pytest.mark.asyncio +@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) +async def test_async_base_max_retries_used_as_default(mock_sleep: AsyncMock) -> None: + """Async: base_max_retries is used when request_options has no max_retries.""" + mock_client = MagicMock() + mock_client.request = AsyncMock( + side_effect=[ + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + httpx.ConnectError("fail"), + _DummyResponse(), + ] + ) + http_client = AsyncHttpClient( + httpx_client=mock_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + base_max_retries=3, + ) + + response = await http_client.request(path="/test", method="GET") + + assert response.status_code == 200 + # 1 initial + 3 retries = 4 total attempts + assert mock_client.request.call_count == 4 From a1bd6693a6af40215596f27296dd1f34694de713 Mon Sep 17 00:00:00 2001 From: Chirag Jain Date: Tue, 14 Apr 2026 11:50:03 +0530 Subject: [PATCH 2/6] Fix statusCode to status_code in error handling --- src/truefoundry_sdk/_wrapped_clients.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/truefoundry_sdk/_wrapped_clients.py b/src/truefoundry_sdk/_wrapped_clients.py index 727ddec5..6a3388a5 100644 --- a/src/truefoundry_sdk/_wrapped_clients.py +++ b/src/truefoundry_sdk/_wrapped_clients.py @@ -48,7 +48,7 @@ def _get_by_fqn(client: HasListMethod[T, R], *, fqn: str, request_options: Optio raise NotFoundError( body=HttpError( message=f"No entity found with fqn {fqn}", - statusCode=404, + status_code=404, ) ) return result @@ -67,7 +67,7 @@ async def _aget_by_fqn( raise NotFoundError( body=HttpError( message=f"No entity found with fqn {fqn}", - statusCode=404, + status_code=404, ) ) return result From ba18aae586d256af6e204e81dea98d8490a636ac Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 14:54:50 +0000 Subject: [PATCH 3/6] SDK regeneration --- .fern/metadata.json | 2 +- src/truefoundry_sdk/__init__.py | 27 +++++++ src/truefoundry_sdk/types/__init__.py | 27 +++++++ src/truefoundry_sdk/types/application.py | 11 +-- .../types/application_debug_info.py | 42 +++++++++++ .../types/application_problem.py | 19 +++++ src/truefoundry_sdk/types/deployment.py | 3 +- .../types/flyte_task_custom_truefoundry.py | 3 +- .../types/flyte_task_template.py | 19 +---- .../get_application_deployment_response.py | 8 ++- .../types/get_application_response.py | 5 +- .../list_application_deployments_response.py | 8 ++- .../types/list_applications_response.py | 5 +- .../native_snowflake_flyte_task_template.py | 28 ++++++++ ...ve_snowflake_flyte_task_template_config.py | 28 ++++++++ ...ative_snowflake_flyte_task_template_sql.py | 18 +++++ .../types/snowflake_task_config.py | 70 +++++++++++++++++++ .../types/snowflake_task_config_image.py | 8 +++ .../snowflake_task_config_mounts_item.py | 9 +++ .../types/truefoundry_flyte_task_template.py | 21 ++++++ 20 files changed, 334 insertions(+), 27 deletions(-) create mode 100644 src/truefoundry_sdk/types/application_debug_info.py create mode 100644 src/truefoundry_sdk/types/application_problem.py create mode 100644 src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py create mode 100644 src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.py create mode 100644 src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py create mode 100644 src/truefoundry_sdk/types/snowflake_task_config.py create mode 100644 src/truefoundry_sdk/types/snowflake_task_config_image.py create mode 100644 src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py create mode 100644 src/truefoundry_sdk/types/truefoundry_flyte_task_template.py diff --git a/.fern/metadata.json b/.fern/metadata.json index f883100e..4eb398da 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,6 +22,6 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "94e2c4c06e5c9b7c67e60377e31f8929dfd564b0", + "originGitCommit": "5057cbacbb78492b614b2f631dbeae7c7305635b", "sdkVersion": "0.0.0" } \ No newline at end of file diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index f65b2955..518f9b12 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -48,8 +48,10 @@ AnthropicModel, AnthropicProviderAccount, Application, + ApplicationDebugInfo, ApplicationLifecycleStage, ApplicationMetadata, + ApplicationProblem, ApplicationSet, ApplicationSetComponentsItem, ApplicationType, @@ -604,6 +606,9 @@ MultiPartUpload, MultiPartUploadResponse, MultiPartUploadStorageProvider, + NativeSnowflakeFlyteTaskTemplate, + NativeSnowflakeFlyteTaskTemplateConfig, + NativeSnowflakeFlyteTaskTemplateSql, NatsInputConfig, NatsMetricConfig, NatsOutputConfig, @@ -838,6 +843,9 @@ SnowflakeCortexModel, SnowflakeCortexPatTokenAuth, SnowflakeCortexProviderAccount, + SnowflakeTaskConfig, + SnowflakeTaskConfigImage, + SnowflakeTaskConfigMountsItem, SortDirection, SpaCyFramework, SpanAttributeFilter, @@ -954,6 +962,7 @@ TrueFoundryInteractiveLogin, TrueFoundryManagedSource, TrueFoundryProviderAccount, + TruefoundryFlyteTaskTemplate, TtlIntegrations, TtlProviderAccount, TtlRegistry, @@ -1111,8 +1120,10 @@ "AnthropicModel": ".types", "AnthropicProviderAccount": ".types", "Application": ".types", + "ApplicationDebugInfo": ".types", "ApplicationLifecycleStage": ".types", "ApplicationMetadata": ".types", + "ApplicationProblem": ".types", "ApplicationSet": ".types", "ApplicationSetComponentsItem": ".types", "ApplicationType": ".types", @@ -1680,6 +1691,9 @@ "MultiPartUpload": ".types", "MultiPartUploadResponse": ".types", "MultiPartUploadStorageProvider": ".types", + "NativeSnowflakeFlyteTaskTemplate": ".types", + "NativeSnowflakeFlyteTaskTemplateConfig": ".types", + "NativeSnowflakeFlyteTaskTemplateSql": ".types", "NatsInputConfig": ".types", "NatsMetricConfig": ".types", "NatsOutputConfig": ".types", @@ -1917,6 +1931,9 @@ "SnowflakeCortexModel": ".types", "SnowflakeCortexPatTokenAuth": ".types", "SnowflakeCortexProviderAccount": ".types", + "SnowflakeTaskConfig": ".types", + "SnowflakeTaskConfigImage": ".types", + "SnowflakeTaskConfigMountsItem": ".types", "SortDirection": ".types", "SpaCyFramework": ".types", "SpanAttributeFilter": ".types", @@ -2037,6 +2054,7 @@ "TrueFoundryInteractiveLogin": ".types", "TrueFoundryManagedSource": ".types", "TrueFoundryProviderAccount": ".types", + "TruefoundryFlyteTaskTemplate": ".types", "TtlIntegrations": ".types", "TtlProviderAccount": ".types", "TtlRegistry": ".types", @@ -2193,8 +2211,10 @@ def __dir__(): "AnthropicModel", "AnthropicProviderAccount", "Application", + "ApplicationDebugInfo", "ApplicationLifecycleStage", "ApplicationMetadata", + "ApplicationProblem", "ApplicationSet", "ApplicationSetComponentsItem", "ApplicationType", @@ -2762,6 +2782,9 @@ def __dir__(): "MultiPartUpload", "MultiPartUploadResponse", "MultiPartUploadStorageProvider", + "NativeSnowflakeFlyteTaskTemplate", + "NativeSnowflakeFlyteTaskTemplateConfig", + "NativeSnowflakeFlyteTaskTemplateSql", "NatsInputConfig", "NatsMetricConfig", "NatsOutputConfig", @@ -2999,6 +3022,9 @@ def __dir__(): "SnowflakeCortexModel", "SnowflakeCortexPatTokenAuth", "SnowflakeCortexProviderAccount", + "SnowflakeTaskConfig", + "SnowflakeTaskConfigImage", + "SnowflakeTaskConfigMountsItem", "SortDirection", "SpaCyFramework", "SpanAttributeFilter", @@ -3119,6 +3145,7 @@ def __dir__(): "TrueFoundryInteractiveLogin", "TrueFoundryManagedSource", "TrueFoundryProviderAccount", + "TruefoundryFlyteTaskTemplate", "TtlIntegrations", "TtlProviderAccount", "TtlRegistry", diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index a7ffa387..0da19032 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -50,8 +50,10 @@ from .anthropic_model import AnthropicModel from .anthropic_provider_account import AnthropicProviderAccount from .application import Application + from .application_debug_info import ApplicationDebugInfo from .application_lifecycle_stage import ApplicationLifecycleStage from .application_metadata import ApplicationMetadata + from .application_problem import ApplicationProblem from .application_set import ApplicationSet from .application_set_components_item import ApplicationSetComponentsItem from .application_type import ApplicationType @@ -620,6 +622,9 @@ from .multi_part_upload import MultiPartUpload from .multi_part_upload_response import MultiPartUploadResponse from .multi_part_upload_storage_provider import MultiPartUploadStorageProvider + from .native_snowflake_flyte_task_template import NativeSnowflakeFlyteTaskTemplate + from .native_snowflake_flyte_task_template_config import NativeSnowflakeFlyteTaskTemplateConfig + from .native_snowflake_flyte_task_template_sql import NativeSnowflakeFlyteTaskTemplateSql from .nats_input_config import NatsInputConfig from .nats_metric_config import NatsMetricConfig from .nats_output_config import NatsOutputConfig @@ -851,6 +856,9 @@ from .snowflake_cortex_model import SnowflakeCortexModel from .snowflake_cortex_pat_token_auth import SnowflakeCortexPatTokenAuth from .snowflake_cortex_provider_account import SnowflakeCortexProviderAccount + from .snowflake_task_config import SnowflakeTaskConfig + from .snowflake_task_config_image import SnowflakeTaskConfigImage + from .snowflake_task_config_mounts_item import SnowflakeTaskConfigMountsItem from .sort_direction import SortDirection from .spa_cy_framework import SpaCyFramework from .span_attribute_filter import SpanAttributeFilter @@ -969,6 +977,7 @@ from .true_foundry_interactive_login import TrueFoundryInteractiveLogin from .true_foundry_managed_source import TrueFoundryManagedSource from .true_foundry_provider_account import TrueFoundryProviderAccount + from .truefoundry_flyte_task_template import TruefoundryFlyteTaskTemplate from .ttl_integrations import TtlIntegrations from .ttl_provider_account import TtlProviderAccount from .ttl_registry import TtlRegistry @@ -1070,8 +1079,10 @@ "AnthropicModel": ".anthropic_model", "AnthropicProviderAccount": ".anthropic_provider_account", "Application": ".application", + "ApplicationDebugInfo": ".application_debug_info", "ApplicationLifecycleStage": ".application_lifecycle_stage", "ApplicationMetadata": ".application_metadata", + "ApplicationProblem": ".application_problem", "ApplicationSet": ".application_set", "ApplicationSetComponentsItem": ".application_set_components_item", "ApplicationType": ".application_type", @@ -1626,6 +1637,9 @@ "MultiPartUpload": ".multi_part_upload", "MultiPartUploadResponse": ".multi_part_upload_response", "MultiPartUploadStorageProvider": ".multi_part_upload_storage_provider", + "NativeSnowflakeFlyteTaskTemplate": ".native_snowflake_flyte_task_template", + "NativeSnowflakeFlyteTaskTemplateConfig": ".native_snowflake_flyte_task_template_config", + "NativeSnowflakeFlyteTaskTemplateSql": ".native_snowflake_flyte_task_template_sql", "NatsInputConfig": ".nats_input_config", "NatsMetricConfig": ".nats_metric_config", "NatsOutputConfig": ".nats_output_config", @@ -1860,6 +1874,9 @@ "SnowflakeCortexModel": ".snowflake_cortex_model", "SnowflakeCortexPatTokenAuth": ".snowflake_cortex_pat_token_auth", "SnowflakeCortexProviderAccount": ".snowflake_cortex_provider_account", + "SnowflakeTaskConfig": ".snowflake_task_config", + "SnowflakeTaskConfigImage": ".snowflake_task_config_image", + "SnowflakeTaskConfigMountsItem": ".snowflake_task_config_mounts_item", "SortDirection": ".sort_direction", "SpaCyFramework": ".spa_cy_framework", "SpanAttributeFilter": ".span_attribute_filter", @@ -1976,6 +1993,7 @@ "TrueFoundryInteractiveLogin": ".true_foundry_interactive_login", "TrueFoundryManagedSource": ".true_foundry_managed_source", "TrueFoundryProviderAccount": ".true_foundry_provider_account", + "TruefoundryFlyteTaskTemplate": ".truefoundry_flyte_task_template", "TtlIntegrations": ".ttl_integrations", "TtlProviderAccount": ".ttl_provider_account", "TtlRegistry": ".ttl_registry", @@ -2101,8 +2119,10 @@ def __dir__(): "AnthropicModel", "AnthropicProviderAccount", "Application", + "ApplicationDebugInfo", "ApplicationLifecycleStage", "ApplicationMetadata", + "ApplicationProblem", "ApplicationSet", "ApplicationSetComponentsItem", "ApplicationType", @@ -2657,6 +2677,9 @@ def __dir__(): "MultiPartUpload", "MultiPartUploadResponse", "MultiPartUploadStorageProvider", + "NativeSnowflakeFlyteTaskTemplate", + "NativeSnowflakeFlyteTaskTemplateConfig", + "NativeSnowflakeFlyteTaskTemplateSql", "NatsInputConfig", "NatsMetricConfig", "NatsOutputConfig", @@ -2891,6 +2914,9 @@ def __dir__(): "SnowflakeCortexModel", "SnowflakeCortexPatTokenAuth", "SnowflakeCortexProviderAccount", + "SnowflakeTaskConfig", + "SnowflakeTaskConfigImage", + "SnowflakeTaskConfigMountsItem", "SortDirection", "SpaCyFramework", "SpanAttributeFilter", @@ -3007,6 +3033,7 @@ def __dir__(): "TrueFoundryInteractiveLogin", "TrueFoundryManagedSource", "TrueFoundryProviderAccount", + "TruefoundryFlyteTaskTemplate", "TtlIntegrations", "TtlProviderAccount", "TtlRegistry", diff --git a/src/truefoundry_sdk/types/application.py b/src/truefoundry_sdk/types/application.py index 19e71b35..cc01b1ff 100644 --- a/src/truefoundry_sdk/types/application.py +++ b/src/truefoundry_sdk/types/application.py @@ -9,8 +9,10 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata +from .alert import Alert from .application_lifecycle_stage import ApplicationLifecycleStage from .application_metadata import ApplicationMetadata +from .application_problem import ApplicationProblem from .application_type import ApplicationType from .recommendation import Recommendation from .subject import Subject @@ -51,7 +53,7 @@ class Application(UniversalBaseModel): Recommendations for this application """ - alerts: typing.Optional[typing.List[typing.List[typing.Any]]] = pydantic.Field(default=None) + alerts: typing.Optional[typing.List[Alert]] = pydantic.Field(default=None) """ Alerts for this application """ @@ -62,12 +64,12 @@ class Application(UniversalBaseModel): pydantic.Field(alias="alertsSummary", description="Summary of alerts for this application"), ] = None application_debug_infos: typing_extensions.Annotated[ - typing.Optional[typing.List[typing.List[typing.Any]]], + typing.Optional[typing.List["ApplicationDebugInfo"]], FieldMetadata(alias="applicationDebugInfos"), pydantic.Field(alias="applicationDebugInfos", description="Debug infos for this application"), ] = None potential_problems: typing_extensions.Annotated[ - typing.Optional[typing.List[typing.List[typing.Any]]], + typing.Optional[typing.List[ApplicationProblem]], FieldMetadata(alias="potentialProblems"), pydantic.Field(alias="potentialProblems", description="Potential problems with the application"), ] = None @@ -95,6 +97,7 @@ class Config: extra = pydantic.Extra.allow +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(Application, Deployment=Deployment) +update_forward_refs(Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/application_debug_info.py b/src/truefoundry_sdk/types/application_debug_info.py new file mode 100644 index 00000000..44050873 --- /dev/null +++ b/src/truefoundry_sdk/types/application_debug_info.py @@ -0,0 +1,42 @@ +# 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 + + +class ApplicationDebugInfo(UniversalBaseModel): + id: typing.Optional[str] = None + application_id: typing_extensions.Annotated[ + str, FieldMetadata(alias="applicationId"), pydantic.Field(alias="applicationId") + ] + application: typing.Optional["Application"] = None + debug_info: typing_extensions.Annotated[ + typing.Dict[str, typing.Any], FieldMetadata(alias="debugInfo"), pydantic.Field(alias="debugInfo") + ] + 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 + + +from .application import Application # noqa: E402, I001 +from .deployment import Deployment # noqa: E402, I001 + +update_forward_refs(ApplicationDebugInfo, Application=Application, Deployment=Deployment) diff --git a/src/truefoundry_sdk/types/application_problem.py b/src/truefoundry_sdk/types/application_problem.py new file mode 100644 index 00000000..26d2afcd --- /dev/null +++ b/src/truefoundry_sdk/types/application_problem.py @@ -0,0 +1,19 @@ +# 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 ApplicationProblem(UniversalBaseModel): + name: str + description: 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/deployment.py b/src/truefoundry_sdk/types/deployment.py index 3b606e85..d00f791f 100644 --- a/src/truefoundry_sdk/types/deployment.py +++ b/src/truefoundry_sdk/types/deployment.py @@ -69,5 +69,6 @@ class Config: from .application import Application # noqa: E402, I001 +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 -update_forward_refs(Deployment, Application=Application) +update_forward_refs(Deployment, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo) diff --git a/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py index c34cdf9e..6cbdb7c6 100644 --- a/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py +++ b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py @@ -6,7 +6,8 @@ from .databricks_job_task_config import DatabricksJobTaskConfig from .py_spark_task_config import PySparkTaskConfig from .python_task_config import PythonTaskConfig +from .snowflake_task_config import SnowflakeTaskConfig FlyteTaskCustomTruefoundry = typing.Union[ - PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig, DatabricksJobTaskConfig + PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig, DatabricksJobTaskConfig, SnowflakeTaskConfig ] diff --git a/src/truefoundry_sdk/types/flyte_task_template.py b/src/truefoundry_sdk/types/flyte_task_template.py index 030e1380..5cf53cf4 100644 --- a/src/truefoundry_sdk/types/flyte_task_template.py +++ b/src/truefoundry_sdk/types/flyte_task_template.py @@ -2,20 +2,7 @@ import typing -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .flyte_task_custom import FlyteTaskCustom -from .flyte_task_id import FlyteTaskId +from .native_snowflake_flyte_task_template import NativeSnowflakeFlyteTaskTemplate +from .truefoundry_flyte_task_template import TruefoundryFlyteTaskTemplate - -class FlyteTaskTemplate(UniversalBaseModel): - id: FlyteTaskId - custom: FlyteTaskCustom - - 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 +FlyteTaskTemplate = typing.Union[TruefoundryFlyteTaskTemplate, NativeSnowflakeFlyteTaskTemplate] diff --git a/src/truefoundry_sdk/types/get_application_deployment_response.py b/src/truefoundry_sdk/types/get_application_deployment_response.py index 8e20d7b4..bd90c13c 100644 --- a/src/truefoundry_sdk/types/get_application_deployment_response.py +++ b/src/truefoundry_sdk/types/get_application_deployment_response.py @@ -24,6 +24,12 @@ class Config: from .application import Application # noqa: E402, I001 +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(GetApplicationDeploymentResponse, Application=Application, Deployment=Deployment) +update_forward_refs( + GetApplicationDeploymentResponse, + Application=Application, + ApplicationDebugInfo=ApplicationDebugInfo, + Deployment=Deployment, +) diff --git a/src/truefoundry_sdk/types/get_application_response.py b/src/truefoundry_sdk/types/get_application_response.py index e3bfeb41..0b776fda 100644 --- a/src/truefoundry_sdk/types/get_application_response.py +++ b/src/truefoundry_sdk/types/get_application_response.py @@ -24,6 +24,9 @@ class Config: from .application import Application # noqa: E402, I001 +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(GetApplicationResponse, Application=Application, Deployment=Deployment) +update_forward_refs( + GetApplicationResponse, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment +) diff --git a/src/truefoundry_sdk/types/list_application_deployments_response.py b/src/truefoundry_sdk/types/list_application_deployments_response.py index 71f5aa1e..a470172a 100644 --- a/src/truefoundry_sdk/types/list_application_deployments_response.py +++ b/src/truefoundry_sdk/types/list_application_deployments_response.py @@ -30,6 +30,12 @@ class Config: from .application import Application # noqa: E402, I001 +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(ListApplicationDeploymentsResponse, Application=Application, Deployment=Deployment) +update_forward_refs( + ListApplicationDeploymentsResponse, + Application=Application, + ApplicationDebugInfo=ApplicationDebugInfo, + Deployment=Deployment, +) diff --git a/src/truefoundry_sdk/types/list_applications_response.py b/src/truefoundry_sdk/types/list_applications_response.py index 4a9a46f1..a7ab2d12 100644 --- a/src/truefoundry_sdk/types/list_applications_response.py +++ b/src/truefoundry_sdk/types/list_applications_response.py @@ -30,6 +30,9 @@ class Config: from .application import Application # noqa: E402, I001 +from .application_debug_info import ApplicationDebugInfo # noqa: E402, I001 from .deployment import Deployment # noqa: E402, I001 -update_forward_refs(ListApplicationsResponse, Application=Application, Deployment=Deployment) +update_forward_refs( + ListApplicationsResponse, Application=Application, ApplicationDebugInfo=ApplicationDebugInfo, Deployment=Deployment +) diff --git a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py new file mode 100644 index 00000000..72185c6d --- /dev/null +++ b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.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 .flyte_task_id import FlyteTaskId +from .native_snowflake_flyte_task_template_config import NativeSnowflakeFlyteTaskTemplateConfig +from .native_snowflake_flyte_task_template_sql import NativeSnowflakeFlyteTaskTemplateSql + + +class NativeSnowflakeFlyteTaskTemplate(UniversalBaseModel): + id: FlyteTaskId + type: typing.Literal["snowflake"] = "snowflake" + config: NativeSnowflakeFlyteTaskTemplateConfig = pydantic.Field() + """ + Flyte snowflake task plugin specific config + """ + + sql: NativeSnowflakeFlyteTaskTemplateSql + + 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/native_snowflake_flyte_task_template_config.py b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.py new file mode 100644 index 00000000..4d062d07 --- /dev/null +++ b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.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 + + +class NativeSnowflakeFlyteTaskTemplateConfig(UniversalBaseModel): + """ + Flyte snowflake task plugin specific config + """ + + account: str + schema_: typing_extensions.Annotated[str, FieldMetadata(alias="schema"), pydantic.Field(alias="schema")] + user: str + warehouse: str + database: 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/native_snowflake_flyte_task_template_sql.py b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py new file mode 100644 index 00000000..c2e2f251 --- /dev/null +++ b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py @@ -0,0 +1,18 @@ +# 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 NativeSnowflakeFlyteTaskTemplateSql(UniversalBaseModel): + statement: 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/snowflake_task_config.py b/src/truefoundry_sdk/types/snowflake_task_config.py new file mode 100644 index 00000000..d61495fa --- /dev/null +++ b/src/truefoundry_sdk/types/snowflake_task_config.py @@ -0,0 +1,70 @@ +# 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 .resources import Resources +from .snowflake_task_config_image import SnowflakeTaskConfigImage +from .snowflake_task_config_mounts_item import SnowflakeTaskConfigMountsItem + + +class SnowflakeTaskConfig(UniversalBaseModel): + type: typing.Literal["snowflake-task-config"] = pydantic.Field(default="snowflake-task-config") + """ + +value=snowflake-task-config + """ + + image: SnowflakeTaskConfigImage = pydantic.Field() + """ + Specify the image spec for the task + """ + + user: str = pydantic.Field() + """ + Snowflake config for the task. + """ + + account: str = pydantic.Field() + """ + Snowflake account for the task. + """ + + database: str = pydantic.Field() + """ + Snowflake database for the task. + """ + + schema_name: str = pydantic.Field() + """ + Snowflake schema for the task. + """ + + warehouse: str = pydantic.Field() + """ + Snowflake warehouse for the task. + """ + + env: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) + """ + Configure environment variables to be injected in the task either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables) + """ + + resources: typing.Optional[Resources] = None + mounts: typing.Optional[typing.List[SnowflakeTaskConfigMountsItem]] = pydantic.Field(default=None) + """ + Configure data to be mounted to Workflow pod(s) as a volume. + """ + + service_account: typing.Optional[str] = pydantic.Field(default=None) + """ + Service 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/snowflake_task_config_image.py b/src/truefoundry_sdk/types/snowflake_task_config_image.py new file mode 100644 index 00000000..ee80ccc9 --- /dev/null +++ b/src/truefoundry_sdk/types/snowflake_task_config_image.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .task_docker_file_build import TaskDockerFileBuild +from .task_python_build import TaskPythonBuild + +SnowflakeTaskConfigImage = typing.Union[TaskPythonBuild, TaskDockerFileBuild] diff --git a/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py b/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py new file mode 100644 index 00000000..09a1ccd7 --- /dev/null +++ b/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .secret_mount import SecretMount +from .string_data_mount import StringDataMount +from .volume_mount import VolumeMount + +SnowflakeTaskConfigMountsItem = typing.Union[SecretMount, StringDataMount, VolumeMount] diff --git a/src/truefoundry_sdk/types/truefoundry_flyte_task_template.py b/src/truefoundry_sdk/types/truefoundry_flyte_task_template.py new file mode 100644 index 00000000..1e8b1f9a --- /dev/null +++ b/src/truefoundry_sdk/types/truefoundry_flyte_task_template.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 +from .flyte_task_custom import FlyteTaskCustom +from .flyte_task_id import FlyteTaskId + + +class TruefoundryFlyteTaskTemplate(UniversalBaseModel): + id: FlyteTaskId + custom: FlyteTaskCustom + + 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 0443b8760af730bb07179bf3d5b2166a9c401633 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:59:45 +0000 Subject: [PATCH 4/6] SDK regeneration --- .fern/metadata.json | 4 +- README.md | 15 +- poetry.lock | 617 +----------------- pyproject.toml | 10 +- reference.md | 52 +- requirements.txt | 2 +- src/truefoundry_sdk/__init__.py | 5 - src/truefoundry_sdk/_default_clients.py | 32 - .../agent_skill_versions/raw_client.py | 10 +- .../agent_skills/raw_client.py | 10 +- .../application_versions/raw_client.py | 10 +- .../applications/raw_client.py | 26 +- .../artifact_versions/raw_client.py | 10 +- src/truefoundry_sdk/artifacts/raw_client.py | 10 +- src/truefoundry_sdk/base_client.py | 27 +- src/truefoundry_sdk/clusters/raw_client.py | 18 +- src/truefoundry_sdk/core/__init__.py | 4 +- src/truefoundry_sdk/core/http_client.py | 108 +-- src/truefoundry_sdk/core/jsonable_encoder.py | 12 - .../data_directories/raw_client.py | 10 +- .../environments/raw_client.py | 10 +- .../internal/ai_gateway/raw_client.py | 6 +- .../internal/applications/raw_client.py | 10 +- .../internal/build_logs/raw_client.py | 6 +- .../internal/clusters/raw_client.py | 6 +- .../internal/deployments/raw_client.py | 10 +- .../internal/metrics/raw_client.py | 6 +- src/truefoundry_sdk/internal/raw_client.py | 6 +- .../internal/workflows/raw_client.py | 6 +- src/truefoundry_sdk/jobs/raw_client.py | 14 +- src/truefoundry_sdk/ml_repos/raw_client.py | 10 +- .../model_versions/raw_client.py | 10 +- src/truefoundry_sdk/models/raw_client.py | 10 +- .../personal_access_tokens/raw_client.py | 10 +- .../prompt_versions/raw_client.py | 10 +- src/truefoundry_sdk/prompts/raw_client.py | 10 +- .../secret_groups/raw_client.py | 14 +- src/truefoundry_sdk/secrets/raw_client.py | 10 +- src/truefoundry_sdk/teams/raw_client.py | 14 +- .../types/non_negative_float.py | 3 - src/truefoundry_sdk/users/raw_client.py | 22 +- .../virtual_accounts/raw_client.py | 26 +- src/truefoundry_sdk/workspaces/raw_client.py | 10 +- tests/conftest.py | 21 - tests/test_aiohttp_autodetect.py | 116 ---- tests/utils/test_http_client.py | 362 ---------- 46 files changed, 234 insertions(+), 1496 deletions(-) delete mode 100644 src/truefoundry_sdk/_default_clients.py delete mode 100644 tests/conftest.py delete mode 100644 tests/test_aiohttp_autodetect.py diff --git a/.fern/metadata.json b/.fern/metadata.json index 4eb398da..dee1545a 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { "cliVersion": "4.68.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "5.3.13", + "generatorVersion": "4.64.1", "generatorConfig": { "package_name": "truefoundry_sdk", "pydantic_config": { @@ -22,6 +22,6 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "5057cbacbb78492b614b2f631dbeae7c7305635b", + "originGitCommit": "b21f8faecb9e7a36b5f7c48bcaf48d0bb6af465a", "sdkVersion": "0.0.0" } \ No newline at end of file diff --git a/README.md b/README.md index e67ed25c..ee37a6d3 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,6 @@ Instantiate and use the client with the following: ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( api_key="", @@ -63,9 +62,9 @@ client.applications.list( cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, + device_type_filter="cpu", last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, + lifecycle_stage="active", is_recommendation_present_and_visible=True, ) ``` @@ -76,7 +75,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 @@ -101,9 +99,9 @@ async def main() -> None: cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, + device_type_filter="cpu", last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, + lifecycle_stage="active", is_recommendation_present_and_visible=True, ) @@ -132,7 +130,6 @@ Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( api_key="", @@ -153,9 +150,9 @@ client.applications.list( cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, + device_type_filter="cpu", last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, + lifecycle_stage="active", is_recommendation_present_and_visible=True, ) ``` diff --git a/poetry.lock b/poetry.lock index 9cf7cdbc..0fb0f8c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,142 +1,5 @@ # This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. -[[package]] -name = "aiohappyeyeballs" -version = "2.4.4" -description = "Happy Eyeballs for asyncio" -optional = true -python-versions = ">=3.8" -files = [ - {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, - {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, -] - -[[package]] -name = "aiohttp" -version = "3.10.11" -description = "Async http client/server framework (asyncio)" -optional = true -python-versions = ">=3.8" -files = [ - {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"}, - {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"}, - {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"}, - {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"}, - {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"}, - {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"}, - {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"}, - {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"}, - {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"}, - {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"}, - {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"}, - {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"}, - {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"}, - {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"}, - {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"}, - {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"}, - {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"}, - {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"}, - {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"}, - {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"}, - {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"}, - {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"}, - {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"}, - {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"}, - {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"}, - {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"}, - {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"}, - {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"}, - {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"}, - {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"}, - {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"}, - {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"}, - {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"}, - {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"}, - {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"}, - {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"}, - {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"}, - {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"}, - {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"}, - {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"}, - {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"}, - {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"}, - {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"}, - {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"}, - {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"}, - {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"}, - {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"}, - {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"}, - {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"}, - {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"}, - {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"}, - {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"}, - {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"}, - {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"}, - {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"}, - {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"}, - {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"}, - {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"}, - {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"}, - {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"}, - {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"}, - {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"}, - {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"}, - {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"}, - {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"}, - {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"}, - {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"}, - {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"}, - {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"}, - {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"}, - {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"}, - {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"}, - {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"}, - {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"}, - {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"}, - {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"}, - {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"}, - {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"}, - {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"}, - {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"}, - {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"}, - {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"}, - {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"}, - {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"}, - {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"}, - {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"}, - {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"}, - {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"}, - {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"}, - {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"}, - {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"}, -] - -[package.dependencies] -aiohappyeyeballs = ">=2.3.0" -aiosignal = ">=1.1.2" -async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} -attrs = ">=17.3.0" -frozenlist = ">=1.1.1" -multidict = ">=4.5,<7.0" -yarl = ">=1.12.0,<2.0" - -[package.extras] -speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] - -[[package]] -name = "aiosignal" -version = "1.3.1" -description = "aiosignal: a list of registered asynchronous callbacks" -optional = true -python-versions = ">=3.7" -files = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, -] - -[package.dependencies] -frozenlist = ">=1.1.0" - [[package]] name = "alabaster" version = "0.7.13" @@ -210,36 +73,6 @@ files = [ astroid = ["astroid (>=2,<5)"] test = ["astroid (>=2,<5)", "pytest (<9.0)", "pytest-cov", "pytest-xdist"] -[[package]] -name = "async-timeout" -version = "5.0.1" -description = "Timeout context manager for asyncio programs" -optional = true -python-versions = ">=3.8" -files = [ - {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, - {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, -] - -[[package]] -name = "attrs" -version = "25.3.0" -description = "Classes Without Boilerplate" -optional = true -python-versions = ">=3.8" -files = [ - {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, - {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, -] - -[package.extras] -benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] -tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] - [[package]] name = "babel" version = "2.18.0" @@ -495,107 +328,6 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] -[[package]] -name = "frozenlist" -version = "1.5.0" -description = "A list-like structure which implements collections.abc.MutableSequence" -optional = true -python-versions = ">=3.8" -files = [ - {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, - {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, - {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, - {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, - {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, - {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, - {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, - {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, - {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, - {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, - {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, - {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, - {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, - {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, - {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, - {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, - {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, - {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, - {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, - {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, - {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, - {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, - {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, - {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, - {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, - {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, - {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, - {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, - {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, - {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, - {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, - {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, - {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, - {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, - {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, - {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, - {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, - {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, - {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, - {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, - {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, - {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, - {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, - {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, - {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, - {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, - {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, - {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, - {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, - {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, - {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, - {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, - {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, - {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, - {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, - {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, - {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, - {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, - {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, - {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, - {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, - {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, - {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, - {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, - {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, - {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, - {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, - {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, - {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, - {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, - {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, - {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, - {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, - {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, - {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, - {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, - {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, - {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, - {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, - {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, - {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, - {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, -] - [[package]] name = "h11" version = "0.16.0" @@ -652,21 +384,6 @@ http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] zstd = ["zstandard (>=0.18.0)"] -[[package]] -name = "httpx-aiohttp" -version = "0.1.8" -description = "Aiohttp transport for HTTPX" -optional = true -python-versions = ">=3.8" -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"}, -] - -[package.dependencies] -aiohttp = ">=3.10.0,<4" -httpx = ">=0.27.0" - [[package]] name = "idna" version = "3.11" @@ -884,110 +601,6 @@ files = [ [package.dependencies] traitlets = "*" -[[package]] -name = "multidict" -version = "6.1.0" -description = "multidict implementation" -optional = true -python-versions = ">=3.8" -files = [ - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, - {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, - {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, - {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, - {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, - {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, - {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, - {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, - {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, - {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, - {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, - {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, - {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f"}, - {file = "multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44"}, - {file = "multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4"}, - {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6"}, - {file = "multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81"}, - {file = "multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a"}, - {file = "multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d"}, - {file = "multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492"}, - {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd"}, - {file = "multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167"}, - {file = "multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1"}, - {file = "multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255"}, - {file = "multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972"}, - {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43"}, - {file = "multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada"}, - {file = "multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a"}, - {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, - {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} - [[package]] name = "mypy" version = "1.13.0" @@ -1075,13 +688,13 @@ test = ["matplotlib", "pytest", "pytest-cov"] [[package]] name = "packaging" -version = "26.0" +version = "26.1" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529"}, - {file = "packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4"}, + {file = "packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f"}, + {file = "packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de"}, ] [[package]] @@ -1153,113 +766,6 @@ files = [ [package.dependencies] wcwidth = "*" -[[package]] -name = "propcache" -version = "0.2.0" -description = "Accelerated property cache" -optional = true -python-versions = ">=3.8" -files = [ - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"}, - {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"}, - {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"}, - {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"}, - {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"}, - {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"}, - {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"}, - {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"}, - {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"}, - {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"}, - {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"}, - {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"}, - {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"}, - {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"}, - {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"}, - {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"}, - {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"}, - {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"}, - {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"}, - {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"}, - {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, -] - [[package]] name = "ptyprocess" version = "0.7.0" @@ -1875,118 +1381,6 @@ files = [ {file = "wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159"}, ] -[[package]] -name = "yarl" -version = "1.15.2" -description = "Yet another URL library" -optional = true -python-versions = ">=3.8" -files = [ - {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e4ee8b8639070ff246ad3649294336b06db37a94bdea0d09ea491603e0be73b8"}, - {file = "yarl-1.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7cf963a357c5f00cb55b1955df8bbe68d2f2f65de065160a1c26b85a1e44172"}, - {file = "yarl-1.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:43ebdcc120e2ca679dba01a779333a8ea76b50547b55e812b8b92818d604662c"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3433da95b51a75692dcf6cc8117a31410447c75a9a8187888f02ad45c0a86c50"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d0124fa992dbacd0c48b1b755d3ee0a9f924f427f95b0ef376556a24debf01"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ded1b1803151dd0f20a8945508786d57c2f97a50289b16f2629f85433e546d47"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace4cad790f3bf872c082366c9edd7f8f8f77afe3992b134cfc810332206884f"}, - {file = "yarl-1.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c77494a2f2282d9bbbbcab7c227a4d1b4bb829875c96251f66fb5f3bae4fb053"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b7f227ca6db5a9fda0a2b935a2ea34a7267589ffc63c8045f0e4edb8d8dcf956"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:31561a5b4d8dbef1559b3600b045607cf804bae040f64b5f5bca77da38084a8a"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3e52474256a7db9dcf3c5f4ca0b300fdea6c21cca0148c8891d03a025649d935"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1af74a9529a1137c67c887ed9cde62cff53aa4d84a3adbec329f9ec47a3936"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:15c87339490100c63472a76d87fe7097a0835c705eb5ae79fd96e343473629ed"}, - {file = "yarl-1.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:74abb8709ea54cc483c4fb57fb17bb66f8e0f04438cff6ded322074dbd17c7ec"}, - {file = "yarl-1.15.2-cp310-cp310-win32.whl", hash = "sha256:ffd591e22b22f9cb48e472529db6a47203c41c2c5911ff0a52e85723196c0d75"}, - {file = "yarl-1.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:1695497bb2a02a6de60064c9f077a4ae9c25c73624e0d43e3aa9d16d983073c2"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9fcda20b2de7042cc35cf911702fa3d8311bd40055a14446c1e62403684afdc5"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0545de8c688fbbf3088f9e8b801157923be4bf8e7b03e97c2ecd4dfa39e48e0e"}, - {file = "yarl-1.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbda058a9a68bec347962595f50546a8a4a34fd7b0654a7b9697917dc2bf810d"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ac2bc069f4a458634c26b101c2341b18da85cb96afe0015990507efec2e417"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd126498171f752dd85737ab1544329a4520c53eed3997f9b08aefbafb1cc53b"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3db817b4e95eb05c362e3b45dafe7144b18603e1211f4a5b36eb9522ecc62bcf"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:076b1ed2ac819933895b1a000904f62d615fe4533a5cf3e052ff9a1da560575c"}, - {file = "yarl-1.15.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8cfd847e6b9ecf9f2f2531c8427035f291ec286c0a4944b0a9fce58c6446046"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:32b66be100ac5739065496c74c4b7f3015cef792c3174982809274d7e51b3e04"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:34a2d76a1984cac04ff8b1bfc939ec9dc0914821264d4a9c8fd0ed6aa8d4cfd2"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0afad2cd484908f472c8fe2e8ef499facee54a0a6978be0e0cff67b1254fd747"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c68e820879ff39992c7f148113b46efcd6ec765a4865581f2902b3c43a5f4bbb"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:98f68df80ec6ca3015186b2677c208c096d646ef37bbf8b49764ab4a38183931"}, - {file = "yarl-1.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3c56ec1eacd0a5d35b8a29f468659c47f4fe61b2cab948ca756c39b7617f0aa5"}, - {file = "yarl-1.15.2-cp311-cp311-win32.whl", hash = "sha256:eedc3f247ee7b3808ea07205f3e7d7879bc19ad3e6222195cd5fbf9988853e4d"}, - {file = "yarl-1.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:0ccaa1bc98751fbfcf53dc8dfdb90d96e98838010fc254180dd6707a6e8bb179"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82d5161e8cb8f36ec778fd7ac4d740415d84030f5b9ef8fe4da54784a1f46c94"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa2bea05ff0a8fb4d8124498e00e02398f06d23cdadd0fe027d84a3f7afde31e"}, - {file = "yarl-1.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99e12d2bf587b44deb74e0d6170fec37adb489964dbca656ec41a7cd8f2ff178"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:243fbbbf003754fe41b5bdf10ce1e7f80bcc70732b5b54222c124d6b4c2ab31c"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:856b7f1a7b98a8c31823285786bd566cf06226ac4f38b3ef462f593c608a9bd6"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:553dad9af802a9ad1a6525e7528152a015b85fb8dbf764ebfc755c695f488367"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30c3ff305f6e06650a761c4393666f77384f1cc6c5c0251965d6bfa5fbc88f7f"}, - {file = "yarl-1.15.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:353665775be69bbfc6d54c8d134bfc533e332149faeddd631b0bc79df0897f46"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f4fe99ce44128c71233d0d72152db31ca119711dfc5f2c82385ad611d8d7f897"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9c1e3ff4b89cdd2e1a24c214f141e848b9e0451f08d7d4963cb4108d4d798f1f"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:711bdfae4e699a6d4f371137cbe9e740dc958530cb920eb6f43ff9551e17cfbc"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4388c72174868884f76affcdd3656544c426407e0043c89b684d22fb265e04a5"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f0e1844ad47c7bd5d6fa784f1d4accc5f4168b48999303a868fe0f8597bde715"}, - {file = "yarl-1.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5cafb02cf097a82d74403f7e0b6b9df3ffbfe8edf9415ea816314711764a27b"}, - {file = "yarl-1.15.2-cp312-cp312-win32.whl", hash = "sha256:156ececdf636143f508770bf8a3a0498de64da5abd890c7dbb42ca9e3b6c05b8"}, - {file = "yarl-1.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:435aca062444a7f0c884861d2e3ea79883bd1cd19d0a381928b69ae1b85bc51d"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:416f2e3beaeae81e2f7a45dc711258be5bdc79c940a9a270b266c0bec038fb84"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:173563f3696124372831007e3d4b9821746964a95968628f7075d9231ac6bb33"}, - {file = "yarl-1.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9ce2e0f6123a60bd1a7f5ae3b2c49b240c12c132847f17aa990b841a417598a2"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaea112aed589131f73d50d570a6864728bd7c0c66ef6c9154ed7b59f24da611"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4ca3b9f370f218cc2a0309542cab8d0acdfd66667e7c37d04d617012485f904"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23ec1d3c31882b2a8a69c801ef58ebf7bae2553211ebbddf04235be275a38548"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75119badf45f7183e10e348edff5a76a94dc19ba9287d94001ff05e81475967b"}, - {file = "yarl-1.15.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e6fdc976ec966b99e4daa3812fac0274cc28cd2b24b0d92462e2e5ef90d368"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8657d3f37f781d987037f9cc20bbc8b40425fa14380c87da0cb8dfce7c92d0fb"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:93bed8a8084544c6efe8856c362af08a23e959340c87a95687fdbe9c9f280c8b"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:69d5856d526802cbda768d3e6246cd0d77450fa2a4bc2ea0ea14f0d972c2894b"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ccad2800dfdff34392448c4bf834be124f10a5bc102f254521d931c1c53c455a"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a880372e2e5dbb9258a4e8ff43f13888039abb9dd6d515f28611c54361bc5644"}, - {file = "yarl-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c998d0558805860503bc3a595994895ca0f7835e00668dadc673bbf7f5fbfcbe"}, - {file = "yarl-1.15.2-cp313-cp313-win32.whl", hash = "sha256:533a28754e7f7439f217550a497bb026c54072dbe16402b183fdbca2431935a9"}, - {file = "yarl-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:5838f2b79dc8f96fdc44077c9e4e2e33d7089b10788464609df788eb97d03aad"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fbbb63bed5fcd70cd3dd23a087cd78e4675fb5a2963b8af53f945cbbca79ae16"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2e93b88ecc8f74074012e18d679fb2e9c746f2a56f79cd5e2b1afcf2a8a786b"}, - {file = "yarl-1.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af8ff8d7dc07ce873f643de6dfbcd45dc3db2c87462e5c387267197f59e6d776"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66f629632220a4e7858b58e4857927dd01a850a4cef2fb4044c8662787165cf7"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:833547179c31f9bec39b49601d282d6f0ea1633620701288934c5f66d88c3e50"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2aa738e0282be54eede1e3f36b81f1e46aee7ec7602aa563e81e0e8d7b67963f"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a13a07532e8e1c4a5a3afff0ca4553da23409fad65def1b71186fb867eeae8d"}, - {file = "yarl-1.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c45817e3e6972109d1a2c65091504a537e257bc3c885b4e78a95baa96df6a3f8"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:670eb11325ed3a6209339974b276811867defe52f4188fe18dc49855774fa9cf"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:d417a4f6943112fae3924bae2af7112562285848d9bcee737fc4ff7cbd450e6c"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bc8936d06cd53fddd4892677d65e98af514c8d78c79864f418bbf78a4a2edde4"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:954dde77c404084c2544e572f342aef384240b3e434e06cecc71597e95fd1ce7"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5bc0df728e4def5e15a754521e8882ba5a5121bd6b5a3a0ff7efda5d6558ab3d"}, - {file = "yarl-1.15.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b71862a652f50babab4a43a487f157d26b464b1dedbcc0afda02fd64f3809d04"}, - {file = "yarl-1.15.2-cp38-cp38-win32.whl", hash = "sha256:63eab904f8630aed5a68f2d0aeab565dcfc595dc1bf0b91b71d9ddd43dea3aea"}, - {file = "yarl-1.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:2cf441c4b6e538ba0d2591574f95d3fdd33f1efafa864faa077d9636ecc0c4e9"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a32d58f4b521bb98b2c0aa9da407f8bd57ca81f34362bcb090e4a79e9924fefc"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:766dcc00b943c089349d4060b935c76281f6be225e39994c2ccec3a2a36ad627"}, - {file = "yarl-1.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bed1b5dbf90bad3bfc19439258c97873eab453c71d8b6869c136346acfe497e7"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed20a4bdc635f36cb19e630bfc644181dd075839b6fc84cac51c0f381ac472e2"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d538df442c0d9665664ab6dd5fccd0110fa3b364914f9c85b3ef9b7b2e157980"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c6cf1d92edf936ceedc7afa61b07e9d78a27b15244aa46bbcd534c7458ee1b"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce44217ad99ffad8027d2fde0269ae368c86db66ea0571c62a000798d69401fb"}, - {file = "yarl-1.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47a6000a7e833ebfe5886b56a31cb2ff12120b1efd4578a6fcc38df16cc77bd"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e52f77a0cd246086afde8815039f3e16f8d2be51786c0a39b57104c563c5cbb0"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f9ca0e6ce7774dc7830dc0cc4bb6b3eec769db667f230e7c770a628c1aa5681b"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:136f9db0f53c0206db38b8cd0c985c78ded5fd596c9a86ce5c0b92afb91c3a19"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:173866d9f7409c0fb514cf6e78952e65816600cb888c68b37b41147349fe0057"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:6e840553c9c494a35e449a987ca2c4f8372668ee954a03a9a9685075228e5036"}, - {file = "yarl-1.15.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:458c0c65802d816a6b955cf3603186de79e8fdb46d4f19abaec4ef0a906f50a7"}, - {file = "yarl-1.15.2-cp39-cp39-win32.whl", hash = "sha256:5b48388ded01f6f2429a8c55012bdbd1c2a0c3735b3e73e221649e524c34a58d"}, - {file = "yarl-1.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:81dadafb3aa124f86dc267a2168f71bbd2bfb163663661ab0038f6e4b8edb810"}, - {file = "yarl-1.15.2-py3-none-any.whl", hash = "sha256:0d3105efab7c5c091609abacad33afff33bdff0035bece164c98bcf5a85ef90a"}, - {file = "yarl-1.15.2.tar.gz", hash = "sha256:a39c36f4218a5bb668b4f06874d676d35a035ee668e6e7e3538835c703634b84"}, -] - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" -propcache = ">=0.2.0" - [[package]] name = "zipp" version = "3.20.2" @@ -2006,10 +1400,7 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] -[extras] -aiohttp = ["aiohttp", "httpx-aiohttp"] - [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "26f2271a4fdfe59582412a00827b9823b335d3a4339ec708219804b8c645da05" +content-hash = "467d9c9c9207b7d74127c6809b14048829f83d64d12ccd46e8eae6d2b154ad09" diff --git a/pyproject.toml b/pyproject.toml index 7654e02b..299affc5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,11 +39,9 @@ Repository = 'https://github.com/truefoundry/truefoundry-python-sdk' [tool.poetry.dependencies] python = ">=3.8" -aiohttp = { version = ">=3.10.0,<4", optional = true} httpx = ">=0.21.2" -httpx-aiohttp = { version = "0.1.8", optional = true} pydantic = ">= 1.9.2" -pydantic-core = ">=2.18.2,<2.44.0" +pydantic-core = ">=2.18.2" typing_extensions = ">= 4.0.0" [tool.poetry.group.dev.dependencies] @@ -61,9 +59,6 @@ ruff = "==0.11.5" [tool.pytest.ini_options] testpaths = [ "tests" ] asyncio_mode = "auto" -markers = [ - "aiohttp: tests that require httpx_aiohttp to be installed", -] [tool.mypy] plugins = ["pydantic.mypy"] @@ -95,6 +90,3 @@ section-order = ["future", "standard-library", "third-party", "first-party"] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" - -[tool.poetry.extras] -aiohttp=["aiohttp", "httpx-aiohttp"] diff --git a/reference.md b/reference.md index 5f024d1f..32d1856a 100644 --- a/reference.md +++ b/reference.md @@ -1277,7 +1277,6 @@ Retrieve all teams associated with the authenticated user. If the user is a tena ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.teams import TeamsListRequestType client = TrueFoundry( api_key="", @@ -1287,7 +1286,7 @@ client = TrueFoundry( client.teams.list( limit=10, offset=0, - type=TeamsListRequestType.TEAM, + type="team", ) ``` @@ -2803,7 +2802,7 @@ Create or Update cluster with provided manifest
```python -from truefoundry_sdk import TrueFoundry, ClusterManifest, ClusterManifestClusterType, Collaborator +from truefoundry_sdk import TrueFoundry, ClusterManifest, Collaborator client = TrueFoundry( api_key="", @@ -2814,7 +2813,7 @@ client.clusters.create_or_update( manifest=ClusterManifest( type="cluster", name="name", - cluster_type=ClusterManifestClusterType.AWS_EKS, + cluster_type="aws-eks", environment_names=[ "environment_names" ], @@ -3204,7 +3203,6 @@ Retrieves a list of all latest applications. Supports filtering by application I ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.applications import ApplicationsListRequestDeviceTypeFilter, ApplicationsListRequestLifecycleStage client = TrueFoundry( api_key="", @@ -3225,9 +3223,9 @@ client.applications.list( cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, + device_type_filter="cpu", last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, + lifecycle_stage="active", is_recommendation_present_and_visible=True, ) @@ -4191,7 +4189,7 @@ List Job Runs for provided Job Id. Filter the data based on parameters passed in
```python -from truefoundry_sdk import TrueFoundry, JobRunsSortBy, SortDirection +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -4203,8 +4201,8 @@ client.jobs.list_runs( limit=10, offset=0, search_prefix="searchPrefix", - sort_by=JobRunsSortBy.START_TIME, - order=SortDirection.ASC, + sort_by="startTime", + order="asc", ) ``` @@ -4751,7 +4749,7 @@ Creates a new Environment or updates an existing Environment.
```python -from truefoundry_sdk import TrueFoundry, EnvironmentManifest, EnvironmentColor, EnvironmentOptimizeFor +from truefoundry_sdk import TrueFoundry, EnvironmentManifest, EnvironmentColor client = TrueFoundry( api_key="", @@ -4764,7 +4762,7 @@ client.environments.create_or_update( name="name", color=EnvironmentColor(), is_production=True, - optimize_for=EnvironmentOptimizeFor.COST, + optimize_for="COST", ), ) @@ -6316,7 +6314,7 @@ 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="", @@ -6328,7 +6326,7 @@ client.alerts.list( end_ts="endTs", cluster_id="clusterId", application_id="applicationId", - alert_status=AlertStatus.FIRING, + alert_status="firing", ) ``` @@ -6425,7 +6423,7 @@ Fetch logs for various workload components, including Services, Jobs, Workflows,
```python -from truefoundry_sdk import TrueFoundry, LogsSortingDirection, LogsSearchFilterType, LogsSearchOperatorType +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -6436,7 +6434,7 @@ client.logs.get( start_ts=1000000, end_ts=1000000, limit=1, - direction=LogsSortingDirection.ASC, + direction="asc", num_logs_to_ignore=1, application_id="applicationId", application_fqn="applicationFqn", @@ -6447,8 +6445,8 @@ client.logs.get( pod_names_regex="podNamesRegex", search_filters="searchFilters", search_string="searchString", - search_type=LogsSearchFilterType.REGEX, - search_operator=LogsSearchOperatorType.EQUAL, + search_type="regex", + search_operator="equal", ) ``` @@ -8585,7 +8583,7 @@ Get pre-signed URLs for reading or writing files in an artifact version.
```python -from truefoundry_sdk import TrueFoundry, Operation +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -8597,7 +8595,7 @@ client.artifact_versions.get_signed_urls( paths=[ "paths" ], - operation=Operation.READ, + operation="READ", ) ``` @@ -10815,7 +10813,7 @@ Get pre-signed URLs for reading or writing files in a data directory.
```python -from truefoundry_sdk import TrueFoundry, Operation +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -10827,7 +10825,7 @@ client.data_directories.get_signed_urls( paths=[ "paths" ], - operation=Operation.READ, + operation="READ", ) ``` @@ -11030,7 +11028,6 @@ Get Gateway configuration based on type for the tenant. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.internal.ai_gateway import AiGatewayGetGatewayConfigRequestType client = TrueFoundry( api_key="", @@ -11038,7 +11035,7 @@ client = TrueFoundry( ) client.internal.ai_gateway.get_gateway_config( - type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, + type="gateway-rate-limiting-config", ) ``` @@ -11419,7 +11416,7 @@ Generate deployment endpoint based on the provided query parameters.
```python -from truefoundry_sdk import TrueFoundry, ApplicationType +from truefoundry_sdk import TrueFoundry client = TrueFoundry( api_key="", @@ -11427,7 +11424,7 @@ client = TrueFoundry( ) client.internal.deployments.get_suggested_endpoint( - application_type=ApplicationType.ASYNC_SERVICE, + application_type="async-service", application_name="applicationName", workspace_id="workspaceId", base_domain="baseDomain", @@ -11701,7 +11698,6 @@ List charts for a given Application based on parameters passed in the query. ```python from truefoundry_sdk import TrueFoundry -from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity client = TrueFoundry( api_key="", @@ -11713,7 +11709,7 @@ client.internal.metrics.get_charts( application_id="applicationId", start_ts="startTs", end_ts="endTs", - filter_entity=MetricsGetChartsRequestFilterEntity.APPLICATION, + filter_entity="application", filter_query="filterQuery", ) diff --git a/requirements.txt b/requirements.txt index 0141a1a5..e80f640a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ httpx>=0.21.2 pydantic>= 1.9.2 -pydantic-core>=2.18.2,<2.44.0 +pydantic-core>=2.18.2 typing_extensions>= 4.0.0 diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index 518f9b12..fbd31171 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -1064,7 +1064,6 @@ virtual_accounts, workspaces, ) - from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient from .applications import ( ApplicationsCancelDeploymentResponse, ApplicationsListRequestDeviceTypeFilter, @@ -1341,8 +1340,6 @@ "DeepinfraKeyAuth": ".types", "DeepinfraModel": ".types", "DeepinfraProviderAccount": ".types", - "DefaultAioHttpClient": "._default_clients", - "DefaultAsyncHttpxClient": "._default_clients", "DeleteApplicationResponse": ".types", "DeleteJobRunResponse": ".types", "DeletePersonalAccessTokenResponse": ".types", @@ -2432,8 +2429,6 @@ def __dir__(): "DeepinfraKeyAuth", "DeepinfraModel", "DeepinfraProviderAccount", - "DefaultAioHttpClient", - "DefaultAsyncHttpxClient", "DeleteApplicationResponse", "DeleteJobRunResponse", "DeletePersonalAccessTokenResponse", diff --git a/src/truefoundry_sdk/_default_clients.py b/src/truefoundry_sdk/_default_clients.py deleted file mode 100644 index 84661579..00000000 --- a/src/truefoundry_sdk/_default_clients.py +++ /dev/null @@ -1,32 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import httpx - -SDK_DEFAULT_TIMEOUT = 60 - -try: - import httpx_aiohttp # type: ignore[import-not-found] -except ImportError: - - class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore - def __init__(self, **kwargs: typing.Any) -> None: - raise RuntimeError( - "To use the aiohttp client, install the aiohttp extra: pip install truefoundry-sdk[aiohttp]" - ) - -else: - - class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore - def __init__(self, **kwargs: typing.Any) -> None: - kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) - kwargs.setdefault("follow_redirects", True) - super().__init__(**kwargs) - - -class DefaultAsyncHttpxClient(httpx.AsyncClient): - def __init__(self, **kwargs: typing.Any) -> None: - kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT) - kwargs.setdefault("follow_redirects", True) - super().__init__(**kwargs) diff --git a/src/truefoundry_sdk/agent_skill_versions/raw_client.py b/src/truefoundry_sdk/agent_skill_versions/raw_client.py index 6370de14..b5376ab7 100644 --- a/src/truefoundry_sdk/agent_skill_versions/raw_client.py +++ b/src/truefoundry_sdk/agent_skill_versions/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -40,7 +40,7 @@ def get( Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + f"api/ml/v1/agent-skill-versions/{jsonable_encoder(agent_skill_version_id)}", method="GET", request_options=request_options, ) @@ -91,7 +91,7 @@ def delete( Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + f"api/ml/v1/agent-skill-versions/{jsonable_encoder(agent_skill_version_id)}", method="DELETE", request_options=request_options, ) @@ -251,7 +251,7 @@ async def get( Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + f"api/ml/v1/agent-skill-versions/{jsonable_encoder(agent_skill_version_id)}", method="GET", request_options=request_options, ) @@ -302,7 +302,7 @@ async def delete( Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skill-versions/{encode_path_param(agent_skill_version_id)}", + f"api/ml/v1/agent-skill-versions/{jsonable_encoder(agent_skill_version_id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/agent_skills/raw_client.py b/src/truefoundry_sdk/agent_skills/raw_client.py index b5e7b7df..43e888e4 100644 --- a/src/truefoundry_sdk/agent_skills/raw_client.py +++ b/src/truefoundry_sdk/agent_skills/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -48,7 +48,7 @@ def get( Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + f"api/ml/v1/agent-skills/{jsonable_encoder(agent_skill_id)}", method="GET", request_options=request_options, ) @@ -101,7 +101,7 @@ def delete( Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + f"api/ml/v1/agent-skills/{jsonable_encoder(agent_skill_id)}", method="DELETE", request_options=request_options, ) @@ -320,7 +320,7 @@ async def get( Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + f"api/ml/v1/agent-skills/{jsonable_encoder(agent_skill_id)}", method="GET", request_options=request_options, ) @@ -373,7 +373,7 @@ async def delete( Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/agent-skills/{encode_path_param(agent_skill_id)}", + f"api/ml/v1/agent-skills/{jsonable_encoder(agent_skill_id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/application_versions/raw_client.py b/src/truefoundry_sdk/application_versions/raw_client.py index 08b9cd2b..6a544760 100644 --- a/src/truefoundry_sdk/application_versions/raw_client.py +++ b/src/truefoundry_sdk/application_versions/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -65,7 +65,7 @@ def list( offset = offset if offset is not None else 0 _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments", method="GET", params={ "limit": limit, @@ -149,7 +149,7 @@ def get( Deployment details returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}", method="GET", request_options=request_options, ) @@ -240,7 +240,7 @@ async def list( offset = offset if offset is not None else 0 _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments", method="GET", params={ "limit": limit, @@ -327,7 +327,7 @@ async def get( Deployment details returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/applications/raw_client.py b/src/truefoundry_sdk/applications/raw_client.py index 46d5308f..dc16d414 100644 --- a/src/truefoundry_sdk/applications/raw_client.py +++ b/src/truefoundry_sdk/applications/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -356,7 +356,7 @@ def get( Application details retrieved successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -421,7 +421,7 @@ def delete( Delete application response. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -489,7 +489,7 @@ def redeploy( Returns the new deployment. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/redeploy", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/redeploy", method="POST", request_options=request_options, ) @@ -551,7 +551,7 @@ def scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOpti HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-zero", + f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-zero", method="PATCH", request_options=request_options, ) @@ -631,7 +631,7 @@ def scale_to_original( Scales back a paused applicaion to the original number of replicas """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-original", + f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-original", method="PATCH", request_options=request_options, ) @@ -710,7 +710,7 @@ def cancel_deployment( Deployment cancelled successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/cancel", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/cancel", method="POST", request_options=request_options, ) @@ -1093,7 +1093,7 @@ async def get( Application details retrieved successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -1158,7 +1158,7 @@ async def delete( Delete application response. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}", + f"api/svc/v1/apps/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -1226,7 +1226,7 @@ async def redeploy( Returns the new deployment. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/redeploy", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/redeploy", method="POST", request_options=request_options, ) @@ -1290,7 +1290,7 @@ async def scale_to_zero( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-zero", + f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-zero", method="PATCH", request_options=request_options, ) @@ -1370,7 +1370,7 @@ async def scale_to_original( Scales back a paused applicaion to the original number of replicas """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/scale-to-original", + f"api/svc/v1/apps/{jsonable_encoder(id)}/scale-to-original", method="PATCH", request_options=request_options, ) @@ -1449,7 +1449,7 @@ async def cancel_deployment( Deployment cancelled successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/cancel", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/cancel", method="POST", request_options=request_options, ) diff --git a/src/truefoundry_sdk/artifact_versions/raw_client.py b/src/truefoundry_sdk/artifact_versions/raw_client.py index 74451a6e..cc700a77 100644 --- a/src/truefoundry_sdk/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/artifact_versions/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -127,7 +127,7 @@ def get( The artifact version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{encode_path_param(id)}", + f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -180,7 +180,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{encode_path_param(id)}", + f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -799,7 +799,7 @@ async def get( The artifact version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{encode_path_param(id)}", + f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -852,7 +852,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifact-versions/{encode_path_param(id)}", + f"api/ml/v1/artifact-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/artifacts/raw_client.py b/src/truefoundry_sdk/artifacts/raw_client.py index bf64b13b..179be032 100644 --- a/src/truefoundry_sdk/artifacts/raw_client.py +++ b/src/truefoundry_sdk/artifacts/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -48,7 +48,7 @@ def get( The artifact data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{encode_path_param(id)}", + f"api/ml/v1/artifacts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -101,7 +101,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{encode_path_param(id)}", + f"api/ml/v1/artifacts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -326,7 +326,7 @@ async def get( The artifact data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{encode_path_param(id)}", + f"api/ml/v1/artifacts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -379,7 +379,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/artifacts/{encode_path_param(id)}", + f"api/ml/v1/artifacts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/base_client.py b/src/truefoundry_sdk/base_client.py index 1a90b255..840e7033 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -459,24 +459,6 @@ def data_directories(self): return self._data_directories -def _make_default_async_client( - timeout: typing.Optional[float], - follow_redirects: typing.Optional[bool], -) -> httpx.AsyncClient: - try: - import httpx_aiohttp # type: ignore[import-not-found] - except ImportError: - pass - else: - if follow_redirects is not None: - return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects) - return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout) - - if follow_redirects is not None: - return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects) - return httpx.AsyncClient(timeout=timeout) - - class AsyncBaseTrueFoundry: """ Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions. @@ -490,9 +472,6 @@ class AsyncBaseTrueFoundry: headers : typing.Optional[typing.Dict[str, str]] Additional headers to send with every request. - async_token : typing.Optional[typing.Callable[[], typing.Awaitable[str]]] - An async callable that returns a bearer token. Use this when token acquisition involves async I/O (e.g., refreshing tokens via an async HTTP client). When provided, this is used instead of the synchronous token for async requests. - timeout : typing.Optional[float] The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced. @@ -521,7 +500,6 @@ def __init__( base_url: str, api_key: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("TFY_API_KEY"), headers: typing.Optional[typing.Dict[str, str]] = None, - async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, @@ -536,10 +514,11 @@ def __init__( base_url=base_url, api_key=api_key, headers=headers, - async_token=async_token, httpx_client=httpx_client if httpx_client is not None - else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects), + else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects) + if follow_redirects is not None + else httpx.AsyncClient(timeout=_defaulted_timeout), timeout=_defaulted_timeout, logging=logging, ) diff --git a/src/truefoundry_sdk/clusters/raw_client.py b/src/truefoundry_sdk/clusters/raw_client.py index 859b088e..d17e47c1 100644 --- a/src/truefoundry_sdk/clusters/raw_client.py +++ b/src/truefoundry_sdk/clusters/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -221,7 +221,7 @@ def get( Return the cluster associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}", + f"api/svc/v1/clusters/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -286,7 +286,7 @@ def delete( Returns success message on successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}", + f"api/svc/v1/clusters/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -362,7 +362,7 @@ def get_addons( Returns a paginated list of addons for the cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/get-addons", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/get-addons", method="GET", params={ "limit": limit, @@ -431,7 +431,7 @@ def is_connected( Returns the status of provided cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/is-connected", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/is-connected", method="GET", request_options=request_options, ) @@ -660,7 +660,7 @@ async def get( Return the cluster associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}", + f"api/svc/v1/clusters/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -725,7 +725,7 @@ async def delete( Returns success message on successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}", + f"api/svc/v1/clusters/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -801,7 +801,7 @@ async def get_addons( Returns a paginated list of addons for the cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/get-addons", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/get-addons", method="GET", params={ "limit": limit, @@ -870,7 +870,7 @@ async def is_connected( Returns the status of provided cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/is-connected", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/is-connected", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/core/__init__.py b/src/truefoundry_sdk/core/__init__.py index e2be580f..2a2b56e7 100644 --- a/src/truefoundry_sdk/core/__init__.py +++ b/src/truefoundry_sdk/core/__init__.py @@ -12,7 +12,7 @@ from .file import File, convert_file_dict_to_httpx_tuples, with_content_type from .http_client import AsyncHttpClient, HttpClient from .http_response import AsyncHttpResponse, HttpResponse - from .jsonable_encoder import encode_path_param, jsonable_encoder + from .jsonable_encoder import jsonable_encoder from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger from .pagination import AsyncPager, SyncPager from .parse_error import ParsingError @@ -56,7 +56,6 @@ "convert_and_respect_annotation_metadata": ".serialization", "convert_file_dict_to_httpx_tuples": ".file", "create_logger": ".logging", - "encode_path_param": ".jsonable_encoder", "encode_query": ".query_encoder", "jsonable_encoder": ".jsonable_encoder", "parse_obj_as": ".pydantic_utilities", @@ -118,7 +117,6 @@ def __dir__(): "convert_and_respect_annotation_metadata", "convert_file_dict_to_httpx_tuples", "create_logger", - "encode_path_param", "encode_query", "jsonable_encoder", "parse_obj_as", diff --git a/src/truefoundry_sdk/core/http_client.py b/src/truefoundry_sdk/core/http_client.py index f0a39ca8..ee937589 100644 --- a/src/truefoundry_sdk/core/http_client.py +++ b/src/truefoundry_sdk/core/http_client.py @@ -118,12 +118,6 @@ def _retry_timeout(response: httpx.Response, retries: int) -> float: return _add_symmetric_jitter(backoff) -def _retry_timeout_from_retries(retries: int) -> float: - """Determine retry timeout using exponential backoff when no response is available.""" - backoff = min(INITIAL_RETRY_DELAY_SECONDS * pow(2.0, retries), MAX_RETRY_DELAY_SECONDS) - return _add_symmetric_jitter(backoff) - - def _should_retry(response: httpx.Response) -> bool: retryable_400s = [429, 408, 409] return response.status_code >= 500 or response.status_code in retryable_400s @@ -271,13 +265,11 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, - base_max_retries: int = 2, logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers - self.base_max_retries = base_max_retries self.httpx_client = httpx_client self.logger = create_logger(logging_config) @@ -372,44 +364,19 @@ def request( has_body=json_body is not None or data_body is not None, ) - max_retries: int = ( - request_options.get("max_retries", self.base_max_retries) - if request_options is not None - else self.base_max_retries + response = self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, ) - try: - response = self.httpx_client.request( - method=method, - url=_request_url, - headers=_request_headers, - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, - ) - except (httpx.ConnectError, httpx.RemoteProtocolError): - if retries < max_retries: - time.sleep(_retry_timeout_from_retries(retries=retries)) - return self.request( - path=path, - method=method, - base_url=base_url, - params=params, - json=json, - data=data, - content=content, - files=files, - headers=headers, - request_options=request_options, - retries=retries + 1, - omit=omit, - force_multipart=force_multipart, - ) - raise - + max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 if _should_retry(response=response): if retries < max_retries: time.sleep(_retry_timeout(response=response, retries=retries)) @@ -419,14 +386,12 @@ def request( base_url=base_url, params=params, json=json, - data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, - force_multipart=force_multipart, ) if self.logger.is_debug(): @@ -553,14 +518,12 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, - base_max_retries: int = 2, async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None, logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers - self.base_max_retries = base_max_retries self.async_base_headers = async_base_headers self.httpx_client = httpx_client self.logger = create_logger(logging_config) @@ -664,44 +627,19 @@ async def request( has_body=json_body is not None or data_body is not None, ) - max_retries: int = ( - request_options.get("max_retries", self.base_max_retries) - if request_options is not None - else self.base_max_retries + response = await self.httpx_client.request( + method=method, + url=_request_url, + headers=_request_headers, + params=_encoded_params if _encoded_params else None, + json=json_body, + data=data_body, + content=content, + files=request_files, + timeout=timeout, ) - try: - response = await self.httpx_client.request( - method=method, - url=_request_url, - headers=_request_headers, - params=_encoded_params if _encoded_params else None, - json=json_body, - data=data_body, - content=content, - files=request_files, - timeout=timeout, - ) - except (httpx.ConnectError, httpx.RemoteProtocolError): - if retries < max_retries: - await asyncio.sleep(_retry_timeout_from_retries(retries=retries)) - return await self.request( - path=path, - method=method, - base_url=base_url, - params=params, - json=json, - data=data, - content=content, - files=files, - headers=headers, - request_options=request_options, - retries=retries + 1, - omit=omit, - force_multipart=force_multipart, - ) - raise - + max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 if _should_retry(response=response): if retries < max_retries: await asyncio.sleep(_retry_timeout(response=response, retries=retries)) @@ -711,14 +649,12 @@ async def request( base_url=base_url, params=params, json=json, - data=data, content=content, files=files, headers=headers, request_options=request_options, retries=retries + 1, omit=omit, - force_multipart=force_multipart, ) if self.logger.is_debug(): diff --git a/src/truefoundry_sdk/core/jsonable_encoder.py b/src/truefoundry_sdk/core/jsonable_encoder.py index 5b0902eb..f8beaeaf 100644 --- a/src/truefoundry_sdk/core/jsonable_encoder.py +++ b/src/truefoundry_sdk/core/jsonable_encoder.py @@ -106,15 +106,3 @@ def fallback_serializer(o: Any) -> Any: return jsonable_encoder(data, custom_encoder=custom_encoder) return to_jsonable_with_fallback(obj, fallback_serializer) - - -def encode_path_param(obj: Any) -> str: - """Encode a value for use in a URL path segment. - - Ensures proper string conversion for all types, including - booleans which need lowercase 'true'/'false' rather than - Python's 'True'/'False'. - """ - if isinstance(obj, bool): - return "true" if obj else "false" - return str(jsonable_encoder(obj)) diff --git a/src/truefoundry_sdk/data_directories/raw_client.py b/src/truefoundry_sdk/data_directories/raw_client.py index 2bfe761e..3fc5bcc7 100644 --- a/src/truefoundry_sdk/data_directories/raw_client.py +++ b/src/truefoundry_sdk/data_directories/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -52,7 +52,7 @@ def get( The data directory data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{encode_path_param(id)}", + f"api/ml/v1/data-directories/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -111,7 +111,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{encode_path_param(id)}", + f"api/ml/v1/data-directories/{jsonable_encoder(id)}", method="DELETE", params={ "delete_contents": delete_contents, @@ -627,7 +627,7 @@ async def get( The data directory data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{encode_path_param(id)}", + f"api/ml/v1/data-directories/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -686,7 +686,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/data-directories/{encode_path_param(id)}", + f"api/ml/v1/data-directories/{jsonable_encoder(id)}", method="DELETE", params={ "delete_contents": delete_contents, diff --git a/src/truefoundry_sdk/environments/raw_client.py b/src/truefoundry_sdk/environments/raw_client.py index 0526b7a5..6f5acfad 100644 --- a/src/truefoundry_sdk/environments/raw_client.py +++ b/src/truefoundry_sdk/environments/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -184,7 +184,7 @@ def get( Returns the Environment associated with the provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{encode_path_param(id)}", + f"api/svc/v1/environments/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -225,7 +225,7 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = Returns true if the Environment is deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{encode_path_param(id)}", + f"api/svc/v1/environments/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -432,7 +432,7 @@ async def get( Returns the Environment associated with the provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{encode_path_param(id)}", + f"api/svc/v1/environments/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -475,7 +475,7 @@ async def delete( Returns true if the Environment is deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/environments/{encode_path_param(id)}", + f"api/svc/v1/environments/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py index 4efccb72..01949eaa 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py +++ b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -39,7 +39,7 @@ def get_gateway_config( Gateway configuration retrieved successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/llm-gateway/config/{encode_path_param(type)}", + f"api/svc/v1/llm-gateway/config/{jsonable_encoder(type)}", method="GET", request_options=request_options, ) @@ -87,7 +87,7 @@ async def get_gateway_config( Gateway configuration retrieved successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/llm-gateway/config/{encode_path_param(type)}", + f"api/svc/v1/llm-gateway/config/{jsonable_encoder(type)}", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/internal/applications/raw_client.py b/src/truefoundry_sdk/internal/applications/raw_client.py index 516ba969..fa9dc9e2 100644 --- a/src/truefoundry_sdk/internal/applications/raw_client.py +++ b/src/truefoundry_sdk/internal/applications/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -42,7 +42,7 @@ def promote_rollout( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/rollout/promote", + f"api/svc/v1/apps/{jsonable_encoder(id)}/rollout/promote", method="POST", params={ "full": full, @@ -110,7 +110,7 @@ def get_pod_template_hash_to_deployment_version( Successfully retrieved the pod template hash to deployment version map. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/pod-template-hash-deployment-version-map", + f"api/svc/v1/apps/{jsonable_encoder(id)}/pod-template-hash-deployment-version-map", method="GET", params={ "podTemplateHashes": pod_template_hashes, @@ -174,7 +174,7 @@ async def promote_rollout( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/rollout/promote", + f"api/svc/v1/apps/{jsonable_encoder(id)}/rollout/promote", method="POST", params={ "full": full, @@ -242,7 +242,7 @@ async def get_pod_template_hash_to_deployment_version( Successfully retrieved the pod template hash to deployment version map. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/pod-template-hash-deployment-version-map", + f"api/svc/v1/apps/{jsonable_encoder(id)}/pod-template-hash-deployment-version-map", method="GET", params={ "podTemplateHashes": pod_template_hashes, diff --git a/src/truefoundry_sdk/internal/build_logs/raw_client.py b/src/truefoundry_sdk/internal/build_logs/raw_client.py index 9f7afbbd..399c0302 100644 --- a/src/truefoundry_sdk/internal/build_logs/raw_client.py +++ b/src/truefoundry_sdk/internal/build_logs/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -68,7 +68,7 @@ def get( Successfully retrieved build logs for the pipeline run """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/build-logs/{encode_path_param(pipeline_run_name)}", + f"api/svc/v1/build-logs/{jsonable_encoder(pipeline_run_name)}", method="GET", params={ "startTs": start_ts, @@ -164,7 +164,7 @@ async def get( Successfully retrieved build logs for the pipeline run """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/build-logs/{encode_path_param(pipeline_run_name)}", + f"api/svc/v1/build-logs/{jsonable_encoder(pipeline_run_name)}", method="GET", params={ "startTs": start_ts, diff --git a/src/truefoundry_sdk/internal/clusters/raw_client.py b/src/truefoundry_sdk/internal/clusters/raw_client.py index 24143c34..958a7a2f 100644 --- a/src/truefoundry_sdk/internal/clusters/raw_client.py +++ b/src/truefoundry_sdk/internal/clusters/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -40,7 +40,7 @@ def get_autoprovisioning_state( Returns the auto provisioning status for the cluster """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/autoprovisioning-state", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/autoprovisioning-state", method="GET", request_options=request_options, ) @@ -99,7 +99,7 @@ async def get_autoprovisioning_state( Returns the auto provisioning status for the cluster """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/clusters/{encode_path_param(id)}/autoprovisioning-state", + f"api/svc/v1/clusters/{jsonable_encoder(id)}/autoprovisioning-state", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/internal/deployments/raw_client.py b/src/truefoundry_sdk/internal/deployments/raw_client.py index e96b1cb4..63619100 100644 --- a/src/truefoundry_sdk/internal/deployments/raw_client.py +++ b/src/truefoundry_sdk/internal/deployments/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -50,7 +50,7 @@ def get_deployment_statuses( Deployment statuses returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/statuses", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/statuses", method="GET", request_options=request_options, ) @@ -107,7 +107,7 @@ def get_builds( Deployment builds returned successfully. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/builds", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/builds", method="GET", request_options=request_options, ) @@ -308,7 +308,7 @@ async def get_deployment_statuses( Deployment statuses returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/statuses", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/statuses", method="GET", request_options=request_options, ) @@ -365,7 +365,7 @@ async def get_builds( Deployment builds returned successfully. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/apps/{encode_path_param(id)}/deployments/{encode_path_param(deployment_id)}/builds", + f"api/svc/v1/apps/{jsonable_encoder(id)}/deployments/{jsonable_encoder(deployment_id)}/builds", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/internal/metrics/raw_client.py b/src/truefoundry_sdk/internal/metrics/raw_client.py index 263ddf63..d4de7122 100644 --- a/src/truefoundry_sdk/internal/metrics/raw_client.py +++ b/src/truefoundry_sdk/internal/metrics/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -62,7 +62,7 @@ def get_charts( Charts have been successfully retrieved. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/metrics/{encode_path_param(workspace_id)}/charts", + f"api/svc/v1/metrics/{jsonable_encoder(workspace_id)}/charts", method="GET", params={ "applicationId": application_id, @@ -170,7 +170,7 @@ async def get_charts( Charts have been successfully retrieved. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/metrics/{encode_path_param(workspace_id)}/charts", + f"api/svc/v1/metrics/{jsonable_encoder(workspace_id)}/charts", method="GET", params={ "applicationId": application_id, diff --git a/src/truefoundry_sdk/internal/raw_client.py b/src/truefoundry_sdk/internal/raw_client.py index ba915ec2..05b09787 100644 --- a/src/truefoundry_sdk/internal/raw_client.py +++ b/src/truefoundry_sdk/internal/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions @@ -42,7 +42,7 @@ def get_id_from_fqn( Returns the IDs for the specified entity type based on the provided FQN. For example, deploymentId, applicationId, and workspaceId for type deployment, or applicationId and workspaceId for type app. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/fqn/{encode_path_param(type)}", + f"api/svc/v1/fqn/{jsonable_encoder(type)}", method="GET", params={ "fqn": fqn, @@ -118,7 +118,7 @@ async def get_id_from_fqn( Returns the IDs for the specified entity type based on the provided FQN. For example, deploymentId, applicationId, and workspaceId for type deployment, or applicationId and workspaceId for type app. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/fqn/{encode_path_param(type)}", + f"api/svc/v1/fqn/{jsonable_encoder(type)}", method="GET", params={ "fqn": fqn, diff --git a/src/truefoundry_sdk/internal/workflows/raw_client.py b/src/truefoundry_sdk/internal/workflows/raw_client.py index 01a14081..62eba734 100644 --- a/src/truefoundry_sdk/internal/workflows/raw_client.py +++ b/src/truefoundry_sdk/internal/workflows/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions @@ -54,7 +54,7 @@ def execute_workflow( Returns execution name of the workflow """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workflow/{encode_path_param(application_id)}/executions", + f"api/svc/v1/workflow/{jsonable_encoder(application_id)}/executions", method="POST", json={ "inputs": inputs, @@ -143,7 +143,7 @@ async def execute_workflow( Returns execution name of the workflow """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workflow/{encode_path_param(application_id)}/executions", + f"api/svc/v1/workflow/{jsonable_encoder(application_id)}/executions", method="POST", json={ "inputs": inputs, diff --git a/src/truefoundry_sdk/jobs/raw_client.py b/src/truefoundry_sdk/jobs/raw_client.py index 9df855f1..784c1aa5 100644 --- a/src/truefoundry_sdk/jobs/raw_client.py +++ b/src/truefoundry_sdk/jobs/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -97,7 +97,7 @@ def list_runs( offset = offset if offset is not None else 0 _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs", method="GET", params={ "limit": limit, @@ -200,7 +200,7 @@ def get_run( Return JobRun details of the provided jobRunName """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", method="GET", request_options=request_options, ) @@ -268,7 +268,7 @@ def delete_run( Job Run deleted """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", method="DELETE", request_options=request_options, ) @@ -596,7 +596,7 @@ async def list_runs( offset = offset if offset is not None else 0 _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs", method="GET", params={ "limit": limit, @@ -702,7 +702,7 @@ async def get_run( Return JobRun details of the provided jobRunName """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", method="GET", request_options=request_options, ) @@ -770,7 +770,7 @@ async def delete_run( Job Run deleted """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/jobs/{encode_path_param(job_id)}/runs/{encode_path_param(job_run_name)}", + f"api/svc/v1/jobs/{jsonable_encoder(job_id)}/runs/{jsonable_encoder(job_run_name)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/ml_repos/raw_client.py b/src/truefoundry_sdk/ml_repos/raw_client.py index 8c8297e9..33cc1e3d 100644 --- a/src/truefoundry_sdk/ml_repos/raw_client.py +++ b/src/truefoundry_sdk/ml_repos/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -155,7 +155,7 @@ def get( The ML Repo data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{encode_path_param(id)}", + f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -208,7 +208,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{encode_path_param(id)}", + f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -450,7 +450,7 @@ async def get( The ML Repo data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{encode_path_param(id)}", + f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -503,7 +503,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/ml-repos/{encode_path_param(id)}", + f"api/ml/v1/ml-repos/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/model_versions/raw_client.py b/src/truefoundry_sdk/model_versions/raw_client.py index b8e3d3ea..06fab126 100644 --- a/src/truefoundry_sdk/model_versions/raw_client.py +++ b/src/truefoundry_sdk/model_versions/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -119,7 +119,7 @@ def get( The model version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{encode_path_param(id)}", + f"api/ml/v1/model-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -172,7 +172,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{encode_path_param(id)}", + f"api/ml/v1/model-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -432,7 +432,7 @@ async def get( The model version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{encode_path_param(id)}", + f"api/ml/v1/model-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -485,7 +485,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/model-versions/{encode_path_param(id)}", + f"api/ml/v1/model-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/models/raw_client.py b/src/truefoundry_sdk/models/raw_client.py index e8115cb2..c27ca42a 100644 --- a/src/truefoundry_sdk/models/raw_client.py +++ b/src/truefoundry_sdk/models/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -48,7 +48,7 @@ def get( The model data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{encode_path_param(id)}", + f"api/ml/v1/models/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -101,7 +101,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{encode_path_param(id)}", + f"api/ml/v1/models/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -326,7 +326,7 @@ async def get( The model data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{encode_path_param(id)}", + f"api/ml/v1/models/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -379,7 +379,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/models/{encode_path_param(id)}", + f"api/ml/v1/models/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/personal_access_tokens/raw_client.py b/src/truefoundry_sdk/personal_access_tokens/raw_client.py index 0b9474dd..9c558797 100644 --- a/src/truefoundry_sdk/personal_access_tokens/raw_client.py +++ b/src/truefoundry_sdk/personal_access_tokens/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -266,7 +266,7 @@ def delete( Personal Access Token deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{encode_path_param(id)}", + f"api/svc/v1/personal-access-tokens/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -319,7 +319,7 @@ def get( Personal Access Token found successfully and returned with token """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{encode_path_param(name)}", + f"api/svc/v1/personal-access-tokens/{jsonable_encoder(name)}", method="GET", request_options=request_options, ) @@ -596,7 +596,7 @@ async def delete( Personal Access Token deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{encode_path_param(id)}", + f"api/svc/v1/personal-access-tokens/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -649,7 +649,7 @@ async def get( Personal Access Token found successfully and returned with token """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/personal-access-tokens/{encode_path_param(name)}", + f"api/svc/v1/personal-access-tokens/{jsonable_encoder(name)}", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/prompt_versions/raw_client.py b/src/truefoundry_sdk/prompt_versions/raw_client.py index d5816f5e..e1bec984 100644 --- a/src/truefoundry_sdk/prompt_versions/raw_client.py +++ b/src/truefoundry_sdk/prompt_versions/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -119,7 +119,7 @@ def get( The prompt version data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{encode_path_param(id)}", + f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -172,7 +172,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{encode_path_param(id)}", + f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -414,7 +414,7 @@ async def get( The prompt version data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{encode_path_param(id)}", + f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -467,7 +467,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompt-versions/{encode_path_param(id)}", + f"api/ml/v1/prompt-versions/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/prompts/raw_client.py b/src/truefoundry_sdk/prompts/raw_client.py index 4b3a6ff9..74b88206 100644 --- a/src/truefoundry_sdk/prompts/raw_client.py +++ b/src/truefoundry_sdk/prompts/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -48,7 +48,7 @@ def get( The prompt data """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{encode_path_param(id)}", + f"api/ml/v1/prompts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -101,7 +101,7 @@ def delete( Empty response indicating successful deletion """ _response = self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{encode_path_param(id)}", + f"api/ml/v1/prompts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -320,7 +320,7 @@ async def get( The prompt data """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{encode_path_param(id)}", + f"api/ml/v1/prompts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -373,7 +373,7 @@ async def delete( Empty response indicating successful deletion """ _response = await self._client_wrapper.httpx_client.request( - f"api/ml/v1/prompts/{encode_path_param(id)}", + f"api/ml/v1/prompts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/secret_groups/raw_client.py b/src/truefoundry_sdk/secret_groups/raw_client.py index 2eabd01c..fc9eee28 100644 --- a/src/truefoundry_sdk/secret_groups/raw_client.py +++ b/src/truefoundry_sdk/secret_groups/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -333,7 +333,7 @@ def get( Returns the Secret Group associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -404,7 +404,7 @@ def update( Returns the updated secret group without associated secrets. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="PUT", json={ "secrets": convert_and_respect_annotation_metadata( @@ -500,7 +500,7 @@ def delete( Deletes Secret Group. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -850,7 +850,7 @@ async def get( Returns the Secret Group associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -921,7 +921,7 @@ async def update( Returns the updated secret group without associated secrets. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="PUT", json={ "secrets": convert_and_respect_annotation_metadata( @@ -1017,7 +1017,7 @@ async def delete( Deletes Secret Group. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secret-groups/{encode_path_param(id)}", + f"api/svc/v1/secret-groups/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/secrets/raw_client.py b/src/truefoundry_sdk/secrets/raw_client.py index 95bfee11..c1b6930d 100644 --- a/src/truefoundry_sdk/secrets/raw_client.py +++ b/src/truefoundry_sdk/secrets/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -155,7 +155,7 @@ def get( Returns the Secret associated with provided id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{encode_path_param(id)}", + f"api/svc/v1/secrets/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -227,7 +227,7 @@ def delete( Deletes a secret and its versions along with its values and returns the count of the deleted secrets. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{encode_path_param(id)}", + f"api/svc/v1/secrets/{jsonable_encoder(id)}", method="DELETE", params={ "forceDelete": force_delete, @@ -421,7 +421,7 @@ async def get( Returns the Secret associated with provided id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{encode_path_param(id)}", + f"api/svc/v1/secrets/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -493,7 +493,7 @@ async def delete( Deletes a secret and its versions along with its values and returns the count of the deleted secrets. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/secrets/{encode_path_param(id)}", + f"api/svc/v1/secrets/{jsonable_encoder(id)}", method="DELETE", params={ "forceDelete": force_delete, diff --git a/src/truefoundry_sdk/teams/raw_client.py b/src/truefoundry_sdk/teams/raw_client.py index c464a270..eff26076 100644 --- a/src/truefoundry_sdk/teams/raw_client.py +++ b/src/truefoundry_sdk/teams/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -203,7 +203,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns the Team associated with provided team id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}", + f"api/svc/v1/teams/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -257,7 +257,7 @@ def delete( Successfully deleted the team. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}", + f"api/svc/v1/teams/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -322,7 +322,7 @@ def get_permissions( Returns role bindings for the team. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}/permissions", + f"api/svc/v1/teams/{jsonable_encoder(id)}/permissions", method="GET", request_options=request_options, ) @@ -546,7 +546,7 @@ async def get( Returns the Team associated with provided team id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}", + f"api/svc/v1/teams/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -600,7 +600,7 @@ async def delete( Successfully deleted the team. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}", + f"api/svc/v1/teams/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -665,7 +665,7 @@ async def get_permissions( Returns role bindings for the team. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/teams/{encode_path_param(id)}/permissions", + f"api/svc/v1/teams/{jsonable_encoder(id)}/permissions", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/types/non_negative_float.py b/src/truefoundry_sdk/types/non_negative_float.py index 940f6df3..da8968da 100644 --- a/src/truefoundry_sdk/types/non_negative_float.py +++ b/src/truefoundry_sdk/types/non_negative_float.py @@ -1,6 +1,3 @@ # This file was auto-generated by Fern from our API Definition. NonNegativeFloat = float -""" -+uiProps={"allowDecimal":true, "allowNegative":false} -""" diff --git a/src/truefoundry_sdk/users/raw_client.py b/src/truefoundry_sdk/users/raw_client.py index ee7ba751..e48f88c2 100644 --- a/src/truefoundry_sdk/users/raw_client.py +++ b/src/truefoundry_sdk/users/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -335,7 +335,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non Returns the User associated with provided User id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}", + f"api/svc/v1/users/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -396,7 +396,7 @@ def delete( User has been successfully deleted. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}", + f"api/svc/v1/users/{jsonable_encoder(id)}", method="DELETE", params={ "tenantName": tenant_name, @@ -785,7 +785,7 @@ def get_resources( Returns all resources for the user. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/resources", + f"api/svc/v1/users/{jsonable_encoder(id)}/resources", method="GET", request_options=request_options, ) @@ -850,7 +850,7 @@ def get_permissions( Returns role bindings for the user (including team-inherited). """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/permissions", + f"api/svc/v1/users/{jsonable_encoder(id)}/permissions", method="GET", request_options=request_options, ) @@ -915,7 +915,7 @@ def get_teams( Returns all teams for the user with their roles. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/teams", + f"api/svc/v1/users/{jsonable_encoder(id)}/teams", method="GET", request_options=request_options, ) @@ -1264,7 +1264,7 @@ async def get( Returns the User associated with provided User id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}", + f"api/svc/v1/users/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -1325,7 +1325,7 @@ async def delete( User has been successfully deleted. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}", + f"api/svc/v1/users/{jsonable_encoder(id)}", method="DELETE", params={ "tenantName": tenant_name, @@ -1714,7 +1714,7 @@ async def get_resources( Returns all resources for the user. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/resources", + f"api/svc/v1/users/{jsonable_encoder(id)}/resources", method="GET", request_options=request_options, ) @@ -1779,7 +1779,7 @@ async def get_permissions( Returns role bindings for the user (including team-inherited). """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/permissions", + f"api/svc/v1/users/{jsonable_encoder(id)}/permissions", method="GET", request_options=request_options, ) @@ -1844,7 +1844,7 @@ async def get_teams( Returns all teams for the user with their roles. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/users/{encode_path_param(id)}/teams", + f"api/svc/v1/users/{jsonable_encoder(id)}/teams", method="GET", request_options=request_options, ) diff --git a/src/truefoundry_sdk/virtual_accounts/raw_client.py b/src/truefoundry_sdk/virtual_accounts/raw_client.py index afbd0de2..a7553a94 100644 --- a/src/truefoundry_sdk/virtual_accounts/raw_client.py +++ b/src/truefoundry_sdk/virtual_accounts/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -221,7 +221,7 @@ def get( Returns the virtual account associated with the provided virtual account id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -275,7 +275,7 @@ def delete( Virtual account deleted successfully """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -329,7 +329,7 @@ def get_token( Token for the virtual account """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/token", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/token", method="GET", request_options=request_options, ) @@ -372,7 +372,7 @@ def sync_to_secret_store( Token synced successfully to secret store """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/sync-to-secret-store", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/sync-to-secret-store", method="POST", request_options=request_options, ) @@ -440,7 +440,7 @@ def regenerate_token( Token for the virtual account """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/regenerate-token", method="POST", json={ "gracePeriodInDays": grace_period_in_days, @@ -492,7 +492,7 @@ def delete_jwt( HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/jwt/{encode_path_param(jwt_id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/jwt/{jsonable_encoder(jwt_id)}", method="DELETE", request_options=request_options, ) @@ -705,7 +705,7 @@ async def get( Returns the virtual account associated with the provided virtual account id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -759,7 +759,7 @@ async def delete( Virtual account deleted successfully """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -813,7 +813,7 @@ async def get_token( Token for the virtual account """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/token", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/token", method="GET", request_options=request_options, ) @@ -856,7 +856,7 @@ async def sync_to_secret_store( Token synced successfully 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", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/sync-to-secret-store", method="POST", request_options=request_options, ) @@ -924,7 +924,7 @@ async def regenerate_token( Token for the virtual account """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/regenerate-token", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/regenerate-token", method="POST", json={ "gracePeriodInDays": grace_period_in_days, @@ -976,7 +976,7 @@ async def delete_jwt( AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/virtual-accounts/{encode_path_param(id)}/jwt/{encode_path_param(jwt_id)}", + f"api/svc/v1/virtual-accounts/{jsonable_encoder(id)}/jwt/{jsonable_encoder(jwt_id)}", method="DELETE", request_options=request_options, ) diff --git a/src/truefoundry_sdk/workspaces/raw_client.py b/src/truefoundry_sdk/workspaces/raw_client.py index 45069b3b..4df831b5 100644 --- a/src/truefoundry_sdk/workspaces/raw_client.py +++ b/src/truefoundry_sdk/workspaces/raw_client.py @@ -6,7 +6,7 @@ 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.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as @@ -321,7 +321,7 @@ def get( Returns the workspaces associated with provided workspace id """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{encode_path_param(id)}", + f"api/svc/v1/workspaces/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -377,7 +377,7 @@ def delete( Successfully deletes the workspace and returns the workspace details along with a confirmation message. """ _response = self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{encode_path_param(id)}", + f"api/svc/v1/workspaces/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) @@ -721,7 +721,7 @@ async def get( Returns the workspaces associated with provided workspace id """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{encode_path_param(id)}", + f"api/svc/v1/workspaces/{jsonable_encoder(id)}", method="GET", request_options=request_options, ) @@ -777,7 +777,7 @@ async def delete( Successfully deletes the workspace and returns the workspace details along with a confirmation message. """ _response = await self._client_wrapper.httpx_client.request( - f"api/svc/v1/workspaces/{encode_path_param(id)}", + f"api/svc/v1/workspaces/{jsonable_encoder(id)}", method="DELETE", request_options=request_options, ) diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 25710dbe..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest - - -def _has_httpx_aiohttp() -> bool: - """Check if httpx_aiohttp is importable.""" - try: - import httpx_aiohttp # type: ignore[import-not-found] # noqa: F401 - - return True - except ImportError: - return False - - -def pytest_collection_modifyitems(config: pytest.Config, items: list) -> None: - """Auto-skip @pytest.mark.aiohttp tests when httpx_aiohttp is not installed.""" - if _has_httpx_aiohttp(): - return - skip_aiohttp = pytest.mark.skip(reason="httpx_aiohttp not installed") - for item in items: - if "aiohttp" in item.keywords: - item.add_marker(skip_aiohttp) diff --git a/tests/test_aiohttp_autodetect.py b/tests/test_aiohttp_autodetect.py deleted file mode 100644 index 69daf0bd..00000000 --- a/tests/test_aiohttp_autodetect.py +++ /dev/null @@ -1,116 +0,0 @@ -import importlib -import sys -import unittest -from unittest import mock - -import httpx -import pytest - - -class TestMakeDefaultAsyncClientWithoutAiohttp(unittest.TestCase): - """Tests for _make_default_async_client when httpx_aiohttp is NOT installed.""" - - def test_returns_httpx_async_client(self) -> None: - """When httpx_aiohttp is not installed, returns plain httpx.AsyncClient.""" - with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): - from truefoundry_sdk.base_client import _make_default_async_client - - client = _make_default_async_client(timeout=60, follow_redirects=True) - self.assertIsInstance(client, httpx.AsyncClient) - self.assertEqual(client.timeout.read, 60) - self.assertTrue(client.follow_redirects) - - def test_follow_redirects_none(self) -> None: - """When follow_redirects is None, omits it from httpx.AsyncClient.""" - with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): - from truefoundry_sdk.base_client import _make_default_async_client - - client = _make_default_async_client(timeout=60, follow_redirects=None) - self.assertIsInstance(client, httpx.AsyncClient) - self.assertFalse(client.follow_redirects) - - def test_explicit_httpx_client_bypasses_autodetect(self) -> None: - """When user passes httpx_client explicitly, _make_default_async_client is not called.""" - - explicit_client = httpx.AsyncClient(timeout=120) - with mock.patch("truefoundry_sdk.base_client._make_default_async_client") as mock_make: - # Replicate the generated conditional: httpx_client if httpx_client is not None else _make_default_async_client(...) - result = explicit_client if explicit_client is not None else mock_make(timeout=60, follow_redirects=True) - mock_make.assert_not_called() - self.assertIs(result, explicit_client) - - -@pytest.mark.aiohttp -class TestMakeDefaultAsyncClientWithAiohttp(unittest.TestCase): - """Tests for _make_default_async_client when httpx_aiohttp IS installed.""" - - def test_returns_aiohttp_client(self) -> None: - """When httpx_aiohttp is installed, returns HttpxAiohttpClient.""" - import httpx_aiohttp # type: ignore[import-not-found] - - from truefoundry_sdk.base_client import _make_default_async_client - - client = _make_default_async_client(timeout=60, follow_redirects=True) - self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) - self.assertEqual(client.timeout.read, 60) - self.assertTrue(client.follow_redirects) - - def test_follow_redirects_none(self) -> None: - """When httpx_aiohttp is installed and follow_redirects is None, omits it.""" - import httpx_aiohttp # type: ignore[import-not-found] - - from truefoundry_sdk.base_client import _make_default_async_client - - client = _make_default_async_client(timeout=60, follow_redirects=None) - self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) - self.assertFalse(client.follow_redirects) - - -class TestDefaultClientsWithoutAiohttp(unittest.TestCase): - """Tests for _default_clients.py convenience classes (no aiohttp).""" - - def test_default_async_httpx_client_defaults(self) -> None: - """DefaultAsyncHttpxClient applies SDK defaults.""" - from truefoundry_sdk._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAsyncHttpxClient - - client = DefaultAsyncHttpxClient() - self.assertIsInstance(client, httpx.AsyncClient) - self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) - self.assertTrue(client.follow_redirects) - - def test_default_async_httpx_client_overrides(self) -> None: - """DefaultAsyncHttpxClient allows overriding defaults.""" - from truefoundry_sdk._default_clients import DefaultAsyncHttpxClient - - client = DefaultAsyncHttpxClient(timeout=30, follow_redirects=False) - self.assertEqual(client.timeout.read, 30) - self.assertFalse(client.follow_redirects) - - def test_default_aiohttp_client_raises_without_package(self) -> None: - """DefaultAioHttpClient raises RuntimeError when httpx_aiohttp not installed.""" - import truefoundry_sdk._default_clients - - with mock.patch.dict(sys.modules, {"httpx_aiohttp": None}): - importlib.reload(truefoundry_sdk._default_clients) - - with self.assertRaises(RuntimeError) as ctx: - truefoundry_sdk._default_clients.DefaultAioHttpClient() - self.assertIn("pip install truefoundry-sdk[aiohttp]", str(ctx.exception)) - - importlib.reload(truefoundry_sdk._default_clients) - - -@pytest.mark.aiohttp -class TestDefaultClientsWithAiohttp(unittest.TestCase): - """Tests for _default_clients.py when httpx_aiohttp IS installed.""" - - def test_default_aiohttp_client_defaults(self) -> None: - """DefaultAioHttpClient works when httpx_aiohttp is installed.""" - import httpx_aiohttp # type: ignore[import-not-found] - - from truefoundry_sdk._default_clients import SDK_DEFAULT_TIMEOUT, DefaultAioHttpClient - - client = DefaultAioHttpClient() - self.assertIsInstance(client, httpx_aiohttp.HttpxAiohttpClient) - self.assertEqual(client.timeout.read, SDK_DEFAULT_TIMEOUT) - self.assertTrue(client.follow_redirects) diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index bf0dbcc7..e2083580 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -1,9 +1,7 @@ # This file was auto-generated by Fern from our API Definition. from typing import Any, Dict -from unittest.mock import AsyncMock, MagicMock, patch -import httpx import pytest from truefoundry_sdk.core.http_client import ( @@ -300,363 +298,3 @@ def test_preserves_base_url_path_prefix_trailing_slash() -> None: """Test that path prefixes in base URL are preserved.""" result = _build_url("https://cloud.example.com/org/tenant/api/", "/users") assert result == "https://cloud.example.com/org/tenant/api/users" - - -# --------------------------------------------------------------------------- -# Connection error retry tests -# --------------------------------------------------------------------------- - - -def _make_sync_http_client(mock_client: Any) -> HttpClient: - return HttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - ) - - -def _make_async_http_client(mock_client: Any) -> AsyncHttpClient: - return AsyncHttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - async_base_headers=None, - ) - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_retries_on_connect_error(mock_sleep: MagicMock) -> None: - """Sync: connection error retries on httpx.ConnectError.""" - mock_client = MagicMock() - mock_client.request.side_effect = [ - httpx.ConnectError("connection failed"), - _DummyResponse(), - ] - http_client = _make_sync_http_client(mock_client) - - response = http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - assert mock_client.request.call_count == 2 - mock_sleep.assert_called_once() - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_retries_on_remote_protocol_error(mock_sleep: MagicMock) -> None: - """Sync: connection error retries on httpx.RemoteProtocolError.""" - mock_client = MagicMock() - mock_client.request.side_effect = [ - httpx.RemoteProtocolError("Remote end closed connection without response"), - _DummyResponse(), - ] - http_client = _make_sync_http_client(mock_client) - - response = http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - assert mock_client.request.call_count == 2 - mock_sleep.assert_called_once() - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_connection_error_exhausts_retries(mock_sleep: MagicMock) -> None: - """Sync: connection error exhausts retries then raises.""" - mock_client = MagicMock() - mock_client.request.side_effect = httpx.ConnectError("connection failed") - http_client = _make_sync_http_client(mock_client) - - with pytest.raises(httpx.ConnectError): - http_client.request( - path="/test", - method="GET", - request_options={"max_retries": 2}, - ) - - # 1 initial + 2 retries = 3 total attempts - assert mock_client.request.call_count == 3 - assert mock_sleep.call_count == 2 - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_connection_error_respects_max_retries_zero(mock_sleep: MagicMock) -> None: - """Sync: connection error respects max_retries=0.""" - mock_client = MagicMock() - mock_client.request.side_effect = httpx.ConnectError("connection failed") - http_client = _make_sync_http_client(mock_client) - - with pytest.raises(httpx.ConnectError): - http_client.request( - path="/test", - method="GET", - request_options={"max_retries": 0}, - ) - - # No retries, just the initial attempt - assert mock_client.request.call_count == 1 - mock_sleep.assert_not_called() - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_retries_on_connect_error(mock_sleep: AsyncMock) -> None: - """Async: connection error retries on httpx.ConnectError.""" - mock_client = MagicMock() - mock_client.request = AsyncMock( - side_effect=[ - httpx.ConnectError("connection failed"), - _DummyResponse(), - ] - ) - http_client = _make_async_http_client(mock_client) - - response = await http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - assert mock_client.request.call_count == 2 - mock_sleep.assert_called_once() - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_retries_on_remote_protocol_error(mock_sleep: AsyncMock) -> None: - """Async: connection error retries on httpx.RemoteProtocolError.""" - mock_client = MagicMock() - mock_client.request = AsyncMock( - side_effect=[ - httpx.RemoteProtocolError("Remote end closed connection without response"), - _DummyResponse(), - ] - ) - http_client = _make_async_http_client(mock_client) - - response = await http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - assert mock_client.request.call_count == 2 - mock_sleep.assert_called_once() - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_connection_error_exhausts_retries(mock_sleep: AsyncMock) -> None: - """Async: connection error exhausts retries then raises.""" - mock_client = MagicMock() - mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) - http_client = _make_async_http_client(mock_client) - - with pytest.raises(httpx.ConnectError): - await http_client.request( - path="/test", - method="GET", - request_options={"max_retries": 2}, - ) - - # 1 initial + 2 retries = 3 total attempts - assert mock_client.request.call_count == 3 - assert mock_sleep.call_count == 2 - - -# --------------------------------------------------------------------------- -# base_max_retries constructor parameter tests -# --------------------------------------------------------------------------- - - -def test_sync_http_client_default_base_max_retries() -> None: - """HttpClient defaults to base_max_retries=2.""" - http_client = HttpClient( - httpx_client=MagicMock(), # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - ) - assert http_client.base_max_retries == 2 - - -def test_async_http_client_default_base_max_retries() -> None: - """AsyncHttpClient defaults to base_max_retries=2.""" - http_client = AsyncHttpClient( - httpx_client=MagicMock(), # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - ) - assert http_client.base_max_retries == 2 - - -def test_sync_http_client_custom_base_max_retries() -> None: - """HttpClient accepts a custom base_max_retries value.""" - http_client = HttpClient( - httpx_client=MagicMock(), # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_max_retries=5, - ) - assert http_client.base_max_retries == 5 - - -def test_async_http_client_custom_base_max_retries() -> None: - """AsyncHttpClient accepts a custom base_max_retries value.""" - http_client = AsyncHttpClient( - httpx_client=MagicMock(), # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_max_retries=5, - ) - assert http_client.base_max_retries == 5 - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_base_max_retries_zero_disables_retries(mock_sleep: MagicMock) -> None: - """Sync: base_max_retries=0 disables retries when no request_options override.""" - mock_client = MagicMock() - mock_client.request.side_effect = httpx.ConnectError("connection failed") - http_client = HttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=0, - ) - - with pytest.raises(httpx.ConnectError): - http_client.request(path="/test", method="GET") - - # No retries, just the initial attempt - assert mock_client.request.call_count == 1 - mock_sleep.assert_not_called() - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_base_max_retries_zero_disables_retries(mock_sleep: AsyncMock) -> None: - """Async: base_max_retries=0 disables retries when no request_options override.""" - mock_client = MagicMock() - mock_client.request = AsyncMock(side_effect=httpx.ConnectError("connection failed")) - http_client = AsyncHttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=0, - ) - - with pytest.raises(httpx.ConnectError): - await http_client.request(path="/test", method="GET") - - # No retries, just the initial attempt - assert mock_client.request.call_count == 1 - mock_sleep.assert_not_called() - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_request_options_override_base_max_retries(mock_sleep: MagicMock) -> None: - """Sync: request_options max_retries overrides base_max_retries.""" - mock_client = MagicMock() - mock_client.request.side_effect = [ - httpx.ConnectError("connection failed"), - httpx.ConnectError("connection failed"), - _DummyResponse(), - ] - http_client = HttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=0, # base says no retries - ) - - # But request_options overrides to allow 2 retries - response = http_client.request( - path="/test", - method="GET", - request_options={"max_retries": 2}, - ) - - assert response.status_code == 200 - # 1 initial + 2 retries = 3 total attempts - assert mock_client.request.call_count == 3 - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_request_options_override_base_max_retries(mock_sleep: AsyncMock) -> None: - """Async: request_options max_retries overrides base_max_retries.""" - mock_client = MagicMock() - mock_client.request = AsyncMock( - side_effect=[ - httpx.ConnectError("connection failed"), - httpx.ConnectError("connection failed"), - _DummyResponse(), - ] - ) - http_client = AsyncHttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=0, # base says no retries - ) - - # But request_options overrides to allow 2 retries - response = await http_client.request( - path="/test", - method="GET", - request_options={"max_retries": 2}, - ) - - assert response.status_code == 200 - # 1 initial + 2 retries = 3 total attempts - assert mock_client.request.call_count == 3 - - -@patch("truefoundry_sdk.core.http_client.time.sleep", return_value=None) -def test_sync_base_max_retries_used_as_default(mock_sleep: MagicMock) -> None: - """Sync: base_max_retries is used when request_options has no max_retries.""" - mock_client = MagicMock() - mock_client.request.side_effect = [ - httpx.ConnectError("fail"), - httpx.ConnectError("fail"), - httpx.ConnectError("fail"), - _DummyResponse(), - ] - http_client = HttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=3, - ) - - response = http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - # 1 initial + 3 retries = 4 total attempts - assert mock_client.request.call_count == 4 - - -@pytest.mark.asyncio -@patch("truefoundry_sdk.core.http_client.asyncio.sleep", new_callable=AsyncMock) -async def test_async_base_max_retries_used_as_default(mock_sleep: AsyncMock) -> None: - """Async: base_max_retries is used when request_options has no max_retries.""" - mock_client = MagicMock() - mock_client.request = AsyncMock( - side_effect=[ - httpx.ConnectError("fail"), - httpx.ConnectError("fail"), - httpx.ConnectError("fail"), - _DummyResponse(), - ] - ) - http_client = AsyncHttpClient( - httpx_client=mock_client, # type: ignore[arg-type] - base_timeout=lambda: None, - base_headers=lambda: {}, - base_url=lambda: "https://example.com", - base_max_retries=3, - ) - - response = await http_client.request(path="/test", method="GET") - - assert response.status_code == 200 - # 1 initial + 3 retries = 4 total attempts - assert mock_client.request.call_count == 4 From e71005f86a97ea69bf6a944b53b5d793538c1812 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:25:53 +0000 Subject: [PATCH 5/6] SDK regeneration --- .fern/metadata.json | 6 +- README.md | 78 +- reference.md | 1292 +++++++++-------- .../agent_skill_versions/raw_client.py | 26 - .../agent_skills/raw_client.py | 34 - src/truefoundry_sdk/alerts/raw_client.py | 10 - .../application_versions/raw_client.py | 18 - src/truefoundry_sdk/applications/client.py | 4 +- .../applications/raw_client.py | 70 +- .../artifact_versions/client.py | 4 +- .../artifact_versions/raw_client.py | 78 +- src/truefoundry_sdk/artifacts/raw_client.py | 34 - src/truefoundry_sdk/base_client.py | 15 +- src/truefoundry_sdk/clusters/client.py | 4 +- src/truefoundry_sdk/clusters/raw_client.py | 54 +- src/truefoundry_sdk/core/__init__.py | 27 +- src/truefoundry_sdk/core/client_wrapper.py | 11 +- src/truefoundry_sdk/core/custom_pagination.py | 152 ++ src/truefoundry_sdk/core/datetime_utils.py | 42 - src/truefoundry_sdk/core/http_client.py | 195 +-- src/truefoundry_sdk/core/logging.py | 107 -- src/truefoundry_sdk/core/parse_error.py | 36 - .../core/pydantic_utilities.py | 96 +- .../data_directories/raw_client.py | 66 - src/truefoundry_sdk/environments/client.py | 4 +- .../environments/raw_client.py | 38 +- src/truefoundry_sdk/events/raw_client.py | 10 - .../internal/ai_gateway/raw_client.py | 10 - .../internal/applications/raw_client.py | 18 - .../internal/artifact_versions/raw_client.py | 10 - .../internal/build_logs/raw_client.py | 10 - .../internal/clusters/raw_client.py | 10 - .../internal/deployments/raw_client.py | 34 - .../internal/docker_registries/raw_client.py | 18 - .../internal/metrics/raw_client.py | 10 - src/truefoundry_sdk/internal/ml/raw_client.py | 18 - src/truefoundry_sdk/internal/raw_client.py | 10 - .../internal/users/raw_client.py | 10 - .../internal/vcs/raw_client.py | 18 - .../internal/workflows/raw_client.py | 10 - src/truefoundry_sdk/jobs/raw_client.py | 42 - src/truefoundry_sdk/logs/raw_client.py | 10 - src/truefoundry_sdk/ml_repos/client.py | 4 +- src/truefoundry_sdk/ml_repos/raw_client.py | 38 +- src/truefoundry_sdk/model_versions/client.py | 4 +- .../model_versions/raw_client.py | 38 +- src/truefoundry_sdk/models/raw_client.py | 34 - .../personal_access_tokens/raw_client.py | 42 - src/truefoundry_sdk/prompt_versions/client.py | 4 +- .../prompt_versions/raw_client.py | 38 +- src/truefoundry_sdk/prompts/raw_client.py | 34 - src/truefoundry_sdk/raw_base_client.py | 22 +- src/truefoundry_sdk/secret_groups/client.py | 4 +- .../secret_groups/raw_client.py | 54 +- src/truefoundry_sdk/secrets/client.py | 12 +- src/truefoundry_sdk/secrets/raw_client.py | 38 +- src/truefoundry_sdk/teams/client.py | 4 +- src/truefoundry_sdk/teams/raw_client.py | 46 +- src/truefoundry_sdk/traces/client.py | 4 +- src/truefoundry_sdk/traces/raw_client.py | 14 +- src/truefoundry_sdk/types/a2a_framework.py | 2 +- .../types/akto_guardrail_config.py | 4 +- .../types/amqp_input_config.py | 2 +- .../types/artifact_manifest.py | 2 +- .../types/artifacts_cache_volume.py | 2 +- .../types/async_processor_sidecar.py | 2 +- src/truefoundry_sdk/types/auto_rotate.py | 4 +- src/truefoundry_sdk/types/autoshutdown.py | 2 +- .../types/aws_bedrock_guardrail_config.py | 6 +- .../azure_content_safety_guardrail_config.py | 4 +- ..._content_safety_guardrail_config_config.py | 4 +- .../types/azure_pii_guardrail_config.py | 6 +- .../azure_pii_guardrail_config_config.py | 6 +- .../azure_prompt_shield_guardrail_config.py | 4 +- ...e_prompt_shield_guardrail_config_config.py | 2 +- src/truefoundry_sdk/types/base_autoscaling.py | 4 +- .../types/base_workbench_input.py | 2 +- src/truefoundry_sdk/types/blue_green.py | 4 +- src/truefoundry_sdk/types/budget_rule.py | 2 +- .../types/cedar_guardrail_config.py | 4 +- .../code_safety_linter_guardrail_config.py | 4 +- .../types/common_tools_settings.py | 10 +- src/truefoundry_sdk/types/cron_metric.py | 2 +- .../types/custom_guardrail_config.py | 6 +- .../types/custom_regex_pattern.py | 2 +- .../types/custom_tls_settings.py | 2 +- .../types/data_access_rule_base.py | 2 +- .../types/databricks_job_task_config.py | 2 +- .../types/docker_file_build.py | 4 +- .../types/enkrypt_ai_guardrail_config.py | 6 +- .../types/exact_match_cache_config.py | 2 +- .../types/fiddler_guardrail_config.py | 4 +- src/truefoundry_sdk/types/function_schema.py | 2 +- ...gateway_data_routing_config_destination.py | 2 +- .../google_model_armor_guardrail_config.py | 6 +- .../gray_swan_cygnal_guardrail_config.py | 4 +- src/truefoundry_sdk/types/header_match.py | 2 +- src/truefoundry_sdk/types/health_probe.py | 10 +- src/truefoundry_sdk/types/http_probe.py | 2 +- .../types/ingress_controller_config.py | 4 +- .../types/internal_model_version.py | 2 +- src/truefoundry_sdk/types/job.py | 2 +- src/truefoundry_sdk/types/job_alert.py | 6 +- .../types/kafka_input_config.py | 4 +- .../types/kafka_output_config.py | 2 +- .../latency_based_load_balance_target.py | 2 +- .../types/load_balance_target.py | 2 +- src/truefoundry_sdk/types/local_source.py | 4 +- src/truefoundry_sdk/types/logging_config.py | 2 +- .../types/mcp_server_with_fqn.py | 2 +- .../types/mcp_server_with_url.py | 2 +- src/truefoundry_sdk/types/mcp_tool_target.py | 2 +- src/truefoundry_sdk/types/metric.py | 2 +- src/truefoundry_sdk/types/model_manifest.py | 2 +- src/truefoundry_sdk/types/model_version.py | 2 +- .../types/nats_input_config.py | 2 +- .../types/nats_user_password_auth.py | 2 +- src/truefoundry_sdk/types/notebook.py | 2 +- .../types/opa_guardrail_config.py | 4 +- .../open_ai_moderations_guardrail_config.py | 4 +- ..._ai_moderations_guardrail_config_config.py | 2 +- .../palo_alto_prisma_airs_guardrail_config.py | 4 +- .../types/pangea_guardrail_config.py | 6 +- .../types/patronus_guardrail_config.py | 4 +- src/truefoundry_sdk/types/poetry.py | 2 +- src/truefoundry_sdk/types/port.py | 4 +- .../priority_based_load_balance_target.py | 4 +- .../types/prometheus_alert_rule.py | 2 +- src/truefoundry_sdk/types/python_build.py | 2 +- .../types/regex_guardrail_config.py | 6 +- src/truefoundry_sdk/types/resources.py | 12 +- src/truefoundry_sdk/types/retry_config.py | 2 +- src/truefoundry_sdk/types/rolling.py | 4 +- .../secret_detection_guardrail_config.py | 6 +- ...ecret_detection_guardrail_config_config.py | 2 +- .../types/semantic_cache_config.py | 2 +- src/truefoundry_sdk/types/service.py | 2 +- src/truefoundry_sdk/types/smtp_credentials.py | 4 +- src/truefoundry_sdk/types/spark_build.py | 4 +- .../types/spark_executor_dynamic_scaling.py | 4 +- .../types/spark_executor_fixed_instances.py | 2 +- src/truefoundry_sdk/types/spark_image.py | 2 +- src/truefoundry_sdk/types/spark_job.py | 2 +- .../types/sql_sanitizer_guardrail_config.py | 6 +- .../sql_sanitizer_guardrail_config_config.py | 18 +- src/truefoundry_sdk/types/sqs_input_config.py | 2 +- .../types/stdio_mcp_server_manifest.py | 2 +- .../types/task_docker_file_build.py | 2 +- .../types/task_py_spark_build.py | 2 +- ...tfy_content_moderation_guardrail_config.py | 2 +- ...tent_moderation_guardrail_config_config.py | 2 +- .../types/tfy_pii_guardrail_config.py | 6 +- .../tfy_prompt_injection_guardrail_config.py | 2 +- .../types/troj_ai_guardrail_config.py | 4 +- .../types/true_foundry_agent_mcp_server.py | 2 +- src/truefoundry_sdk/types/ttl_registry.py | 2 +- src/truefoundry_sdk/types/uv.py | 2 +- .../types/webhook_bearer_auth.py | 2 +- src/truefoundry_sdk/types/worker_config.py | 2 +- src/truefoundry_sdk/types/workflow_alert.py | 4 +- src/truefoundry_sdk/users/client.py | 12 +- src/truefoundry_sdk/users/raw_client.py | 110 +- .../virtual_accounts/client.py | 4 +- .../virtual_accounts/raw_client.py | 70 +- src/truefoundry_sdk/workspaces/client.py | 4 +- src/truefoundry_sdk/workspaces/raw_client.py | 46 +- 166 files changed, 1216 insertions(+), 2557 deletions(-) create mode 100644 src/truefoundry_sdk/core/custom_pagination.py delete mode 100644 src/truefoundry_sdk/core/logging.py delete mode 100644 src/truefoundry_sdk/core/parse_error.py diff --git a/.fern/metadata.json b/.fern/metadata.json index dee1545a..fdd9d299 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { - "cliVersion": "4.68.0", + "cliVersion": "4.71.5", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "4.64.1", + "generatorVersion": "4.54.3", "generatorConfig": { "package_name": "truefoundry_sdk", "pydantic_config": { @@ -22,6 +22,6 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "b21f8faecb9e7a36b5f7c48bcaf48d0bb6af465a", + "originGitCommit": "0a7e4e0f82186360e1999b049382462657c261cc", "sdkVersion": "0.0.0" } \ No newline at end of file diff --git a/README.md b/README.md index ee37a6d3..433cba06 100644 --- a/README.md +++ b/README.md @@ -42,13 +42,16 @@ Instantiate and use the client with the following: ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.applications import ( + ApplicationsListRequestDeviceTypeFilter, + ApplicationsListRequestLifecycleStage, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.applications.list( +response = client.applications.list( limit=10, offset=0, application_id="applicationId", @@ -62,11 +65,16 @@ client.applications.list( cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter="cpu", + device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage="active", + lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, is_recommendation_present_and_visible=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` ## Async Client @@ -77,15 +85,19 @@ The SDK also exports an `async` client so that you can make non-blocking calls t import asyncio from truefoundry_sdk import AsyncTrueFoundry +from truefoundry_sdk.applications import ( + ApplicationsListRequestDeviceTypeFilter, + ApplicationsListRequestLifecycleStage, +) client = AsyncTrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) async def main() -> None: - await client.applications.list( + response = await client.applications.list( limit=10, offset=0, application_id="applicationId", @@ -99,11 +111,17 @@ async def main() -> None: cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter="cpu", + device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage="active", + lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, is_recommendation_present_and_visible=True, ) + async for item in response: + yield item + + # alternatively, you can paginate page-by-page + async for page in response.iter_pages(): + yield page asyncio.run(main()) @@ -132,34 +150,25 @@ Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.applications.list( +response = client.users.list( limit=10, offset=0, - application_id="applicationId", - workspace_id="workspaceId", - application_name="applicationName", - fqn="fqn", - workspace_fqn="workspaceFqn", - application_type="applicationType", - name_search_query="nameSearchQuery", - environment_id="environmentId", - cluster_id="clusterId", - application_set_id="applicationSetId", - paused=True, - device_type_filter="cpu", - last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage="active", - is_recommendation_present_and_visible=True, + query="query", + show_invalid_users=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` ```python # You can also iterate through pages and access the typed response per page -pager = client.applications.list(...) +pager = client.users.list(...) for page in pager.iter_pages(): print(page.response) # access the typed response for each page for item in page: @@ -179,7 +188,11 @@ from truefoundry_sdk import TrueFoundry client = TrueFoundry( ..., ) -pager = client.applications.list(...) +response = client.applications.with_raw_response.list(...) +print(response.headers) # access the response headers +print(response.status_code) # access the response status code +print(response.data) # access the underlying object +pager = client.users.list(...) print(pager.response) # access the typed response for the first page for item in pager: print(item) # access the underlying object(s) @@ -214,9 +227,14 @@ client.applications.list(..., request_options={ The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level. ```python + from truefoundry_sdk import TrueFoundry -client = TrueFoundry(..., timeout=20.0) +client = TrueFoundry( + ..., + timeout=20.0, +) + # Override timeout for a specific method client.applications.list(..., request_options={ diff --git a/reference.md b/reference.md index 32d1856a..02741563 100644 --- a/reference.md +++ b/reference.md @@ -1,5 +1,5 @@ # Reference -
client.apply(...) -> TrueFoundryApplyResponse +
client.apply(...) -> AsyncHttpResponse[TrueFoundryApplyResponse]
@@ -26,16 +26,14 @@ Applies a given manifest to create or update resources of specific types, such a
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.apply( manifest=MlRepoManifest( - type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", collaborators=[ @@ -89,7 +87,7 @@ client.apply(
-
client.delete(...) +
client.delete(...) -> AsyncHttpResponse[None]
@@ -116,16 +114,14 @@ Deletes resources of specific types, such as provider-account, cluster, workspac
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.delete( manifest=MlRepoManifest( - type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", collaborators=[ @@ -172,7 +168,7 @@ client.delete(
## Internal -
client.internal.get_id_from_fqn(...) -> typing.Dict[str, typing.Any] +
client.internal.get_id_from_fqn(...) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]
@@ -202,10 +198,9 @@ Get IDs associated with the FQN for various entity types, such as deployment, ap from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.get_id_from_fqn( type="type", fqn="fqn", @@ -254,7 +249,7 @@ client.internal.get_id_from_fqn(
## Users -
client.users.list(...) -> ListUsersResponse +
client.users.list(...) -> AsyncPager[User, ListUsersResponse]
@@ -284,16 +279,20 @@ List all users of tenant filtered by query and showInvalidUsers. Pagination is a from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.users.list( +response = client.users.list( limit=10, offset=0, query="query", show_invalid_users=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -353,7 +352,7 @@ client.users.list(
-
client.users.pre_register_users(...) -> RegisterUsersResponse +
client.users.pre_register_users(...) -> AsyncHttpResponse[RegisterUsersResponse]
@@ -383,10 +382,9 @@ This endpoint allows tenant administrators to register users within their tenant from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.pre_register_users( email="email", ) @@ -457,7 +455,7 @@ client.users.pre_register_users(
-
client.users.update_roles(...) -> UpdateUserRolesResponse +
client.users.update_roles(...) -> AsyncHttpResponse[UpdateUserRolesResponse]
@@ -487,15 +485,12 @@ This endpoint allows tenant administrators to update the roles of a user within from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.update_roles( email="email", - roles=[ - "roles" - ], + roles=["roles"], ) ``` @@ -520,7 +515,7 @@ client.users.update_roles(
-**roles:** `typing.List[str]` — Role names for the user +**roles:** `typing.Sequence[str]` — Role names for the user
@@ -548,7 +543,7 @@ client.users.update_roles(
-
client.users.get(...) -> GetUserResponse +
client.users.get(...) -> AsyncHttpResponse[GetUserResponse]
@@ -578,10 +573,9 @@ Get User associated with provided User id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.get( id="id", ) @@ -620,7 +614,7 @@ client.users.get(
-
client.users.delete(...) -> DeleteUserResponse +
client.users.delete(...) -> AsyncHttpResponse[DeleteUserResponse]
@@ -650,10 +644,9 @@ Delete user if they are not a collaborator in any resource and not part of any t from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.delete( id="id", tenant_name="tenantName", @@ -701,7 +694,7 @@ client.users.delete(
-
client.users.invite_user(...) -> InviteUserResponse +
client.users.invite_user(...) -> AsyncHttpResponse[InviteUserResponse]
@@ -731,10 +724,9 @@ Invite a user to the tenant from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.invite_user( accept_invite_client_url="/invite-accept", email="email", @@ -782,7 +774,7 @@ client.users.invite_user(
-
client.users.deactivate(...) -> DeactivateUserResponse +
client.users.deactivate(...) -> AsyncHttpResponse[DeactivateUserResponse]
@@ -812,10 +804,9 @@ Deactivate user associated with the provided email within the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.deactivate( email="email", ) @@ -862,7 +853,7 @@ client.users.deactivate(
-
client.users.activate(...) -> ActivateUserResponse +
client.users.activate(...) -> AsyncHttpResponse[ActivateUserResponse]
@@ -892,10 +883,9 @@ Activate user associated with the provided email within the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.activate( email="email", ) @@ -942,7 +932,7 @@ client.users.activate(
-
client.users.change_password(...) -> ChangePasswordResponse +
client.users.change_password(...) -> AsyncHttpResponse[ChangePasswordResponse]
@@ -972,10 +962,9 @@ Change password for the authenticated user. Requires clientId and loginId in the from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.change_password( login_id="loginId", new_password="newPassword", @@ -1032,7 +1021,7 @@ client.users.change_password(
-
client.users.get_resources(...) -> GetUserResourcesResponse +
client.users.get_resources(...) -> AsyncHttpResponse[GetUserResourcesResponse]
@@ -1062,10 +1051,9 @@ Get all resources associated with a user. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.get_resources( id="id", ) @@ -1104,7 +1092,7 @@ client.users.get_resources(
-
client.users.get_permissions(...) -> GetUserPermissionsResponse +
client.users.get_permissions(...) -> AsyncHttpResponse[GetUserPermissionsResponse]
@@ -1134,10 +1122,9 @@ Get all role bindings associated with a user, including team-inherited bindings. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.get_permissions( id="id", ) @@ -1176,7 +1163,7 @@ client.users.get_permissions(
-
client.users.get_teams(...) -> GetUserTeamsResponse +
client.users.get_teams(...) -> AsyncHttpResponse[GetUserTeamsResponse]
@@ -1206,10 +1193,9 @@ Get all teams associated with a user, including their role in each team. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.users.get_teams( id="id", ) @@ -1249,7 +1235,7 @@ client.users.get_teams(
## Teams -
client.teams.list(...) -> ListTeamsResponse +
client.teams.list(...) -> AsyncPager[Team, ListTeamsResponse]
@@ -1277,17 +1263,22 @@ Retrieve all teams associated with the authenticated user. If the user is a tena ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.teams import TeamsListRequestType client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.teams.list( +response = client.teams.list( limit=10, offset=0, - type="team", + type=TeamsListRequestType.TEAM, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -1339,7 +1330,7 @@ client.teams.list(
-
client.teams.create_or_update(...) -> GetTeamResponse +
client.teams.create_or_update(...) -> AsyncHttpResponse[GetTeamResponse]
@@ -1366,20 +1357,16 @@ Creates a new team or updates an existing team. It ensures that the team name is
```python -from truefoundry_sdk import TrueFoundry, TeamManifest +from truefoundry_sdk import TeamManifest, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.teams.create_or_update( manifest=TeamManifest( - type="team", name="name", - members=[ - "members" - ], + members=["members"], ), ) @@ -1425,7 +1412,7 @@ client.teams.create_or_update(
-
client.teams.get(...) -> GetTeamResponse +
client.teams.get(...) -> AsyncHttpResponse[GetTeamResponse]
@@ -1455,10 +1442,9 @@ Get Team associated with provided team id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.teams.get( id="id", ) @@ -1497,7 +1483,7 @@ client.teams.get(
-
client.teams.delete(...) -> DeleteTeamResponse +
client.teams.delete(...) -> AsyncHttpResponse[DeleteTeamResponse]
@@ -1527,10 +1513,9 @@ Deletes the Team associated with the provided Id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.teams.delete( id="id", ) @@ -1569,7 +1554,7 @@ client.teams.delete(
-
client.teams.get_permissions(...) -> GetTeamPermissionsResponse +
client.teams.get_permissions(...) -> AsyncHttpResponse[GetTeamPermissionsResponse]
@@ -1599,10 +1584,9 @@ Get all role bindings associated with a team. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.teams.get_permissions( id="id", ) @@ -1642,7 +1626,7 @@ client.teams.get_permissions(
## PersonalAccessTokens -
client.personal_access_tokens.list(...) -> ListPersonalAccessTokenResponse +
client.personal_access_tokens.list(...) -> AsyncPager[VirtualAccount, ListPersonalAccessTokenResponse]
@@ -1672,15 +1656,19 @@ List Personal Access Tokens created by the user in the current tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.personal_access_tokens.list( +response = client.personal_access_tokens.list( limit=10, offset=0, name_search_query="nameSearchQuery", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -1732,7 +1720,7 @@ client.personal_access_tokens.list(
-
client.personal_access_tokens.create(...) -> CreatePersonalAccessTokenResponse +
client.personal_access_tokens.create(...) -> AsyncHttpResponse[CreatePersonalAccessTokenResponse]
@@ -1762,10 +1750,9 @@ Create Personal Access Token from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.personal_access_tokens.create( name="name", ) @@ -1820,7 +1807,7 @@ client.personal_access_tokens.create(
-
client.personal_access_tokens.revoke_all(...) -> RevokeAllPersonalAccessTokenResponse +
client.personal_access_tokens.revoke_all(...) -> AsyncHttpResponse[RevokeAllPersonalAccessTokenResponse]
@@ -1850,10 +1837,9 @@ Revoke All Personal Access Tokens for the user with the given email from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.personal_access_tokens.revoke_all( email="email", ) @@ -1892,7 +1878,7 @@ client.personal_access_tokens.revoke_all(
-
client.personal_access_tokens.delete(...) -> DeletePersonalAccessTokenResponse +
client.personal_access_tokens.delete(...) -> AsyncHttpResponse[DeletePersonalAccessTokenResponse]
@@ -1922,10 +1908,9 @@ Delete Personal Access Token associated with the provided serviceAccountId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.personal_access_tokens.delete( id="id", ) @@ -1964,7 +1949,7 @@ client.personal_access_tokens.delete(
-
client.personal_access_tokens.get(...) -> GetOrCreatePersonalAccessTokenResponse +
client.personal_access_tokens.get(...) -> AsyncHttpResponse[GetOrCreatePersonalAccessTokenResponse]
@@ -1994,10 +1979,9 @@ Get an existing Personal Access Token by name, if it doesn't exist, it will crea from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.personal_access_tokens.get( name="name", ) @@ -2037,7 +2021,7 @@ client.personal_access_tokens.get(
## VirtualAccounts -
client.virtual_accounts.list(...) -> ListVirtualAccountResponse +
client.virtual_accounts.list(...) -> AsyncPager[VirtualAccount, ListVirtualAccountResponse]
@@ -2067,17 +2051,21 @@ List virtual accounts for the tenant. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.virtual_accounts.list( +response = client.virtual_accounts.list( limit=10, offset=0, name_search_query="nameSearchQuery", is_expired=True, filter="filter", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -2153,7 +2141,7 @@ client.virtual_accounts.list(
-
client.virtual_accounts.create_or_update(...) -> GetVirtualAccountResponse +
client.virtual_accounts.create_or_update(...) -> AsyncHttpResponse[GetVirtualAccountResponse]
@@ -2180,17 +2168,15 @@ Creates a new virtual account or updates an existing one based on the provided m
```python -from truefoundry_sdk import TrueFoundry, VirtualAccountManifest, Permissions +from truefoundry_sdk import Permissions, TrueFoundry, VirtualAccountManifest client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.create_or_update( manifest=VirtualAccountManifest( name="name", - type="virtual-account", permissions=[ Permissions( resource_fqn="resource_fqn", @@ -2243,7 +2229,7 @@ client.virtual_accounts.create_or_update(
-
client.virtual_accounts.get(...) -> GetVirtualAccountResponse +
client.virtual_accounts.get(...) -> AsyncHttpResponse[GetVirtualAccountResponse]
@@ -2273,10 +2259,9 @@ Get virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.get( id="id", ) @@ -2315,7 +2300,7 @@ client.virtual_accounts.get(
-
client.virtual_accounts.delete(...) -> DeleteVirtualAccountResponse +
client.virtual_accounts.delete(...) -> AsyncHttpResponse[DeleteVirtualAccountResponse]
@@ -2345,10 +2330,9 @@ Delete a virtual account associated with the provided virtual account id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.delete( id="id", ) @@ -2387,7 +2371,7 @@ client.virtual_accounts.delete(
-
client.virtual_accounts.get_token(...) -> GetTokenForVirtualAccountResponse +
client.virtual_accounts.get_token(...) -> AsyncHttpResponse[GetTokenForVirtualAccountResponse]
@@ -2417,10 +2401,9 @@ Get token for a virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.get_token( id="id", ) @@ -2459,7 +2442,7 @@ client.virtual_accounts.get_token(
-
client.virtual_accounts.sync_to_secret_store(...) -> SyncVirtualAccountTokenResponse +
client.virtual_accounts.sync_to_secret_store(...) -> AsyncHttpResponse[SyncVirtualAccountTokenResponse]
@@ -2489,10 +2472,9 @@ Syncs the virtual account token to the configured secret store. Returns the upda from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.sync_to_secret_store( id="id", ) @@ -2531,7 +2513,7 @@ client.virtual_accounts.sync_to_secret_store(
-
client.virtual_accounts.regenerate_token(...) -> GetTokenForVirtualAccountResponse +
client.virtual_accounts.regenerate_token(...) -> AsyncHttpResponse[GetTokenForVirtualAccountResponse]
@@ -2561,13 +2543,12 @@ Regenerate token for a virtual account by id. The old token will remain valid fo from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.regenerate_token( id="id", - grace_period_in_days=30, + grace_period_in_days=30.0, ) ``` @@ -2612,7 +2593,7 @@ client.virtual_accounts.regenerate_token(
-
client.virtual_accounts.delete_jwt(...) +
client.virtual_accounts.delete_jwt(...) -> AsyncHttpResponse[None]
@@ -2642,10 +2623,9 @@ Delete a JWT for a virtual account by id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.virtual_accounts.delete_jwt( id="id", jwt_id="jwtId", @@ -2694,7 +2674,7 @@ client.virtual_accounts.delete_jwt(
## Clusters -
client.clusters.list(...) -> ListClustersResponse +
client.clusters.list(...) -> AsyncPager[Cluster, ListClustersResponse]
@@ -2724,14 +2704,18 @@ Retrieves a list of all latest Clusters. Pagination is available based on query from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.clusters.list( +response = client.clusters.list( limit=10, offset=0, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -2775,7 +2759,7 @@ client.clusters.list(
-
client.clusters.create_or_update(...) -> GetClusterResponse +
client.clusters.create_or_update(...) -> AsyncHttpResponse[GetClusterResponse]
@@ -2802,21 +2786,22 @@ Create or Update cluster with provided manifest
```python -from truefoundry_sdk import TrueFoundry, ClusterManifest, Collaborator +from truefoundry_sdk import ( + ClusterManifest, + ClusterManifestClusterType, + Collaborator, + TrueFoundry, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.clusters.create_or_update( manifest=ClusterManifest( - type="cluster", name="name", - cluster_type="aws-eks", - environment_names=[ - "environment_names" - ], + cluster_type=ClusterManifestClusterType.AWS_EKS, + environment_names=["environment_names"], collaborators=[ Collaborator( subject="subject", @@ -2868,7 +2853,7 @@ client.clusters.create_or_update(
-
client.clusters.get(...) -> GetClusterResponse +
client.clusters.get(...) -> AsyncHttpResponse[GetClusterResponse]
@@ -2898,10 +2883,9 @@ Get cluster associated with provided id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.clusters.get( id="id", ) @@ -2940,7 +2924,7 @@ client.clusters.get(
-
client.clusters.delete(...) -> ClustersDeleteResponse +
client.clusters.delete(...) -> AsyncHttpResponse[ClustersDeleteResponse]
@@ -2970,10 +2954,9 @@ Delete cluster associated with provided cluster id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.clusters.delete( id="id", ) @@ -3012,7 +2995,7 @@ client.clusters.delete(
-
client.clusters.get_addons(...) -> ListClusterAddonsResponse +
client.clusters.get_addons(...) -> AsyncHttpResponse[ListClusterAddonsResponse]
@@ -3042,10 +3025,9 @@ List addons for the provided cluster. Pagination is available based on query par from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.clusters.get_addons( id="id", limit=10, @@ -3102,7 +3084,7 @@ client.clusters.get_addons(
-
client.clusters.is_connected(...) -> IsClusterConnectedResponse +
client.clusters.is_connected(...) -> AsyncHttpResponse[IsClusterConnectedResponse]
@@ -3132,10 +3114,9 @@ Get the status of provided cluster from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.clusters.is_connected( id="id", ) @@ -3175,7 +3156,7 @@ client.clusters.is_connected(
## Applications -
client.applications.list(...) -> ListApplicationsResponse +
client.applications.list(...) -> AsyncPager[Application, ListApplicationsResponse]
@@ -3203,13 +3184,16 @@ Retrieves a list of all latest applications. Supports filtering by application I ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.applications import ( + ApplicationsListRequestDeviceTypeFilter, + ApplicationsListRequestLifecycleStage, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.applications.list( +response = client.applications.list( limit=10, offset=0, application_id="applicationId", @@ -3223,11 +3207,16 @@ client.applications.list( cluster_id="clusterId", application_set_id="applicationSetId", paused=True, - device_type_filter="cpu", + device_type_filter=ApplicationsListRequestDeviceTypeFilter.CPU, last_deployed_by_subjects="lastDeployedBySubjects", - lifecycle_stage="active", + lifecycle_stage=ApplicationsListRequestLifecycleStage.ACTIVE, is_recommendation_present_and_visible=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -3391,7 +3380,7 @@ client.applications.list(
-
client.applications.create_or_update(...) -> GetApplicationDeploymentResponse +
client.applications.create_or_update(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse]
@@ -3421,14 +3410,11 @@ Create a new Application Deployment based on the provided manifest. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.create_or_update( - manifest={ - "key": "value" - }, + manifest={"key": "value"}, ) ``` @@ -3521,7 +3507,7 @@ client.applications.create_or_update(
-
client.applications.get(...) -> GetApplicationResponse +
client.applications.get(...) -> AsyncHttpResponse[GetApplicationResponse]
@@ -3551,10 +3537,9 @@ Get Application associated with the provided application ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.get( id="id", ) @@ -3593,7 +3578,7 @@ client.applications.get(
-
client.applications.delete(...) -> DeleteApplicationResponse +
client.applications.delete(...) -> AsyncHttpResponse[DeleteApplicationResponse]
@@ -3623,10 +3608,9 @@ Delete Application associated with the provided application ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.delete( id="id", ) @@ -3665,7 +3649,7 @@ client.applications.delete(
-
client.applications.redeploy(...) -> GetApplicationDeploymentResponse +
client.applications.redeploy(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse]
@@ -3695,10 +3679,9 @@ Creates a new deployment with the same manifest as the given deployment. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.redeploy( id="id", deployment_id="deploymentId", @@ -3746,7 +3729,7 @@ client.applications.redeploy(
-
client.applications.scale_to_zero(...) +
client.applications.scale_to_zero(...) -> AsyncHttpResponse[None]
@@ -3776,10 +3759,9 @@ Pause a running application by scaling to 0 replicas from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.scale_to_zero( id="id", ) @@ -3818,7 +3800,7 @@ client.applications.scale_to_zero(
-
client.applications.scale_to_original(...) -> Deployment +
client.applications.scale_to_original(...) -> AsyncHttpResponse[Deployment]
@@ -3848,10 +3830,9 @@ Resume a paused application by scaling back to the original number of replicas from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.scale_to_original( id="id", ) @@ -3890,7 +3871,7 @@ client.applications.scale_to_original(
-
client.applications.cancel_deployment(...) -> ApplicationsCancelDeploymentResponse +
client.applications.cancel_deployment(...) -> AsyncHttpResponse[ApplicationsCancelDeploymentResponse]
@@ -3920,10 +3901,9 @@ Cancel an ongoing deployment associated with the provided application ID and dep from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.applications.cancel_deployment( id="id", deployment_id="deploymentId", @@ -3972,7 +3952,7 @@ client.applications.cancel_deployment(
## ApplicationVersions -
client.application_versions.list(...) -> ListApplicationDeploymentsResponse +
client.application_versions.list(...) -> AsyncPager[Deployment, ListApplicationDeploymentsResponse]
@@ -4002,17 +3982,21 @@ Fetch all deployments for a given application ID with optional filters such as d from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.application_versions.list( +response = client.application_versions.list( id="id", limit=10, offset=0, version="1", deployment_id="deployment123", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -4080,7 +4064,7 @@ client.application_versions.list(
-
client.application_versions.get(...) -> GetApplicationDeploymentResponse +
client.application_versions.get(...) -> AsyncHttpResponse[GetApplicationDeploymentResponse]
@@ -4110,10 +4094,9 @@ Get Deployment associated with the provided application ID and deployment ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.application_versions.get( id="id", deployment_id="deploymentId", @@ -4162,7 +4145,7 @@ client.application_versions.get(
## Jobs -
client.jobs.list_runs(...) -> ListJobRunResponse +
client.jobs.list_runs(...) -> AsyncPager[JobRun, ListJobRunResponse]
@@ -4189,21 +4172,25 @@ List Job Runs for provided Job Id. Filter the data based on parameters passed in
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import JobRunsSortBy, SortDirection, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.jobs.list_runs( +response = client.jobs.list_runs( job_id="jobId", limit=10, offset=0, search_prefix="searchPrefix", - sort_by="startTime", - order="asc", + sort_by=JobRunsSortBy.START_TIME, + order=SortDirection.ASC, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -4303,7 +4290,7 @@ client.jobs.list_runs(
-
client.jobs.get_run(...) -> GetJobRunResponse +
client.jobs.get_run(...) -> AsyncHttpResponse[GetJobRunResponse]
@@ -4333,10 +4320,9 @@ Get Job Run for provided jobRunName and jobId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.jobs.get_run( job_id="jobId", job_run_name="jobRunName", @@ -4384,7 +4370,7 @@ client.jobs.get_run(
-
client.jobs.delete_run(...) -> DeleteJobRunResponse +
client.jobs.delete_run(...) -> AsyncHttpResponse[DeleteJobRunResponse]
@@ -4414,10 +4400,9 @@ Delete Job Run for provided jobRunName and jobId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.jobs.delete_run( job_id="jobId", job_run_name="jobRunName", @@ -4465,7 +4450,7 @@ client.jobs.delete_run(
-
client.jobs.trigger(...) -> TriggerJobRunResponse +
client.jobs.trigger(...) -> AsyncHttpResponse[TriggerJobRunResponse]
@@ -4495,10 +4480,9 @@ Trigger Job for provided deploymentId or applicationId from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.jobs.trigger() ``` @@ -4559,7 +4543,7 @@ client.jobs.trigger()
-
client.jobs.terminate(...) -> TerminateJobResponse +
client.jobs.terminate(...) -> AsyncHttpResponse[TerminateJobResponse]
@@ -4589,10 +4573,9 @@ Terminate Job for provided deploymentId and jobRunName from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.jobs.terminate( deployment_id="deploymentId", job_run_name="jobRunName", @@ -4641,7 +4624,7 @@ client.jobs.terminate(
## Environments -
client.environments.list(...) -> ListEnvironmentsResponse +
client.environments.list(...) -> AsyncPager[Environment, ListEnvironmentsResponse]
@@ -4671,14 +4654,18 @@ List environments, if no environments are found, default environments are create from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.environments.list( +response = client.environments.list( limit=10, offset=0, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -4722,7 +4709,7 @@ client.environments.list(
-
client.environments.create_or_update(...) -> GetEnvironmentResponse +
client.environments.create_or_update(...) -> AsyncHttpResponse[GetEnvironmentResponse]
@@ -4749,20 +4736,23 @@ Creates a new Environment or updates an existing Environment.
```python -from truefoundry_sdk import TrueFoundry, EnvironmentManifest, EnvironmentColor +from truefoundry_sdk import ( + EnvironmentColor, + EnvironmentManifest, + EnvironmentOptimizeFor, + TrueFoundry, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.environments.create_or_update( manifest=EnvironmentManifest( - type="environment", name="name", color=EnvironmentColor(), is_production=True, - optimize_for="COST", + optimize_for=EnvironmentOptimizeFor.COST, ), ) @@ -4808,7 +4798,7 @@ client.environments.create_or_update(
-
client.environments.get(...) -> GetEnvironmentResponse +
client.environments.get(...) -> AsyncHttpResponse[GetEnvironmentResponse]
@@ -4838,10 +4828,9 @@ Get Environment associated with the provided id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.environments.get( id="id", ) @@ -4880,7 +4869,7 @@ client.environments.get(
-
client.environments.delete(...) -> bool +
client.environments.delete(...) -> AsyncHttpResponse[bool]
@@ -4910,10 +4899,9 @@ Delete Environment associated with the provided id. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.environments.delete( id="id", ) @@ -4953,7 +4941,7 @@ client.environments.delete(
## Workspaces -
client.workspaces.list(...) -> ListWorkspacesResponse +
client.workspaces.list(...) -> AsyncPager[Workspace, ListWorkspacesResponse]
@@ -4983,11 +4971,10 @@ List workspaces associated with the user. Optional filters include clusterId, fq from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.workspaces.list( +response = client.workspaces.list( limit=10, offset=0, cluster_id="clusterId", @@ -4995,6 +4982,11 @@ client.workspaces.list( fqn="fqn", include_cluster=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -5070,7 +5062,7 @@ client.workspaces.list(
-
client.workspaces.create_or_update(...) -> GetWorkspaceResponse +
client.workspaces.create_or_update(...) -> AsyncHttpResponse[GetWorkspaceResponse]
@@ -5100,13 +5092,11 @@ Creates a new workspace or updates an existing one based on the provided manifes from truefoundry_sdk import TrueFoundry, WorkspaceManifest client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.workspaces.create_or_update( manifest=WorkspaceManifest( - type="workspace", cluster_fqn="cluster_fqn", name="name", ), @@ -5154,7 +5144,7 @@ client.workspaces.create_or_update(
-
client.workspaces.search(...) -> ListWorkspacesResponse +
client.workspaces.search(...) -> AsyncPager[Workspace, ListWorkspacesResponse]
@@ -5184,16 +5174,20 @@ List workspaces the user can read with optional structured `filter` (name, id, e from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.workspaces.search( +response = client.workspaces.search( limit=10, offset=0, filter="filter", include_cluster=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -5253,7 +5247,7 @@ client.workspaces.search(
-
client.workspaces.get(...) -> GetWorkspaceResponse +
client.workspaces.get(...) -> AsyncHttpResponse[GetWorkspaceResponse]
@@ -5283,10 +5277,9 @@ Get workspace associated with provided workspace id from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.workspaces.get( id="id", ) @@ -5325,7 +5318,7 @@ client.workspaces.get(
-
client.workspaces.delete(...) -> WorkspacesDeleteResponse +
client.workspaces.delete(...) -> AsyncHttpResponse[WorkspacesDeleteResponse]
@@ -5357,10 +5350,9 @@ Deletes the workspace with the given workspace ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.workspaces.delete( id="id", ) @@ -5400,7 +5392,7 @@ client.workspaces.delete(
## Secrets -
client.secrets.list(...) -> ListSecretsResponse +
client.secrets.list(...) -> AsyncPager[Secret, ListSecretsResponse]
@@ -5430,11 +5422,15 @@ List secrets associated with a user filtered with optional parameters passed in from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.secrets.list() +response = client.secrets.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -5466,7 +5462,7 @@ client.secrets.list()
-**secret_fqns:** `typing.Optional[typing.List[str]]` — Array of FQNs +**secret_fqns:** `typing.Optional[typing.Sequence[str]]` — Array of FQNs
@@ -5502,7 +5498,7 @@ client.secrets.list()
-
client.secrets.get(...) -> GetSecretResponse +
client.secrets.get(...) -> AsyncHttpResponse[GetSecretResponse]
@@ -5532,10 +5528,9 @@ Get Secret associated with provided id. The secret value is not returned if the from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secrets.get( id="id", ) @@ -5574,7 +5569,7 @@ client.secrets.get(
-
client.secrets.delete(...) -> float +
client.secrets.delete(...) -> AsyncHttpResponse[float]
@@ -5604,10 +5599,9 @@ Deletes a secret and its versions along with its values. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secrets.delete( id="id", force_delete=True, @@ -5656,7 +5650,7 @@ client.secrets.delete(
## SecretGroups -
client.secret_groups.list(...) -> ListSecretGroupResponse +
client.secret_groups.list(...) -> AsyncPager[SecretGroup, ListSecretGroupResponse]
@@ -5686,16 +5680,20 @@ List the secret groups associated with a user along with the associated secrets from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.secret_groups.list( +response = client.secret_groups.list( limit=10, offset=0, fqn="fqn", search="search", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -5755,7 +5753,7 @@ client.secret_groups.list(
-
client.secret_groups.create(...) -> GetSecretGroupResponse +
client.secret_groups.create(...) -> AsyncHttpResponse[GetSecretGroupResponse]
@@ -5782,13 +5780,12 @@ Creates a secret group with secrets in it. A secret version for each of the crea
```python -from truefoundry_sdk import TrueFoundry, SecretInput +from truefoundry_sdk import SecretInput, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secret_groups.create( name="name", integration_id="integrationId", @@ -5830,7 +5827,7 @@ client.secret_groups.create(
-**secrets:** `typing.List[SecretInput]` — The secrets to be associated with the secret group +**secrets:** `typing.Sequence[SecretInput]` — The secrets to be associated with the secret group
@@ -5850,7 +5847,7 @@ client.secret_groups.create(
-
client.secret_groups.create_or_update(...) -> GetSecretGroupResponse +
client.secret_groups.create_or_update(...) -> AsyncHttpResponse[GetSecretGroupResponse]
@@ -5877,16 +5874,14 @@ Creates a new secret group or updates an existing one based on the provided mani
```python -from truefoundry_sdk import TrueFoundry, SecretGroupManifest, Collaborator +from truefoundry_sdk import Collaborator, SecretGroupManifest, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secret_groups.create_or_update( manifest=SecretGroupManifest( - type="secret-group", name="name", integration_fqn="integration_fqn", collaborators=[ @@ -5940,7 +5935,7 @@ client.secret_groups.create_or_update(
-
client.secret_groups.get(...) -> GetSecretGroupResponse +
client.secret_groups.get(...) -> AsyncHttpResponse[GetSecretGroupResponse]
@@ -5970,10 +5965,9 @@ Get Secret Group by id. This method does not return the secret values of the
-
client.secret_groups.update(...) -> GetSecretGroupResponse +
client.secret_groups.update(...) -> AsyncHttpResponse[GetSecretGroupResponse]
@@ -6042,10 +6036,9 @@ Updates the secrets in a secret group with new values. A new secret version is c from truefoundry_sdk import TrueFoundry, UpdateSecretInput client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secret_groups.update( id="id", secrets=[ @@ -6077,7 +6070,7 @@ client.secret_groups.update(
-**secrets:** `typing.List[UpdateSecretInput]` +**secrets:** `typing.Sequence[UpdateSecretInput]`
@@ -6097,7 +6090,7 @@ client.secret_groups.update(
-
client.secret_groups.delete(...) -> DeleteSecretGroupResponse +
client.secret_groups.delete(...) -> AsyncHttpResponse[DeleteSecretGroupResponse]
@@ -6127,10 +6120,9 @@ Deletes the secret group, its associated secrets and secret versions of those se from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.secret_groups.delete( id="id", ) @@ -6170,7 +6162,7 @@ client.secret_groups.delete(
## Events -
client.events.get(...) -> GetEventsResponse +
client.events.get(...) -> AsyncHttpResponse[GetEventsResponse]
@@ -6200,10 +6192,9 @@ Get Events for Pod, Job Run, Application. The events are sourced from Kubernetes from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.events.get( start_ts="startTs", end_ts="endTs", @@ -6287,7 +6278,7 @@ client.events.get(
## Alerts -
client.alerts.list(...) -> GetAlertsResponse +
client.alerts.list(...) -> AsyncHttpResponse[GetAlertsResponse]
@@ -6314,19 +6305,18 @@ Get alerts for a given application or cluster filtered by start and end timestam
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import AlertStatus, TrueFoundry client = TrueFoundry( - api_key="", + 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="firing", + alert_status=AlertStatus.FIRING, ) ``` @@ -6396,7 +6386,7 @@ client.alerts.list(
## Logs -
client.logs.get(...) -> GetLogsResponse +
client.logs.get(...) -> AsyncHttpResponse[GetLogsResponse]
@@ -6423,18 +6413,22 @@ Fetch logs for various workload components, including Services, Jobs, Workflows,
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import ( + LogsSearchFilterType, + LogsSearchOperatorType, + LogsSortingDirection, + TrueFoundry, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.logs.get( start_ts=1000000, end_ts=1000000, limit=1, - direction="asc", + direction=LogsSortingDirection.ASC, num_logs_to_ignore=1, application_id="applicationId", application_fqn="applicationFqn", @@ -6445,8 +6439,8 @@ client.logs.get( pod_names_regex="podNamesRegex", search_filters="searchFilters", search_string="searchString", - search_type="regex", - search_operator="equal", + search_type=LogsSearchFilterType.REGEX, + search_operator=LogsSearchOperatorType.EQUAL, ) ``` @@ -6612,7 +6606,7 @@ client.logs.get(
## MlRepos -
client.ml_repos.create_or_update(...) -> GetMlRepoResponse +
client.ml_repos.create_or_update(...) -> AsyncHttpResponse[GetMlRepoResponse]
@@ -6639,16 +6633,14 @@ Creates or updates an MLRepo entity based on the provided manifest.
```python -from truefoundry_sdk import TrueFoundry, MlRepoManifest, Collaborator +from truefoundry_sdk import Collaborator, MlRepoManifest, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.ml_repos.create_or_update( manifest=MlRepoManifest( - type="ml-repo", name="name", storage_integration_fqn="storage_integration_fqn", collaborators=[ @@ -6702,7 +6694,7 @@ client.ml_repos.create_or_update(
-
client.ml_repos.get(...) -> GetMlRepoResponse +
client.ml_repos.get(...) -> AsyncHttpResponse[GetMlRepoResponse]
@@ -6732,10 +6724,9 @@ Get an ML Repo by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.ml_repos.get( id="id", ) @@ -6774,7 +6765,7 @@ client.ml_repos.get(
-
client.ml_repos.delete(...) -> EmptyResponse +
client.ml_repos.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -6804,10 +6795,9 @@ Delete an ML Repo by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.ml_repos.delete( id="id", ) @@ -6846,7 +6836,7 @@ client.ml_repos.delete(
-
client.ml_repos.list(...) -> ListMlReposResponse +
client.ml_repos.list(...) -> AsyncPager[MlRepo, ListMlReposResponse]
@@ -6876,15 +6866,19 @@ List ML Repos with optional filtering by name. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.ml_repos.list( +response = client.ml_repos.list( name="name", limit=1, offset=1, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -6937,7 +6931,7 @@ client.ml_repos.list(
## Traces -
client.traces.query_spans(...) -> QuerySpansResponse +
client.traces.query_spans(...) -> AsyncPager[TraceSpan, QuerySpansResponse]
@@ -6953,13 +6947,17 @@ client.ml_repos.list( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.traces.query_spans( +response = client.traces.query_spans( start_time="startTime", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -6991,7 +6989,7 @@ client.traces.query_spans(
-**trace_ids:** `typing.Optional[typing.List[str]]` — Array of trace IDs to filter by +**trace_ids:** `typing.Optional[typing.Sequence[str]]` — Array of trace IDs to filter by
@@ -6999,7 +6997,7 @@ client.traces.query_spans(
-**span_ids:** `typing.Optional[typing.List[str]]` — Array of span IDs to filter by +**span_ids:** `typing.Optional[typing.Sequence[str]]` — Array of span IDs to filter by
@@ -7007,7 +7005,7 @@ client.traces.query_spans(
-**parent_span_ids:** `typing.Optional[typing.List[str]]` — Array of parent span IDs to filter by +**parent_span_ids:** `typing.Optional[typing.Sequence[str]]` — Array of parent span IDs to filter by
@@ -7015,7 +7013,7 @@ client.traces.query_spans(
-**created_by_subject_types:** `typing.Optional[typing.List[SubjectType]]` — Array of subject types to filter by +**created_by_subject_types:** `typing.Optional[typing.Sequence[SubjectType]]` — Array of subject types to filter by
@@ -7023,7 +7021,7 @@ client.traces.query_spans(
-**created_by_subject_slugs:** `typing.Optional[typing.List[str]]` — Array of subject slugs to filter by +**created_by_subject_slugs:** `typing.Optional[typing.Sequence[str]]` — Array of subject slugs to filter by
@@ -7031,7 +7029,7 @@ client.traces.query_spans(
-**application_names:** `typing.Optional[typing.List[str]]` — Array of application names to filter by +**application_names:** `typing.Optional[typing.Sequence[str]]` — Array of application names to filter by
@@ -7079,7 +7077,7 @@ client.traces.query_spans(
-**filters:** `typing.Optional[typing.List[QuerySpansRequestFiltersItem]]` — Array of filters +**filters:** `typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]]` — Array of filters
@@ -7108,7 +7106,7 @@ client.traces.query_spans(
## Artifacts -
client.artifacts.get(...) -> GetArtifactResponse +
client.artifacts.get(...) -> AsyncHttpResponse[GetArtifactResponse]
@@ -7138,10 +7136,9 @@ Get an artifact by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifacts.get( id="id", ) @@ -7180,7 +7177,7 @@ client.artifacts.get(
-
client.artifacts.delete(...) -> EmptyResponse +
client.artifacts.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -7210,10 +7207,9 @@ Delete an artifact by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifacts.delete( id="id", ) @@ -7252,7 +7248,7 @@ client.artifacts.delete(
-
client.artifacts.list(...) -> ListArtifactsResponse +
client.artifacts.list(...) -> AsyncPager[Artifact, ListArtifactsResponse]
@@ -7282,11 +7278,10 @@ List artifacts with optional filtering by FQN, ML Repo, name, or run ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.artifacts.list( +response = client.artifacts.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", @@ -7295,6 +7290,11 @@ client.artifacts.list( run_id="run_id", include_empty_artifacts=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -7378,7 +7378,7 @@ client.artifacts.list(
-
client.artifacts.create_or_update(...) -> GetArtifactVersionResponse +
client.artifacts.create_or_update(...) -> AsyncHttpResponse[GetArtifactVersionResponse]
@@ -7405,24 +7405,22 @@ Create or update an artifact version.
```python -from truefoundry_sdk import TrueFoundry, ArtifactManifest, TrueFoundryManagedSource +from truefoundry_sdk import ( + ArtifactManifest, + TrueFoundry, + TrueFoundryManagedSource, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifacts.create_or_update( manifest=ArtifactManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="artifact-version", - source=TrueFoundryManagedSource( - type="truefoundry", - ), + source=TrueFoundryManagedSource(), ), ) @@ -7461,7 +7459,7 @@ client.artifacts.create_or_update(
## Prompts -
client.prompts.get(...) -> GetPromptResponse +
client.prompts.get(...) -> AsyncHttpResponse[GetPromptResponse]
@@ -7491,10 +7489,9 @@ Get a prompt by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompts.get( id="id", ) @@ -7533,7 +7530,7 @@ client.prompts.get(
-
client.prompts.delete(...) -> EmptyResponse +
client.prompts.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -7563,10 +7560,9 @@ Delete a prompt by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompts.delete( id="id", ) @@ -7605,7 +7601,7 @@ client.prompts.delete(
-
client.prompts.list(...) -> ListPromptsResponse +
client.prompts.list(...) -> AsyncPager[Prompt, ListPromptsResponse]
@@ -7635,11 +7631,10 @@ List prompts with optional filtering by FQN, ML Repo, or name. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.prompts.list( +response = client.prompts.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", @@ -7647,6 +7642,11 @@ client.prompts.list( limit=1, include_empty_prompts=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -7722,7 +7722,7 @@ client.prompts.list(
-
client.prompts.create_or_update(...) -> GetPromptVersionResponse +
client.prompts.create_or_update(...) -> AsyncHttpResponse[GetPromptVersionResponse]
@@ -7749,24 +7749,19 @@ Create or update a prompt version.
```python -from truefoundry_sdk import TrueFoundry, ChatPromptManifest, SystemMessage +from truefoundry_sdk import ChatPromptManifest, SystemMessage, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompts.create_or_update( manifest=ChatPromptManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="chat_prompt", messages=[ SystemMessage( - role="system", content="content", ) ], @@ -7808,7 +7803,7 @@ client.prompts.create_or_update(
## Models -
client.models.get(...) -> GetModelResponse +
client.models.get(...) -> AsyncHttpResponse[GetModelResponse]
@@ -7838,10 +7833,9 @@ Get a model by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.models.get( id="id", ) @@ -7880,7 +7874,7 @@ client.models.get(
-
client.models.delete(...) -> EmptyResponse +
client.models.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -7910,10 +7904,9 @@ Delete a model by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.models.delete( id="id", ) @@ -7952,7 +7945,7 @@ client.models.delete(
-
client.models.list(...) -> ListModelsResponse +
client.models.list(...) -> AsyncPager[Model, ListModelsResponse]
@@ -7982,11 +7975,10 @@ List models with optional filtering by FQN, ML Repo, name, or run ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.models.list( +response = client.models.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", @@ -7995,6 +7987,11 @@ client.models.list( run_id="run_id", include_empty_models=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -8078,7 +8075,7 @@ client.models.list(
-
client.models.create_or_update(...) -> GetModelVersionResponse +
client.models.create_or_update(...) -> AsyncHttpResponse[GetModelVersionResponse]
@@ -8105,24 +8102,18 @@ Create or update a model version.
```python -from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource +from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.models.create_or_update( manifest=ModelManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="model-version", - source=TrueFoundryManagedSource( - type="truefoundry", - ), + source=TrueFoundryManagedSource(), ), ) @@ -8161,7 +8152,7 @@ client.models.create_or_update(
## ArtifactVersions -
client.artifact_versions.apply_tags(...) -> EmptyResponse +
client.artifact_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse]
@@ -8191,15 +8182,12 @@ Apply tags to an artifact version. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.apply_tags( artifact_version_id="artifact_version_id", - tags=[ - "tags" - ], + tags=["tags"], ) ``` @@ -8224,7 +8212,7 @@ client.artifact_versions.apply_tags(
-**tags:** `typing.List[str]` — List of tags to apply to the artifact version +**tags:** `typing.Sequence[str]` — List of tags to apply to the artifact version
@@ -8252,7 +8240,7 @@ client.artifact_versions.apply_tags(
-
client.artifact_versions.get(...) -> GetArtifactVersionResponse +
client.artifact_versions.get(...) -> AsyncHttpResponse[GetArtifactVersionResponse]
@@ -8282,10 +8270,9 @@ Get an artifact version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.get( id="id", ) @@ -8324,7 +8311,7 @@ client.artifact_versions.get(
-
client.artifact_versions.delete(...) -> EmptyResponse +
client.artifact_versions.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -8354,10 +8341,9 @@ Delete an artifact version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.delete( id="id", ) @@ -8396,7 +8382,7 @@ client.artifact_versions.delete(
-
client.artifact_versions.list(...) -> ListArtifactVersionsResponse +
client.artifact_versions.list(...) -> AsyncPager[ArtifactVersion, ListArtifactVersionsResponse]
@@ -8426,11 +8412,10 @@ List artifact versions with optional filtering by tag, FQN, artifact ID, ML Repo from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.artifact_versions.list( +response = client.artifact_versions.list( tag="tag", fqn="fqn", artifact_id="artifact_id", @@ -8441,6 +8426,11 @@ client.artifact_versions.list( limit=1, include_internal_metadata=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -8556,7 +8546,7 @@ client.artifact_versions.list(
-
client.artifact_versions.get_signed_urls(...) -> GetSignedUrLsResponse +
client.artifact_versions.get_signed_urls(...) -> AsyncHttpResponse[GetSignedUrLsResponse]
@@ -8583,19 +8573,16 @@ Get pre-signed URLs for reading or writing files in an artifact version.
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import Operation, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.get_signed_urls( id="id", - paths=[ - "paths" - ], - operation="READ", + paths=["paths"], + operation=Operation.READ, ) ``` @@ -8612,7 +8599,23 @@ client.artifact_versions.get_signed_urls(
-**request:** `GetSignedUrLsRequest` +**id:** `str` — ID of the artifact version to get signed URLs for + +
+
+ +
+
+ +**paths:** `typing.Sequence[str]` — List of relative file paths within the artifact version to get signed URLs for + +
+
+ +
+
+ +**operation:** `Operation` — Operation type for the signed URL (e.g., 'READ' or 'WRITE')
@@ -8632,7 +8635,7 @@ client.artifact_versions.get_signed_urls(
-
client.artifact_versions.create_multi_part_upload(...) -> MultiPartUploadResponse +
client.artifact_versions.create_multi_part_upload(...) -> AsyncHttpResponse[MultiPartUploadResponse]
@@ -8662,10 +8665,9 @@ Create a multipart upload for large files in an artifact version. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.create_multi_part_upload( id="id", path="path", @@ -8686,7 +8688,23 @@ client.artifact_versions.create_multi_part_upload(
-**request:** `CreateMultiPartUploadRequest` +**id:** `str` — ID of the artifact version to upload files to + +
+
+ +
+
+ +**path:** `str` — Relative path within the artifact version where the file should be uploaded + +
+
+ +
+
+ +**num_parts:** `int` — Number of parts to split the upload into for multipart upload
@@ -8706,7 +8724,7 @@ client.artifact_versions.create_multi_part_upload(
-
client.artifact_versions.stage(...) -> StageArtifactResponse +
client.artifact_versions.stage(...) -> AsyncHttpResponse[StageArtifactResponse]
@@ -8733,24 +8751,18 @@ Stage an artifact version for upload, returning storage location and version ID.
```python -from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource +from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.stage( manifest=ModelManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="model-version", - source=TrueFoundryManagedSource( - type="truefoundry", - ), + source=TrueFoundryManagedSource(), ), ) @@ -8788,7 +8800,7 @@ client.artifact_versions.stage(
-
client.artifact_versions.list_files(...) -> ListFilesResponse +
client.artifact_versions.list_files(...) -> AsyncPager[FileInfo, ListFilesResponse]
@@ -8818,13 +8830,17 @@ List files and directories in an artifact version. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.artifact_versions.list_files( +response = client.artifact_versions.list_files( id="id", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -8840,7 +8856,31 @@ client.artifact_versions.list_files(
-**request:** `ListFilesRequest` +**id:** `str` — ID of the artifact version to list files from + +
+
+ +
+
+ +**path:** `typing.Optional[str]` — Relative path within the artifact version to list files from (defaults to root) + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of files/directories to return + +
+
+ +
+
+ +**page_token:** `typing.Optional[str]` — Token to retrieve the next page of results
@@ -8860,7 +8900,7 @@ client.artifact_versions.list_files(
-
client.artifact_versions.mark_stage_failure(...) -> EmptyResponse +
client.artifact_versions.mark_stage_failure(...) -> AsyncHttpResponse[EmptyResponse]
@@ -8890,10 +8930,9 @@ Mark a staged artifact version as failed. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.artifact_versions.mark_stage_failure( id="id", ) @@ -8933,7 +8972,7 @@ client.artifact_versions.mark_stage_failure(
## ModelVersions -
client.model_versions.apply_tags(...) -> EmptyResponse +
client.model_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse]
@@ -8963,15 +9002,12 @@ Apply tags to a model version. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.model_versions.apply_tags( model_version_id="model_version_id", - tags=[ - "tags" - ], + tags=["tags"], ) ``` @@ -8996,7 +9032,7 @@ client.model_versions.apply_tags(
-**tags:** `typing.List[str]` — List of tags to apply to the model version +**tags:** `typing.Sequence[str]` — List of tags to apply to the model version
@@ -9024,7 +9060,7 @@ client.model_versions.apply_tags(
-
client.model_versions.get(...) -> GetModelVersionResponse +
client.model_versions.get(...) -> AsyncHttpResponse[GetModelVersionResponse]
@@ -9054,10 +9090,9 @@ Get a model version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.model_versions.get( id="id", ) @@ -9096,7 +9131,7 @@ client.model_versions.get(
-
client.model_versions.delete(...) -> EmptyResponse +
client.model_versions.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -9126,10 +9161,9 @@ Delete a model version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.model_versions.delete( id="id", ) @@ -9168,7 +9202,7 @@ client.model_versions.delete(
-
client.model_versions.list(...) -> ListModelVersionsResponse +
client.model_versions.list(...) -> AsyncPager[ModelVersion, ListModelVersionsResponse]
@@ -9198,11 +9232,10 @@ List model versions with optional filtering by tag, FQN, model ID, ML Repo, name from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.model_versions.list( +response = client.model_versions.list( tag="tag", fqn="fqn", model_id="model_id", @@ -9213,6 +9246,11 @@ client.model_versions.list( limit=1, include_internal_metadata=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -9329,7 +9367,7 @@ client.model_versions.list(
## PromptVersions -
client.prompt_versions.apply_tags(...) -> EmptyResponse +
client.prompt_versions.apply_tags(...) -> AsyncHttpResponse[EmptyResponse]
@@ -9359,15 +9397,12 @@ Apply tags to a prompt version. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompt_versions.apply_tags( prompt_version_id="prompt_version_id", - tags=[ - "tags" - ], + tags=["tags"], ) ``` @@ -9392,7 +9427,7 @@ client.prompt_versions.apply_tags(
-**tags:** `typing.List[str]` — List of tags to apply to the prompt version +**tags:** `typing.Sequence[str]` — List of tags to apply to the prompt version
@@ -9420,7 +9455,7 @@ client.prompt_versions.apply_tags(
-
client.prompt_versions.get(...) -> GetPromptVersionResponse +
client.prompt_versions.get(...) -> AsyncHttpResponse[GetPromptVersionResponse]
@@ -9450,10 +9485,9 @@ Get a prompt version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompt_versions.get( id="id", ) @@ -9492,7 +9526,7 @@ client.prompt_versions.get(
-
client.prompt_versions.delete(...) -> EmptyResponse +
client.prompt_versions.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -9522,10 +9556,9 @@ Delete a prompt version by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.prompt_versions.delete( id="id", ) @@ -9564,7 +9597,7 @@ client.prompt_versions.delete(
-
client.prompt_versions.list(...) -> ListPromptVersionsResponse +
client.prompt_versions.list(...) -> AsyncPager[PromptVersion, ListPromptVersionsResponse]
@@ -9594,11 +9627,10 @@ List prompt versions with optional filtering by tag, FQN, prompt ID, ML Repo, na from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.prompt_versions.list( +response = client.prompt_versions.list( tag="tag", fqn="fqn", prompt_id="prompt_id", @@ -9608,6 +9640,11 @@ client.prompt_versions.list( offset=1, limit=1, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -9700,7 +9737,7 @@ client.prompt_versions.list(
## AgentSkills -
client.agent_skills.get(...) -> GetAgentSkillResponse +
client.agent_skills.get(...) -> AsyncHttpResponse[GetAgentSkillResponse]
@@ -9730,10 +9767,9 @@ Get an agent skill artifact by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.agent_skills.get( agent_skill_id="agent_skill_id", ) @@ -9772,7 +9808,7 @@ client.agent_skills.get(
-
client.agent_skills.delete(...) -> EmptyResponse +
client.agent_skills.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -9802,10 +9838,9 @@ Delete an agent skill artifact by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.agent_skills.delete( agent_skill_id="agent_skill_id", ) @@ -9844,7 +9879,7 @@ client.agent_skills.delete(
-
client.agent_skills.list(...) -> ListAgentSkillsResponse +
client.agent_skills.list(...) -> AsyncPager[AgentSkill, ListAgentSkillsResponse]
@@ -9874,11 +9909,10 @@ List agent skills with optional filtering by FQN, ML Repo, or name. When present from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.agent_skills.list( +response = client.agent_skills.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", @@ -9886,6 +9920,11 @@ client.agent_skills.list( limit=1, include_empty_agent_skills=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -9961,7 +10000,7 @@ client.agent_skills.list(
-
client.agent_skills.create_or_update(...) -> GetAgentSkillVersionResponse +
client.agent_skills.create_or_update(...) -> AsyncHttpResponse[GetAgentSkillVersionResponse]
@@ -9988,23 +10027,22 @@ Create or update an agent skill version from a manifest.
```python -from truefoundry_sdk import TrueFoundry, AgentSkillManifest, AgentSkillSourceInline +from truefoundry_sdk import ( + AgentSkillManifest, + AgentSkillSourceInline, + TrueFoundry, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.agent_skills.create_or_update( manifest=AgentSkillManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="agent_skill", source=AgentSkillSourceInline( - type="inline", skill_md="skill_md", ), ), @@ -10045,7 +10083,7 @@ client.agent_skills.create_or_update(
## AgentSkillVersions -
client.agent_skill_versions.get(...) -> GetAgentSkillVersionResponse +
client.agent_skill_versions.get(...) -> AsyncHttpResponse[GetAgentSkillVersionResponse]
@@ -10061,10 +10099,9 @@ client.agent_skills.create_or_update( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.agent_skill_versions.get( agent_skill_version_id="agent_skill_version_id", ) @@ -10103,7 +10140,7 @@ client.agent_skill_versions.get(
-
client.agent_skill_versions.delete(...) -> EmptyResponse +
client.agent_skill_versions.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -10119,10 +10156,9 @@ client.agent_skill_versions.get( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.agent_skill_versions.delete( agent_skill_version_id="agent_skill_version_id", ) @@ -10161,7 +10197,7 @@ client.agent_skill_versions.delete(
-
client.agent_skill_versions.list(...) -> ListAgentSkillVersionsResponse +
client.agent_skill_versions.list(...) -> AsyncPager[AgentSkillVersion, ListAgentSkillVersionsResponse]
@@ -10191,11 +10227,10 @@ List agent skill versions. Each manifest has `source.type` `blob-storage` and `d from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.agent_skill_versions.list( +response = client.agent_skill_versions.list( fqn="fqn", agent_skill_id="agent_skill_id", ml_repo_id="ml_repo_id", @@ -10204,6 +10239,11 @@ client.agent_skill_versions.list( offset=1, limit=1, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -10288,7 +10328,7 @@ client.agent_skill_versions.list(
## DataDirectories -
client.data_directories.get(...) -> GetDataDirectoryResponse +
client.data_directories.get(...) -> AsyncHttpResponse[GetDataDirectoryResponse]
@@ -10318,10 +10358,9 @@ Get a data directory by its ID. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.get( id="id", ) @@ -10360,7 +10399,7 @@ client.data_directories.get(
-
client.data_directories.delete(...) -> EmptyResponse +
client.data_directories.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -10390,10 +10429,9 @@ Delete a data directory, optionally including its contents. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.delete( id="id", delete_contents=True, @@ -10441,7 +10479,7 @@ client.data_directories.delete(
-
client.data_directories.list(...) -> ListDataDirectoriesResponse +
client.data_directories.list(...) -> AsyncPager[DataDirectory, ListDataDirectoriesResponse]
@@ -10471,17 +10509,21 @@ List data directories with optional filtering by FQN, ML Repo, or name. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.data_directories.list( +response = client.data_directories.list( fqn="fqn", ml_repo_id="ml_repo_id", name="name", limit=1, offset=1, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -10549,7 +10591,7 @@ client.data_directories.list(
-
client.data_directories.create_or_update(...) -> GetDataDirectoryResponse +
client.data_directories.create_or_update(...) -> AsyncHttpResponse[GetDataDirectoryResponse]
@@ -10576,24 +10618,22 @@ Create or update a data directory.
```python -from truefoundry_sdk import TrueFoundry, DataDirectoryManifest, TrueFoundryManagedSource +from truefoundry_sdk import ( + DataDirectoryManifest, + TrueFoundry, + TrueFoundryManagedSource, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.create_or_update( manifest=DataDirectoryManifest( - type="data-dir", name="name", ml_repo="ml_repo", - metadata={ - "key": "value" - }, - source=TrueFoundryManagedSource( - type="truefoundry", - ), + metadata={"key": "value"}, + source=TrueFoundryManagedSource(), ), ) @@ -10631,7 +10671,7 @@ client.data_directories.create_or_update(
-
client.data_directories.list_files(...) -> ListFilesResponse +
client.data_directories.list_files(...) -> AsyncPager[FileInfo, ListFilesResponse]
@@ -10661,13 +10701,17 @@ List files and directories in a data directory. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.data_directories.list_files( +response = client.data_directories.list_files( id="id", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -10683,7 +10727,31 @@ client.data_directories.list_files(
-**request:** `ListFilesRequest` +**id:** `str` — ID of the artifact version to list files from + +
+
+ +
+
+ +**path:** `typing.Optional[str]` — Relative path within the artifact version to list files from (defaults to root) + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — Maximum number of files/directories to return + +
+
+ +
+
+ +**page_token:** `typing.Optional[str]` — Token to retrieve the next page of results
@@ -10703,7 +10771,7 @@ client.data_directories.list_files(
-
client.data_directories.delete_files(...) -> EmptyResponse +
client.data_directories.delete_files(...) -> AsyncHttpResponse[EmptyResponse]
@@ -10733,15 +10801,12 @@ Delete files from a data directory. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.delete_files( id="id", - paths=[ - "paths" - ], + paths=["paths"], ) ``` @@ -10766,7 +10831,7 @@ client.data_directories.delete_files(
-**paths:** `typing.List[str]` — List of relative file paths within the artifact version to delete +**paths:** `typing.Sequence[str]` — List of relative file paths within the artifact version to delete
@@ -10786,7 +10851,7 @@ client.data_directories.delete_files(
-
client.data_directories.get_signed_urls(...) -> GetSignedUrLsResponse +
client.data_directories.get_signed_urls(...) -> AsyncHttpResponse[GetSignedUrLsResponse]
@@ -10813,19 +10878,16 @@ Get pre-signed URLs for reading or writing files in a data directory.
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import Operation, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.get_signed_urls( id="id", - paths=[ - "paths" - ], - operation="READ", + paths=["paths"], + operation=Operation.READ, ) ``` @@ -10842,7 +10904,23 @@ client.data_directories.get_signed_urls(
-**request:** `GetSignedUrLsRequest` +**id:** `str` — ID of the artifact version to get signed URLs for + +
+
+ +
+
+ +**paths:** `typing.Sequence[str]` — List of relative file paths within the artifact version to get signed URLs for + +
+
+ +
+
+ +**operation:** `Operation` — Operation type for the signed URL (e.g., 'READ' or 'WRITE')
@@ -10862,7 +10940,7 @@ client.data_directories.get_signed_urls(
-
client.data_directories.create_multipart_upload(...) -> MultiPartUploadResponse +
client.data_directories.create_multipart_upload(...) -> AsyncHttpResponse[MultiPartUploadResponse]
@@ -10892,10 +10970,9 @@ Create a multipart upload for large files in a data directory. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.data_directories.create_multipart_upload( id="id", path="path", @@ -10916,7 +10993,23 @@ client.data_directories.create_multipart_upload(
-**request:** `CreateMultiPartUploadRequest` +**id:** `str` — ID of the artifact version to upload files to + +
+
+ +
+
+ +**path:** `str` — Relative path within the artifact version where the file should be uploaded + +
+
+ +
+
+ +**num_parts:** `int` — Number of parts to split the upload into for multipart upload
@@ -10937,7 +11030,7 @@ client.data_directories.create_multipart_upload(
## Internal Users -
client.internal.users.get_info() -> Session +
client.internal.users.get_info() -> AsyncHttpResponse[Session]
@@ -10967,10 +11060,9 @@ Get the user session details for the currently authenticated user from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.users.get_info() ``` @@ -11000,7 +11092,7 @@ client.internal.users.get_info()
## Internal AiGateway -
client.internal.ai_gateway.get_gateway_config(...) -> GatewayConfiguration +
client.internal.ai_gateway.get_gateway_config(...) -> AsyncHttpResponse[GatewayConfiguration]
@@ -11028,14 +11120,16 @@ Get Gateway configuration based on type for the tenant. ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.internal.ai_gateway import ( + AiGatewayGetGatewayConfigRequestType, +) client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.ai_gateway.get_gateway_config( - type="gateway-rate-limiting-config", + type=AiGatewayGetGatewayConfigRequestType.GATEWAY_RATE_LIMITING_CONFIG, ) ``` @@ -11073,7 +11167,7 @@ client.internal.ai_gateway.get_gateway_config(
## Internal Clusters -
client.internal.clusters.get_autoprovisioning_state(...) -> GetAutoProvisioningStateResponse +
client.internal.clusters.get_autoprovisioning_state(...) -> AsyncHttpResponse[GetAutoProvisioningStateResponse]
@@ -11103,10 +11197,9 @@ Get the auto provisioning status for the provided cluster from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.clusters.get_autoprovisioning_state( id="id", ) @@ -11146,7 +11239,7 @@ client.internal.clusters.get_autoprovisioning_state(
## Internal Deployments -
client.internal.deployments.get_deployment_statuses(...) -> typing.List[DeploymentStatus] +
client.internal.deployments.get_deployment_statuses(...) -> AsyncHttpResponse[typing.List[DeploymentStatus]]
@@ -11176,10 +11269,9 @@ This endpoint returns all statuses for a specific deployment in a given applicat from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.deployments.get_deployment_statuses( id="id", deployment_id="deploymentId", @@ -11227,7 +11319,7 @@ client.internal.deployments.get_deployment_statuses(
-
client.internal.deployments.get_builds(...) -> typing.List[DeploymentBuild] +
client.internal.deployments.get_builds(...) -> AsyncHttpResponse[typing.List[DeploymentBuild]]
@@ -11257,10 +11349,9 @@ This endpoint returns all build details associated with a specific deployment in from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.deployments.get_builds( id="id", deployment_id="deploymentId", @@ -11308,7 +11399,7 @@ client.internal.deployments.get_builds(
-
client.internal.deployments.get_code_upload_url(...) -> PresignedUrlObject +
client.internal.deployments.get_code_upload_url(...) -> AsyncHttpResponse[PresignedUrlObject]
@@ -11338,10 +11429,9 @@ Generate presigned URL to upload code for given serviceName and workspaceFqn from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.deployments.get_code_upload_url( service_name="serviceName", workspace_fqn="workspaceFqn", @@ -11389,7 +11479,7 @@ client.internal.deployments.get_code_upload_url(
-
client.internal.deployments.get_suggested_endpoint(...) -> GetSuggestedDeploymentEndpointResponse +
client.internal.deployments.get_suggested_endpoint(...) -> AsyncHttpResponse[GetSuggestedDeploymentEndpointResponse]
@@ -11416,15 +11506,14 @@ Generate deployment endpoint based on the provided query parameters.
```python -from truefoundry_sdk import TrueFoundry +from truefoundry_sdk import ApplicationType, TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.deployments.get_suggested_endpoint( - application_type="async-service", + application_type=ApplicationType.ASYNC_SERVICE, application_name="applicationName", workspace_id="workspaceId", base_domain="baseDomain", @@ -11507,7 +11596,7 @@ client.internal.deployments.get_suggested_endpoint(
## Internal Applications -
client.internal.applications.promote_rollout(...) +
client.internal.applications.promote_rollout(...) -> AsyncHttpResponse[None]
@@ -11537,10 +11626,9 @@ Promote an application rollout for canary and blue-green. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.applications.promote_rollout( id="id", full=True, @@ -11588,7 +11676,7 @@ client.internal.applications.promote_rollout(
-
client.internal.applications.get_pod_template_hash_to_deployment_version(...) -> typing.Dict[str, float] +
client.internal.applications.get_pod_template_hash_to_deployment_version(...) -> AsyncHttpResponse[typing.Dict[str, float]]
@@ -11618,10 +11706,9 @@ This endpoint fetches the pod template hash to deployment version map for a spec from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.applications.get_pod_template_hash_to_deployment_version( id="id", pod_template_hashes="podTemplateHashes", @@ -11670,7 +11757,7 @@ client.internal.applications.get_pod_template_hash_to_deployment_version(
## Internal Metrics -
client.internal.metrics.get_charts(...) -> GetChartsResponse +
client.internal.metrics.get_charts(...) -> AsyncHttpResponse[GetChartsResponse]
@@ -11698,18 +11785,18 @@ List charts for a given Application based on parameters passed in the query. ```python from truefoundry_sdk import TrueFoundry +from truefoundry_sdk.internal.metrics import MetricsGetChartsRequestFilterEntity client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.metrics.get_charts( workspace_id="workspaceId", application_id="applicationId", start_ts="startTs", end_ts="endTs", - filter_entity="application", + filter_entity=MetricsGetChartsRequestFilterEntity.APPLICATION, filter_query="filterQuery", ) @@ -11788,7 +11875,7 @@ client.internal.metrics.get_charts(
## Internal Vcs -
client.internal.vcs.get_repository_details(...) -> GitRepositoryExistsResponse +
client.internal.vcs.get_repository_details(...) -> AsyncHttpResponse[GitRepositoryExistsResponse]
@@ -11804,10 +11891,9 @@ client.internal.metrics.get_charts( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.vcs.get_repository_details( repo_url="repoURL", ) @@ -11854,7 +11940,7 @@ client.internal.vcs.get_repository_details(
-
client.internal.vcs.get_authenticated_url(...) -> GetAuthenticatedVcsurlResponse +
client.internal.vcs.get_authenticated_url(...) -> AsyncHttpResponse[GetAuthenticatedVcsurlResponse]
@@ -11870,10 +11956,9 @@ client.internal.vcs.get_repository_details( from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.vcs.get_authenticated_url( repo_url="repoURL", ) @@ -11913,7 +11998,7 @@ client.internal.vcs.get_authenticated_url(
## Internal DockerRegistries -
client.internal.docker_registries.create_repository(...) -> CreateDockerRepositoryResponse +
client.internal.docker_registries.create_repository(...) -> AsyncHttpResponse[CreateDockerRepositoryResponse]
@@ -11943,10 +12028,9 @@ Create a docker repository in the provided workspace. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.docker_registries.create_repository( fqn="fqn", application_name="applicationName", @@ -12003,7 +12087,7 @@ client.internal.docker_registries.create_repository(
-
client.internal.docker_registries.get_credentials(...) -> GetDockerRegistryCredentialsResponse +
client.internal.docker_registries.get_credentials(...) -> AsyncHttpResponse[GetDockerRegistryCredentialsResponse]
@@ -12033,10 +12117,9 @@ Get docker registry credentials for building and pushing an image. from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.docker_registries.get_credentials( fqn="fqn", cluster_id="clusterId", @@ -12085,7 +12168,7 @@ client.internal.docker_registries.get_credentials(
## Internal Workflows -
client.internal.workflows.execute_workflow(...) -> WorkflowsExecuteWorkflowResponse +
client.internal.workflows.execute_workflow(...) -> AsyncHttpResponse[WorkflowsExecuteWorkflowResponse]
@@ -12115,10 +12198,9 @@ Execute a workflow for the specified application from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.workflows.execute_workflow( application_id="applicationId", ) @@ -12174,7 +12256,7 @@ client.internal.workflows.execute_workflow(
## Internal BuildLogs -
client.internal.build_logs.get(...) -> LogsResponse +
client.internal.build_logs.get(...) -> AsyncHttpResponse[LogsResponse]
@@ -12204,10 +12286,9 @@ Get logs for a given pipeline run by its name, with optional filters and time ra from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.build_logs.get( pipeline_run_name="pipelineRunName", start_ts="1635467890123456789", @@ -12300,7 +12381,10 @@ client.internal.build_logs.get(
## Internal ArtifactVersions -
client.internal.artifact_versions.list(...) -> InternalListArtifactVersionsResponse +
client.internal.artifact_versions.list(...) -> AsyncPager[ + InternalListArtifactVersionsResponseDataItem, + InternalListArtifactVersionsResponse, +]
@@ -12330,11 +12414,10 @@ List artifact versions with internal metadata, optionally including model versio from truefoundry_sdk import TrueFoundry client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - -client.internal.artifact_versions.list( +response = client.internal.artifact_versions.list( tag="tag", fqn="fqn", artifact_id="artifact_id", @@ -12346,6 +12429,11 @@ client.internal.artifact_versions.list( include_internal_metadata=True, include_model_versions=True, ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -12470,7 +12558,7 @@ client.internal.artifact_versions.list(
## Internal Ml -
client.internal.ml.apply(...) -> ApplyMlEntityResponse +
client.internal.ml.apply(...) -> AsyncHttpResponse[ApplyMlEntityResponse]
@@ -12497,24 +12585,18 @@ Create or update an ML entity (model, prompt, artifact, or data directory).
```python -from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource +from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.ml.apply( manifest=ModelManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="model-version", - source=TrueFoundryManagedSource( - type="truefoundry", - ), + source=TrueFoundryManagedSource(), ), ) @@ -12552,7 +12634,7 @@ client.internal.ml.apply(
-
client.internal.ml.delete(...) -> EmptyResponse +
client.internal.ml.delete(...) -> AsyncHttpResponse[EmptyResponse]
@@ -12579,24 +12661,18 @@ Delete an ML entity (model, prompt, artifact, agent skill, data directory, or ML
```python -from truefoundry_sdk import TrueFoundry, ModelManifest, TrueFoundryManagedSource +from truefoundry_sdk import ModelManifest, TrueFoundry, TrueFoundryManagedSource client = TrueFoundry( - api_key="", + api_key="YOUR_API_KEY", base_url="https://yourhost.com/path/to/api", ) - client.internal.ml.delete( manifest=ModelManifest( name="name", - metadata={ - "key": "value" - }, + metadata={"key": "value"}, ml_repo="ml_repo", - type="model-version", - source=TrueFoundryManagedSource( - type="truefoundry", - ), + source=TrueFoundryManagedSource(), ), ) diff --git a/src/truefoundry_sdk/agent_skill_versions/raw_client.py b/src/truefoundry_sdk/agent_skill_versions/raw_client.py index b5376ab7..ba63cb55 100644 --- a/src/truefoundry_sdk/agent_skill_versions/raw_client.py +++ b/src/truefoundry_sdk/agent_skill_versions/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.unprocessable_entity_error import UnprocessableEntityError @@ -16,7 +15,6 @@ from ..types.empty_response import EmptyResponse from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse from ..types.list_agent_skill_versions_response import ListAgentSkillVersionsResponse -from pydantic import ValidationError class RawAgentSkillVersionsClient: @@ -68,10 +66,6 @@ def get( _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( @@ -119,10 +113,6 @@ def delete( _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 list( @@ -223,10 +213,6 @@ def list( _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) @@ -279,10 +265,6 @@ async def get( _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( @@ -330,10 +312,6 @@ async def delete( _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 list( @@ -437,8 +415,4 @@ async def _get_next(): _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/agent_skills/raw_client.py b/src/truefoundry_sdk/agent_skills/raw_client.py index 43e888e4..48545bf3 100644 --- a/src/truefoundry_sdk/agent_skills/raw_client.py +++ b/src/truefoundry_sdk/agent_skills/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -19,7 +18,6 @@ from ..types.get_agent_skill_response import GetAgentSkillResponse from ..types.get_agent_skill_version_response import GetAgentSkillVersionResponse from ..types.list_agent_skills_response import ListAgentSkillsResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -76,10 +74,6 @@ def get( _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( @@ -129,10 +123,6 @@ def delete( _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 list( @@ -227,10 +217,6 @@ def list( _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( @@ -290,10 +276,6 @@ def create_or_update( _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) @@ -348,10 +330,6 @@ async def get( _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( @@ -401,10 +379,6 @@ async def delete( _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 list( @@ -502,10 +476,6 @@ async def _get_next(): _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( @@ -565,8 +535,4 @@ async def create_or_update( _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/alerts/raw_client.py b/src/truefoundry_sdk/alerts/raw_client.py index 565af1a0..430342fe 100644 --- a/src/truefoundry_sdk/alerts/raw_client.py +++ b/src/truefoundry_sdk/alerts/raw_client.py @@ -6,7 +6,6 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -14,7 +13,6 @@ from ..types.alert_status import AlertStatus from ..types.get_alerts_response import GetAlertsResponse from ..types.http_error import HttpError -from pydantic import ValidationError class RawAlertsClient: @@ -106,10 +104,6 @@ def list( _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) @@ -202,8 +196,4 @@ async def list( _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/raw_client.py b/src/truefoundry_sdk/application_versions/raw_client.py index 6a544760..fb685a39 100644 --- a/src/truefoundry_sdk/application_versions/raw_client.py +++ b/src/truefoundry_sdk/application_versions/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.forbidden_error import ForbiddenError @@ -17,7 +16,6 @@ from ..types.get_application_deployment_response import GetApplicationDeploymentResponse from ..types.http_error import HttpError from ..types.list_application_deployments_response import ListApplicationDeploymentsResponse -from pydantic import ValidationError class RawApplicationVersionsClient: @@ -120,10 +118,6 @@ def list( _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( @@ -188,10 +182,6 @@ def get( _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) @@ -298,10 +288,6 @@ async def _get_next(): _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( @@ -366,8 +352,4 @@ async def get( _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/applications/client.py b/src/truefoundry_sdk/applications/client.py index 045dda83..cd2f97c9 100644 --- a/src/truefoundry_sdk/applications/client.py +++ b/src/truefoundry_sdk/applications/client.py @@ -183,7 +183,7 @@ def create_or_update( self, *, manifest: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -633,7 +633,7 @@ async def create_or_update( self, *, manifest: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, diff --git a/src/truefoundry_sdk/applications/raw_client.py b/src/truefoundry_sdk/applications/raw_client.py index dc16d414..49f9dd55 100644 --- a/src/truefoundry_sdk/applications/raw_client.py +++ b/src/truefoundry_sdk/applications/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -27,7 +26,6 @@ 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 pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -195,17 +193,13 @@ def list( _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: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -330,10 +324,6 @@ def create_or_update( _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( @@ -395,10 +385,6 @@ def get( _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( @@ -460,10 +446,6 @@ def delete( _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 redeploy( @@ -528,10 +510,6 @@ def redeploy( _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 scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[None]: @@ -605,10 +583,6 @@ def scale_to_zero(self, id: str, *, request_options: typing.Optional[RequestOpti _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 scale_to_original( @@ -681,10 +655,6 @@ def scale_to_original( _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 cancel_deployment( @@ -760,10 +730,6 @@ def cancel_deployment( _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) @@ -932,17 +898,13 @@ async def _get_next(): _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: typing.Dict[str, typing.Any], - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, force_deploy: typing.Optional[bool] = OMIT, trigger_on_deploy: typing.Optional[bool] = OMIT, workspace_id: typing.Optional[str] = OMIT, @@ -1067,10 +1029,6 @@ async def create_or_update( _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( @@ -1132,10 +1090,6 @@ async def get( _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( @@ -1197,10 +1151,6 @@ async def delete( _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 redeploy( @@ -1265,10 +1215,6 @@ async def redeploy( _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 scale_to_zero( @@ -1344,10 +1290,6 @@ async def scale_to_zero( _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 scale_to_original( @@ -1420,10 +1362,6 @@ async def scale_to_original( _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 cancel_deployment( @@ -1499,8 +1437,4 @@ async def cancel_deployment( _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/artifact_versions/client.py b/src/truefoundry_sdk/artifact_versions/client.py index 9e0967e7..2017edc1 100644 --- a/src/truefoundry_sdk/artifact_versions/client.py +++ b/src/truefoundry_sdk/artifact_versions/client.py @@ -42,7 +42,7 @@ def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ @@ -489,7 +489,7 @@ async def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ diff --git a/src/truefoundry_sdk/artifact_versions/raw_client.py b/src/truefoundry_sdk/artifact_versions/raw_client.py index cc700a77..c8157acd 100644 --- a/src/truefoundry_sdk/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/artifact_versions/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -24,7 +23,6 @@ from ..types.operation import Operation from ..types.stage_artifact_response import StageArtifactResponse from .types.stage_artifact_request_manifest import StageArtifactRequestManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -39,7 +37,7 @@ def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ @@ -102,10 +100,6 @@ def apply_tags( _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( @@ -155,10 +149,6 @@ def get( _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( @@ -208,10 +198,6 @@ def delete( _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 list( @@ -336,10 +322,6 @@ def list( _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_signed_urls( @@ -410,10 +392,6 @@ def get_signed_urls( _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_multi_part_upload( @@ -479,10 +457,6 @@ def create_multi_part_upload( _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 stage( @@ -542,10 +516,6 @@ def stage( _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 list_files( @@ -634,10 +604,6 @@ def list_files( _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 mark_stage_failure( @@ -695,10 +661,6 @@ def mark_stage_failure( _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) @@ -711,7 +673,7 @@ async def apply_tags( *, artifact_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ @@ -774,10 +736,6 @@ async def apply_tags( _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( @@ -827,10 +785,6 @@ async def get( _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( @@ -880,10 +834,6 @@ async def delete( _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 list( @@ -1011,10 +961,6 @@ async def _get_next(): _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_signed_urls( @@ -1085,10 +1031,6 @@ async def get_signed_urls( _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_multi_part_upload( @@ -1154,10 +1096,6 @@ async def create_multi_part_upload( _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 stage( @@ -1217,10 +1155,6 @@ async def stage( _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 list_files( @@ -1312,10 +1246,6 @@ async def _get_next(): _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 mark_stage_failure( @@ -1373,8 +1303,4 @@ async def mark_stage_failure( _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/artifacts/raw_client.py b/src/truefoundry_sdk/artifacts/raw_client.py index 179be032..94f02f9e 100644 --- a/src/truefoundry_sdk/artifacts/raw_client.py +++ b/src/truefoundry_sdk/artifacts/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -19,7 +18,6 @@ from ..types.get_artifact_response import GetArtifactResponse from ..types.get_artifact_version_response import GetArtifactVersionResponse from ..types.list_artifacts_response import ListArtifactsResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -76,10 +74,6 @@ def get( _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( @@ -129,10 +123,6 @@ def delete( _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 list( @@ -233,10 +223,6 @@ def list( _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( @@ -296,10 +282,6 @@ def create_or_update( _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) @@ -354,10 +336,6 @@ async def get( _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( @@ -407,10 +385,6 @@ async def delete( _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 list( @@ -514,10 +488,6 @@ async def _get_next(): _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( @@ -577,8 +547,4 @@ async def create_or_update( _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 840e7033..cf825ea8 100644 --- a/src/truefoundry_sdk/base_client.py +++ b/src/truefoundry_sdk/base_client.py @@ -8,7 +8,6 @@ import httpx from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from .core.logging import LogConfig, Logger from .core.request_options import RequestOptions from .raw_base_client import AsyncRawBaseTrueFoundry, RawBaseTrueFoundry from .types.true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest @@ -69,9 +68,6 @@ class BaseTrueFoundry: httpx_client : typing.Optional[httpx.Client] The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. - logging : typing.Optional[typing.Union[LogConfig, Logger]] - Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance. - Examples -------- from truefoundry_sdk import TrueFoundry @@ -91,7 +87,6 @@ def __init__( timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, 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 @@ -108,7 +103,6 @@ def __init__( if follow_redirects is not None else httpx.Client(timeout=_defaulted_timeout), timeout=_defaulted_timeout, - logging=logging, ) self._raw_client = RawBaseTrueFoundry(client_wrapper=self._client_wrapper) self._internal: typing.Optional[InternalClient] = None @@ -154,7 +148,7 @@ def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ @@ -481,9 +475,6 @@ class AsyncBaseTrueFoundry: httpx_client : typing.Optional[httpx.AsyncClient] The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration. - logging : typing.Optional[typing.Union[LogConfig, Logger]] - Configure logging for the SDK. Accepts a LogConfig dict with 'level' (debug/info/warn/error), 'logger' (custom logger implementation), and 'silent' (boolean, defaults to True) fields. You can also pass a pre-configured Logger instance. - Examples -------- from truefoundry_sdk import AsyncTrueFoundry @@ -503,7 +494,6 @@ def __init__( timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, 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 @@ -520,7 +510,6 @@ def __init__( if follow_redirects is not None else httpx.AsyncClient(timeout=_defaulted_timeout), timeout=_defaulted_timeout, - logging=logging, ) self._raw_client = AsyncRawBaseTrueFoundry(client_wrapper=self._client_wrapper) self._internal: typing.Optional[AsyncInternalClient] = None @@ -566,7 +555,7 @@ async def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> TrueFoundryApplyResponse: """ diff --git a/src/truefoundry_sdk/clusters/client.py b/src/truefoundry_sdk/clusters/client.py index 53113207..6a90b240 100644 --- a/src/truefoundry_sdk/clusters/client.py +++ b/src/truefoundry_sdk/clusters/client.py @@ -83,7 +83,7 @@ def create_or_update( self, *, manifest: ClusterManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetClusterResponse: """ @@ -357,7 +357,7 @@ async def create_or_update( self, *, manifest: ClusterManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetClusterResponse: """ diff --git a/src/truefoundry_sdk/clusters/raw_client.py b/src/truefoundry_sdk/clusters/raw_client.py index d17e47c1..d549625c 100644 --- a/src/truefoundry_sdk/clusters/raw_client.py +++ b/src/truefoundry_sdk/clusters/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -24,7 +23,6 @@ from ..types.list_cluster_addons_response import ListClusterAddonsResponse from ..types.list_clusters_response import ListClustersResponse from .types.clusters_delete_response import ClustersDeleteResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -102,17 +100,13 @@ def list( _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: ClusterManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetClusterResponse]: """ @@ -195,10 +189,6 @@ def create_or_update( _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( @@ -260,10 +250,6 @@ def get( _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( @@ -325,10 +311,6 @@ def delete( _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_addons( @@ -405,10 +387,6 @@ def get_addons( _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 is_connected( @@ -459,10 +437,6 @@ def is_connected( _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) @@ -541,17 +515,13 @@ async def _get_next(): _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: ClusterManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetClusterResponse]: """ @@ -634,10 +604,6 @@ async def create_or_update( _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( @@ -699,10 +665,6 @@ async def get( _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( @@ -764,10 +726,6 @@ async def delete( _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_addons( @@ -844,10 +802,6 @@ async def get_addons( _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 is_connected( @@ -898,8 +852,4 @@ async def is_connected( _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/core/__init__.py b/src/truefoundry_sdk/core/__init__.py index 2a2b56e7..3b5240ad 100644 --- a/src/truefoundry_sdk/core/__init__.py +++ b/src/truefoundry_sdk/core/__init__.py @@ -8,14 +8,13 @@ if typing.TYPE_CHECKING: from .api_error import ApiError from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper - from .datetime_utils import Rfc2822DateTime, parse_rfc2822_datetime, serialize_datetime + from .custom_pagination import AsyncCustomPager, SyncCustomPager + from .datetime_utils import serialize_datetime from .file import File, convert_file_dict_to_httpx_tuples, with_content_type from .http_client import AsyncHttpClient, HttpClient from .http_response import AsyncHttpResponse, HttpResponse from .jsonable_encoder import jsonable_encoder - from .logging import ConsoleLogger, ILogger, LogConfig, LogLevel, Logger, create_logger from .pagination import AsyncPager, SyncPager - from .parse_error import ParsingError from .pydantic_utilities import ( IS_PYDANTIC_V2, UniversalBaseModel, @@ -32,34 +31,27 @@ _dynamic_imports: typing.Dict[str, str] = { "ApiError": ".api_error", "AsyncClientWrapper": ".client_wrapper", + "AsyncCustomPager": ".custom_pagination", "AsyncHttpClient": ".http_client", "AsyncHttpResponse": ".http_response", "AsyncPager": ".pagination", "BaseClientWrapper": ".client_wrapper", - "ConsoleLogger": ".logging", "FieldMetadata": ".serialization", "File": ".file", "HttpClient": ".http_client", "HttpResponse": ".http_response", - "ILogger": ".logging", "IS_PYDANTIC_V2": ".pydantic_utilities", - "LogConfig": ".logging", - "LogLevel": ".logging", - "Logger": ".logging", - "ParsingError": ".parse_error", "RequestOptions": ".request_options", - "Rfc2822DateTime": ".datetime_utils", "SyncClientWrapper": ".client_wrapper", + "SyncCustomPager": ".custom_pagination", "SyncPager": ".pagination", "UniversalBaseModel": ".pydantic_utilities", "UniversalRootModel": ".pydantic_utilities", "convert_and_respect_annotation_metadata": ".serialization", "convert_file_dict_to_httpx_tuples": ".file", - "create_logger": ".logging", "encode_query": ".query_encoder", "jsonable_encoder": ".jsonable_encoder", "parse_obj_as": ".pydantic_utilities", - "parse_rfc2822_datetime": ".datetime_utils", "remove_none_from_dict": ".remove_none_from_dict", "serialize_datetime": ".datetime_utils", "universal_field_validator": ".pydantic_utilities", @@ -93,34 +85,27 @@ def __dir__(): __all__ = [ "ApiError", "AsyncClientWrapper", + "AsyncCustomPager", "AsyncHttpClient", "AsyncHttpResponse", "AsyncPager", "BaseClientWrapper", - "ConsoleLogger", "FieldMetadata", "File", "HttpClient", "HttpResponse", - "ILogger", "IS_PYDANTIC_V2", - "LogConfig", - "LogLevel", - "Logger", - "ParsingError", "RequestOptions", - "Rfc2822DateTime", "SyncClientWrapper", + "SyncCustomPager", "SyncPager", "UniversalBaseModel", "UniversalRootModel", "convert_and_respect_annotation_metadata", "convert_file_dict_to_httpx_tuples", - "create_logger", "encode_query", "jsonable_encoder", "parse_obj_as", - "parse_rfc2822_datetime", "remove_none_from_dict", "serialize_datetime", "universal_field_validator", diff --git a/src/truefoundry_sdk/core/client_wrapper.py b/src/truefoundry_sdk/core/client_wrapper.py index 9cc2e02f..18d1f335 100644 --- a/src/truefoundry_sdk/core/client_wrapper.py +++ b/src/truefoundry_sdk/core/client_wrapper.py @@ -4,7 +4,6 @@ import httpx from .http_client import AsyncHttpClient, HttpClient -from .logging import LogConfig, Logger class BaseClientWrapper: @@ -15,13 +14,11 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, - logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self._api_key = api_key self._headers = headers self._base_url = base_url self._timeout = timeout - self._logging = logging def get_headers(self) -> typing.Dict[str, str]: import platform @@ -62,16 +59,14 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, - logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, httpx_client: httpx.Client, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) + super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout) self.httpx_client = HttpClient( httpx_client=httpx_client, base_headers=self.get_headers, base_timeout=self.get_timeout, base_url=self.get_base_url, - logging_config=self._logging, ) @@ -83,11 +78,10 @@ def __init__( headers: typing.Optional[typing.Dict[str, str]] = None, base_url: str, timeout: typing.Optional[float] = None, - logging: typing.Optional[typing.Union[LogConfig, Logger]] = None, async_token: typing.Optional[typing.Callable[[], typing.Awaitable[str]]] = None, httpx_client: httpx.AsyncClient, ): - super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout, logging=logging) + super().__init__(api_key=api_key, headers=headers, base_url=base_url, timeout=timeout) self._async_token = async_token self.httpx_client = AsyncHttpClient( httpx_client=httpx_client, @@ -95,7 +89,6 @@ def __init__( base_timeout=self.get_timeout, base_url=self.get_base_url, async_base_headers=self.async_get_headers, - logging_config=self._logging, ) async def async_get_headers(self) -> typing.Dict[str, str]: diff --git a/src/truefoundry_sdk/core/custom_pagination.py b/src/truefoundry_sdk/core/custom_pagination.py new file mode 100644 index 00000000..5de2c7a8 --- /dev/null +++ b/src/truefoundry_sdk/core/custom_pagination.py @@ -0,0 +1,152 @@ +# This file was auto-generated by Fern from our API Definition. + +""" +Custom Pagination Support + +This file is designed to be modified by SDK users to implement their own +pagination logic. The generator will import SyncCustomPager and AsyncCustomPager +from this module when custom pagination is used. + +Users should: +1. Implement their custom pager (e.g., PayrocPager, MyCustomPager, etc.) +2. Create adapter classes (SyncCustomPager/AsyncCustomPager) that bridge + between the generated SDK code and their custom pager implementation +""" + +from __future__ import annotations + +from typing import Any, AsyncIterator, Generic, Iterator, TypeVar + +# Import the base utilities you'll need +# Adjust these imports based on your actual structure +try: + from .client_wrapper import AsyncClientWrapper, SyncClientWrapper +except ImportError: + # Fallback for type hints + AsyncClientWrapper = Any # type: ignore + SyncClientWrapper = Any # type: ignore + +TItem = TypeVar("TItem") +TResponse = TypeVar("TResponse") + + +class SyncCustomPager(Generic[TItem, TResponse]): + """ + Adapter for custom synchronous pagination. + + The generator will call this with: + SyncCustomPager(initial_response=response, client_wrapper=client_wrapper) + + Implement this class to extract pagination metadata from your response + and delegate to your custom pager implementation. + + Example implementation: + + class SyncCustomPager(Generic[TItem, TResponse]): + def __init__( + self, + *, + initial_response: TResponse, + client_wrapper: SyncClientWrapper, + ): + # Extract data and pagination metadata from response + data = initial_response.data # Adjust based on your response structure + links = initial_response.links + + # Initialize your custom pager + self._pager = MyCustomPager( + current_page=Page(data), + httpx_client=client_wrapper.httpx_client, + get_headers=client_wrapper.get_headers, + # ... other parameters + ) + + def __iter__(self): + return iter(self._pager) + + # Delegate other methods to your pager... + """ + + def __init__( + self, + *, + initial_response: TResponse, + client_wrapper: SyncClientWrapper, + ): + """ + Initialize the custom pager. + + Args: + initial_response: The parsed API response from the first request + client_wrapper: The client wrapper providing HTTP client and utilities + """ + raise NotImplementedError( + "SyncCustomPager must be implemented. " + "Please implement this class in core/custom_pagination.py to define your pagination logic. " + "See the class docstring for examples." + ) + + def __iter__(self) -> Iterator[TItem]: + """Iterate through all items across all pages.""" + raise NotImplementedError("Must implement __iter__ method") + + +class AsyncCustomPager(Generic[TItem, TResponse]): + """ + Adapter for custom asynchronous pagination. + + The generator will call this with: + AsyncCustomPager(initial_response=response, client_wrapper=client_wrapper) + + Implement this class to extract pagination metadata from your response + and delegate to your custom async pager implementation. + + Example implementation: + + class AsyncCustomPager(Generic[TItem, TResponse]): + def __init__( + self, + *, + initial_response: TResponse, + client_wrapper: AsyncClientWrapper, + ): + # Extract data and pagination metadata from response + data = initial_response.data # Adjust based on your response structure + links = initial_response.links + + # Initialize your custom async pager + self._pager = MyAsyncCustomPager( + current_page=Page(data), + httpx_client=client_wrapper.httpx_client, + get_headers=client_wrapper.get_headers, + # ... other parameters + ) + + async def __aiter__(self): + return self._pager.__aiter__() + + # Delegate other methods to your pager... + """ + + def __init__( + self, + *, + initial_response: TResponse, + client_wrapper: AsyncClientWrapper, + ): + """ + Initialize the custom async pager. + + Args: + initial_response: The parsed API response from the first request + client_wrapper: The client wrapper providing HTTP client and utilities + """ + raise NotImplementedError( + "AsyncCustomPager must be implemented. " + "Please implement this class in core/custom_pagination.py to define your pagination logic. " + "See the class docstring for examples." + ) + + async def __aiter__(self) -> AsyncIterator[TItem]: + """Asynchronously iterate through all items across all pages.""" + raise NotImplementedError("Must implement __aiter__ method") diff --git a/src/truefoundry_sdk/core/datetime_utils.py b/src/truefoundry_sdk/core/datetime_utils.py index a12b2ad0..7c9864a9 100644 --- a/src/truefoundry_sdk/core/datetime_utils.py +++ b/src/truefoundry_sdk/core/datetime_utils.py @@ -1,48 +1,6 @@ # This file was auto-generated by Fern from our API Definition. import datetime as dt -from email.utils import parsedate_to_datetime -from typing import Any - -import pydantic - -IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") - - -def parse_rfc2822_datetime(v: Any) -> dt.datetime: - """ - Parse an RFC 2822 datetime string (e.g., "Wed, 02 Oct 2002 13:00:00 GMT") - into a datetime object. If the value is already a datetime, return it as-is. - Falls back to ISO 8601 parsing if RFC 2822 parsing fails. - """ - if isinstance(v, dt.datetime): - return v - if isinstance(v, str): - try: - return parsedate_to_datetime(v) - except Exception: - pass - # Fallback to ISO 8601 parsing - return dt.datetime.fromisoformat(v.replace("Z", "+00:00")) - raise ValueError(f"Expected str or datetime, got {type(v)}") - - -class Rfc2822DateTime(dt.datetime): - """A datetime subclass that parses RFC 2822 date strings. - - On Pydantic V1, uses __get_validators__ for pre-validation. - On Pydantic V2, uses __get_pydantic_core_schema__ for BeforeValidator-style parsing. - """ - - @classmethod - def __get_validators__(cls): # type: ignore[no-untyped-def] - yield parse_rfc2822_datetime - - @classmethod - def __get_pydantic_core_schema__(cls, _source_type: Any, _handler: Any) -> Any: # type: ignore[override] - from pydantic_core import core_schema - - return core_schema.no_info_before_validator_function(parse_rfc2822_datetime, core_schema.datetime_schema()) def serialize_datetime(v: dt.datetime) -> str: diff --git a/src/truefoundry_sdk/core/http_client.py b/src/truefoundry_sdk/core/http_client.py index ee937589..7c6c936f 100644 --- a/src/truefoundry_sdk/core/http_client.py +++ b/src/truefoundry_sdk/core/http_client.py @@ -12,7 +12,6 @@ from .file import File, convert_file_dict_to_httpx_tuples from .force_multipart import FORCE_MULTIPART from .jsonable_encoder import jsonable_encoder -from .logging import LogConfig, Logger, create_logger from .query_encoder import encode_query from .remove_none_from_dict import remove_none_from_dict as remove_none_from_dict from .request_options import RequestOptions @@ -123,32 +122,6 @@ def _should_retry(response: httpx.Response) -> bool: return response.status_code >= 500 or response.status_code in retryable_400s -_SENSITIVE_HEADERS = frozenset( - { - "authorization", - "www-authenticate", - "x-api-key", - "api-key", - "apikey", - "x-api-token", - "x-auth-token", - "auth-token", - "cookie", - "set-cookie", - "proxy-authorization", - "proxy-authenticate", - "x-csrf-token", - "x-xsrf-token", - "x-session-token", - "x-access-token", - } -) - - -def _redact_headers(headers: typing.Dict[str, str]) -> typing.Dict[str, str]: - return {k: ("[REDACTED]" if k.lower() in _SENSITIVE_HEADERS else v) for k, v in headers.items()} - - def _build_url(base_url: str, path: typing.Optional[str]) -> str: """ Build a full URL by joining a base URL with a path. @@ -265,13 +238,11 @@ def __init__( base_timeout: typing.Callable[[], typing.Optional[float]], base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, - logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers self.httpx_client = httpx_client - self.logger = create_logger(logging_config) def get_base_url(self, maybe_base_url: typing.Optional[str]) -> str: base_url = maybe_base_url @@ -344,30 +315,18 @@ def request( ) ) - _request_url = _build_url(base_url, path) - _request_headers = jsonable_encoder( - remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } - ) - ) - - if self.logger.is_debug(): - self.logger.debug( - "Making HTTP request", - method=method, - url=_request_url, - headers=_redact_headers(_request_headers), - has_body=json_body is not None or data_body is not None, - ) - response = self.httpx_client.request( method=method, - url=_request_url, - headers=_request_headers, + url=_build_url(base_url, path), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self.base_headers(), + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), + } + ) + ), params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, @@ -394,24 +353,6 @@ def request( omit=omit, ) - if self.logger.is_debug(): - if 200 <= response.status_code < 400: - self.logger.debug( - "HTTP request succeeded", - method=method, - url=_request_url, - status_code=response.status_code, - ) - - if self.logger.is_error(): - if response.status_code >= 400: - self.logger.error( - "HTTP request failed with error status", - method=method, - url=_request_url, - status_code=response.status_code, - ) - return response @contextmanager @@ -477,29 +418,18 @@ def stream( ) ) - _request_url = _build_url(base_url, path) - _request_headers = jsonable_encoder( - remove_none_from_dict( - { - **self.base_headers(), - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } - ) - ) - - if self.logger.is_debug(): - self.logger.debug( - "Making streaming HTTP request", - method=method, - url=_request_url, - headers=_redact_headers(_request_headers), - ) - with self.httpx_client.stream( method=method, - url=_request_url, - headers=_request_headers, + url=_build_url(base_url, path), + headers=jsonable_encoder( + remove_none_from_dict( + { + **self.base_headers(), + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, @@ -519,14 +449,12 @@ def __init__( base_headers: typing.Callable[[], typing.Dict[str, str]], base_url: typing.Optional[typing.Callable[[], str]] = None, async_base_headers: typing.Optional[typing.Callable[[], typing.Awaitable[typing.Dict[str, str]]]] = None, - logging_config: typing.Optional[typing.Union[LogConfig, Logger]] = None, ): self.base_url = base_url self.base_timeout = base_timeout self.base_headers = base_headers self.async_base_headers = async_base_headers self.httpx_client = httpx_client - self.logger = create_logger(logging_config) async def _get_headers(self) -> typing.Dict[str, str]: if self.async_base_headers is not None: @@ -607,30 +535,19 @@ async def request( ) ) - _request_url = _build_url(base_url, path) - _request_headers = jsonable_encoder( - remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), - } - ) - ) - - if self.logger.is_debug(): - self.logger.debug( - "Making HTTP request", - method=method, - url=_request_url, - headers=_redact_headers(_request_headers), - has_body=json_body is not None or data_body is not None, - ) - + # Add the input to each of these and do None-safety checks response = await self.httpx_client.request( method=method, - url=_request_url, - headers=_request_headers, + url=_build_url(base_url, path), + headers=jsonable_encoder( + remove_none_from_dict( + { + **_headers, + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) or {} if request_options is not None else {}), + } + ) + ), params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, @@ -656,25 +573,6 @@ async def request( retries=retries + 1, omit=omit, ) - - if self.logger.is_debug(): - if 200 <= response.status_code < 400: - self.logger.debug( - "HTTP request succeeded", - method=method, - url=_request_url, - status_code=response.status_code, - ) - - if self.logger.is_error(): - if response.status_code >= 400: - self.logger.error( - "HTTP request failed with error status", - method=method, - url=_request_url, - status_code=response.status_code, - ) - return response @asynccontextmanager @@ -743,29 +641,18 @@ async def stream( ) ) - _request_url = _build_url(base_url, path) - _request_headers = jsonable_encoder( - remove_none_from_dict( - { - **_headers, - **(headers if headers is not None else {}), - **(request_options.get("additional_headers", {}) if request_options is not None else {}), - } - ) - ) - - if self.logger.is_debug(): - self.logger.debug( - "Making streaming HTTP request", - method=method, - url=_request_url, - headers=_redact_headers(_request_headers), - ) - async with self.httpx_client.stream( method=method, - url=_request_url, - headers=_request_headers, + url=_build_url(base_url, path), + headers=jsonable_encoder( + remove_none_from_dict( + { + **_headers, + **(headers if headers is not None else {}), + **(request_options.get("additional_headers", {}) if request_options is not None else {}), + } + ) + ), params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, diff --git a/src/truefoundry_sdk/core/logging.py b/src/truefoundry_sdk/core/logging.py deleted file mode 100644 index e5e57245..00000000 --- a/src/truefoundry_sdk/core/logging.py +++ /dev/null @@ -1,107 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import logging -import typing - -LogLevel = typing.Literal["debug", "info", "warn", "error"] - -_LOG_LEVEL_MAP: typing.Dict[LogLevel, int] = { - "debug": 1, - "info": 2, - "warn": 3, - "error": 4, -} - - -class ILogger(typing.Protocol): - def debug(self, message: str, **kwargs: typing.Any) -> None: ... - def info(self, message: str, **kwargs: typing.Any) -> None: ... - def warn(self, message: str, **kwargs: typing.Any) -> None: ... - def error(self, message: str, **kwargs: typing.Any) -> None: ... - - -class ConsoleLogger: - _logger: logging.Logger - - def __init__(self) -> None: - self._logger = logging.getLogger("fern") - if not self._logger.handlers: - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter("%(levelname)s - %(message)s")) - self._logger.addHandler(handler) - self._logger.setLevel(logging.DEBUG) - - def debug(self, message: str, **kwargs: typing.Any) -> None: - self._logger.debug(message, extra=kwargs) - - def info(self, message: str, **kwargs: typing.Any) -> None: - self._logger.info(message, extra=kwargs) - - def warn(self, message: str, **kwargs: typing.Any) -> None: - self._logger.warning(message, extra=kwargs) - - def error(self, message: str, **kwargs: typing.Any) -> None: - self._logger.error(message, extra=kwargs) - - -class LogConfig(typing.TypedDict, total=False): - level: LogLevel - logger: ILogger - silent: bool - - -class Logger: - _level: int - _logger: ILogger - _silent: bool - - def __init__(self, *, level: LogLevel, logger: ILogger, silent: bool) -> None: - self._level = _LOG_LEVEL_MAP[level] - self._logger = logger - self._silent = silent - - def _should_log(self, level: LogLevel) -> bool: - return not self._silent and self._level <= _LOG_LEVEL_MAP[level] - - def is_debug(self) -> bool: - return self._should_log("debug") - - def is_info(self) -> bool: - return self._should_log("info") - - def is_warn(self) -> bool: - return self._should_log("warn") - - def is_error(self) -> bool: - return self._should_log("error") - - def debug(self, message: str, **kwargs: typing.Any) -> None: - if self.is_debug(): - self._logger.debug(message, **kwargs) - - def info(self, message: str, **kwargs: typing.Any) -> None: - if self.is_info(): - self._logger.info(message, **kwargs) - - def warn(self, message: str, **kwargs: typing.Any) -> None: - if self.is_warn(): - self._logger.warn(message, **kwargs) - - def error(self, message: str, **kwargs: typing.Any) -> None: - if self.is_error(): - self._logger.error(message, **kwargs) - - -_default_logger: Logger = Logger(level="info", logger=ConsoleLogger(), silent=True) - - -def create_logger(config: typing.Optional[typing.Union[LogConfig, Logger]] = None) -> Logger: - if config is None: - return _default_logger - if isinstance(config, Logger): - return config - return Logger( - level=config.get("level", "info"), - logger=config.get("logger", ConsoleLogger()), - silent=config.get("silent", True), - ) diff --git a/src/truefoundry_sdk/core/parse_error.py b/src/truefoundry_sdk/core/parse_error.py deleted file mode 100644 index 4527c6a8..00000000 --- a/src/truefoundry_sdk/core/parse_error.py +++ /dev/null @@ -1,36 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from typing import Any, Dict, Optional - - -class ParsingError(Exception): - """ - Raised when the SDK fails to parse/validate a response from the server. - This typically indicates that the server returned a response whose shape - does not match the expected schema. - """ - - headers: Optional[Dict[str, str]] - status_code: Optional[int] - body: Any - cause: Optional[Exception] - - def __init__( - self, - *, - headers: Optional[Dict[str, str]] = None, - status_code: Optional[int] = None, - body: Any = None, - cause: Optional[Exception] = None, - ) -> None: - self.headers = headers - self.status_code = status_code - self.body = body - self.cause = cause - super().__init__() - if cause is not None: - self.__cause__ = cause - - def __str__(self) -> str: - cause_str = f", cause: {self.cause}" if self.cause is not None else "" - return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}{cause_str}" diff --git a/src/truefoundry_sdk/core/pydantic_utilities.py b/src/truefoundry_sdk/core/pydantic_utilities.py index fea3a08d..789081b0 100644 --- a/src/truefoundry_sdk/core/pydantic_utilities.py +++ b/src/truefoundry_sdk/core/pydantic_utilities.py @@ -26,7 +26,6 @@ import pydantic import typing_extensions -from pydantic.fields import FieldInfo as _FieldInfo _logger = logging.getLogger(__name__) @@ -36,95 +35,22 @@ IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") if IS_PYDANTIC_V2: - _datetime_adapter = pydantic.TypeAdapter(dt.datetime) # type: ignore[attr-defined] - _date_adapter = pydantic.TypeAdapter(dt.date) # type: ignore[attr-defined] - - def parse_datetime(value: Any) -> dt.datetime: # type: ignore[misc] - if isinstance(value, dt.datetime): - return value - return _datetime_adapter.validate_python(value) - - def parse_date(value: Any) -> dt.date: # type: ignore[misc] - if isinstance(value, dt.datetime): - return value.date() - if isinstance(value, dt.date): - return value - return _date_adapter.validate_python(value) - - # Avoid importing from pydantic.v1 to maintain Python 3.14 compatibility. - from typing import get_args as get_args # type: ignore[assignment] - from typing import get_origin as get_origin # type: ignore[assignment] - - def is_literal_type(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc] - return typing_extensions.get_origin(tp) is typing_extensions.Literal - - def is_union(tp: Optional[Type[Any]]) -> bool: # type: ignore[misc] - return tp is Union or typing_extensions.get_origin(tp) is Union # type: ignore[comparison-overlap] - - # Inline encoders_by_type to avoid importing from pydantic.v1.json - import re as _re - from collections import deque as _deque - from decimal import Decimal as _Decimal - from enum import Enum as _Enum - from ipaddress import ( - IPv4Address as _IPv4Address, - ) - from ipaddress import ( - IPv4Interface as _IPv4Interface, - ) - from ipaddress import ( - IPv4Network as _IPv4Network, - ) - from ipaddress import ( - IPv6Address as _IPv6Address, - ) - from ipaddress import ( - IPv6Interface as _IPv6Interface, - ) - from ipaddress import ( - IPv6Network as _IPv6Network, - ) - from pathlib import Path as _Path - from types import GeneratorType as _GeneratorType - from uuid import UUID as _UUID - - from pydantic.fields import FieldInfo as ModelField # type: ignore[no-redef, assignment] - - def _decimal_encoder(dec_value: Any) -> Any: - if dec_value.as_tuple().exponent >= 0: - return int(dec_value) - return float(dec_value) - - encoders_by_type: Dict[Type[Any], Callable[[Any], Any]] = { # type: ignore[no-redef] - bytes: lambda o: o.decode(), - dt.date: lambda o: o.isoformat(), - dt.datetime: lambda o: o.isoformat(), - dt.time: lambda o: o.isoformat(), - dt.timedelta: lambda td: td.total_seconds(), - _Decimal: _decimal_encoder, - _Enum: lambda o: o.value, - frozenset: list, - _deque: list, - _GeneratorType: list, - _IPv4Address: str, - _IPv4Interface: str, - _IPv4Network: str, - _IPv6Address: str, - _IPv6Interface: str, - _IPv6Network: str, - _Path: str, - _re.Pattern: lambda o: o.pattern, - set: list, - _UUID: str, - } + from pydantic.v1.datetime_parse import parse_date as parse_date + from pydantic.v1.datetime_parse import parse_datetime as parse_datetime + from pydantic.v1.fields import ModelField as ModelField + from pydantic.v1.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[attr-defined] + from pydantic.v1.typing import get_args as get_args + from pydantic.v1.typing import get_origin as get_origin + from pydantic.v1.typing import is_literal_type as is_literal_type + from pydantic.v1.typing import is_union as is_union else: from pydantic.datetime_parse import parse_date as parse_date # type: ignore[no-redef] from pydantic.datetime_parse import parse_datetime as parse_datetime # type: ignore[no-redef] - from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef, assignment] + from pydantic.fields import ModelField as ModelField # type: ignore[attr-defined, no-redef] from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type # type: ignore[no-redef] from pydantic.typing import get_args as get_args # type: ignore[no-redef] from pydantic.typing import get_origin as get_origin # type: ignore[no-redef] - from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef, assignment] + from pydantic.typing import is_literal_type as is_literal_type # type: ignore[no-redef] from pydantic.typing import is_union as is_union # type: ignore[no-redef] from .datetime_utils import serialize_datetime @@ -611,7 +537,7 @@ def decorator(func: AnyCallable) -> AnyCallable: return decorator -PydanticField = Union[ModelField, _FieldInfo] +PydanticField = Union[ModelField, pydantic.fields.FieldInfo] def _get_model_fields(model: Type["Model"]) -> Mapping[str, PydanticField]: diff --git a/src/truefoundry_sdk/data_directories/raw_client.py b/src/truefoundry_sdk/data_directories/raw_client.py index 3fc5bcc7..267e3bbb 100644 --- a/src/truefoundry_sdk/data_directories/raw_client.py +++ b/src/truefoundry_sdk/data_directories/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -23,7 +22,6 @@ from ..types.list_files_response import ListFilesResponse from ..types.multi_part_upload_response import MultiPartUploadResponse from ..types.operation import Operation -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -80,10 +78,6 @@ def get( _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( @@ -142,10 +136,6 @@ def delete( _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 list( @@ -234,10 +224,6 @@ def list( _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( @@ -297,10 +283,6 @@ def create_or_update( _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 list_files( @@ -389,10 +371,6 @@ def list_files( _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_files( @@ -454,10 +432,6 @@ def delete_files( _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_signed_urls( @@ -528,10 +502,6 @@ def get_signed_urls( _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_multipart_upload( @@ -597,10 +567,6 @@ def create_multipart_upload( _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) @@ -655,10 +621,6 @@ async def get( _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( @@ -717,10 +679,6 @@ async def delete( _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 list( @@ -812,10 +770,6 @@ async def _get_next(): _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( @@ -875,10 +829,6 @@ async def create_or_update( _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 list_files( @@ -970,10 +920,6 @@ async def _get_next(): _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_files( @@ -1035,10 +981,6 @@ async def delete_files( _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_signed_urls( @@ -1109,10 +1051,6 @@ async def get_signed_urls( _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_multipart_upload( @@ -1178,8 +1116,4 @@ async def create_multipart_upload( _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/environments/client.py b/src/truefoundry_sdk/environments/client.py index 9095e64a..0718d420 100644 --- a/src/truefoundry_sdk/environments/client.py +++ b/src/truefoundry_sdk/environments/client.py @@ -80,7 +80,7 @@ def create_or_update( self, *, manifest: EnvironmentManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetEnvironmentResponse: """ @@ -268,7 +268,7 @@ async def create_or_update( self, *, manifest: EnvironmentManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetEnvironmentResponse: """ diff --git a/src/truefoundry_sdk/environments/raw_client.py b/src/truefoundry_sdk/environments/raw_client.py index 6f5acfad..42bf0255 100644 --- a/src/truefoundry_sdk/environments/raw_client.py +++ b/src/truefoundry_sdk/environments/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -20,7 +19,6 @@ from ..types.get_environment_response import GetEnvironmentResponse from ..types.http_error import HttpError from ..types.list_environments_response import ListEnvironmentsResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -87,17 +85,13 @@ def list( _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: EnvironmentManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetEnvironmentResponse]: """ @@ -158,10 +152,6 @@ def create_or_update( _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( @@ -201,10 +191,6 @@ def get( _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[bool]: @@ -264,10 +250,6 @@ def delete(self, id: str, *, request_options: typing.Optional[RequestOptions] = _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) @@ -335,17 +317,13 @@ async def _get_next(): _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: EnvironmentManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetEnvironmentResponse]: """ @@ -406,10 +384,6 @@ async def create_or_update( _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( @@ -449,10 +423,6 @@ async def get( _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( @@ -514,8 +484,4 @@ async def delete( _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/events/raw_client.py b/src/truefoundry_sdk/events/raw_client.py index fd7dfbc9..80ada6d8 100644 --- a/src/truefoundry_sdk/events/raw_client.py +++ b/src/truefoundry_sdk/events/raw_client.py @@ -6,7 +6,6 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -14,7 +13,6 @@ from ..errors.not_found_error import NotFoundError from ..types.get_events_response import GetEventsResponse from ..types.http_error import HttpError -from pydantic import ValidationError class RawEventsClient: @@ -122,10 +120,6 @@ def get( _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) @@ -234,8 +228,4 @@ async def get( _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/internal/ai_gateway/raw_client.py b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py index 01949eaa..60880dd9 100644 --- a/src/truefoundry_sdk/internal/ai_gateway/raw_client.py +++ b/src/truefoundry_sdk/internal/ai_gateway/raw_client.py @@ -7,12 +7,10 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...types.gateway_configuration import GatewayConfiguration from .types.ai_gateway_get_gateway_config_request_type import AiGatewayGetGatewayConfigRequestType -from pydantic import ValidationError class RawAiGatewayClient: @@ -56,10 +54,6 @@ def get_gateway_config( _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) @@ -104,8 +98,4 @@ async def get_gateway_config( _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/internal/applications/raw_client.py b/src/truefoundry_sdk/internal/applications/raw_client.py index fa9dc9e2..f0f62538 100644 --- a/src/truefoundry_sdk/internal/applications/raw_client.py +++ b/src/truefoundry_sdk/internal/applications/raw_client.py @@ -7,13 +7,11 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError from ...errors.method_not_allowed_error import MethodNotAllowedError from ...errors.not_found_error import NotFoundError -from pydantic import ValidationError class RawApplicationsClient: @@ -77,10 +75,6 @@ def promote_rollout( _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_pod_template_hash_to_deployment_version( @@ -141,10 +135,6 @@ def get_pod_template_hash_to_deployment_version( _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) @@ -209,10 +199,6 @@ async def promote_rollout( _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_pod_template_hash_to_deployment_version( @@ -273,8 +259,4 @@ async def get_pod_template_hash_to_deployment_version( _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/internal/artifact_versions/raw_client.py b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py index 89679e71..71e2a5b5 100644 --- a/src/truefoundry_sdk/internal/artifact_versions/raw_client.py +++ b/src/truefoundry_sdk/internal/artifact_versions/raw_client.py @@ -6,13 +6,11 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.pagination import AsyncPager, SyncPager -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.unprocessable_entity_error import UnprocessableEntityError from ...types.internal_list_artifact_versions_response import InternalListArtifactVersionsResponse from ...types.internal_list_artifact_versions_response_data_item import InternalListArtifactVersionsResponseDataItem -from pydantic import ValidationError class RawArtifactVersionsClient: @@ -147,10 +145,6 @@ def list( _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) @@ -289,8 +283,4 @@ async def _get_next(): _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/internal/build_logs/raw_client.py b/src/truefoundry_sdk/internal/build_logs/raw_client.py index 399c0302..aa0cbb56 100644 --- a/src/truefoundry_sdk/internal/build_logs/raw_client.py +++ b/src/truefoundry_sdk/internal/build_logs/raw_client.py @@ -7,14 +7,12 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -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 ...types.logs_filter_query import LogsFilterQuery from ...types.logs_response import LogsResponse -from pydantic import ValidationError class RawBuildLogsClient: @@ -106,10 +104,6 @@ def get( _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) @@ -202,8 +196,4 @@ async def get( _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/internal/clusters/raw_client.py b/src/truefoundry_sdk/internal/clusters/raw_client.py index 958a7a2f..1a68dcda 100644 --- a/src/truefoundry_sdk/internal/clusters/raw_client.py +++ b/src/truefoundry_sdk/internal/clusters/raw_client.py @@ -7,13 +7,11 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.unauthorized_error import UnauthorizedError from ...types.get_auto_provisioning_state_response import GetAutoProvisioningStateResponse from ...types.http_error import HttpError -from pydantic import ValidationError class RawClustersClient: @@ -68,10 +66,6 @@ def get_autoprovisioning_state( _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) @@ -127,8 +121,4 @@ async def get_autoprovisioning_state( _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/internal/deployments/raw_client.py b/src/truefoundry_sdk/internal/deployments/raw_client.py index 63619100..6b820904 100644 --- a/src/truefoundry_sdk/internal/deployments/raw_client.py +++ b/src/truefoundry_sdk/internal/deployments/raw_client.py @@ -7,7 +7,6 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError @@ -17,7 +16,6 @@ from ...types.deployment_status import DeploymentStatus from ...types.get_suggested_deployment_endpoint_response import GetSuggestedDeploymentEndpointResponse from ...types.presigned_url_object import PresignedUrlObject -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -78,10 +76,6 @@ def get_deployment_statuses( _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_builds( @@ -135,10 +129,6 @@ def get_builds( _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_code_upload_url( @@ -189,10 +179,6 @@ def get_code_upload_url( _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_suggested_endpoint( @@ -274,10 +260,6 @@ def get_suggested_endpoint( _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) @@ -336,10 +318,6 @@ async def get_deployment_statuses( _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_builds( @@ -393,10 +371,6 @@ async def get_builds( _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_code_upload_url( @@ -447,10 +421,6 @@ async def get_code_upload_url( _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_suggested_endpoint( @@ -532,8 +502,4 @@ async def get_suggested_endpoint( _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/internal/docker_registries/raw_client.py b/src/truefoundry_sdk/internal/docker_registries/raw_client.py index f23aaaa7..b6d1f3dc 100644 --- a/src/truefoundry_sdk/internal/docker_registries/raw_client.py +++ b/src/truefoundry_sdk/internal/docker_registries/raw_client.py @@ -6,13 +6,11 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.not_found_error import NotFoundError from ...types.create_docker_repository_response import CreateDockerRepositoryResponse from ...types.get_docker_registry_credentials_response import GetDockerRegistryCredentialsResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -90,10 +88,6 @@ def create_repository( _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_credentials( @@ -144,10 +138,6 @@ def get_credentials( _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) @@ -223,10 +213,6 @@ async def create_repository( _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_credentials( @@ -277,8 +263,4 @@ async def get_credentials( _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/internal/metrics/raw_client.py b/src/truefoundry_sdk/internal/metrics/raw_client.py index d4de7122..1b6b7d28 100644 --- a/src/truefoundry_sdk/internal/metrics/raw_client.py +++ b/src/truefoundry_sdk/internal/metrics/raw_client.py @@ -7,7 +7,6 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...errors.bad_request_error import BadRequestError @@ -15,7 +14,6 @@ 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 pydantic import ValidationError class RawMetricsClient: @@ -119,10 +117,6 @@ def get_charts( _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) @@ -227,8 +221,4 @@ async def get_charts( _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/internal/ml/raw_client.py b/src/truefoundry_sdk/internal/ml/raw_client.py index 6d0e28cc..7c1ad610 100644 --- a/src/truefoundry_sdk/internal/ml/raw_client.py +++ b/src/truefoundry_sdk/internal/ml/raw_client.py @@ -6,7 +6,6 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -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 @@ -15,7 +14,6 @@ from ...types.empty_response import EmptyResponse from .types.apply_ml_entity_request_manifest import ApplyMlEntityRequestManifest from .types.delete_ml_entity_request_manifest import DeleteMlEntityRequestManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -82,10 +80,6 @@ def apply( _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( @@ -145,10 +139,6 @@ def delete( _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) @@ -213,10 +203,6 @@ async def apply( _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( @@ -276,8 +262,4 @@ async def delete( _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/internal/raw_client.py b/src/truefoundry_sdk/internal/raw_client.py index 05b09787..cc90b88a 100644 --- a/src/truefoundry_sdk/internal/raw_client.py +++ b/src/truefoundry_sdk/internal/raw_client.py @@ -7,12 +7,10 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError -from pydantic import ValidationError class RawInternalClient: @@ -84,10 +82,6 @@ def get_id_from_fqn( _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) @@ -160,8 +154,4 @@ async def get_id_from_fqn( _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/internal/users/raw_client.py b/src/truefoundry_sdk/internal/users/raw_client.py index fbed119e..ddc359a2 100644 --- a/src/truefoundry_sdk/internal/users/raw_client.py +++ b/src/truefoundry_sdk/internal/users/raw_client.py @@ -6,11 +6,9 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...types.session import Session -from pydantic import ValidationError class RawUsersClient: @@ -49,10 +47,6 @@ def get_info(self, *, request_options: typing.Optional[RequestOptions] = None) - _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) @@ -92,8 +86,4 @@ async def get_info(self, *, request_options: typing.Optional[RequestOptions] = N _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/internal/vcs/raw_client.py b/src/truefoundry_sdk/internal/vcs/raw_client.py index cda33908..fb35c9df 100644 --- a/src/truefoundry_sdk/internal/vcs/raw_client.py +++ b/src/truefoundry_sdk/internal/vcs/raw_client.py @@ -6,12 +6,10 @@ from ...core.api_error import ApiError from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as from ...core.request_options import RequestOptions from ...types.get_authenticated_vcsurl_response import GetAuthenticatedVcsurlResponse from ...types.git_repository_exists_response import GitRepositoryExistsResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -67,10 +65,6 @@ def get_repository_details( _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_authenticated_url( @@ -115,10 +109,6 @@ def get_authenticated_url( _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) @@ -172,10 +162,6 @@ async def get_repository_details( _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_authenticated_url( @@ -220,8 +206,4 @@ async def get_authenticated_url( _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/internal/workflows/raw_client.py b/src/truefoundry_sdk/internal/workflows/raw_client.py index 62eba734..7ce6bb72 100644 --- a/src/truefoundry_sdk/internal/workflows/raw_client.py +++ b/src/truefoundry_sdk/internal/workflows/raw_client.py @@ -7,13 +7,11 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.http_response import AsyncHttpResponse, HttpResponse from ...core.jsonable_encoder import jsonable_encoder -from ...core.parse_error import ParsingError from ...core.pydantic_utilities import parse_obj_as 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 pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -101,10 +99,6 @@ def execute_workflow( _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) @@ -190,8 +184,4 @@ async def execute_workflow( _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/jobs/raw_client.py b/src/truefoundry_sdk/jobs/raw_client.py index 784c1aa5..fbc137b4 100644 --- a/src/truefoundry_sdk/jobs/raw_client.py +++ b/src/truefoundry_sdk/jobs/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -30,7 +29,6 @@ from ..types.terminate_job_response import TerminateJobResponse from ..types.trigger_job_run_response import TriggerJobRunResponse from .types.trigger_job_request_input import TriggerJobRequestInput -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -171,10 +169,6 @@ def list_runs( _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_run( @@ -239,10 +233,6 @@ def get_run( _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_run( @@ -318,10 +308,6 @@ def delete_run( _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 trigger( @@ -434,10 +420,6 @@ def trigger( _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 terminate( @@ -528,10 +510,6 @@ def terminate( _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) @@ -673,10 +651,6 @@ async def _get_next(): _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_run( @@ -741,10 +715,6 @@ async def get_run( _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_run( @@ -820,10 +790,6 @@ async def delete_run( _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 trigger( @@ -936,10 +902,6 @@ async def trigger( _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 terminate( @@ -1030,8 +992,4 @@ async def terminate( _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/logs/raw_client.py b/src/truefoundry_sdk/logs/raw_client.py index 8abc89d7..ddc35056 100644 --- a/src/truefoundry_sdk/logs/raw_client.py +++ b/src/truefoundry_sdk/logs/raw_client.py @@ -6,7 +6,6 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -14,7 +13,6 @@ from ..types.logs_search_filter_type import LogsSearchFilterType from ..types.logs_search_operator_type import LogsSearchOperatorType from ..types.logs_sorting_direction import LogsSortingDirection -from pydantic import ValidationError class RawLogsClient: @@ -155,10 +153,6 @@ def get( _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) @@ -300,8 +294,4 @@ async def get( _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/ml_repos/client.py b/src/truefoundry_sdk/ml_repos/client.py index 59080e60..bc25b27b 100644 --- a/src/truefoundry_sdk/ml_repos/client.py +++ b/src/truefoundry_sdk/ml_repos/client.py @@ -35,7 +35,7 @@ def create_or_update( self, *, manifest: MlRepoManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetMlRepoResponse: """ @@ -216,7 +216,7 @@ async def create_or_update( self, *, manifest: MlRepoManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetMlRepoResponse: """ diff --git a/src/truefoundry_sdk/ml_repos/raw_client.py b/src/truefoundry_sdk/ml_repos/raw_client.py index 33cc1e3d..194a8c48 100644 --- a/src/truefoundry_sdk/ml_repos/raw_client.py +++ b/src/truefoundry_sdk/ml_repos/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -22,7 +21,6 @@ from ..types.list_ml_repos_response import ListMlReposResponse from ..types.ml_repo import MlRepo from ..types.ml_repo_manifest import MlRepoManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -36,7 +34,7 @@ def create_or_update( self, *, manifest: MlRepoManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetMlRepoResponse]: """ @@ -130,10 +128,6 @@ def create_or_update( _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( @@ -183,10 +177,6 @@ def get( _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( @@ -236,10 +226,6 @@ def delete( _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 list( @@ -316,10 +302,6 @@ def list( _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) @@ -331,7 +313,7 @@ async def create_or_update( self, *, manifest: MlRepoManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetMlRepoResponse]: """ @@ -425,10 +407,6 @@ async def create_or_update( _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( @@ -478,10 +456,6 @@ async def get( _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( @@ -531,10 +505,6 @@ async def delete( _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 list( @@ -614,8 +584,4 @@ async def _get_next(): _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/model_versions/client.py b/src/truefoundry_sdk/model_versions/client.py index dfdedc47..c51d4000 100644 --- a/src/truefoundry_sdk/model_versions/client.py +++ b/src/truefoundry_sdk/model_versions/client.py @@ -35,7 +35,7 @@ def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ @@ -263,7 +263,7 @@ async def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ diff --git a/src/truefoundry_sdk/model_versions/raw_client.py b/src/truefoundry_sdk/model_versions/raw_client.py index 06fab126..57598932 100644 --- a/src/truefoundry_sdk/model_versions/raw_client.py +++ b/src/truefoundry_sdk/model_versions/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.unprocessable_entity_error import UnprocessableEntityError @@ -16,7 +15,6 @@ from ..types.get_model_version_response import GetModelVersionResponse from ..types.list_model_versions_response import ListModelVersionsResponse from ..types.model_version import ModelVersion -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,7 +29,7 @@ def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ @@ -94,10 +92,6 @@ def apply_tags( _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( @@ -147,10 +141,6 @@ def get( _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( @@ -200,10 +190,6 @@ def delete( _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 list( @@ -328,10 +314,6 @@ def list( _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) @@ -344,7 +326,7 @@ async def apply_tags( *, model_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ @@ -407,10 +389,6 @@ async def apply_tags( _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( @@ -460,10 +438,6 @@ async def get( _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( @@ -513,10 +487,6 @@ async def delete( _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 list( @@ -644,8 +614,4 @@ async def _get_next(): _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/models/raw_client.py b/src/truefoundry_sdk/models/raw_client.py index c27ca42a..63d808dd 100644 --- a/src/truefoundry_sdk/models/raw_client.py +++ b/src/truefoundry_sdk/models/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -19,7 +18,6 @@ from ..types.list_models_response import ListModelsResponse from ..types.model import Model from ..types.model_manifest import ModelManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -76,10 +74,6 @@ def get( _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( @@ -129,10 +123,6 @@ def delete( _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 list( @@ -233,10 +223,6 @@ def list( _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( @@ -296,10 +282,6 @@ def create_or_update( _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) @@ -354,10 +336,6 @@ async def get( _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( @@ -407,10 +385,6 @@ async def delete( _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 list( @@ -514,10 +488,6 @@ async def _get_next(): _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( @@ -577,8 +547,4 @@ async def create_or_update( _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/personal_access_tokens/raw_client.py b/src/truefoundry_sdk/personal_access_tokens/raw_client.py index 9c558797..39d85efe 100644 --- a/src/truefoundry_sdk/personal_access_tokens/raw_client.py +++ b/src/truefoundry_sdk/personal_access_tokens/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -21,7 +20,6 @@ from ..types.list_personal_access_token_response import ListPersonalAccessTokenResponse from ..types.revoke_all_personal_access_token_response import RevokeAllPersonalAccessTokenResponse from ..types.virtual_account import VirtualAccount -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -94,10 +92,6 @@ def list( _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( @@ -179,10 +173,6 @@ def create( _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( @@ -240,10 +230,6 @@ def revoke_all( _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( @@ -294,10 +280,6 @@ def delete( _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( @@ -347,10 +329,6 @@ def get( _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) @@ -424,10 +402,6 @@ async def _get_next(): _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( @@ -509,10 +483,6 @@ async def create( _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( @@ -570,10 +540,6 @@ async def revoke_all( _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( @@ -624,10 +590,6 @@ async def delete( _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( @@ -677,8 +639,4 @@ async def get( _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/prompt_versions/client.py b/src/truefoundry_sdk/prompt_versions/client.py index f7ad6733..f1a44543 100644 --- a/src/truefoundry_sdk/prompt_versions/client.py +++ b/src/truefoundry_sdk/prompt_versions/client.py @@ -35,7 +35,7 @@ def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ @@ -247,7 +247,7 @@ async def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> EmptyResponse: """ diff --git a/src/truefoundry_sdk/prompt_versions/raw_client.py b/src/truefoundry_sdk/prompt_versions/raw_client.py index e1bec984..b3ea68a7 100644 --- a/src/truefoundry_sdk/prompt_versions/raw_client.py +++ b/src/truefoundry_sdk/prompt_versions/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.unprocessable_entity_error import UnprocessableEntityError @@ -16,7 +15,6 @@ from ..types.get_prompt_version_response import GetPromptVersionResponse from ..types.list_prompt_versions_response import ListPromptVersionsResponse from ..types.prompt_version import PromptVersion -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,7 +29,7 @@ def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EmptyResponse]: """ @@ -94,10 +92,6 @@ def apply_tags( _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( @@ -147,10 +141,6 @@ def get( _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( @@ -200,10 +190,6 @@ def delete( _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 list( @@ -310,10 +296,6 @@ def list( _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) @@ -326,7 +308,7 @@ async def apply_tags( *, prompt_version_id: str, tags: typing.Sequence[str], - force: typing.Optional[bool] = OMIT, + force: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EmptyResponse]: """ @@ -389,10 +371,6 @@ async def apply_tags( _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( @@ -442,10 +420,6 @@ async def get( _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( @@ -495,10 +469,6 @@ async def delete( _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 list( @@ -608,8 +578,4 @@ async def _get_next(): _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/prompts/raw_client.py b/src/truefoundry_sdk/prompts/raw_client.py index 74b88206..5dce0cd9 100644 --- a/src/truefoundry_sdk/prompts/raw_client.py +++ b/src/truefoundry_sdk/prompts/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -19,7 +18,6 @@ from ..types.get_prompt_version_response import GetPromptVersionResponse from ..types.list_prompts_response import ListPromptsResponse from ..types.prompt import Prompt -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -76,10 +74,6 @@ def get( _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( @@ -129,10 +123,6 @@ def delete( _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 list( @@ -227,10 +217,6 @@ def list( _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( @@ -290,10 +276,6 @@ def create_or_update( _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) @@ -348,10 +330,6 @@ async def get( _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( @@ -401,10 +379,6 @@ async def delete( _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 list( @@ -502,10 +476,6 @@ async def _get_next(): _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( @@ -565,8 +535,4 @@ async def create_or_update( _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/raw_base_client.py b/src/truefoundry_sdk/raw_base_client.py index db933b65..5247df4d 100644 --- a/src/truefoundry_sdk/raw_base_client.py +++ b/src/truefoundry_sdk/raw_base_client.py @@ -6,14 +6,12 @@ from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .core.http_response import AsyncHttpResponse, HttpResponse -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 .types.true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest from .types.true_foundry_apply_response import TrueFoundryApplyResponse from .types.true_foundry_delete_request_manifest import TrueFoundryDeleteRequestManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -27,7 +25,7 @@ def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TrueFoundryApplyResponse]: """ @@ -77,10 +75,6 @@ def apply( _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( @@ -121,10 +115,6 @@ def delete( _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) @@ -136,7 +126,7 @@ async def apply( self, *, manifest: TrueFoundryApplyRequestManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TrueFoundryApplyResponse]: """ @@ -186,10 +176,6 @@ async def apply( _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( @@ -230,8 +216,4 @@ async def delete( _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/secret_groups/client.py b/src/truefoundry_sdk/secret_groups/client.py index e69a7f3d..ec363496 100644 --- a/src/truefoundry_sdk/secret_groups/client.py +++ b/src/truefoundry_sdk/secret_groups/client.py @@ -149,7 +149,7 @@ def create_or_update( self, *, manifest: SecretGroupManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetSecretGroupResponse: """ @@ -455,7 +455,7 @@ async def create_or_update( self, *, manifest: SecretGroupManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetSecretGroupResponse: """ diff --git a/src/truefoundry_sdk/secret_groups/raw_client.py b/src/truefoundry_sdk/secret_groups/raw_client.py index fc9eee28..463af059 100644 --- a/src/truefoundry_sdk/secret_groups/raw_client.py +++ b/src/truefoundry_sdk/secret_groups/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -26,7 +25,6 @@ from ..types.secret_group_manifest import SecretGroupManifest from ..types.secret_input import SecretInput from ..types.update_secret_input import UpdateSecretInput -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -105,10 +103,6 @@ def list( _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( @@ -192,17 +186,13 @@ def create( _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: SecretGroupManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetSecretGroupResponse]: """ @@ -307,10 +297,6 @@ def create_or_update( _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( @@ -372,10 +358,6 @@ def get( _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 update( @@ -474,10 +456,6 @@ def update( _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( @@ -539,10 +517,6 @@ def delete( _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) @@ -622,10 +596,6 @@ async def _get_next(): _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( @@ -709,17 +679,13 @@ async def create( _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: SecretGroupManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetSecretGroupResponse]: """ @@ -824,10 +790,6 @@ async def create_or_update( _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( @@ -889,10 +851,6 @@ async def get( _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 update( @@ -991,10 +949,6 @@ async def update( _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( @@ -1056,8 +1010,4 @@ async def delete( _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/secrets/client.py b/src/truefoundry_sdk/secrets/client.py index 4f3dbed9..7356c92a 100644 --- a/src/truefoundry_sdk/secrets/client.py +++ b/src/truefoundry_sdk/secrets/client.py @@ -32,11 +32,11 @@ def with_raw_response(self) -> RawSecretsClient: def list( self, *, - limit: typing.Optional[int] = OMIT, - offset: typing.Optional[int] = OMIT, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = OMIT, + with_value: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Secret, ListSecretsResponse]: """ @@ -184,11 +184,11 @@ def with_raw_response(self) -> AsyncRawSecretsClient: async def list( self, *, - limit: typing.Optional[int] = OMIT, - offset: typing.Optional[int] = OMIT, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = OMIT, + with_value: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Secret, ListSecretsResponse]: """ diff --git a/src/truefoundry_sdk/secrets/raw_client.py b/src/truefoundry_sdk/secrets/raw_client.py index c1b6930d..ff668387 100644 --- a/src/truefoundry_sdk/secrets/raw_client.py +++ b/src/truefoundry_sdk/secrets/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.failed_dependency_error import FailedDependencyError @@ -18,7 +17,6 @@ from ..types.http_error import HttpError from ..types.list_secrets_response import ListSecretsResponse from ..types.secret import Secret -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -31,11 +29,11 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list( self, *, - limit: typing.Optional[int] = OMIT, - offset: typing.Optional[int] = OMIT, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = OMIT, + with_value: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Secret, ListSecretsResponse]: """ @@ -129,10 +127,6 @@ def list( _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( @@ -194,10 +188,6 @@ def get( _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( @@ -280,10 +270,6 @@ def delete( _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) @@ -294,11 +280,11 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list( self, *, - limit: typing.Optional[int] = OMIT, - offset: typing.Optional[int] = OMIT, + limit: typing.Optional[int] = 100, + offset: typing.Optional[int] = 0, secret_fqns: typing.Optional[typing.Sequence[str]] = OMIT, secret_group_id: typing.Optional[str] = OMIT, - with_value: typing.Optional[bool] = OMIT, + with_value: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Secret, ListSecretsResponse]: """ @@ -395,10 +381,6 @@ async def _get_next(): _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( @@ -460,10 +442,6 @@ async def get( _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( @@ -546,8 +524,4 @@ async def delete( _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/teams/client.py b/src/truefoundry_sdk/teams/client.py index ab6335ed..ac9092e9 100644 --- a/src/truefoundry_sdk/teams/client.py +++ b/src/truefoundry_sdk/teams/client.py @@ -89,7 +89,7 @@ def create_or_update( self, *, manifest: TeamManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetTeamResponse: """ @@ -310,7 +310,7 @@ async def create_or_update( self, *, manifest: TeamManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, 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 eff26076..2f32a8a8 100644 --- a/src/truefoundry_sdk/teams/raw_client.py +++ b/src/truefoundry_sdk/teams/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -24,7 +23,6 @@ from ..types.team import Team from ..types.team_manifest import TeamManifest from .types.teams_list_request_type import TeamsListRequestType -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -97,17 +95,13 @@ def list( _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: TeamManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetTeamResponse]: """ @@ -179,10 +173,6 @@ def create_or_update( _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[GetTeamResponse]: @@ -231,10 +221,6 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non _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( @@ -296,10 +282,6 @@ def delete( _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_permissions( @@ -361,10 +343,6 @@ def get_permissions( _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) @@ -438,17 +416,13 @@ async def _get_next(): _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: TeamManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetTeamResponse]: """ @@ -520,10 +494,6 @@ async def create_or_update( _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( @@ -574,10 +544,6 @@ async def get( _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( @@ -639,10 +605,6 @@ async def delete( _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_permissions( @@ -704,8 +666,4 @@ async def get_permissions( _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/traces/client.py b/src/truefoundry_sdk/traces/client.py index b793b387..7ce2f88e 100644 --- a/src/truefoundry_sdk/traces/client.py +++ b/src/truefoundry_sdk/traces/client.py @@ -48,7 +48,7 @@ def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = OMIT, + include_feedbacks: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TraceSpan, QuerySpansResponse]: """ @@ -176,7 +176,7 @@ async def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = OMIT, + include_feedbacks: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TraceSpan, QuerySpansResponse]: """ diff --git a/src/truefoundry_sdk/traces/raw_client.py b/src/truefoundry_sdk/traces/raw_client.py index 1ea3c7e7..4ae7c14a 100644 --- a/src/truefoundry_sdk/traces/raw_client.py +++ b/src/truefoundry_sdk/traces/raw_client.py @@ -6,7 +6,6 @@ from ..core.api_error import ApiError from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.pagination import AsyncPager, SyncPager -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 @@ -15,7 +14,6 @@ from ..types.subject_type import SubjectType from ..types.trace_span import TraceSpan from .types.query_spans_request_filters_item import QuerySpansRequestFiltersItem -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -42,7 +40,7 @@ def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = OMIT, + include_feedbacks: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[TraceSpan, QuerySpansResponse]: """ @@ -166,10 +164,6 @@ def query_spans( _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) @@ -194,7 +188,7 @@ async def query_spans( tracing_project_fqn: typing.Optional[str] = OMIT, data_routing_destination: typing.Optional[str] = OMIT, filters: typing.Optional[typing.Sequence[QuerySpansRequestFiltersItem]] = OMIT, - include_feedbacks: typing.Optional[bool] = OMIT, + include_feedbacks: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[TraceSpan, QuerySpansResponse]: """ @@ -321,8 +315,4 @@ async def _get_next(): _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/types/a2a_framework.py b/src/truefoundry_sdk/types/a2a_framework.py index c8bfec91..8ace8e05 100644 --- a/src/truefoundry_sdk/types/a2a_framework.py +++ b/src/truefoundry_sdk/types/a2a_framework.py @@ -16,7 +16,7 @@ class A2AFramework(UniversalBaseModel): Type """ - agent_card_path: str = pydantic.Field() + agent_card_path: str = pydantic.Field(default="/.well-known/agent-card.json") """ Path to the agent card JSON, relative to the base URL """ diff --git a/src/truefoundry_sdk/types/akto_guardrail_config.py b/src/truefoundry_sdk/types/akto_guardrail_config.py index 53f51f5c..4d72b9c0 100644 --- a/src/truefoundry_sdk/types/akto_guardrail_config.py +++ b/src/truefoundry_sdk/types/akto_guardrail_config.py @@ -19,7 +19,9 @@ class AktoGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Akto guardrail for LLM security, prompt injection detection, and policy violation monitoring" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/amqp_input_config.py b/src/truefoundry_sdk/types/amqp_input_config.py index 83784e36..78007103 100644 --- a/src/truefoundry_sdk/types/amqp_input_config.py +++ b/src/truefoundry_sdk/types/amqp_input_config.py @@ -26,7 +26,7 @@ class AmqpInputConfig(UniversalBaseModel): AMQP Queue Name """ - wait_time_seconds: int = pydantic.Field() + wait_time_seconds: int = pydantic.Field(default=5) """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/artifact_manifest.py b/src/truefoundry_sdk/types/artifact_manifest.py index 88afcc2b..3f48a99b 100644 --- a/src/truefoundry_sdk/types/artifact_manifest.py +++ b/src/truefoundry_sdk/types/artifact_manifest.py @@ -40,7 +40,7 @@ class ArtifactManifest(UniversalBaseModel): """ source: ArtifactManifestSource - step: typing.Optional[int] = pydantic.Field(default=None) + step: typing.Optional[int] = pydantic.Field(default=0) """ Step/Epoch number in an iterative training loop the artifact version was created. Generally useful when logging a model version from a MLRepo Run """ diff --git a/src/truefoundry_sdk/types/artifacts_cache_volume.py b/src/truefoundry_sdk/types/artifacts_cache_volume.py index d53c0166..c2dab808 100644 --- a/src/truefoundry_sdk/types/artifacts_cache_volume.py +++ b/src/truefoundry_sdk/types/artifacts_cache_volume.py @@ -16,7 +16,7 @@ class ArtifactsCacheVolume(UniversalBaseModel): Storage class of the Volume where artifacts will be cached """ - cache_size: int = pydantic.Field() + cache_size: int = pydantic.Field(default=200) """ Size of the Volume (in GB) where artifacts will be cached. Should be greater than twice the size of artifacts getting cached """ diff --git a/src/truefoundry_sdk/types/async_processor_sidecar.py b/src/truefoundry_sdk/types/async_processor_sidecar.py index a442c419..ffac1a4f 100644 --- a/src/truefoundry_sdk/types/async_processor_sidecar.py +++ b/src/truefoundry_sdk/types/async_processor_sidecar.py @@ -12,7 +12,7 @@ class AsyncProcessorSidecar(UniversalBaseModel): URL for the processor to invoke """ - request_timeout: typing.Optional[int] = pydantic.Field(default=None) + request_timeout: typing.Optional[int] = pydantic.Field(default=10) """ Timeout for the invoke request in seconds """ diff --git a/src/truefoundry_sdk/types/auto_rotate.py b/src/truefoundry_sdk/types/auto_rotate.py index 24f75269..33d45dd8 100644 --- a/src/truefoundry_sdk/types/auto_rotate.py +++ b/src/truefoundry_sdk/types/auto_rotate.py @@ -11,12 +11,12 @@ class AutoRotate(UniversalBaseModel): Enable Auto Rotation to automatically rotate the token """ - auto_rotate_interval: int = pydantic.Field() + auto_rotate_interval: int = pydantic.Field(default=360) """ Rotation Interval in days after which the token will be rotated. Minimum value is 30. """ - grace_period: int = pydantic.Field() + grace_period: int = pydantic.Field(default=30) """ Grace Period in days for which the token will be valid after rotation interval. Minimum value is 1. """ diff --git a/src/truefoundry_sdk/types/autoshutdown.py b/src/truefoundry_sdk/types/autoshutdown.py index 794e3a35..cf7f2938 100644 --- a/src/truefoundry_sdk/types/autoshutdown.py +++ b/src/truefoundry_sdk/types/autoshutdown.py @@ -7,7 +7,7 @@ class Autoshutdown(UniversalBaseModel): - wait_time: int = pydantic.Field() + wait_time: int = pydantic.Field(default=900) """ The period to wait after the last received request before scaling the replicas to 0. This value should be high enough to allow for the replicas of the service to come up to avoid premature scaling down. """ diff --git a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py index 4b982012..d8f4c744 100644 --- a/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py +++ b/src/truefoundry_sdk/types/aws_bedrock_guardrail_config.py @@ -20,7 +20,9 @@ class AwsBedrockGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="AWS Bedrock Guardrails for content filtering and safety policies" + ) """ Optional description for this Guardrail Config. """ @@ -44,7 +46,7 @@ class AwsBedrockGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py index b9bb6a42..924706a3 100644 --- a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config.py @@ -19,7 +19,9 @@ class AzureContentSafetyGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Azure Content Safety for hate, self-harm, sexual, and violence detection" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py index a70bb5bd..6b9c9fb4 100644 --- a/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_content_safety_guardrail_config_config.py @@ -18,7 +18,7 @@ class AzureContentSafetyGuardrailConfigConfig(UniversalBaseModel): Name of your Azure Content Safety resource where the service is deployed (e.g., my-content-safety) """ - api_version: str = pydantic.Field() + api_version: str = pydantic.Field(default="2024-09-01") """ API version for the Content Safety API """ @@ -33,7 +33,7 @@ class AzureContentSafetyGuardrailConfigConfig(UniversalBaseModel): Names of custom blocklists created in Azure Content Safety to check text against. Leave empty if not using custom blocklists """ - severity_threshold: float = pydantic.Field() + severity_threshold: float = pydantic.Field(default=2.0) """ Minimum severity level (0-6) to flag content. Higher values are more restrictive. 0=Safe, 2=Low risk, 4=Medium risk, 6=High risk """ diff --git a/src/truefoundry_sdk/types/azure_pii_guardrail_config.py b/src/truefoundry_sdk/types/azure_pii_guardrail_config.py index 16072ad3..cb74e739 100644 --- a/src/truefoundry_sdk/types/azure_pii_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_pii_guardrail_config.py @@ -20,7 +20,9 @@ class AzurePiiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Azure AI Language PII detection and redaction for sensitive data" + ) """ Optional description for this Guardrail Config. """ @@ -43,7 +45,7 @@ class AzurePiiGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py index 796f5195..3ea0df00 100644 --- a/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_pii_guardrail_config_config.py @@ -19,7 +19,7 @@ class AzurePiiGuardrailConfigConfig(UniversalBaseModel): Name of your Azure AI Language resource where the PII detection service is deployed (e.g., my-language-resource) """ - api_version: str = pydantic.Field() + api_version: str = pydantic.Field(default="2024-11-01") """ API version for the PII detection API """ @@ -39,12 +39,12 @@ class AzurePiiGuardrailConfigConfig(UniversalBaseModel): Categories of PII to detect. """ - model_version: str = pydantic.Field() + model_version: str = pydantic.Field(default="latest") """ Version of the PII detection model to use, use latest for the newest model or specify a specific version for consistency """ - language: str = pydantic.Field() + language: str = pydantic.Field(default="en") """ Language code for PII detection (e.g., en for English) """ diff --git a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py index d8b01b60..4128ced1 100644 --- a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py +++ b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config.py @@ -19,7 +19,9 @@ class AzurePromptShieldGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Azure Prompt Shield for jailbreak and prompt injection detection" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py index 35cf54e9..c93f55bf 100644 --- a/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/azure_prompt_shield_guardrail_config_config.py @@ -17,7 +17,7 @@ class AzurePromptShieldGuardrailConfigConfig(UniversalBaseModel): Name of your Azure Content Safety resource where the Prompt Shield service is deployed (e.g., my-content-safety) """ - api_version: str = pydantic.Field() + api_version: str = pydantic.Field(default="2024-09-01") """ API version for the Prompt Shield API """ diff --git a/src/truefoundry_sdk/types/base_autoscaling.py b/src/truefoundry_sdk/types/base_autoscaling.py index 36351de4..df777249 100644 --- a/src/truefoundry_sdk/types/base_autoscaling.py +++ b/src/truefoundry_sdk/types/base_autoscaling.py @@ -7,7 +7,7 @@ class BaseAutoscaling(UniversalBaseModel): - min_replicas: int = pydantic.Field() + min_replicas: int = pydantic.Field(default=1) """ Minimum number of replicas to keep available """ @@ -17,7 +17,7 @@ class BaseAutoscaling(UniversalBaseModel): Maximum number of replicas allowed for the component. """ - polling_interval: typing.Optional[int] = pydantic.Field(default=None) + polling_interval: typing.Optional[int] = pydantic.Field(default=30) """ This is the interval to check each trigger on. """ diff --git a/src/truefoundry_sdk/types/base_workbench_input.py b/src/truefoundry_sdk/types/base_workbench_input.py index 550d8ee0..908053bf 100644 --- a/src/truefoundry_sdk/types/base_workbench_input.py +++ b/src/truefoundry_sdk/types/base_workbench_input.py @@ -20,7 +20,7 @@ class BaseWorkbenchInput(UniversalBaseModel): > Name can only contain alphanumeric characters and '-' and can be atmost 25 characters long """ - home_directory_size: int = pydantic.Field() + home_directory_size: int = pydantic.Field(default=20) """ Size of the home directory for the workbench (Persistent Storage) """ diff --git a/src/truefoundry_sdk/types/blue_green.py b/src/truefoundry_sdk/types/blue_green.py index 23e7d6ec..9fc217bb 100644 --- a/src/truefoundry_sdk/types/blue_green.py +++ b/src/truefoundry_sdk/types/blue_green.py @@ -17,12 +17,12 @@ class BlueGreen(UniversalBaseModel): +value=blue_green """ - enable_auto_promotion: typing.Optional[bool] = pydantic.Field(default=None) + enable_auto_promotion: typing.Optional[bool] = pydantic.Field(default=False) """ Promote the new release to handle the complete traffic. A manual promotion would be needed if this is disabled """ - auto_promotion_seconds: typing.Optional[int] = pydantic.Field(default=None) + auto_promotion_seconds: typing.Optional[int] = pydantic.Field(default=30) """ Promote the new release to handle the complete traffic after waiting for these many seconds """ diff --git a/src/truefoundry_sdk/types/budget_rule.py b/src/truefoundry_sdk/types/budget_rule.py index 9ad1e509..26d37c5b 100644 --- a/src/truefoundry_sdk/types/budget_rule.py +++ b/src/truefoundry_sdk/types/budget_rule.py @@ -32,7 +32,7 @@ class BudgetRule(UniversalBaseModel): """ alerts: typing.Optional[BudgetAlert] = None - audit_mode: typing.Optional[bool] = pydantic.Field(default=None) + audit_mode: typing.Optional[bool] = pydantic.Field(default=False) """ When enabled, requests exceeding the budget are tracked but not blocked """ diff --git a/src/truefoundry_sdk/types/cedar_guardrail_config.py b/src/truefoundry_sdk/types/cedar_guardrail_config.py index 429afd2b..e4816096 100644 --- a/src/truefoundry_sdk/types/cedar_guardrail_config.py +++ b/src/truefoundry_sdk/types/cedar_guardrail_config.py @@ -18,7 +18,9 @@ class CedarGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Enforces access control policies using Cedar policy language" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py b/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py index d95126c4..de72cce1 100644 --- a/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py +++ b/src/truefoundry_sdk/types/code_safety_linter_guardrail_config.py @@ -17,7 +17,9 @@ class CodeSafetyLinterGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Detects unsafe code patterns in tool outputs (eval, exec, os.system, subprocess, rm -rf)" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/common_tools_settings.py b/src/truefoundry_sdk/types/common_tools_settings.py index e1845171..a9810265 100644 --- a/src/truefoundry_sdk/types/common_tools_settings.py +++ b/src/truefoundry_sdk/types/common_tools_settings.py @@ -16,31 +16,31 @@ class CommonToolsSettings(UniversalBaseModel): +value=settings/common-tools """ - web_search: bool = pydantic.Field() + web_search: bool = pydantic.Field(default=True) """ Enable web search tool Allows model to search the web for information. """ - code_executor: bool = pydantic.Field() + code_executor: bool = pydantic.Field(default=True) """ Enable code executor tool Allows model to execute code and return the results. """ - sandbox_exec: bool = pydantic.Field() + sandbox_exec: bool = pydantic.Field(default=True) """ Enable sandbox executor tool Allows model to execute shell command in an isolated stateful sandbox environment. """ - sequential_thinking: bool = pydantic.Field() + sequential_thinking: bool = pydantic.Field(default=True) """ Enable sequential thinking tool Allows model to reason step-by-step to solve complex problems. """ - web_scrape: bool = pydantic.Field() + web_scrape: bool = pydantic.Field(default=True) """ Enable web scraping tool. Allows model to scrape content from web pages with intelligent format selection for structured or unstructured data. diff --git a/src/truefoundry_sdk/types/cron_metric.py b/src/truefoundry_sdk/types/cron_metric.py index 86d361c4..f342d102 100644 --- a/src/truefoundry_sdk/types/cron_metric.py +++ b/src/truefoundry_sdk/types/cron_metric.py @@ -45,7 +45,7 @@ class CronMetric(UniversalBaseModel): ``` """ - timezone: str = pydantic.Field() + timezone: str = pydantic.Field(default="UTC") """ Timezone against which the cron schedule will be calculated, e.g. "Asia/Tokyo". Default is machine's local time. https://docs.truefoundry.com/docs/list-of-supported-timezones diff --git a/src/truefoundry_sdk/types/custom_guardrail_config.py b/src/truefoundry_sdk/types/custom_guardrail_config.py index 9d85b93f..652d0b05 100644 --- a/src/truefoundry_sdk/types/custom_guardrail_config.py +++ b/src/truefoundry_sdk/types/custom_guardrail_config.py @@ -21,7 +21,9 @@ class CustomGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Custom guardrail server for validate or mutate via HTTP endpoint" + ) """ Optional description for this Guardrail Config. """ @@ -45,7 +47,7 @@ class CustomGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/custom_regex_pattern.py b/src/truefoundry_sdk/types/custom_regex_pattern.py index dd42d4dc..2670d73a 100644 --- a/src/truefoundry_sdk/types/custom_regex_pattern.py +++ b/src/truefoundry_sdk/types/custom_regex_pattern.py @@ -16,7 +16,7 @@ class CustomRegexPattern(UniversalBaseModel): A custom regex pattern to match against content (e.g., "\\\\b\\\\d{3}-\\\\d{2}-\\\\d{4}\\\\b" for SSN) """ - redaction_text: typing.Optional[str] = pydantic.Field(default=None) + redaction_text: typing.Optional[str] = pydantic.Field(default="[REDACTED]") """ Text to use when redacting matched content (only applicable in mutate mode). Defaults to '[REDACTED]'. """ diff --git a/src/truefoundry_sdk/types/custom_tls_settings.py b/src/truefoundry_sdk/types/custom_tls_settings.py index 8b5229a5..e62aa26e 100644 --- a/src/truefoundry_sdk/types/custom_tls_settings.py +++ b/src/truefoundry_sdk/types/custom_tls_settings.py @@ -11,7 +11,7 @@ class CustomTlsSettings(UniversalBaseModel): Configure TLS settings for secure connections with custom CA certificates. """ - reject_unauthorized: bool = pydantic.Field() + reject_unauthorized: bool = pydantic.Field(default=True) """ When set to true, it will reject any connection which is not authorized with the list of supplied CAs. """ diff --git a/src/truefoundry_sdk/types/data_access_rule_base.py b/src/truefoundry_sdk/types/data_access_rule_base.py index e0d68429..ff01e08b 100644 --- a/src/truefoundry_sdk/types/data_access_rule_base.py +++ b/src/truefoundry_sdk/types/data_access_rule_base.py @@ -22,7 +22,7 @@ class DataAccessRuleBase(UniversalBaseModel): Description of the rule """ - enabled: typing.Optional[bool] = pydantic.Field(default=None) + enabled: typing.Optional[bool] = pydantic.Field(default=True) """ Whether this rule is enabled """ diff --git a/src/truefoundry_sdk/types/databricks_job_task_config.py b/src/truefoundry_sdk/types/databricks_job_task_config.py index 020ba5ed..e41585bb 100644 --- a/src/truefoundry_sdk/types/databricks_job_task_config.py +++ b/src/truefoundry_sdk/types/databricks_job_task_config.py @@ -48,7 +48,7 @@ class DatabricksJobTaskConfig(UniversalBaseModel): Maximum seconds to wait for the job run to complete. Used by CLI when polling. """ - skip_wait_for_completion: typing.Optional[bool] = pydantic.Field(default=None) + skip_wait_for_completion: typing.Optional[bool] = pydantic.Field(default=False) """ If false, the task waits for the Databricks job run to complete (trigger and poll). If true, only triggers the job and returns. Default false. """ diff --git a/src/truefoundry_sdk/types/docker_file_build.py b/src/truefoundry_sdk/types/docker_file_build.py index 3a7192e3..d4de4824 100644 --- a/src/truefoundry_sdk/types/docker_file_build.py +++ b/src/truefoundry_sdk/types/docker_file_build.py @@ -18,12 +18,12 @@ class DockerFileBuild(UniversalBaseModel): +value=dockerfile """ - dockerfile_path: str = pydantic.Field() + dockerfile_path: str = pydantic.Field(default="./Dockerfile") """ The file path of the Dockerfile relative to project root path. """ - build_context_path: str = pydantic.Field() + build_context_path: str = pydantic.Field(default="./") """ Build context path for the Dockerfile relative to project root path. """ diff --git a/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py b/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py index 2cee7ec3..c68bc092 100644 --- a/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py +++ b/src/truefoundry_sdk/types/enkrypt_ai_guardrail_config.py @@ -20,7 +20,9 @@ class EnkryptAiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Enkrypt AI guardrails for content safety and policy enforcement" + ) """ Optional description for this Guardrail Config. """ @@ -40,7 +42,7 @@ class EnkryptAiGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/exact_match_cache_config.py b/src/truefoundry_sdk/types/exact_match_cache_config.py index 1ef70372..469459a4 100644 --- a/src/truefoundry_sdk/types/exact_match_cache_config.py +++ b/src/truefoundry_sdk/types/exact_match_cache_config.py @@ -17,7 +17,7 @@ class ExactMatchCacheConfig(UniversalBaseModel): Cache namespace (defaults to 'default' if not provided) """ - ttl: float = pydantic.Field() + ttl: float = pydantic.Field(default=3600.0) """ Time-to-live for cached entries in seconds (max 3 days) """ diff --git a/src/truefoundry_sdk/types/fiddler_guardrail_config.py b/src/truefoundry_sdk/types/fiddler_guardrail_config.py index b23aa2cb..8abd8593 100644 --- a/src/truefoundry_sdk/types/fiddler_guardrail_config.py +++ b/src/truefoundry_sdk/types/fiddler_guardrail_config.py @@ -19,7 +19,9 @@ class FiddlerGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Fiddler for harmful content detection or response faithfulness checks" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/function_schema.py b/src/truefoundry_sdk/types/function_schema.py index 7824d6de..fdc8bb2e 100644 --- a/src/truefoundry_sdk/types/function_schema.py +++ b/src/truefoundry_sdk/types/function_schema.py @@ -26,7 +26,7 @@ class FunctionSchema(UniversalBaseModel): Parameters schema for the function """ - strict: typing.Optional[bool] = pydantic.Field(default=None) + strict: typing.Optional[bool] = pydantic.Field(default=False) """ Indicates if the function should be called strictly """ diff --git a/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py b/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py index e56eb065..91f1a601 100644 --- a/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py +++ b/src/truefoundry_sdk/types/gateway_data_routing_config_destination.py @@ -18,7 +18,7 @@ class GatewayDataRoutingConfigDestination(GatewayDataRoutingConfigDestinationSto Name for the destination """ - enabled: bool = pydantic.Field() + enabled: bool = pydantic.Field(default=True) """ Whether this destination is enabled """ diff --git a/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py b/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py index 4c396983..b58c4779 100644 --- a/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py +++ b/src/truefoundry_sdk/types/google_model_armor_guardrail_config.py @@ -20,7 +20,9 @@ class GoogleModelArmorGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Google Cloud Model Armor for prompt injection, harmful content, PII, and malicious URI detection" + ) """ Optional description for this Guardrail Config. """ @@ -43,7 +45,7 @@ class GoogleModelArmorGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py b/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py index e4ee0ca6..9232d4e2 100644 --- a/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py +++ b/src/truefoundry_sdk/types/gray_swan_cygnal_guardrail_config.py @@ -19,7 +19,9 @@ class GraySwanCygnalGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="GraySwan Cygnal for policy violation and content safety monitoring" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/header_match.py b/src/truefoundry_sdk/types/header_match.py index cdfcce5c..8bcdee22 100644 --- a/src/truefoundry_sdk/types/header_match.py +++ b/src/truefoundry_sdk/types/header_match.py @@ -17,7 +17,7 @@ class HeaderMatch(UniversalBaseModel): Header name to match on """ - exact_match: str = pydantic.Field() + exact_match: str = pydantic.Field(default="") """ Header value to match on """ diff --git a/src/truefoundry_sdk/types/health_probe.py b/src/truefoundry_sdk/types/health_probe.py index fd06da28..aa838560 100644 --- a/src/truefoundry_sdk/types/health_probe.py +++ b/src/truefoundry_sdk/types/health_probe.py @@ -14,27 +14,27 @@ class HealthProbe(UniversalBaseModel): """ config: HttpProbe - initial_delay_seconds: typing.Optional[int] = pydantic.Field(default=None) + initial_delay_seconds: typing.Optional[int] = pydantic.Field(default=0) """ Time to wait after container has started before checking the endpoint """ - period_seconds: typing.Optional[int] = pydantic.Field(default=None) + period_seconds: typing.Optional[int] = pydantic.Field(default=10) """ How often to check the endpoint """ - timeout_seconds: typing.Optional[int] = pydantic.Field(default=None) + timeout_seconds: typing.Optional[int] = pydantic.Field(default=1) """ Time to wait for a response from the endpoint before considering it down """ - success_threshold: typing.Optional[int] = pydantic.Field(default=None) + success_threshold: typing.Optional[int] = pydantic.Field(default=1) """ Number of successful responses from the endpoint before container is considered healthy """ - failure_threshold: typing.Optional[int] = pydantic.Field(default=None) + failure_threshold: typing.Optional[int] = pydantic.Field(default=3) """ Number of consecutive failures before the container is considered down """ diff --git a/src/truefoundry_sdk/types/http_probe.py b/src/truefoundry_sdk/types/http_probe.py index d7fbcfbf..d81d0a92 100644 --- a/src/truefoundry_sdk/types/http_probe.py +++ b/src/truefoundry_sdk/types/http_probe.py @@ -32,7 +32,7 @@ class HttpProbe(UniversalBaseModel): Host name to connect to, defaults to the pod IP """ - scheme: typing.Optional[str] = pydantic.Field(default=None) + scheme: typing.Optional[str] = pydantic.Field(default="HTTP") """ Scheme to use for connecting to the host """ diff --git a/src/truefoundry_sdk/types/ingress_controller_config.py b/src/truefoundry_sdk/types/ingress_controller_config.py index 1ad2a533..92744e6e 100644 --- a/src/truefoundry_sdk/types/ingress_controller_config.py +++ b/src/truefoundry_sdk/types/ingress_controller_config.py @@ -7,12 +7,12 @@ class IngressControllerConfig(UniversalBaseModel): - ingress_class_name: str = pydantic.Field() + ingress_class_name: str = pydantic.Field(default="nginx") """ Ingress Class Name """ - tls_enabled: typing.Optional[bool] = pydantic.Field(default=None) + tls_enabled: typing.Optional[bool] = pydantic.Field(default=False) """ Whether TLS is managed by the ingress controller. If enabled, the ingress object will have TLS configuration. """ diff --git a/src/truefoundry_sdk/types/internal_model_version.py b/src/truefoundry_sdk/types/internal_model_version.py index 7ab3aa51..38f70fea 100644 --- a/src/truefoundry_sdk/types/internal_model_version.py +++ b/src/truefoundry_sdk/types/internal_model_version.py @@ -75,7 +75,7 @@ class InternalModelVersion(UniversalBaseModel): List of metrics associated with this model version """ - deployable: typing.Optional[bool] = pydantic.Field(default=None) + deployable: typing.Optional[bool] = pydantic.Field(default=False) """ Whether this model version is ready for deployment """ diff --git a/src/truefoundry_sdk/types/job.py b/src/truefoundry_sdk/types/job.py index ee6158f4..7ea23b9f 100644 --- a/src/truefoundry_sdk/types/job.py +++ b/src/truefoundry_sdk/types/job.py @@ -59,7 +59,7 @@ class Job(UniversalBaseModel): Configure alerts to be sent when the job starts/fails/completes """ - retries: typing.Optional[int] = pydantic.Field(default=None) + retries: typing.Optional[int] = pydantic.Field(default=0) """ Specify the maximum number of attempts to retry a job before it is marked as failed. """ diff --git a/src/truefoundry_sdk/types/job_alert.py b/src/truefoundry_sdk/types/job_alert.py index aafef422..ad681930 100644 --- a/src/truefoundry_sdk/types/job_alert.py +++ b/src/truefoundry_sdk/types/job_alert.py @@ -23,13 +23,13 @@ class JobAlert(UniversalBaseModel): """ notification_target: typing.Optional[NotificationTarget] = None - on_start: typing.Optional[bool] = pydantic.Field(default=None) + on_start: typing.Optional[bool] = pydantic.Field(default=False) """ Send an alert when the job starts """ - on_completion: typing.Optional[bool] = None - on_failure: typing.Optional[bool] = pydantic.Field(default=None) + on_completion: typing.Optional[bool] = False + on_failure: typing.Optional[bool] = pydantic.Field(default=True) """ Send an alert when the job fails """ diff --git a/src/truefoundry_sdk/types/kafka_input_config.py b/src/truefoundry_sdk/types/kafka_input_config.py index 0a3ad185..7a7da58f 100644 --- a/src/truefoundry_sdk/types/kafka_input_config.py +++ b/src/truefoundry_sdk/types/kafka_input_config.py @@ -32,12 +32,12 @@ class KafkaInputConfig(UniversalBaseModel): The name of the consumer group to join for dynamic partition assignment """ - tls: bool = pydantic.Field() + tls: bool = pydantic.Field(default=True) """ TLS configuration for SASL authentication """ - wait_time_seconds: typing.Optional[int] = pydantic.Field(default=None) + wait_time_seconds: typing.Optional[int] = pydantic.Field(default=10) """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/kafka_output_config.py b/src/truefoundry_sdk/types/kafka_output_config.py index 37460632..c148379e 100644 --- a/src/truefoundry_sdk/types/kafka_output_config.py +++ b/src/truefoundry_sdk/types/kafka_output_config.py @@ -27,7 +27,7 @@ class KafkaOutputConfig(UniversalBaseModel): Kafka topic to publish to """ - tls: bool = pydantic.Field() + tls: bool = pydantic.Field(default=True) """ TLS configuration for SASL authentication """ diff --git a/src/truefoundry_sdk/types/latency_based_load_balance_target.py b/src/truefoundry_sdk/types/latency_based_load_balance_target.py index 1d4840b9..f2366fca 100644 --- a/src/truefoundry_sdk/types/latency_based_load_balance_target.py +++ b/src/truefoundry_sdk/types/latency_based_load_balance_target.py @@ -24,7 +24,7 @@ class LatencyBasedLoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) + 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 targets of this load-balance-rule """ diff --git a/src/truefoundry_sdk/types/load_balance_target.py b/src/truefoundry_sdk/types/load_balance_target.py index de2df3d9..b1885521 100644 --- a/src/truefoundry_sdk/types/load_balance_target.py +++ b/src/truefoundry_sdk/types/load_balance_target.py @@ -29,7 +29,7 @@ class LoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) + 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 targets of this load-balance-rule """ diff --git a/src/truefoundry_sdk/types/local_source.py b/src/truefoundry_sdk/types/local_source.py index bc3fd008..c922bcb2 100644 --- a/src/truefoundry_sdk/types/local_source.py +++ b/src/truefoundry_sdk/types/local_source.py @@ -16,12 +16,12 @@ class LocalSource(UniversalBaseModel): +value=local """ - project_root_path: str = pydantic.Field() + project_root_path: str = pydantic.Field(default="./") """ Local project root path. """ - local_build: bool = pydantic.Field() + local_build: bool = pydantic.Field(default=True) """ run docker build locally """ diff --git a/src/truefoundry_sdk/types/logging_config.py b/src/truefoundry_sdk/types/logging_config.py index 3956e12c..a21afc1e 100644 --- a/src/truefoundry_sdk/types/logging_config.py +++ b/src/truefoundry_sdk/types/logging_config.py @@ -11,7 +11,7 @@ class LoggingConfig(UniversalBaseModel): Logging configuration for the chat prompt """ - enabled: bool = pydantic.Field() + enabled: bool = pydantic.Field(default=True) """ Whether logging is enabled for the chat prompt """ diff --git a/src/truefoundry_sdk/types/mcp_server_with_fqn.py b/src/truefoundry_sdk/types/mcp_server_with_fqn.py index a552af22..6dae4cd0 100644 --- a/src/truefoundry_sdk/types/mcp_server_with_fqn.py +++ b/src/truefoundry_sdk/types/mcp_server_with_fqn.py @@ -22,7 +22,7 @@ class McpServerWithFqn(UniversalBaseModel): The FQN of the MCP server """ - enable_all_tools: bool = pydantic.Field() + enable_all_tools: bool = pydantic.Field(default=False) """ Whether to enable all tools from the MCP server """ diff --git a/src/truefoundry_sdk/types/mcp_server_with_url.py b/src/truefoundry_sdk/types/mcp_server_with_url.py index d24d690e..39cc7d04 100644 --- a/src/truefoundry_sdk/types/mcp_server_with_url.py +++ b/src/truefoundry_sdk/types/mcp_server_with_url.py @@ -27,7 +27,7 @@ class McpServerWithUrl(UniversalBaseModel): The headers to send to the MCP server """ - enable_all_tools: bool = pydantic.Field() + enable_all_tools: bool = pydantic.Field(default=False) """ Whether to enable all tools from the MCP server """ diff --git a/src/truefoundry_sdk/types/mcp_tool_target.py b/src/truefoundry_sdk/types/mcp_tool_target.py index 297a0187..28f1a422 100644 --- a/src/truefoundry_sdk/types/mcp_tool_target.py +++ b/src/truefoundry_sdk/types/mcp_tool_target.py @@ -12,7 +12,7 @@ class McpToolTarget(UniversalBaseModel): Name of the MCP server """ - enable_all_tools: bool = pydantic.Field() + enable_all_tools: bool = pydantic.Field(default=False) """ When enabled, all tools from this MCP server are targeted. Disable to select specific tools. """ diff --git a/src/truefoundry_sdk/types/metric.py b/src/truefoundry_sdk/types/metric.py index 8586c477..d3db678c 100644 --- a/src/truefoundry_sdk/types/metric.py +++ b/src/truefoundry_sdk/types/metric.py @@ -22,7 +22,7 @@ class Metric(UniversalBaseModel): Timestamp when the metric was recorded (epoch milliseconds) """ - step: typing.Optional[int] = pydantic.Field(default=None) + step: typing.Optional[int] = pydantic.Field(default=0) """ Training step number when the metric was recorded """ diff --git a/src/truefoundry_sdk/types/model_manifest.py b/src/truefoundry_sdk/types/model_manifest.py index 8083a419..d47960a2 100644 --- a/src/truefoundry_sdk/types/model_manifest.py +++ b/src/truefoundry_sdk/types/model_manifest.py @@ -48,7 +48,7 @@ class ModelManifest(UniversalBaseModel): """ environment: typing.Optional[ModelVersionEnvironment] = None - step: typing.Optional[int] = pydantic.Field(default=None) + step: typing.Optional[int] = pydantic.Field(default=0) """ Step/Epoch number in an iterative training loop the model version was created. Generally useful when logging a model version from a MLRepo Run """ diff --git a/src/truefoundry_sdk/types/model_version.py b/src/truefoundry_sdk/types/model_version.py index 4a3c0216..60680199 100644 --- a/src/truefoundry_sdk/types/model_version.py +++ b/src/truefoundry_sdk/types/model_version.py @@ -75,7 +75,7 @@ class ModelVersion(UniversalBaseModel): List of metrics associated with this model version """ - deployable: typing.Optional[bool] = pydantic.Field(default=None) + deployable: typing.Optional[bool] = pydantic.Field(default=False) """ Whether this model version is ready for deployment """ diff --git a/src/truefoundry_sdk/types/nats_input_config.py b/src/truefoundry_sdk/types/nats_input_config.py index 5f1ec645..efaf9cd9 100644 --- a/src/truefoundry_sdk/types/nats_input_config.py +++ b/src/truefoundry_sdk/types/nats_input_config.py @@ -37,7 +37,7 @@ class NatsInputConfig(UniversalBaseModel): Consumer name of input NATS """ - wait_time_seconds: int = pydantic.Field() + wait_time_seconds: int = pydantic.Field(default=19) """ Wait timeout for long polling. """ diff --git a/src/truefoundry_sdk/types/nats_user_password_auth.py b/src/truefoundry_sdk/types/nats_user_password_auth.py index 331c0fe6..d882ee25 100644 --- a/src/truefoundry_sdk/types/nats_user_password_auth.py +++ b/src/truefoundry_sdk/types/nats_user_password_auth.py @@ -11,7 +11,7 @@ class NatsUserPasswordAuth(UniversalBaseModel): NATS User Password Authentication """ - account_name: str = pydantic.Field() + account_name: str = pydantic.Field(default="$G") """ Name of the NATS account """ diff --git a/src/truefoundry_sdk/types/notebook.py b/src/truefoundry_sdk/types/notebook.py index 84dbee10..77d15c6c 100644 --- a/src/truefoundry_sdk/types/notebook.py +++ b/src/truefoundry_sdk/types/notebook.py @@ -19,7 +19,7 @@ class Notebook(BaseWorkbenchInput): """ image: WorkbenchImage - cull_timeout: typing.Optional[int] = pydantic.Field(default=None) + cull_timeout: typing.Optional[int] = pydantic.Field(default=30) """ Stop the notebook instance after this much time in minutes of inactivity. The notebook instance will be stopped even if the notebook is open in your browser, but nothing is running on the notebook. diff --git a/src/truefoundry_sdk/types/opa_guardrail_config.py b/src/truefoundry_sdk/types/opa_guardrail_config.py index 3675712e..77325ed8 100644 --- a/src/truefoundry_sdk/types/opa_guardrail_config.py +++ b/src/truefoundry_sdk/types/opa_guardrail_config.py @@ -19,7 +19,9 @@ class OpaGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Open Policy Agent (OPA) for policy-based access control and validation" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py index 6a47496f..04041bfc 100644 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py +++ b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config.py @@ -19,7 +19,9 @@ class OpenAiModerationsGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="OpenAI content moderation for hate, harassment, self-harm, sexual, violence, and illicit content" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py index a8081a29..fcd4f372 100644 --- a/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/open_ai_moderations_guardrail_config_config.py @@ -12,7 +12,7 @@ class OpenAiModerationsGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - model: str = pydantic.Field() + model: str = pydantic.Field(default="omni-moderation-latest") """ The model to use for the OpenAI Moderation API. """ diff --git a/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py index efee0680..db1b996f 100644 --- a/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py +++ b/src/truefoundry_sdk/types/palo_alto_prisma_airs_guardrail_config.py @@ -19,7 +19,9 @@ class PaloAltoPrismaAirsGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Palo Alto Prisma AIRS for AI security and content validation" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/pangea_guardrail_config.py b/src/truefoundry_sdk/types/pangea_guardrail_config.py index 81a8928e..0e66c54f 100644 --- a/src/truefoundry_sdk/types/pangea_guardrail_config.py +++ b/src/truefoundry_sdk/types/pangea_guardrail_config.py @@ -20,7 +20,9 @@ class PangeaGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Pangea textGuard for text security or PII detection and redaction" + ) """ Optional description for this Guardrail Config. """ @@ -39,7 +41,7 @@ class PangeaGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/patronus_guardrail_config.py b/src/truefoundry_sdk/types/patronus_guardrail_config.py index 4fab554d..49f230ad 100644 --- a/src/truefoundry_sdk/types/patronus_guardrail_config.py +++ b/src/truefoundry_sdk/types/patronus_guardrail_config.py @@ -19,7 +19,9 @@ class PatronusGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Patronus evaluators for relevance, safety, PII, PHI, toxicity, and more" + ) """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/poetry.py b/src/truefoundry_sdk/types/poetry.py index 6a4f16ed..b7762ab1 100644 --- a/src/truefoundry_sdk/types/poetry.py +++ b/src/truefoundry_sdk/types/poetry.py @@ -17,7 +17,7 @@ class Poetry(UniversalBaseModel): +value=poetry """ - poetry_version: typing.Optional[str] = pydantic.Field(default=None) + poetry_version: typing.Optional[str] = pydantic.Field(default="latest") """ Poetry version to use """ diff --git a/src/truefoundry_sdk/types/port.py b/src/truefoundry_sdk/types/port.py index 3bc7db57..9f038c06 100644 --- a/src/truefoundry_sdk/types/port.py +++ b/src/truefoundry_sdk/types/port.py @@ -14,7 +14,7 @@ class Port(UniversalBaseModel): Describes the ports the service should be exposed to. """ - port: int = pydantic.Field() + port: int = pydantic.Field(default=80) """ Port number to expose. """ @@ -24,7 +24,7 @@ class Port(UniversalBaseModel): Protocol for the port. """ - expose: bool = pydantic.Field() + expose: bool = pydantic.Field(default=True) """ Expose the port """ diff --git a/src/truefoundry_sdk/types/priority_based_load_balance_target.py b/src/truefoundry_sdk/types/priority_based_load_balance_target.py index ee5e68a9..bfc86549 100644 --- a/src/truefoundry_sdk/types/priority_based_load_balance_target.py +++ b/src/truefoundry_sdk/types/priority_based_load_balance_target.py @@ -15,7 +15,7 @@ class PriorityBasedLoadBalanceTarget(UniversalBaseModel): Target model or provider FQN """ - priority: int = pydantic.Field() + priority: int = pydantic.Field(default=0) """ Priority for the target, Lower the number, higher the priority (0 is the highest priority) """ @@ -27,7 +27,7 @@ class PriorityBasedLoadBalanceTarget(UniversalBaseModel): Status Codes for which the request will fallback to other targets. If the status code is not present in fallback_status_codes, it fails immediately. """ - fallback_candidate: typing.Optional[bool] = pydantic.Field(default=None) + 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 targets of this load-balance-rule """ diff --git a/src/truefoundry_sdk/types/prometheus_alert_rule.py b/src/truefoundry_sdk/types/prometheus_alert_rule.py index 12dbb6e5..0dbb1fbc 100644 --- a/src/truefoundry_sdk/types/prometheus_alert_rule.py +++ b/src/truefoundry_sdk/types/prometheus_alert_rule.py @@ -43,7 +43,7 @@ class PrometheusAlertRule(UniversalBaseModel): Description of the alert rule which will be displayed in the alert rule list. This can be used to provide more context about the alert rule. """ - notification_enabled: bool = pydantic.Field() + notification_enabled: bool = pydantic.Field(default=True) """ When enabled, notifications will be sent to all configured target channels when the alert conditions are met. """ diff --git a/src/truefoundry_sdk/types/python_build.py b/src/truefoundry_sdk/types/python_build.py index a4bb5d14..a372ae26 100644 --- a/src/truefoundry_sdk/types/python_build.py +++ b/src/truefoundry_sdk/types/python_build.py @@ -23,7 +23,7 @@ class PythonBuild(UniversalBaseModel): Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python) """ - build_context_path: str = pydantic.Field() + build_context_path: str = pydantic.Field(default="./") """ Build path relative to project root path. """ diff --git a/src/truefoundry_sdk/types/regex_guardrail_config.py b/src/truefoundry_sdk/types/regex_guardrail_config.py index d6449234..18acf1c7 100644 --- a/src/truefoundry_sdk/types/regex_guardrail_config.py +++ b/src/truefoundry_sdk/types/regex_guardrail_config.py @@ -19,7 +19,9 @@ class RegexGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Regex pattern matching for content filtering or redaction" + ) """ Optional description for this Guardrail Config. """ @@ -37,7 +39,7 @@ class RegexGuardrailConfig(UniversalBaseModel): Validate blocks when pattern matches. Mutate replaces matched text and continues. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/resources.py b/src/truefoundry_sdk/types/resources.py index f1ebca90..44d6b261 100644 --- a/src/truefoundry_sdk/types/resources.py +++ b/src/truefoundry_sdk/types/resources.py @@ -13,38 +13,38 @@ class Resources(UniversalBaseModel): Configure resource allocations, specify node constraints and capacity types to improve performance and reduce expenses. [Docs](https://www.truefoundry.com/docs/resources-cpu-memory-storage) """ - cpu_request: float = pydantic.Field() + cpu_request: float = pydantic.Field(default=0.2) """ Requested CPU which determines the minimum cost incurred. The CPU usage can exceed the requested amount, but not the value specified in the limit. 1 CPU means 1 CPU core. Fractional CPU can be requested like `0.5` or `0.05` """ - cpu_limit: float = pydantic.Field() + cpu_limit: float = pydantic.Field(default=0.5) """ CPU limit beyond which the usage cannot be exceeded. 1 CPU means 1 CPU core. Fractional CPU can be requested like `0.5`. CPU limit should be >= cpu request. """ - memory_request: int = pydantic.Field() + memory_request: int = pydantic.Field(default=200) """ Requested memory which determines the minimum cost incurred. The unit of memory is in megabytes(MB). So 1 means 1 MB and 2000 means 2GB. """ - memory_limit: int = pydantic.Field() + memory_limit: int = pydantic.Field(default=500) """ Memory limit after which the application will be killed with an OOM error. The unit of memory is in megabytes(MB). So 1 means 1 MB and 2000 means 2GB. MemoryLimit should be greater than memory request. """ - ephemeral_storage_request: int = pydantic.Field() + ephemeral_storage_request: int = pydantic.Field(default=1000) """ Requested disk storage. The unit of memory is in megabytes(MB). This is ephemeral storage and will be wiped out on pod restarts or eviction """ - ephemeral_storage_limit: int = pydantic.Field() + ephemeral_storage_limit: int = pydantic.Field(default=2000) """ Disk storage limit. The unit of memory is in megabytes(MB). Exceeding this limit will result in eviction. It should be greater than the request. This is ephemeral storage and will be wiped out on pod restarts or eviction diff --git a/src/truefoundry_sdk/types/retry_config.py b/src/truefoundry_sdk/types/retry_config.py index 6abc6397..8dfc105f 100644 --- a/src/truefoundry_sdk/types/retry_config.py +++ b/src/truefoundry_sdk/types/retry_config.py @@ -12,7 +12,7 @@ class RetryConfig(UniversalBaseModel): Number of attempts to retry the request """ - delay: typing.Optional[int] = pydantic.Field(default=None) + delay: typing.Optional[int] = pydantic.Field(default=100) """ Delay between retries in milliseconds """ diff --git a/src/truefoundry_sdk/types/rolling.py b/src/truefoundry_sdk/types/rolling.py index b1925f33..87ec321c 100644 --- a/src/truefoundry_sdk/types/rolling.py +++ b/src/truefoundry_sdk/types/rolling.py @@ -22,14 +22,14 @@ class Rolling(UniversalBaseModel): +value=rolling_update """ - max_unavailable_percentage: int = pydantic.Field() + max_unavailable_percentage: int = pydantic.Field(default=25) """ Percentage of total replicas that can be brought down at one time. For a value of 25 when replicas are set to 12 this would mean minimum (25% of 12) = 3 pods might be unavailable during the deployment. Setting this to a higher value can help in speeding up the deployment process. """ - max_surge_percentage: int = pydantic.Field() + max_surge_percentage: int = pydantic.Field(default=25) """ Percentage of total replicas of updated image that can be brought up over the total replicas count. For a value of 25 when replicas are set to 12 this would mean (12+(25% of 12) = 15) pods might be running at one time. diff --git a/src/truefoundry_sdk/types/secret_detection_guardrail_config.py b/src/truefoundry_sdk/types/secret_detection_guardrail_config.py index fa606d2e..b6a7b69c 100644 --- a/src/truefoundry_sdk/types/secret_detection_guardrail_config.py +++ b/src/truefoundry_sdk/types/secret_detection_guardrail_config.py @@ -19,7 +19,9 @@ class SecretDetectionGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Detects likely credentials/secrets (AWS keys, API keys, JWT tokens, private keys)" + ) """ Optional description for this Guardrail Config. """ @@ -37,7 +39,7 @@ class SecretDetectionGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py b/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py index 9661df3d..3ee0cad5 100644 --- a/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/secret_detection_guardrail_config_config.py @@ -12,7 +12,7 @@ class SecretDetectionGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - redaction_text: typing.Optional[str] = pydantic.Field(default=None) + redaction_text: typing.Optional[str] = pydantic.Field(default="[REDACTED]") """ Text to use when redacting detected secrets in logs and error messages. Defaults to '[REDACTED]'.Only applicable in mutate mode. """ diff --git a/src/truefoundry_sdk/types/semantic_cache_config.py b/src/truefoundry_sdk/types/semantic_cache_config.py index 80d3d515..053ae287 100644 --- a/src/truefoundry_sdk/types/semantic_cache_config.py +++ b/src/truefoundry_sdk/types/semantic_cache_config.py @@ -22,7 +22,7 @@ class SemanticCacheConfig(UniversalBaseModel): Cache namespace (defaults to 'default' if not provided) """ - ttl: float = pydantic.Field() + ttl: float = pydantic.Field(default=3600.0) """ Time-to-live for cached entries in seconds (max 3 days) """ diff --git a/src/truefoundry_sdk/types/service.py b/src/truefoundry_sdk/types/service.py index 567d02d5..180ab206 100644 --- a/src/truefoundry_sdk/types/service.py +++ b/src/truefoundry_sdk/types/service.py @@ -26,7 +26,7 @@ class Service(BaseService): """ auto_shutdown: typing.Optional[Autoshutdown] = None - allow_interception: typing.Optional[bool] = pydantic.Field(default=None) + allow_interception: typing.Optional[bool] = pydantic.Field(default=False) """ Whether to allow intercepts to be applied for this service. This would inject an additional sidecar in each pod of the service. Not recommended on production diff --git a/src/truefoundry_sdk/types/smtp_credentials.py b/src/truefoundry_sdk/types/smtp_credentials.py index f44594be..ea40574d 100644 --- a/src/truefoundry_sdk/types/smtp_credentials.py +++ b/src/truefoundry_sdk/types/smtp_credentials.py @@ -32,12 +32,12 @@ class SmtpCredentials(UniversalBaseModel): The password for the SMTP server. """ - port: int = pydantic.Field() + port: int = pydantic.Field(default=587) """ The port of the SMTP server. """ - tls: bool = pydantic.Field() + tls: bool = pydantic.Field(default=True) """ Whether to use TLS for the SMTP server. """ diff --git a/src/truefoundry_sdk/types/spark_build.py b/src/truefoundry_sdk/types/spark_build.py index 64f0ba8a..0be18066 100644 --- a/src/truefoundry_sdk/types/spark_build.py +++ b/src/truefoundry_sdk/types/spark_build.py @@ -16,12 +16,12 @@ class SparkBuild(UniversalBaseModel): +value=tfy-spark-buildpack """ - spark_version: str = pydantic.Field() + spark_version: str = pydantic.Field(default="3.5.2") """ Spark version should match the spark version installed in the image. """ - build_context_path: str = pydantic.Field() + build_context_path: str = pydantic.Field(default="./") """ Build path relative to project root path. """ diff --git a/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py b/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py index 1ac9e1e8..a706bacc 100644 --- a/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py +++ b/src/truefoundry_sdk/types/spark_executor_dynamic_scaling.py @@ -16,12 +16,12 @@ class SparkExecutorDynamicScaling(UniversalBaseModel): +value=dynamic """ - min: int = pydantic.Field() + min: int = pydantic.Field(default=1) """ Minimum number of instances to start / scale down to """ - max: int = pydantic.Field() + max: int = pydantic.Field(default=1) """ Maximum number of instances to scale up to """ diff --git a/src/truefoundry_sdk/types/spark_executor_fixed_instances.py b/src/truefoundry_sdk/types/spark_executor_fixed_instances.py index 7800d49f..18f31b80 100644 --- a/src/truefoundry_sdk/types/spark_executor_fixed_instances.py +++ b/src/truefoundry_sdk/types/spark_executor_fixed_instances.py @@ -16,7 +16,7 @@ class SparkExecutorFixedInstances(UniversalBaseModel): +value=fixed """ - count: int = pydantic.Field() + count: int = pydantic.Field(default=1) """ Number of instances to start """ diff --git a/src/truefoundry_sdk/types/spark_image.py b/src/truefoundry_sdk/types/spark_image.py index 3c121190..bf4baa60 100644 --- a/src/truefoundry_sdk/types/spark_image.py +++ b/src/truefoundry_sdk/types/spark_image.py @@ -16,7 +16,7 @@ class SparkImage(UniversalBaseModel): +value=spark-image """ - spark_version: str = pydantic.Field() + spark_version: str = pydantic.Field(default="3.5.2") """ Spark version should match the spark version installed in the image. """ diff --git a/src/truefoundry_sdk/types/spark_job.py b/src/truefoundry_sdk/types/spark_job.py index e6a70a1f..b20ab8df 100644 --- a/src/truefoundry_sdk/types/spark_job.py +++ b/src/truefoundry_sdk/types/spark_job.py @@ -50,7 +50,7 @@ class SparkJob(UniversalBaseModel): Configure volumes to be mounted to driver and executors. [Docs](https://docs.truefoundry.com/docs/mounting-volumes-job) """ - retries: typing.Optional[int] = pydantic.Field(default=None) + retries: typing.Optional[int] = pydantic.Field(default=0) """ Specify the maximum number of attempts to retry a job before it is marked as failed. """ diff --git a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py index 018cbb16..d2a2c5a2 100644 --- a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py +++ b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config.py @@ -19,7 +19,9 @@ class SqlSanitizerGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="Detects and sanitizes risky SQL patterns (DROP, TRUNCATE, DELETE/UPDATE without WHERE, string interpolation)" + ) """ Optional description for this Guardrail Config. """ @@ -37,7 +39,7 @@ class SqlSanitizerGuardrailConfig(UniversalBaseModel): Validate (detect and block) or Mutate (detect, sanitize comments, and continue). """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ diff --git a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py index 4f4cd874..6d3dfcd4 100644 --- a/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/sql_sanitizer_guardrail_config_config.py @@ -7,47 +7,47 @@ class SqlSanitizerGuardrailConfigConfig(UniversalBaseModel): - block_drop: typing.Optional[bool] = pydantic.Field(default=None) + block_drop: typing.Optional[bool] = pydantic.Field(default=True) """ Block SQL DROP statements as dangerous operations. """ - block_truncate: typing.Optional[bool] = pydantic.Field(default=None) + block_truncate: typing.Optional[bool] = pydantic.Field(default=True) """ Block SQL TRUNCATE statements as dangerous operations. """ - block_alter: typing.Optional[bool] = pydantic.Field(default=None) + block_alter: typing.Optional[bool] = pydantic.Field(default=True) """ Block SQL ALTER statements as dangerous operations. """ - block_grant: typing.Optional[bool] = pydantic.Field(default=None) + block_grant: typing.Optional[bool] = pydantic.Field(default=True) """ Block SQL GRANT statements as dangerous operations. """ - block_revoke: typing.Optional[bool] = pydantic.Field(default=None) + block_revoke: typing.Optional[bool] = pydantic.Field(default=True) """ Block SQL REVOKE statements as dangerous operations. """ - strip_comments: typing.Optional[bool] = pydantic.Field(default=None) + strip_comments: typing.Optional[bool] = pydantic.Field(default=True) """ Remove SQL comments (-- and block comments) from queries. In mutate mode, comments are stripped from the output. """ - block_delete_without_where: typing.Optional[bool] = pydantic.Field(default=None) + block_delete_without_where: typing.Optional[bool] = pydantic.Field(default=True) """ Flag DELETE FROM statements that lack a WHERE clause as potentially dangerous. """ - block_update_without_where: typing.Optional[bool] = pydantic.Field(default=None) + block_update_without_where: typing.Optional[bool] = pydantic.Field(default=True) """ Flag UPDATE statements that lack a WHERE clause as potentially dangerous. """ - require_parameterization: typing.Optional[bool] = pydantic.Field(default=None) + require_parameterization: typing.Optional[bool] = pydantic.Field(default=False) """ Detect naive string interpolation patterns (+, %., {}) that may indicate SQL injection vulnerabilities. """ diff --git a/src/truefoundry_sdk/types/sqs_input_config.py b/src/truefoundry_sdk/types/sqs_input_config.py index 4c5f9854..f571e9d9 100644 --- a/src/truefoundry_sdk/types/sqs_input_config.py +++ b/src/truefoundry_sdk/types/sqs_input_config.py @@ -32,7 +32,7 @@ class SqsInputConfig(UniversalBaseModel): A period during which Amazon SQS prevents all consumers from receiving and processing the message. If one message takes 5 seconds to process, you can set this number to 7 or any number higher than 5. This will ensure that while the message is being processed, it will not be available to other replicas. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) """ - wait_time_seconds: int = pydantic.Field() + wait_time_seconds: int = pydantic.Field(default=19) """ Wait timeout for long polling. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html) """ diff --git a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py index c0bcf054..15838ec8 100644 --- a/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py +++ b/src/truefoundry_sdk/types/stdio_mcp_server_manifest.py @@ -37,7 +37,7 @@ class StdioMcpServerManifest(UniversalBaseModel): +sort=400 """ - command: str = pydantic.Field() + command: str = pydantic.Field(default="npx") """ Executable to run for the stdio MCP server process. """ diff --git a/src/truefoundry_sdk/types/task_docker_file_build.py b/src/truefoundry_sdk/types/task_docker_file_build.py index 7ca12137..c1a30714 100644 --- a/src/truefoundry_sdk/types/task_docker_file_build.py +++ b/src/truefoundry_sdk/types/task_docker_file_build.py @@ -23,7 +23,7 @@ class TaskDockerFileBuild(UniversalBaseModel): add it through the [Integrations](/integrations?tab=docker-registry) page """ - dockerfile_path: str = pydantic.Field() + dockerfile_path: str = pydantic.Field(default="./Dockerfile") """ The file path of the Dockerfile relative to project root path. """ diff --git a/src/truefoundry_sdk/types/task_py_spark_build.py b/src/truefoundry_sdk/types/task_py_spark_build.py index 360fe68f..594c3533 100644 --- a/src/truefoundry_sdk/types/task_py_spark_build.py +++ b/src/truefoundry_sdk/types/task_py_spark_build.py @@ -17,7 +17,7 @@ class TaskPySparkBuild(UniversalBaseModel): +value=task-pyspark-build """ - spark_version: str = pydantic.Field() + spark_version: str = pydantic.Field(default="3.5.2") """ Spark version should match the spark version installed in the image. """ diff --git a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py index a470fb51..64da5c2c 100644 --- a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config.py @@ -18,7 +18,7 @@ class TfyContentModerationGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field(default="Content moderation guardrail, managed by TrueFoundry") """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py index 38acf7bb..927a74a0 100644 --- a/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py +++ b/src/truefoundry_sdk/types/tfy_content_moderation_guardrail_config_config.py @@ -13,7 +13,7 @@ class TfyContentModerationGuardrailConfigConfig(UniversalBaseModel): +uiProps={"forwardJsonKey": true} """ - severity_threshold: float = pydantic.Field() + severity_threshold: float = pydantic.Field(default=2.0) """ Minimum severity level (0-6) to flag content. 0=Safe, 2=Low risk, 4=Medium risk, 6=High risk """ diff --git a/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py b/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py index f2110996..9a2b1bd1 100644 --- a/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_pii_guardrail_config.py @@ -19,7 +19,9 @@ class TfyPiiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field( + default="PII detection and redaction guardrail, managed by TrueFoundry" + ) """ Optional description for this Guardrail Config. """ @@ -37,7 +39,7 @@ class TfyPiiGuardrailConfig(UniversalBaseModel): The operation type to use for the Guardrail. Validate guardrails are used to validate requests and mutate can validate as well as mutate requests. Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. """ diff --git a/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py b/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py index d2231e7e..8f00b885 100644 --- a/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py +++ b/src/truefoundry_sdk/types/tfy_prompt_injection_guardrail_config.py @@ -17,7 +17,7 @@ class TfyPromptInjectionGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field(default="Prompt injection guardrail, managed by TrueFoundry") """ Optional description for this Guardrail Config. """ diff --git a/src/truefoundry_sdk/types/troj_ai_guardrail_config.py b/src/truefoundry_sdk/types/troj_ai_guardrail_config.py index 0ebcb68a..57b1c058 100644 --- a/src/truefoundry_sdk/types/troj_ai_guardrail_config.py +++ b/src/truefoundry_sdk/types/troj_ai_guardrail_config.py @@ -20,7 +20,7 @@ class TrojAiGuardrailConfig(UniversalBaseModel): The name of the Guardrail Config. """ - description: typing.Optional[str] = pydantic.Field(default=None) + description: typing.Optional[str] = pydantic.Field(default="TrojAI DEFEND firewall for real-time AI security") """ Optional description for this Guardrail Config. """ @@ -40,7 +40,7 @@ class TrojAiGuardrailConfig(UniversalBaseModel): Validate guardrails are run in parallel while mutate guardrails are run sequentially. """ - priority: typing.Optional[int] = pydantic.Field(default=None) + priority: typing.Optional[int] = pydantic.Field(default=1) """ Execution order for mutate guardrails. Lower values run first. Only applicable when operation is mutate. """ 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 e0b9e27b..809fd645 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_mcp_server.py @@ -13,7 +13,7 @@ class TrueFoundryAgentMcpServer(UniversalBaseModel): MCP server name """ - deferred: typing.Optional[bool] = pydantic.Field(default=None) + deferred: typing.Optional[bool] = pydantic.Field(default=False) """ When true, tools from this server are loaded lazily (deferred loading). """ diff --git a/src/truefoundry_sdk/types/ttl_registry.py b/src/truefoundry_sdk/types/ttl_registry.py index e46e4706..98eb9279 100644 --- a/src/truefoundry_sdk/types/ttl_registry.py +++ b/src/truefoundry_sdk/types/ttl_registry.py @@ -21,7 +21,7 @@ class TtlRegistry(UniversalBaseModel): The name of the integration that will be displayed in the TrueFoundry UI. """ - registry_url: str = pydantic.Field() + registry_url: str = pydantic.Field(default="https://ttl.sh") """ The URL of the registry. """ diff --git a/src/truefoundry_sdk/types/uv.py b/src/truefoundry_sdk/types/uv.py index b07e7a6a..dfefdbee 100644 --- a/src/truefoundry_sdk/types/uv.py +++ b/src/truefoundry_sdk/types/uv.py @@ -17,7 +17,7 @@ class Uv(UniversalBaseModel): +value=uv """ - uv_version: typing.Optional[str] = pydantic.Field(default=None) + uv_version: typing.Optional[str] = pydantic.Field(default="latest") """ UV version to use """ diff --git a/src/truefoundry_sdk/types/webhook_bearer_auth.py b/src/truefoundry_sdk/types/webhook_bearer_auth.py index 2f49b11d..3caa261a 100644 --- a/src/truefoundry_sdk/types/webhook_bearer_auth.py +++ b/src/truefoundry_sdk/types/webhook_bearer_auth.py @@ -17,7 +17,7 @@ class WebhookBearerAuth(UniversalBaseModel): Bearer token for authentication """ - prefix: str = pydantic.Field() + prefix: str = pydantic.Field(default="Bearer") """ Prefix for the token """ diff --git a/src/truefoundry_sdk/types/worker_config.py b/src/truefoundry_sdk/types/worker_config.py index 844e1169..3aca0c51 100644 --- a/src/truefoundry_sdk/types/worker_config.py +++ b/src/truefoundry_sdk/types/worker_config.py @@ -19,7 +19,7 @@ class WorkerConfig(UniversalBaseModel): Output Config """ - num_concurrent_workers: int = pydantic.Field() + num_concurrent_workers: int = pydantic.Field(default=1) """ Number of concurrent workers to spawn for the processor """ diff --git a/src/truefoundry_sdk/types/workflow_alert.py b/src/truefoundry_sdk/types/workflow_alert.py index a19d866e..f3e3b4fa 100644 --- a/src/truefoundry_sdk/types/workflow_alert.py +++ b/src/truefoundry_sdk/types/workflow_alert.py @@ -13,12 +13,12 @@ class WorkflowAlert(UniversalBaseModel): """ notification_target: typing.Optional[NotificationTarget] = None - on_completion: typing.Optional[bool] = pydantic.Field(default=None) + on_completion: typing.Optional[bool] = pydantic.Field(default=False) """ Send an alert when the job completes """ - on_failure: typing.Optional[bool] = pydantic.Field(default=None) + on_failure: typing.Optional[bool] = pydantic.Field(default=True) """ Send an alert when the job fails """ diff --git a/src/truefoundry_sdk/users/client.py b/src/truefoundry_sdk/users/client.py index a8fe9ff4..308386f9 100644 --- a/src/truefoundry_sdk/users/client.py +++ b/src/truefoundry_sdk/users/client.py @@ -104,9 +104,9 @@ def pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = OMIT, - skip_if_user_exists: typing.Optional[bool] = OMIT, - dry_run: typing.Optional[bool] = OMIT, + send_invite_email: typing.Optional[bool] = False, + skip_if_user_exists: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = False, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> RegisterUsersResponse: @@ -643,9 +643,9 @@ async def pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = OMIT, - skip_if_user_exists: typing.Optional[bool] = OMIT, - dry_run: typing.Optional[bool] = OMIT, + send_invite_email: typing.Optional[bool] = False, + skip_if_user_exists: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = False, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> RegisterUsersResponse: diff --git a/src/truefoundry_sdk/users/raw_client.py b/src/truefoundry_sdk/users/raw_client.py index e48f88c2..05212206 100644 --- a/src/truefoundry_sdk/users/raw_client.py +++ b/src/truefoundry_sdk/users/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -from ..core.parse_error import ParsingError from ..core.pydantic_utilities import parse_obj_as from ..core.request_options import RequestOptions from ..errors.bad_request_error import BadRequestError @@ -31,7 +30,6 @@ from ..types.register_users_response import RegisterUsersResponse from ..types.update_user_roles_response import UpdateUserRolesResponse from ..types.user import User -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -109,19 +107,15 @@ def list( _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 pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = OMIT, - skip_if_user_exists: typing.Optional[bool] = OMIT, - dry_run: typing.Optional[bool] = OMIT, + send_invite_email: typing.Optional[bool] = False, + skip_if_user_exists: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = False, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[RegisterUsersResponse]: @@ -215,10 +209,6 @@ def pre_register_users( _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 update_roles( @@ -311,10 +301,6 @@ def update_roles( _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[GetUserResponse]: @@ -363,10 +349,6 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non _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( @@ -449,10 +431,6 @@ def delete( _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 invite_user( @@ -536,10 +514,6 @@ def invite_user( _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 deactivate( @@ -616,10 +590,6 @@ def deactivate( _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 activate( @@ -696,10 +666,6 @@ def activate( _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 change_password( @@ -759,10 +725,6 @@ def change_password( _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_resources( @@ -824,10 +786,6 @@ def get_resources( _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_permissions( @@ -889,10 +847,6 @@ def get_permissions( _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_teams( @@ -954,10 +908,6 @@ def get_teams( _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) @@ -1036,19 +986,15 @@ async def _get_next(): _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 pre_register_users( self, *, email: str, - send_invite_email: typing.Optional[bool] = OMIT, - skip_if_user_exists: typing.Optional[bool] = OMIT, - dry_run: typing.Optional[bool] = OMIT, + send_invite_email: typing.Optional[bool] = False, + skip_if_user_exists: typing.Optional[bool] = False, + dry_run: typing.Optional[bool] = False, accept_invite_client_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[RegisterUsersResponse]: @@ -1142,10 +1088,6 @@ async def pre_register_users( _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 update_roles( @@ -1238,10 +1180,6 @@ async def update_roles( _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( @@ -1292,10 +1230,6 @@ async def get( _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( @@ -1378,10 +1312,6 @@ async def delete( _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 invite_user( @@ -1465,10 +1395,6 @@ async def invite_user( _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 deactivate( @@ -1545,10 +1471,6 @@ async def deactivate( _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 activate( @@ -1625,10 +1547,6 @@ async def activate( _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 change_password( @@ -1688,10 +1606,6 @@ async def change_password( _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_resources( @@ -1753,10 +1667,6 @@ async def get_resources( _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_permissions( @@ -1818,10 +1728,6 @@ async def get_permissions( _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_teams( @@ -1883,8 +1789,4 @@ async def get_teams( _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/virtual_accounts/client.py b/src/truefoundry_sdk/virtual_accounts/client.py index 16ab8794..d15cbb59 100644 --- a/src/truefoundry_sdk/virtual_accounts/client.py +++ b/src/truefoundry_sdk/virtual_accounts/client.py @@ -110,7 +110,7 @@ def create_or_update( self, *, manifest: VirtualAccountManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ @@ -469,7 +469,7 @@ async def create_or_update( self, *, manifest: VirtualAccountManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetVirtualAccountResponse: """ diff --git a/src/truefoundry_sdk/virtual_accounts/raw_client.py b/src/truefoundry_sdk/virtual_accounts/raw_client.py index a7553a94..659adf86 100644 --- a/src/truefoundry_sdk/virtual_accounts/raw_client.py +++ b/src/truefoundry_sdk/virtual_accounts/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -22,7 +21,6 @@ from ..types.sync_virtual_account_token_response import SyncVirtualAccountTokenResponse from ..types.virtual_account import VirtualAccount from ..types.virtual_account_manifest import VirtualAccountManifest -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -113,17 +111,13 @@ def list( _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: VirtualAccountManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetVirtualAccountResponse]: """ @@ -195,10 +189,6 @@ def create_or_update( _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( @@ -249,10 +239,6 @@ def get( _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( @@ -303,10 +289,6 @@ def delete( _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_token( @@ -346,10 +328,6 @@ def get_token( _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 sync_to_secret_store( @@ -411,10 +389,6 @@ def sync_to_secret_store( _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( @@ -464,10 +438,6 @@ def regenerate_token( _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_jwt( @@ -502,10 +472,6 @@ def delete_jwt( _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) @@ -597,17 +563,13 @@ async def _get_next(): _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: VirtualAccountManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetVirtualAccountResponse]: """ @@ -679,10 +641,6 @@ async def create_or_update( _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( @@ -733,10 +691,6 @@ async def get( _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( @@ -787,10 +741,6 @@ async def delete( _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_token( @@ -830,10 +780,6 @@ async def get_token( _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 sync_to_secret_store( @@ -895,10 +841,6 @@ async def sync_to_secret_store( _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( @@ -948,10 +890,6 @@ async def regenerate_token( _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_jwt( @@ -986,8 +924,4 @@ async def delete_jwt( _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/workspaces/client.py b/src/truefoundry_sdk/workspaces/client.py index 66e46d7c..c8e232dd 100644 --- a/src/truefoundry_sdk/workspaces/client.py +++ b/src/truefoundry_sdk/workspaces/client.py @@ -109,7 +109,7 @@ def create_or_update( self, *, manifest: WorkspaceManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetWorkspaceResponse: """ @@ -380,7 +380,7 @@ async def create_or_update( self, *, manifest: WorkspaceManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> GetWorkspaceResponse: """ diff --git a/src/truefoundry_sdk/workspaces/raw_client.py b/src/truefoundry_sdk/workspaces/raw_client.py index 4df831b5..56b37d86 100644 --- a/src/truefoundry_sdk/workspaces/raw_client.py +++ b/src/truefoundry_sdk/workspaces/raw_client.py @@ -8,7 +8,6 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, SyncPager -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 @@ -23,7 +22,6 @@ from ..types.workspace import Workspace from ..types.workspace_manifest import WorkspaceManifest from .types.workspaces_delete_response import WorkspacesDeleteResponse -from pydantic import ValidationError # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -114,17 +112,13 @@ def list( _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: WorkspaceManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[GetWorkspaceResponse]: """ @@ -220,10 +214,6 @@ def create_or_update( _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 search( @@ -295,10 +285,6 @@ def search( _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( @@ -349,10 +335,6 @@ def get( _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( @@ -416,10 +398,6 @@ def delete( _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) @@ -511,17 +489,13 @@ async def _get_next(): _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: WorkspaceManifest, - dry_run: typing.Optional[bool] = OMIT, + dry_run: typing.Optional[bool] = False, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[GetWorkspaceResponse]: """ @@ -617,10 +591,6 @@ async def create_or_update( _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 search( @@ -695,10 +665,6 @@ async def _get_next(): _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( @@ -749,10 +715,6 @@ async def get( _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( @@ -816,8 +778,4 @@ async def delete( _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) From d61bf2aac33fb4545fdebf268a14ccf86d970e5f Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 14:36:44 +0000 Subject: [PATCH 6/6] SDK regeneration --- .fern/metadata.json | 2 +- src/truefoundry_sdk/__init__.py | 39 +++++------ src/truefoundry_sdk/types/__init__.py | 39 +++++------ src/truefoundry_sdk/types/custom_endpoint.py | 55 +++++++++++++++ .../types/custom_endpoint_auth_data.py | 9 +++ .../types/custom_endpoint_integrations.py | 5 ++ .../types/custom_endpoint_provider_account.py | 57 +++++++++++++++ ...tom_endpoint_provider_account_auth_data.py | 9 +++ .../types/flyte_task_custom_truefoundry.py | 3 +- .../types/flyte_task_template.py | 19 ++++- .../types/model_provider_account.py | 2 + .../native_snowflake_flyte_task_template.py | 28 -------- ...ve_snowflake_flyte_task_template_config.py | 28 -------- .../types/snowflake_task_config.py | 70 ------------------- .../types/snowflake_task_config_image.py | 8 --- .../snowflake_task_config_mounts_item.py | 9 --- .../types/true_foundry_agent_manifest.py | 6 ++ ...ate_sql.py => true_foundry_agent_skill.py} | 12 +++- .../types/truefoundry_flyte_task_template.py | 21 ------ 19 files changed, 207 insertions(+), 214 deletions(-) create mode 100644 src/truefoundry_sdk/types/custom_endpoint.py create mode 100644 src/truefoundry_sdk/types/custom_endpoint_auth_data.py create mode 100644 src/truefoundry_sdk/types/custom_endpoint_integrations.py create mode 100644 src/truefoundry_sdk/types/custom_endpoint_provider_account.py create mode 100644 src/truefoundry_sdk/types/custom_endpoint_provider_account_auth_data.py delete mode 100644 src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py delete mode 100644 src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.py delete mode 100644 src/truefoundry_sdk/types/snowflake_task_config.py delete mode 100644 src/truefoundry_sdk/types/snowflake_task_config_image.py delete mode 100644 src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py rename src/truefoundry_sdk/types/{native_snowflake_flyte_task_template_sql.py => true_foundry_agent_skill.py} (56%) delete mode 100644 src/truefoundry_sdk/types/truefoundry_flyte_task_template.py diff --git a/.fern/metadata.json b/.fern/metadata.json index fdd9d299..6b0f1b2e 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -22,6 +22,6 @@ "numpydoc": ">=1.7.0,<2.0.0" } }, - "originGitCommit": "0a7e4e0f82186360e1999b049382462657c261cc", + "originGitCommit": "457642c2a485b1c6e24d08e227bc40f36ccedd57", "sdkVersion": "0.0.0" } \ No newline at end of file diff --git a/src/truefoundry_sdk/__init__.py b/src/truefoundry_sdk/__init__.py index fbd31171..aeac82ad 100644 --- a/src/truefoundry_sdk/__init__.py +++ b/src/truefoundry_sdk/__init__.py @@ -225,6 +225,11 @@ CustomBasicAuth, CustomBearerAuth, CustomBlobStorage, + CustomEndpoint, + CustomEndpointAuthData, + CustomEndpointIntegrations, + CustomEndpointProviderAccount, + CustomEndpointProviderAccountAuthData, CustomFramework, CustomGuardrailConfig, CustomGuardrailConfigAuthData, @@ -606,9 +611,6 @@ MultiPartUpload, MultiPartUploadResponse, MultiPartUploadStorageProvider, - NativeSnowflakeFlyteTaskTemplate, - NativeSnowflakeFlyteTaskTemplateConfig, - NativeSnowflakeFlyteTaskTemplateSql, NatsInputConfig, NatsMetricConfig, NatsOutputConfig, @@ -843,9 +845,6 @@ SnowflakeCortexModel, SnowflakeCortexPatTokenAuth, SnowflakeCortexProviderAccount, - SnowflakeTaskConfig, - SnowflakeTaskConfigImage, - SnowflakeTaskConfigMountsItem, SortDirection, SpaCyFramework, SpanAttributeFilter, @@ -949,6 +948,7 @@ TrueFoundryAgentManifestSandbox, TrueFoundryAgentMcpServer, TrueFoundryAgentMcpTool, + TrueFoundryAgentSkill, TrueFoundryAgentUserMessage, TrueFoundryAgentVariable, TrueFoundryApplyRequestManifest, @@ -962,7 +962,6 @@ TrueFoundryInteractiveLogin, TrueFoundryManagedSource, TrueFoundryProviderAccount, - TruefoundryFlyteTaskTemplate, TtlIntegrations, TtlProviderAccount, TtlRegistry, @@ -1303,6 +1302,11 @@ "CustomBasicAuth": ".types", "CustomBearerAuth": ".types", "CustomBlobStorage": ".types", + "CustomEndpoint": ".types", + "CustomEndpointAuthData": ".types", + "CustomEndpointIntegrations": ".types", + "CustomEndpointProviderAccount": ".types", + "CustomEndpointProviderAccountAuthData": ".types", "CustomFramework": ".types", "CustomGuardrailConfig": ".types", "CustomGuardrailConfigAuthData": ".types", @@ -1688,9 +1692,6 @@ "MultiPartUpload": ".types", "MultiPartUploadResponse": ".types", "MultiPartUploadStorageProvider": ".types", - "NativeSnowflakeFlyteTaskTemplate": ".types", - "NativeSnowflakeFlyteTaskTemplateConfig": ".types", - "NativeSnowflakeFlyteTaskTemplateSql": ".types", "NatsInputConfig": ".types", "NatsMetricConfig": ".types", "NatsOutputConfig": ".types", @@ -1928,9 +1929,6 @@ "SnowflakeCortexModel": ".types", "SnowflakeCortexPatTokenAuth": ".types", "SnowflakeCortexProviderAccount": ".types", - "SnowflakeTaskConfig": ".types", - "SnowflakeTaskConfigImage": ".types", - "SnowflakeTaskConfigMountsItem": ".types", "SortDirection": ".types", "SpaCyFramework": ".types", "SpanAttributeFilter": ".types", @@ -2038,6 +2036,7 @@ "TrueFoundryAgentManifestSandbox": ".types", "TrueFoundryAgentMcpServer": ".types", "TrueFoundryAgentMcpTool": ".types", + "TrueFoundryAgentSkill": ".types", "TrueFoundryAgentUserMessage": ".types", "TrueFoundryAgentVariable": ".types", "TrueFoundryApplyRequestManifest": ".types", @@ -2051,7 +2050,6 @@ "TrueFoundryInteractiveLogin": ".types", "TrueFoundryManagedSource": ".types", "TrueFoundryProviderAccount": ".types", - "TruefoundryFlyteTaskTemplate": ".types", "TtlIntegrations": ".types", "TtlProviderAccount": ".types", "TtlRegistry": ".types", @@ -2392,6 +2390,11 @@ def __dir__(): "CustomBasicAuth", "CustomBearerAuth", "CustomBlobStorage", + "CustomEndpoint", + "CustomEndpointAuthData", + "CustomEndpointIntegrations", + "CustomEndpointProviderAccount", + "CustomEndpointProviderAccountAuthData", "CustomFramework", "CustomGuardrailConfig", "CustomGuardrailConfigAuthData", @@ -2777,9 +2780,6 @@ def __dir__(): "MultiPartUpload", "MultiPartUploadResponse", "MultiPartUploadStorageProvider", - "NativeSnowflakeFlyteTaskTemplate", - "NativeSnowflakeFlyteTaskTemplateConfig", - "NativeSnowflakeFlyteTaskTemplateSql", "NatsInputConfig", "NatsMetricConfig", "NatsOutputConfig", @@ -3017,9 +3017,6 @@ def __dir__(): "SnowflakeCortexModel", "SnowflakeCortexPatTokenAuth", "SnowflakeCortexProviderAccount", - "SnowflakeTaskConfig", - "SnowflakeTaskConfigImage", - "SnowflakeTaskConfigMountsItem", "SortDirection", "SpaCyFramework", "SpanAttributeFilter", @@ -3127,6 +3124,7 @@ def __dir__(): "TrueFoundryAgentManifestSandbox", "TrueFoundryAgentMcpServer", "TrueFoundryAgentMcpTool", + "TrueFoundryAgentSkill", "TrueFoundryAgentUserMessage", "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", @@ -3140,7 +3138,6 @@ def __dir__(): "TrueFoundryInteractiveLogin", "TrueFoundryManagedSource", "TrueFoundryProviderAccount", - "TruefoundryFlyteTaskTemplate", "TtlIntegrations", "TtlProviderAccount", "TtlRegistry", diff --git a/src/truefoundry_sdk/types/__init__.py b/src/truefoundry_sdk/types/__init__.py index 0da19032..502302e3 100644 --- a/src/truefoundry_sdk/types/__init__.py +++ b/src/truefoundry_sdk/types/__init__.py @@ -227,6 +227,11 @@ from .custom_basic_auth import CustomBasicAuth from .custom_bearer_auth import CustomBearerAuth from .custom_blob_storage import CustomBlobStorage + from .custom_endpoint import CustomEndpoint + from .custom_endpoint_auth_data import CustomEndpointAuthData + from .custom_endpoint_integrations import CustomEndpointIntegrations + from .custom_endpoint_provider_account import CustomEndpointProviderAccount + from .custom_endpoint_provider_account_auth_data import CustomEndpointProviderAccountAuthData from .custom_framework import CustomFramework from .custom_guardrail_config import CustomGuardrailConfig from .custom_guardrail_config_auth_data import CustomGuardrailConfigAuthData @@ -622,9 +627,6 @@ from .multi_part_upload import MultiPartUpload from .multi_part_upload_response import MultiPartUploadResponse from .multi_part_upload_storage_provider import MultiPartUploadStorageProvider - from .native_snowflake_flyte_task_template import NativeSnowflakeFlyteTaskTemplate - from .native_snowflake_flyte_task_template_config import NativeSnowflakeFlyteTaskTemplateConfig - from .native_snowflake_flyte_task_template_sql import NativeSnowflakeFlyteTaskTemplateSql from .nats_input_config import NatsInputConfig from .nats_metric_config import NatsMetricConfig from .nats_output_config import NatsOutputConfig @@ -856,9 +858,6 @@ from .snowflake_cortex_model import SnowflakeCortexModel from .snowflake_cortex_pat_token_auth import SnowflakeCortexPatTokenAuth from .snowflake_cortex_provider_account import SnowflakeCortexProviderAccount - from .snowflake_task_config import SnowflakeTaskConfig - from .snowflake_task_config_image import SnowflakeTaskConfigImage - from .snowflake_task_config_mounts_item import SnowflakeTaskConfigMountsItem from .sort_direction import SortDirection from .spa_cy_framework import SpaCyFramework from .span_attribute_filter import SpanAttributeFilter @@ -964,6 +963,7 @@ from .true_foundry_agent_manifest_sandbox import TrueFoundryAgentManifestSandbox from .true_foundry_agent_mcp_server import TrueFoundryAgentMcpServer from .true_foundry_agent_mcp_tool import TrueFoundryAgentMcpTool + from .true_foundry_agent_skill import TrueFoundryAgentSkill from .true_foundry_agent_user_message import TrueFoundryAgentUserMessage from .true_foundry_agent_variable import TrueFoundryAgentVariable from .true_foundry_apply_request_manifest import TrueFoundryApplyRequestManifest @@ -977,7 +977,6 @@ from .true_foundry_interactive_login import TrueFoundryInteractiveLogin from .true_foundry_managed_source import TrueFoundryManagedSource from .true_foundry_provider_account import TrueFoundryProviderAccount - from .truefoundry_flyte_task_template import TruefoundryFlyteTaskTemplate from .ttl_integrations import TtlIntegrations from .ttl_provider_account import TtlProviderAccount from .ttl_registry import TtlRegistry @@ -1256,6 +1255,11 @@ "CustomBasicAuth": ".custom_basic_auth", "CustomBearerAuth": ".custom_bearer_auth", "CustomBlobStorage": ".custom_blob_storage", + "CustomEndpoint": ".custom_endpoint", + "CustomEndpointAuthData": ".custom_endpoint_auth_data", + "CustomEndpointIntegrations": ".custom_endpoint_integrations", + "CustomEndpointProviderAccount": ".custom_endpoint_provider_account", + "CustomEndpointProviderAccountAuthData": ".custom_endpoint_provider_account_auth_data", "CustomFramework": ".custom_framework", "CustomGuardrailConfig": ".custom_guardrail_config", "CustomGuardrailConfigAuthData": ".custom_guardrail_config_auth_data", @@ -1637,9 +1641,6 @@ "MultiPartUpload": ".multi_part_upload", "MultiPartUploadResponse": ".multi_part_upload_response", "MultiPartUploadStorageProvider": ".multi_part_upload_storage_provider", - "NativeSnowflakeFlyteTaskTemplate": ".native_snowflake_flyte_task_template", - "NativeSnowflakeFlyteTaskTemplateConfig": ".native_snowflake_flyte_task_template_config", - "NativeSnowflakeFlyteTaskTemplateSql": ".native_snowflake_flyte_task_template_sql", "NatsInputConfig": ".nats_input_config", "NatsMetricConfig": ".nats_metric_config", "NatsOutputConfig": ".nats_output_config", @@ -1874,9 +1875,6 @@ "SnowflakeCortexModel": ".snowflake_cortex_model", "SnowflakeCortexPatTokenAuth": ".snowflake_cortex_pat_token_auth", "SnowflakeCortexProviderAccount": ".snowflake_cortex_provider_account", - "SnowflakeTaskConfig": ".snowflake_task_config", - "SnowflakeTaskConfigImage": ".snowflake_task_config_image", - "SnowflakeTaskConfigMountsItem": ".snowflake_task_config_mounts_item", "SortDirection": ".sort_direction", "SpaCyFramework": ".spa_cy_framework", "SpanAttributeFilter": ".span_attribute_filter", @@ -1980,6 +1978,7 @@ "TrueFoundryAgentManifestSandbox": ".true_foundry_agent_manifest_sandbox", "TrueFoundryAgentMcpServer": ".true_foundry_agent_mcp_server", "TrueFoundryAgentMcpTool": ".true_foundry_agent_mcp_tool", + "TrueFoundryAgentSkill": ".true_foundry_agent_skill", "TrueFoundryAgentUserMessage": ".true_foundry_agent_user_message", "TrueFoundryAgentVariable": ".true_foundry_agent_variable", "TrueFoundryApplyRequestManifest": ".true_foundry_apply_request_manifest", @@ -1993,7 +1992,6 @@ "TrueFoundryInteractiveLogin": ".true_foundry_interactive_login", "TrueFoundryManagedSource": ".true_foundry_managed_source", "TrueFoundryProviderAccount": ".true_foundry_provider_account", - "TruefoundryFlyteTaskTemplate": ".truefoundry_flyte_task_template", "TtlIntegrations": ".ttl_integrations", "TtlProviderAccount": ".ttl_provider_account", "TtlRegistry": ".ttl_registry", @@ -2296,6 +2294,11 @@ def __dir__(): "CustomBasicAuth", "CustomBearerAuth", "CustomBlobStorage", + "CustomEndpoint", + "CustomEndpointAuthData", + "CustomEndpointIntegrations", + "CustomEndpointProviderAccount", + "CustomEndpointProviderAccountAuthData", "CustomFramework", "CustomGuardrailConfig", "CustomGuardrailConfigAuthData", @@ -2677,9 +2680,6 @@ def __dir__(): "MultiPartUpload", "MultiPartUploadResponse", "MultiPartUploadStorageProvider", - "NativeSnowflakeFlyteTaskTemplate", - "NativeSnowflakeFlyteTaskTemplateConfig", - "NativeSnowflakeFlyteTaskTemplateSql", "NatsInputConfig", "NatsMetricConfig", "NatsOutputConfig", @@ -2914,9 +2914,6 @@ def __dir__(): "SnowflakeCortexModel", "SnowflakeCortexPatTokenAuth", "SnowflakeCortexProviderAccount", - "SnowflakeTaskConfig", - "SnowflakeTaskConfigImage", - "SnowflakeTaskConfigMountsItem", "SortDirection", "SpaCyFramework", "SpanAttributeFilter", @@ -3020,6 +3017,7 @@ def __dir__(): "TrueFoundryAgentManifestSandbox", "TrueFoundryAgentMcpServer", "TrueFoundryAgentMcpTool", + "TrueFoundryAgentSkill", "TrueFoundryAgentUserMessage", "TrueFoundryAgentVariable", "TrueFoundryApplyRequestManifest", @@ -3033,7 +3031,6 @@ def __dir__(): "TrueFoundryInteractiveLogin", "TrueFoundryManagedSource", "TrueFoundryProviderAccount", - "TruefoundryFlyteTaskTemplate", "TtlIntegrations", "TtlProviderAccount", "TtlRegistry", diff --git a/src/truefoundry_sdk/types/custom_endpoint.py b/src/truefoundry_sdk/types/custom_endpoint.py new file mode 100644 index 00000000..44081baa --- /dev/null +++ b/src/truefoundry_sdk/types/custom_endpoint.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 .custom_endpoint_auth_data import CustomEndpointAuthData +from .custom_tls_settings import CustomTlsSettings + + +class CustomEndpoint(UniversalBaseModel): + """ + Custom Endpoint + """ + + type: typing.Literal["integration/model/custom-endpoint"] = pydantic.Field( + default="integration/model/custom-endpoint" + ) + """ + +value=integration/model/custom-endpoint + """ + + name: str = pydantic.Field() + """ + A descriptive name to identify this endpoint in the UI + """ + + base_url: str = pydantic.Field() + """ + The target base URL to proxy requests to (e.g., https://my-service.example.com/v1) + """ + + auth_data: typing.Optional[CustomEndpointAuthData] = pydantic.Field(default=None) + """ + Authentication credentials for the upstream endpoint. Overrides account-level auth if set. + """ + + headers: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + Custom headers forwarded to the upstream endpoint with every request. For example: `{"X-Custom-Header": "value"}` + """ + + tls_settings: typing.Optional[CustomTlsSettings] = None + authorized_subjects: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + List of subjects that are authorized to access this endpoint. 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/custom_endpoint_auth_data.py b/src/truefoundry_sdk/types/custom_endpoint_auth_data.py new file mode 100644 index 00000000..f4057688 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_endpoint_auth_data.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .custom_basic_auth import CustomBasicAuth +from .custom_bearer_auth import CustomBearerAuth +from .custom_header_auth import CustomHeaderAuth + +CustomEndpointAuthData = typing.Union[CustomBasicAuth, CustomBearerAuth, CustomHeaderAuth] diff --git a/src/truefoundry_sdk/types/custom_endpoint_integrations.py b/src/truefoundry_sdk/types/custom_endpoint_integrations.py new file mode 100644 index 00000000..7cb3a355 --- /dev/null +++ b/src/truefoundry_sdk/types/custom_endpoint_integrations.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from .custom_endpoint import CustomEndpoint + +CustomEndpointIntegrations = CustomEndpoint diff --git a/src/truefoundry_sdk/types/custom_endpoint_provider_account.py b/src/truefoundry_sdk/types/custom_endpoint_provider_account.py new file mode 100644 index 00000000..a8e2b49b --- /dev/null +++ b/src/truefoundry_sdk/types/custom_endpoint_provider_account.py @@ -0,0 +1,57 @@ +# 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 .custom_endpoint_integrations import CustomEndpointIntegrations +from .custom_endpoint_provider_account_auth_data import CustomEndpointProviderAccountAuthData +from .owned_by import OwnedBy + + +class CustomEndpointProviderAccount(UniversalBaseModel): + """ + Custom Endpoint + """ + + type: typing.Literal["provider-account/custom-endpoint"] = pydantic.Field( + default="provider-account/custom-endpoint" + ) + """ + +value=provider-account/custom-endpoint + """ + + name: str = pydantic.Field() + """ + The name of the custom endpoint provider account. + """ + + auth_data: typing.Optional[CustomEndpointProviderAccountAuthData] = pydantic.Field(default=None) + """ + Default authentication data for all endpoints under this account. Can be overridden at the endpoint level. + """ + + integrations: typing.List[CustomEndpointIntegrations] = pydantic.Field() + """ + List of endpoint integrations associated with this provider account. + """ + + collaborators: typing.Optional[typing.List[Collaborator]] = pydantic.Field(default=None) + """ + Collaborators + """ + + owned_by: typing_extensions.Annotated[ + typing.Optional[OwnedBy], 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 + else: + + class Config: + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/truefoundry_sdk/types/custom_endpoint_provider_account_auth_data.py b/src/truefoundry_sdk/types/custom_endpoint_provider_account_auth_data.py new file mode 100644 index 00000000..64a2dc5b --- /dev/null +++ b/src/truefoundry_sdk/types/custom_endpoint_provider_account_auth_data.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .custom_basic_auth import CustomBasicAuth +from .custom_bearer_auth import CustomBearerAuth +from .custom_header_auth import CustomHeaderAuth + +CustomEndpointProviderAccountAuthData = typing.Union[CustomBasicAuth, CustomBearerAuth, CustomHeaderAuth] diff --git a/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py index 6cbdb7c6..c34cdf9e 100644 --- a/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py +++ b/src/truefoundry_sdk/types/flyte_task_custom_truefoundry.py @@ -6,8 +6,7 @@ from .databricks_job_task_config import DatabricksJobTaskConfig from .py_spark_task_config import PySparkTaskConfig from .python_task_config import PythonTaskConfig -from .snowflake_task_config import SnowflakeTaskConfig FlyteTaskCustomTruefoundry = typing.Union[ - PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig, DatabricksJobTaskConfig, SnowflakeTaskConfig + PythonTaskConfig, ContainerTaskConfig, PySparkTaskConfig, DatabricksJobTaskConfig ] diff --git a/src/truefoundry_sdk/types/flyte_task_template.py b/src/truefoundry_sdk/types/flyte_task_template.py index 5cf53cf4..030e1380 100644 --- a/src/truefoundry_sdk/types/flyte_task_template.py +++ b/src/truefoundry_sdk/types/flyte_task_template.py @@ -2,7 +2,20 @@ import typing -from .native_snowflake_flyte_task_template import NativeSnowflakeFlyteTaskTemplate -from .truefoundry_flyte_task_template import TruefoundryFlyteTaskTemplate +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .flyte_task_custom import FlyteTaskCustom +from .flyte_task_id import FlyteTaskId -FlyteTaskTemplate = typing.Union[TruefoundryFlyteTaskTemplate, NativeSnowflakeFlyteTaskTemplate] + +class FlyteTaskTemplate(UniversalBaseModel): + id: FlyteTaskId + custom: FlyteTaskCustom + + 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/model_provider_account.py b/src/truefoundry_sdk/types/model_provider_account.py index b9a4b58d..90697f0b 100644 --- a/src/truefoundry_sdk/types/model_provider_account.py +++ b/src/truefoundry_sdk/types/model_provider_account.py @@ -13,6 +13,7 @@ from .cerebras_provider_account import CerebrasProviderAccount from .cloudera_provider_account import ClouderaProviderAccount from .cohere_provider_account import CohereProviderAccount +from .custom_endpoint_provider_account import CustomEndpointProviderAccount from .databricks_provider_account import DatabricksProviderAccount from .deepgram_provider_account import DeepgramProviderAccount from .deepinfra_provider_account import DeepinfraProviderAccount @@ -66,4 +67,5 @@ DeepgramProviderAccount, CartesiaProviderAccount, VirtualModelProviderAccount, + CustomEndpointProviderAccount, ] diff --git a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py deleted file mode 100644 index 72185c6d..00000000 --- a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template.py +++ /dev/null @@ -1,28 +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 .flyte_task_id import FlyteTaskId -from .native_snowflake_flyte_task_template_config import NativeSnowflakeFlyteTaskTemplateConfig -from .native_snowflake_flyte_task_template_sql import NativeSnowflakeFlyteTaskTemplateSql - - -class NativeSnowflakeFlyteTaskTemplate(UniversalBaseModel): - id: FlyteTaskId - type: typing.Literal["snowflake"] = "snowflake" - config: NativeSnowflakeFlyteTaskTemplateConfig = pydantic.Field() - """ - Flyte snowflake task plugin specific config - """ - - sql: NativeSnowflakeFlyteTaskTemplateSql - - 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/native_snowflake_flyte_task_template_config.py b/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.py deleted file mode 100644 index 4d062d07..00000000 --- a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_config.py +++ /dev/null @@ -1,28 +0,0 @@ -# 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 NativeSnowflakeFlyteTaskTemplateConfig(UniversalBaseModel): - """ - Flyte snowflake task plugin specific config - """ - - account: str - schema_: typing_extensions.Annotated[str, FieldMetadata(alias="schema"), pydantic.Field(alias="schema")] - user: str - warehouse: str - database: 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/snowflake_task_config.py b/src/truefoundry_sdk/types/snowflake_task_config.py deleted file mode 100644 index d61495fa..00000000 --- a/src/truefoundry_sdk/types/snowflake_task_config.py +++ /dev/null @@ -1,70 +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 .resources import Resources -from .snowflake_task_config_image import SnowflakeTaskConfigImage -from .snowflake_task_config_mounts_item import SnowflakeTaskConfigMountsItem - - -class SnowflakeTaskConfig(UniversalBaseModel): - type: typing.Literal["snowflake-task-config"] = pydantic.Field(default="snowflake-task-config") - """ - +value=snowflake-task-config - """ - - image: SnowflakeTaskConfigImage = pydantic.Field() - """ - Specify the image spec for the task - """ - - user: str = pydantic.Field() - """ - Snowflake config for the task. - """ - - account: str = pydantic.Field() - """ - Snowflake account for the task. - """ - - database: str = pydantic.Field() - """ - Snowflake database for the task. - """ - - schema_name: str = pydantic.Field() - """ - Snowflake schema for the task. - """ - - warehouse: str = pydantic.Field() - """ - Snowflake warehouse for the task. - """ - - env: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) - """ - Configure environment variables to be injected in the task either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables) - """ - - resources: typing.Optional[Resources] = None - mounts: typing.Optional[typing.List[SnowflakeTaskConfigMountsItem]] = pydantic.Field(default=None) - """ - Configure data to be mounted to Workflow pod(s) as a volume. - """ - - service_account: typing.Optional[str] = pydantic.Field(default=None) - """ - Service 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/snowflake_task_config_image.py b/src/truefoundry_sdk/types/snowflake_task_config_image.py deleted file mode 100644 index ee80ccc9..00000000 --- a/src/truefoundry_sdk/types/snowflake_task_config_image.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .task_docker_file_build import TaskDockerFileBuild -from .task_python_build import TaskPythonBuild - -SnowflakeTaskConfigImage = typing.Union[TaskPythonBuild, TaskDockerFileBuild] diff --git a/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py b/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py deleted file mode 100644 index 09a1ccd7..00000000 --- a/src/truefoundry_sdk/types/snowflake_task_config_mounts_item.py +++ /dev/null @@ -1,9 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .secret_mount import SecretMount -from .string_data_mount import StringDataMount -from .volume_mount import VolumeMount - -SnowflakeTaskConfigMountsItem = typing.Union[SecretMount, StringDataMount, VolumeMount] diff --git a/src/truefoundry_sdk/types/true_foundry_agent_manifest.py b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py index dd54d9dd..e35bfe3c 100644 --- a/src/truefoundry_sdk/types/true_foundry_agent_manifest.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_manifest.py @@ -12,6 +12,7 @@ from .true_foundry_agent_manifest_response_format import TrueFoundryAgentManifestResponseFormat from .true_foundry_agent_manifest_sandbox import TrueFoundryAgentManifestSandbox from .true_foundry_agent_mcp_server import TrueFoundryAgentMcpServer +from .true_foundry_agent_skill import TrueFoundryAgentSkill from .true_foundry_agent_user_message import TrueFoundryAgentUserMessage from .true_foundry_agent_variable import TrueFoundryAgentVariable @@ -47,6 +48,11 @@ class TrueFoundryAgentManifest(UniversalBaseModel): Model parameters (default and extra). Keys are param names, values are float, int, bool, or string. """ + skills: typing.Optional[typing.List[TrueFoundryAgentSkill]] = pydantic.Field(default=None) + """ + List of agent skills to attach to this agent + """ + mcp_servers: typing.Optional[typing.List[TrueFoundryAgentMcpServer]] = pydantic.Field(default=None) """ List of MCP servers with name, enable_all_tools, and optional tools filter diff --git a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py b/src/truefoundry_sdk/types/true_foundry_agent_skill.py similarity index 56% rename from src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py rename to src/truefoundry_sdk/types/true_foundry_agent_skill.py index c2e2f251..74d6bed3 100644 --- a/src/truefoundry_sdk/types/native_snowflake_flyte_task_template_sql.py +++ b/src/truefoundry_sdk/types/true_foundry_agent_skill.py @@ -6,8 +6,16 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class NativeSnowflakeFlyteTaskTemplateSql(UniversalBaseModel): - statement: str +class TrueFoundryAgentSkill(UniversalBaseModel): + fqn: str = pydantic.Field() + """ + Fully qualified name of the agent skill + """ + + eager: typing.Optional[bool] = pydantic.Field(default=False) + """ + When true, the skill's markdown content is loaded into the agent context before the first turn + """ 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/truefoundry_flyte_task_template.py b/src/truefoundry_sdk/types/truefoundry_flyte_task_template.py deleted file mode 100644 index 1e8b1f9a..00000000 --- a/src/truefoundry_sdk/types/truefoundry_flyte_task_template.py +++ /dev/null @@ -1,21 +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 .flyte_task_custom import FlyteTaskCustom -from .flyte_task_id import FlyteTaskId - - -class TruefoundryFlyteTaskTemplate(UniversalBaseModel): - id: FlyteTaskId - custom: FlyteTaskCustom - - 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