truefoundry 0.4.3__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truefoundry might be problematic. Click here for more details.
- {truefoundry-0.4.3 → truefoundry-0.4.4}/PKG-INFO +1 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/pyproject.toml +2 -2
- truefoundry-0.4.4/truefoundry/common/constants.py +49 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/credential_provider.py +4 -2
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/request_utils.py +1 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/servicefoundry_client.py +4 -2
- truefoundry-0.4.4/truefoundry/common/tfy_signed_url_client.py +260 -0
- truefoundry-0.4.4/truefoundry/common/tfy_signed_url_fs.py +244 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/utils.py +18 -5
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/auto_gen/models.py +39 -4
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +1 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +2 -4
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/clients/servicefoundry_client.py +2 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/model/entity.py +0 -4
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/python_deploy_codegen.py +79 -7
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/artifact/truefoundry_artifact_repo.py +448 -424
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/__init__.py +24 -3
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/experiments_api.py +0 -137
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/mlfoundry_artifacts_api.py +2 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/__init__.py +24 -3
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_dto.py +9 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_version_dto.py +26 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/artifact_version_serialization_format.py +34 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_artifact_version_response_dto.py +8 -2
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_run_request_dto.py +1 -10
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/dataset_dto.py +9 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/experiment_dto.py +14 -3
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/external_model_source.py +79 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/finalize_artifact_version_request_dto.py +11 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/framework.py +154 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/library_name.py +35 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_dto.py +9 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_version_dto.py +26 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/model_version_manifest.py +119 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_info_dto.py +10 -1
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/source.py +177 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/subject.py +79 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/subject_type.py +34 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/tensorflow_framework.py +74 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/transformers_framework.py +90 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/truefoundry_model_source.py +79 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_model_version_request_dto.py +11 -0
- truefoundry-0.4.4/truefoundry/ml/autogen/client/models/upload_model_source.py +74 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client_README.md +12 -2
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/entities/artifacts.py +236 -4
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/artifact.py +10 -11
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/dataset.py +13 -10
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/general_artifact.py +3 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/model.py +18 -35
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/utils.py +42 -25
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/image/image.py +2 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/plot.py +2 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/mlfoundry_api.py +7 -3
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/session.py +3 -1
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/__init__.py +10 -0
- truefoundry-0.4.3/truefoundry/common/constants.py +0 -15
- truefoundry-0.4.3/truefoundry/ml/autogen/client/models/list_seed_experiments_response_dto.py +0 -81
- truefoundry-0.4.3/truefoundry/ml/env_vars.py +0 -9
- {truefoundry-0.4.3 → truefoundry-0.4.4}/README.md +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/agents/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/agents/base.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/agents/developer.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/agents/tester.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/cli.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/constants.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/exception.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/logger.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/ask.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/base.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/commit.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/docker_build.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/docker_run.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/list_files.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/read_file.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/send_request.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/tools/write_file.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/utils/client.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/utils/diff.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/cli/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/cli/__main__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/auth_service_client.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/credential_file_manager.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/entities.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/common/exceptions.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/constants.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/docker_service.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/builder/utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/cli.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/build_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/create_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/deploy_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/get_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/list_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/login_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/patch_application_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/commands/trigger_command.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/config.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/console.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/const.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/display_util.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/cli/util.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/core/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/core/login.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/core/logout.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/__main__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/app.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/build.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/remote/context.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/remote/method.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/remote/remote.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/route.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/service.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/function_service/utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/io/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/io/output_callback.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/io/rich_output_callback.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/json_util.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/clients/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/const.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/dao/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/dao/application.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/dao/apply.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/dao/version.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/dao/workspace.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/exceptions.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/logs_utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/messages.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/model/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/session.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/util.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/lib/win32.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/deploy.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/deploy_workflow.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/deployable_patched_models.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/models.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/patched_models.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/deploy/v2/lib/source.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/deprecated.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/truefoundry_chat.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/truefoundry_llm.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/langchain/utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/logger.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/artifact/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/auth_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/deprecated_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/health_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/metrics_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/python_deployment_config_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/run_artifacts_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api/runs_api.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api_client.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/api_response.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/configuration.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/exceptions.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/add_custom_metrics_to_model_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/add_features_to_model_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/agent.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/agent_app.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/agent_open_api_tool.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/agent_open_api_tool_with_fqn.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/agent_with_fqn.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_type.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_version_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/artifact_version_status.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/assistant_message.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/authorize_user_for_model_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/authorize_user_for_model_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/blob_storage_reference.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/body_get_search_runs_get.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/chat_prompt.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/chat_prompt_messages_inner.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/columns_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/content.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/content1.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/content2.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/content2_any_of_inner.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_artifact_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_artifact_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_artifact_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_experiment_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_experiment_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_model_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_multi_part_upload_for_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_multi_part_upload_for_dataset_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_multi_part_upload_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_python_deployment_config_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_python_deployment_config_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/create_run_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/dataset_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_artifact_versions_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_files_for_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_model_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_run_request.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/delete_tag_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/experiment_id_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/experiment_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/experiment_tag_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/feature_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/feature_value_type.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/file_info_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_experiment_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_latest_run_log_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_metric_history_response.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_url_for_dataset_write_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_artifact_version_read_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_artifact_version_read_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_artifact_version_write_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_artifact_version_write_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_dataset_read_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_dataset_read_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_signed_urls_for_dataset_write_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/get_tenant_id_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/http_validation_error.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/image_content_part.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/image_url.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/internal_metadata.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/latest_run_log_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_artifact_versions_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_artifact_versions_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_artifacts_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_artifacts_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_colums_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_datasets_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_datasets_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_experiments_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_files_for_artifact_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_files_for_artifact_versions_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_files_for_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_files_for_dataset_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_latest_run_logs_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_metric_history_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_metric_history_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_model_version_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_model_versions_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_models_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_models_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_run_artifacts_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/list_run_logs_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/log_batch_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/log_metric_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/log_param_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/method.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/metric_collection_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/metric_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/mime_type.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_configuration.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_schema_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/model_version_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/multi_part_upload_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/multi_part_upload_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/multi_part_upload_storage_provider.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/notify_artifact_version_failure_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/openapi_spec.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/param_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/parameters.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/prediction_type.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/resolve_agent_app_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/restore_run_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_data_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_log_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_log_input_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/run_tag_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/search_runs_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/search_runs_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/set_experiment_tag_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/set_tag_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/signed_url_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/stop.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/store_run_logs_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/system_message.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/text.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/text_content_part.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_artifact_version_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_dataset_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_experiment_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_run_request_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/update_run_response_dto.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/url.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/user_message.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/validation_error.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/models/validation_error_loc_inner.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/autogen/client/rest.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/cli/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/cli/cli.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/cli/commands/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/cli/commands/download.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/clients/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/clients/entities.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/clients/servicefoundry_client.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/clients/utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/constants.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/entities.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/enums.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/exceptions.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/git_info.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/internal_namespace.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/constants.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/artifacts/model_extras.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/image/__init__.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/image/constants.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/image/image_normalizer.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/image/types.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/pydantic_base.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/log_types/utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/logger.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/mlfoundry_run.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/run_utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/ml/validation_utils.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/pydantic_v1.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/version.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/container_task.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/example/deploy.sh +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/example/hello_world_package/workflow.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/example/package/test_workflow.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/example/truefoundry.yaml +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/example/workflow.yaml +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/map_task.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/python_task.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/task.py +0 -0
- {truefoundry-0.4.3 → truefoundry-0.4.4}/truefoundry/workflow/workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "truefoundry"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.4"
|
|
4
4
|
description = "Truefoundry CLI"
|
|
5
5
|
authors = ["Abhishek Choudhary <abhishek@truefoundry.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -158,5 +158,5 @@ warn_required_dynamic_aliases = true
|
|
|
158
158
|
|
|
159
159
|
[tool.pytest.ini_options]
|
|
160
160
|
env = [
|
|
161
|
-
"
|
|
161
|
+
"TFY_PYTHONBUILD_PYTHON_IMAGE_REPO=docker.io/truefoundrycloud/test/python",
|
|
162
162
|
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from truefoundry.pydantic_v1 import BaseSettings, Field, SecretStr
|
|
6
|
+
|
|
7
|
+
TFY_CONFIG_DIR = Path.home() / ".truefoundry"
|
|
8
|
+
CREDENTIAL_FILEPATH = TFY_CONFIG_DIR / "credentials.json"
|
|
9
|
+
|
|
10
|
+
# These keys are kept separately because we use them in error messages and some checks
|
|
11
|
+
TFY_HOST_ENV_KEY = "TFY_HOST"
|
|
12
|
+
TFY_API_KEY_ENV_KEY = "TFY_API_KEY"
|
|
13
|
+
|
|
14
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_HOST_ENV_KEY = "TFY_INTERNAL_SIGNED_URL_SERVER_HOST"
|
|
15
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN_ENV_KEY = "TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TrueFoundrySdkEnv(BaseSettings):
|
|
19
|
+
# Note: Every field in this class should have a default value
|
|
20
|
+
# Never expect the user to set these values
|
|
21
|
+
TFY_HOST: Optional[str] = Field(default=None, env=TFY_HOST_ENV_KEY)
|
|
22
|
+
TFY_API_KEY: Optional[SecretStr] = Field(default=None, env=TFY_API_KEY_ENV_KEY)
|
|
23
|
+
|
|
24
|
+
# Internal Signed URL Server
|
|
25
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_HOST: Optional[str] = Field(
|
|
26
|
+
default=None, env=TFY_INTERNAL_SIGNED_URL_SERVER_HOST_ENV_KEY
|
|
27
|
+
)
|
|
28
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN: Optional[str] = Field(
|
|
29
|
+
default=None, env=TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN_ENV_KEY
|
|
30
|
+
)
|
|
31
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_MAX_TIMEOUT: int = 5 # default: 5 seconds
|
|
32
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_DEFAULT_TTL: int = 3600 # default: 1 hour
|
|
33
|
+
TFY_INTERNAL_SIGNED_URL_REQUEST_TIMEOUT: int = 3600 # default: 1 hour
|
|
34
|
+
|
|
35
|
+
# Artifacts
|
|
36
|
+
TFY_ARTIFACTS_DOWNLOAD_CHUNK_SIZE_BYTES: int = 100 * 1000 * 1000
|
|
37
|
+
TFY_ARTIFACTS_DOWNLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
|
|
38
|
+
TFY_ARTIFACTS_UPLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
|
|
39
|
+
TFY_ARTIFACTS_DISABLE_MULTIPART_UPLOAD: bool = False
|
|
40
|
+
TFY_ARTIFACTS_DOWNLOAD_FSYNC_CHUNKS: bool = False
|
|
41
|
+
TFY_CLI_LOCAL_DEV_MODE: bool = False
|
|
42
|
+
TFY_PYTHONBUILD_PYTHON_IMAGE_REPO: str = "public.ecr.aws/docker/library/python"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
ENV_VARS = TrueFoundrySdkEnv()
|
|
46
|
+
API_SERVER_RELATIVE_PATH = "api/svc"
|
|
47
|
+
MLFOUNDRY_SERVER_RELATIVE_PATH = "api/ml"
|
|
48
|
+
VERSION_PREFIX = "v1"
|
|
49
|
+
SERVICEFOUNDRY_CLIENT_MAX_RETRIES = 2
|
|
@@ -3,7 +3,7 @@ import threading
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
|
|
5
5
|
from truefoundry.common.auth_service_client import AuthServiceClient
|
|
6
|
-
from truefoundry.common.constants import TFY_API_KEY_ENV_KEY
|
|
6
|
+
from truefoundry.common.constants import ENV_VARS, TFY_API_KEY_ENV_KEY
|
|
7
7
|
from truefoundry.common.credential_file_manager import CredentialsFileManager
|
|
8
8
|
from truefoundry.common.entities import CredentialsFileContent, Token
|
|
9
9
|
from truefoundry.common.utils import resolve_tfy_host
|
|
@@ -30,7 +30,9 @@ class CredentialProvider(ABC):
|
|
|
30
30
|
class EnvCredentialProvider(CredentialProvider):
|
|
31
31
|
def __init__(self) -> None:
|
|
32
32
|
logger.debug("Using env var credential provider")
|
|
33
|
-
api_key =
|
|
33
|
+
api_key = (
|
|
34
|
+
ENV_VARS.TFY_API_KEY.get_secret_value() if ENV_VARS.TFY_API_KEY else None
|
|
35
|
+
)
|
|
34
36
|
if not api_key:
|
|
35
37
|
raise Exception(
|
|
36
38
|
f"Value of {TFY_API_KEY_ENV_KEY} env var should be non-empty string"
|
|
@@ -51,7 +51,7 @@ def urllib3_retry(
|
|
|
51
51
|
def requests_retry_session(
|
|
52
52
|
retries: int = 2,
|
|
53
53
|
backoff_factor: float = 0.3,
|
|
54
|
-
status_forcelist=(408, 429, 500, 502, 503, 504, 524),
|
|
54
|
+
status_forcelist=(408, 429, 417, 500, 502, 503, 504, 524),
|
|
55
55
|
method_whitelist=frozenset({"GET", "POST"}),
|
|
56
56
|
raise_on_status: bool = False,
|
|
57
57
|
session: Optional[requests.Session] = None,
|
|
@@ -43,8 +43,10 @@ def check_min_cli_version(fn):
|
|
|
43
43
|
return inner
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def session_with_retries(
|
|
47
|
-
|
|
46
|
+
def session_with_retries(
|
|
47
|
+
retries: int = SERVICEFOUNDRY_CLIENT_MAX_RETRIES,
|
|
48
|
+
) -> requests.Session:
|
|
49
|
+
return requests_retry_session(retries=retries)
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
@timed_lru_cache(seconds=30 * 60)
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# file: client.py
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
|
4
|
+
from urllib.parse import urlencode, urljoin
|
|
5
|
+
|
|
6
|
+
from requests.exceptions import RequestException
|
|
7
|
+
|
|
8
|
+
from truefoundry.common.constants import (
|
|
9
|
+
ENV_VARS,
|
|
10
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_HOST_ENV_KEY,
|
|
11
|
+
TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN_ENV_KEY,
|
|
12
|
+
)
|
|
13
|
+
from truefoundry.common.request_utils import requests_retry_session
|
|
14
|
+
from truefoundry.common.utils import log_time
|
|
15
|
+
from truefoundry.logger import logger
|
|
16
|
+
from truefoundry.pydantic_v1 import BaseModel, Field
|
|
17
|
+
|
|
18
|
+
LOG_PREFIX = "[tfy][fs]"
|
|
19
|
+
DEFAULT_TTL = ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_DEFAULT_TTL
|
|
20
|
+
MAX_TIMEOUT = ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_MAX_TIMEOUT
|
|
21
|
+
REQUEST_TIMEOUT = ENV_VARS.TFY_INTERNAL_SIGNED_URL_REQUEST_TIMEOUT
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SignedURLAPIResponseDto(BaseModel):
|
|
25
|
+
uri: str
|
|
26
|
+
signed_url: str
|
|
27
|
+
headers: Optional[Dict[str, Any]] = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SignedURLIsDirectoryAPIResponseDto(BaseModel):
|
|
31
|
+
is_directory: bool = Field(..., alias="isDirectory")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SignedURLExistsAPIResponseDto(BaseModel):
|
|
35
|
+
exists: bool
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class FileInfo(BaseModel):
|
|
39
|
+
path: str
|
|
40
|
+
is_directory: bool = Field(..., alias="isDirectory")
|
|
41
|
+
bytes: Optional[int] = None
|
|
42
|
+
signed_url: Optional[str] = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class PagedList(BaseModel):
|
|
46
|
+
items: List[FileInfo]
|
|
47
|
+
token: Optional[str] = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class SignedURLServerEndpoint(str, Enum):
|
|
51
|
+
"""Enumeration for Signed URL Server endpoints."""
|
|
52
|
+
|
|
53
|
+
READ = "/v1/signed-uri/read"
|
|
54
|
+
WRITE = "/v1/signed-uri/write"
|
|
55
|
+
EXISTS = "/v1/exists"
|
|
56
|
+
IS_DIRECTORY = "/v1/is-dir"
|
|
57
|
+
LIST_FILES = "/v1/list-files"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class SignedURLClient:
|
|
61
|
+
"""Client to interact with the Signed URL Server for file operations."""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
base_url: Optional[str] = None,
|
|
66
|
+
token: Optional[str] = None,
|
|
67
|
+
ttl: int = DEFAULT_TTL,
|
|
68
|
+
max_retries: int = 3,
|
|
69
|
+
retry_backoff_factor: float = 0.3,
|
|
70
|
+
):
|
|
71
|
+
"""Initialize the SignedURLClient."""
|
|
72
|
+
# Set the base URL and token from the environment variables
|
|
73
|
+
self.base_url = base_url or ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_HOST
|
|
74
|
+
self.token = token or ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN
|
|
75
|
+
self.signed_url_server_headers = {
|
|
76
|
+
"Authorization": f"Bearer {self.token}",
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if not self.base_url or not self.token:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Set `base_url` and `token` or define env vars "
|
|
83
|
+
f"{TFY_INTERNAL_SIGNED_URL_SERVER_HOST_ENV_KEY} and "
|
|
84
|
+
f"{TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN_ENV_KEY}"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Set the TTL, max retries, and backoff factor
|
|
88
|
+
self.ttl = ttl
|
|
89
|
+
self.max_retries: int = max_retries
|
|
90
|
+
self.retry_backoff_factor: float = retry_backoff_factor
|
|
91
|
+
self.session = requests_retry_session(
|
|
92
|
+
retries=self.max_retries, backoff_factor=self.retry_backoff_factor
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
@log_time
|
|
96
|
+
def _make_request(
|
|
97
|
+
self,
|
|
98
|
+
endpoint: str,
|
|
99
|
+
method: str = "GET",
|
|
100
|
+
payload: Optional[Dict] = None,
|
|
101
|
+
headers: Optional[Dict] = None,
|
|
102
|
+
) -> Dict:
|
|
103
|
+
"""Internal method to handle requests to the signed URL server."""
|
|
104
|
+
url = urljoin(self.base_url, endpoint)
|
|
105
|
+
try:
|
|
106
|
+
response = self.session.request(
|
|
107
|
+
method, url, headers=headers, json=payload, timeout=MAX_TIMEOUT
|
|
108
|
+
)
|
|
109
|
+
response.raise_for_status()
|
|
110
|
+
return response.json()
|
|
111
|
+
except RequestException as e:
|
|
112
|
+
raise RuntimeError(f"Error during request to {url}: {e}") from e
|
|
113
|
+
|
|
114
|
+
def _make_server_api_call(
|
|
115
|
+
self,
|
|
116
|
+
endpoint: SignedURLServerEndpoint,
|
|
117
|
+
params: Optional[Dict] = None,
|
|
118
|
+
headers: Optional[Dict] = None,
|
|
119
|
+
) -> Dict:
|
|
120
|
+
"""Get a signed URL for the specified operation and URI."""
|
|
121
|
+
query_string = urlencode(params or {})
|
|
122
|
+
endpoint_with_params = f"{endpoint.value}?{query_string}"
|
|
123
|
+
return self._make_request(
|
|
124
|
+
endpoint=endpoint_with_params, method="GET", payload=None, headers=headers
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
@log_time
|
|
128
|
+
def _upload_data(self, signed_url: str, data: Any) -> None:
|
|
129
|
+
"""
|
|
130
|
+
Upload data to the specified storage path using a signed URL.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
signed_url: str: The signed URL to upload the data to.
|
|
134
|
+
data: Bytes or IO: The data to upload.
|
|
135
|
+
"""
|
|
136
|
+
try:
|
|
137
|
+
response = self.session.put(
|
|
138
|
+
url=signed_url,
|
|
139
|
+
headers={"Content-Type": "application/octet-stream"},
|
|
140
|
+
data=data,
|
|
141
|
+
timeout=REQUEST_TIMEOUT,
|
|
142
|
+
)
|
|
143
|
+
response.raise_for_status()
|
|
144
|
+
except Exception as e:
|
|
145
|
+
raise RuntimeError(f"Failed to upload data: {e}") from e
|
|
146
|
+
|
|
147
|
+
def upload_from_bytes(self, data: bytes, storage_uri: str) -> str:
|
|
148
|
+
"""Upload bytes to the specified storage path using a signed URL."""
|
|
149
|
+
signed_object = self._make_server_api_call(
|
|
150
|
+
endpoint=SignedURLServerEndpoint.WRITE,
|
|
151
|
+
params={"uri": storage_uri, "expiryInSeconds": self.ttl},
|
|
152
|
+
headers=self.signed_url_server_headers,
|
|
153
|
+
)
|
|
154
|
+
pre_signed_object_dto = SignedURLAPIResponseDto.parse_obj(signed_object)
|
|
155
|
+
self._upload_data(pre_signed_object_dto.signed_url, data)
|
|
156
|
+
return storage_uri
|
|
157
|
+
|
|
158
|
+
@log_time
|
|
159
|
+
def upload(self, file_path: str, storage_uri: str) -> str:
|
|
160
|
+
"""Upload a file to the specified storage path using a signed URL."""
|
|
161
|
+
logger.info(f"{LOG_PREFIX} Uploading {file_path} to {storage_uri}")
|
|
162
|
+
response = self._make_server_api_call(
|
|
163
|
+
endpoint=SignedURLServerEndpoint.WRITE,
|
|
164
|
+
params={"uri": storage_uri, "expiryInSeconds": self.ttl},
|
|
165
|
+
headers=self.signed_url_server_headers,
|
|
166
|
+
)
|
|
167
|
+
pre_signed_object_dto = SignedURLAPIResponseDto.parse_obj(response)
|
|
168
|
+
with open(file_path, "rb") as file:
|
|
169
|
+
self._upload_data(pre_signed_object_dto.signed_url, file)
|
|
170
|
+
return storage_uri
|
|
171
|
+
|
|
172
|
+
@log_time
|
|
173
|
+
def _download_file(
|
|
174
|
+
self, signed_url: str, local_path: Optional[str] = None
|
|
175
|
+
) -> Optional[bytes]:
|
|
176
|
+
"""Common method to download a file using a signed URL."""
|
|
177
|
+
try:
|
|
178
|
+
response = self.session.get(
|
|
179
|
+
signed_url,
|
|
180
|
+
stream=True,
|
|
181
|
+
headers={"Content-Type": "application/octet-stream"},
|
|
182
|
+
timeout=REQUEST_TIMEOUT,
|
|
183
|
+
)
|
|
184
|
+
response.raise_for_status()
|
|
185
|
+
if local_path:
|
|
186
|
+
with open(local_path, "wb") as file:
|
|
187
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
188
|
+
file.write(chunk)
|
|
189
|
+
return None
|
|
190
|
+
return response.content
|
|
191
|
+
except RequestException as e:
|
|
192
|
+
raise RuntimeError(f"Failed to download file from {signed_url}: {e}") from e
|
|
193
|
+
|
|
194
|
+
@log_time
|
|
195
|
+
def download(self, storage_uri: str, local_path: str) -> Optional[str]:
|
|
196
|
+
"""Download a file from the specified storage path to a local path using a signed URL."""
|
|
197
|
+
logger.info(f"{LOG_PREFIX} Downloading {storage_uri} to {local_path}")
|
|
198
|
+
response = self._make_server_api_call(
|
|
199
|
+
endpoint=SignedURLServerEndpoint.READ,
|
|
200
|
+
params={"uri": storage_uri, "expiryInSeconds": self.ttl},
|
|
201
|
+
headers=self.signed_url_server_headers,
|
|
202
|
+
)
|
|
203
|
+
presigned_object = SignedURLAPIResponseDto.parse_obj(response)
|
|
204
|
+
self._download_file(presigned_object.signed_url, local_path)
|
|
205
|
+
return local_path
|
|
206
|
+
|
|
207
|
+
def download_to_bytes(self, storage_uri: str) -> bytes:
|
|
208
|
+
"""Download a file from the specified storage path and return it as bytes."""
|
|
209
|
+
response = self._make_server_api_call(
|
|
210
|
+
endpoint=SignedURLServerEndpoint.READ,
|
|
211
|
+
params={"uri": storage_uri, "expiryInSeconds": self.ttl},
|
|
212
|
+
headers=self.signed_url_server_headers,
|
|
213
|
+
)
|
|
214
|
+
presigned_object = SignedURLAPIResponseDto.parse_obj(response)
|
|
215
|
+
return self._download_file(presigned_object.signed_url)
|
|
216
|
+
|
|
217
|
+
def exists(self, uri: str) -> bool:
|
|
218
|
+
"""Check if a file exists at the specified path."""
|
|
219
|
+
response = self._make_server_api_call(
|
|
220
|
+
endpoint=SignedURLServerEndpoint.EXISTS,
|
|
221
|
+
params={"uri": uri},
|
|
222
|
+
headers=self.signed_url_server_headers,
|
|
223
|
+
)
|
|
224
|
+
return SignedURLExistsAPIResponseDto.parse_obj(response).exists
|
|
225
|
+
|
|
226
|
+
def is_directory(self, uri: str) -> bool:
|
|
227
|
+
"""Check if the specified URI is a directory."""
|
|
228
|
+
response = self._make_server_api_call(
|
|
229
|
+
endpoint=SignedURLServerEndpoint.IS_DIRECTORY,
|
|
230
|
+
params={"path": uri},
|
|
231
|
+
headers=self.signed_url_server_headers,
|
|
232
|
+
)
|
|
233
|
+
is_directory = SignedURLIsDirectoryAPIResponseDto.parse_obj(
|
|
234
|
+
response
|
|
235
|
+
).is_directory
|
|
236
|
+
logger.info(f"{LOG_PREFIX} Path {uri} is a directory: {is_directory}")
|
|
237
|
+
return is_directory
|
|
238
|
+
|
|
239
|
+
@log_time
|
|
240
|
+
def list_files(
|
|
241
|
+
self, path: str, detail: bool = False, max_results: int = 1000
|
|
242
|
+
) -> Union[List[FileInfo], List[str]]:
|
|
243
|
+
"""List files in the specified directory."""
|
|
244
|
+
token = ""
|
|
245
|
+
items: List[FileInfo] = []
|
|
246
|
+
# Fetch all files in the specified path, in pages of max_results
|
|
247
|
+
while True:
|
|
248
|
+
response = self._make_server_api_call(
|
|
249
|
+
endpoint=SignedURLServerEndpoint.LIST_FILES,
|
|
250
|
+
params={"path": path, "maxResults": max_results, "pageToken": token},
|
|
251
|
+
headers=self.signed_url_server_headers,
|
|
252
|
+
)
|
|
253
|
+
response_obj = PagedList.parse_obj(response)
|
|
254
|
+
items.extend(response_obj.items)
|
|
255
|
+
token = response_obj.token
|
|
256
|
+
if not token:
|
|
257
|
+
break
|
|
258
|
+
|
|
259
|
+
# Return the items or paths based on the detail flag
|
|
260
|
+
return items if detail else [item.path for item in items]
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# file: tfy_signed_url_fs.py
|
|
2
|
+
# pylint: disable=W0223
|
|
3
|
+
import io
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from fsspec.spec import DEFAULT_CALLBACK, AbstractBufferedFile, AbstractFileSystem
|
|
9
|
+
|
|
10
|
+
from truefoundry.common.constants import ENV_VARS
|
|
11
|
+
from truefoundry.common.tfy_signed_url_client import SignedURLClient
|
|
12
|
+
from truefoundry.common.utils import log_time
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SignedURLFileSystem(AbstractFileSystem):
|
|
16
|
+
def __init__(
|
|
17
|
+
self, base_url: Optional[str] = None, token: Optional[str] = None, **kwargs
|
|
18
|
+
):
|
|
19
|
+
super().__init__()
|
|
20
|
+
base_url = base_url or ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_HOST
|
|
21
|
+
token = token or ENV_VARS.TFY_INTERNAL_SIGNED_URL_SERVER_TOKEN
|
|
22
|
+
self.client = SignedURLClient(base_url, token)
|
|
23
|
+
|
|
24
|
+
@log_time
|
|
25
|
+
def exists(self, path, **kwargs):
|
|
26
|
+
"""Check if a file exists at the given path."""
|
|
27
|
+
return self.client.exists(path)
|
|
28
|
+
|
|
29
|
+
@log_time
|
|
30
|
+
def get(
|
|
31
|
+
self,
|
|
32
|
+
rpath,
|
|
33
|
+
lpath,
|
|
34
|
+
recursive=False,
|
|
35
|
+
callback=DEFAULT_CALLBACK,
|
|
36
|
+
maxdepth=None,
|
|
37
|
+
**kwargs,
|
|
38
|
+
):
|
|
39
|
+
"""Get file(s) to local"""
|
|
40
|
+
# TODO: Add support for ThreadPoolExecutor here
|
|
41
|
+
# TODO: Add support for async download
|
|
42
|
+
# TODO: Do a proper error handling here
|
|
43
|
+
if self.isdir(rpath):
|
|
44
|
+
if not recursive:
|
|
45
|
+
raise ValueError(
|
|
46
|
+
f"{rpath} is a directory, but recursive is not enabled."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Handle recursive download
|
|
50
|
+
files = self.ls(rpath, detail=True)
|
|
51
|
+
|
|
52
|
+
for file_info in files:
|
|
53
|
+
file_path = file_info.path.rstrip("/").rsplit("/")[-1]
|
|
54
|
+
|
|
55
|
+
is_directory = file_info.is_directory
|
|
56
|
+
# Construct the relative path for local download
|
|
57
|
+
relative_path = rpath.rstrip("/") + "/" + file_path
|
|
58
|
+
target_local_path = lpath.rstrip("/") + "/" + file_path
|
|
59
|
+
|
|
60
|
+
if is_directory:
|
|
61
|
+
# If it's a directory, create the directory locally
|
|
62
|
+
Path(target_local_path).mkdir(parents=True, exist_ok=True)
|
|
63
|
+
relative_path = relative_path + "/"
|
|
64
|
+
if recursive:
|
|
65
|
+
# Recursively download the contents of the directory
|
|
66
|
+
self.get(
|
|
67
|
+
relative_path,
|
|
68
|
+
target_local_path,
|
|
69
|
+
recursive=True,
|
|
70
|
+
maxdepth=maxdepth,
|
|
71
|
+
**kwargs,
|
|
72
|
+
)
|
|
73
|
+
else:
|
|
74
|
+
self.client.download(
|
|
75
|
+
storage_uri=relative_path, local_path=target_local_path
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
else:
|
|
79
|
+
# Ensure the directory exists first
|
|
80
|
+
target_local_path = lpath
|
|
81
|
+
if target_local_path.endswith("/"):
|
|
82
|
+
# If it ends with "/", it's a directory, so create the directory first
|
|
83
|
+
target_local_path = os.path.join(
|
|
84
|
+
target_local_path, rpath.rsplit("/", 1)[-1]
|
|
85
|
+
)
|
|
86
|
+
# Create the directory for the target file path (common for both cases)
|
|
87
|
+
Path(os.path.dirname(target_local_path)).mkdir(parents=True, exist_ok=True)
|
|
88
|
+
self.client.download(storage_uri=rpath, local_path=target_local_path)
|
|
89
|
+
|
|
90
|
+
@log_time
|
|
91
|
+
def put(
|
|
92
|
+
self,
|
|
93
|
+
lpath,
|
|
94
|
+
rpath,
|
|
95
|
+
recursive=False,
|
|
96
|
+
callback=DEFAULT_CALLBACK,
|
|
97
|
+
maxdepth=None,
|
|
98
|
+
**kwargs,
|
|
99
|
+
):
|
|
100
|
+
local_path = Path(lpath)
|
|
101
|
+
if local_path.is_dir():
|
|
102
|
+
if not recursive:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"{lpath} is a directory, but recursive is set to False."
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Optionally limit recursion depth
|
|
108
|
+
max_depth = maxdepth if maxdepth is not None else float("inf")
|
|
109
|
+
|
|
110
|
+
# Walk through the directory structure
|
|
111
|
+
for root, _, files in os.walk(lpath):
|
|
112
|
+
current_depth = Path(root).relative_to(local_path).parts
|
|
113
|
+
if len(current_depth) > max_depth:
|
|
114
|
+
continue # Skip files deeper than the max depth
|
|
115
|
+
|
|
116
|
+
rel_dir = Path(root).relative_to(local_path)
|
|
117
|
+
remote_dir = (
|
|
118
|
+
rpath.rstrip("/")
|
|
119
|
+
if rel_dir == Path(".")
|
|
120
|
+
else rpath.rstrip("/") + "/" + str(rel_dir)
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Upload each file
|
|
124
|
+
for file in files:
|
|
125
|
+
local_file_path = Path(root) / file
|
|
126
|
+
remote_file_path = f"{remote_dir}/{file}"
|
|
127
|
+
self.client.upload(
|
|
128
|
+
file_path=str(local_file_path),
|
|
129
|
+
storage_uri=remote_file_path,
|
|
130
|
+
)
|
|
131
|
+
return None
|
|
132
|
+
else:
|
|
133
|
+
if rpath.endswith("/"):
|
|
134
|
+
rpath = os.path.join(rpath, local_path.name)
|
|
135
|
+
return self.client.upload(file_path=lpath, storage_uri=rpath)
|
|
136
|
+
|
|
137
|
+
@log_time
|
|
138
|
+
def isdir(self, path):
|
|
139
|
+
"""Is this entry directory-like?"""
|
|
140
|
+
return self.client.is_directory(path)
|
|
141
|
+
|
|
142
|
+
def open(
|
|
143
|
+
self,
|
|
144
|
+
path,
|
|
145
|
+
mode="rb",
|
|
146
|
+
block_size=None,
|
|
147
|
+
cache_options=None,
|
|
148
|
+
compression=None,
|
|
149
|
+
**kwargs,
|
|
150
|
+
):
|
|
151
|
+
"""
|
|
152
|
+
Open a file for reading or writing.
|
|
153
|
+
"""
|
|
154
|
+
if "r" in mode:
|
|
155
|
+
# Reading mode
|
|
156
|
+
file_content = self.client.download_to_bytes(path)
|
|
157
|
+
return io.BytesIO(file_content)
|
|
158
|
+
elif "w" in mode or "a" in mode:
|
|
159
|
+
# Writing mode (appending treated as writing)
|
|
160
|
+
buffer = io.BytesIO()
|
|
161
|
+
buffer.seek(0)
|
|
162
|
+
|
|
163
|
+
def on_close(buffer=buffer, path=path):
|
|
164
|
+
"""
|
|
165
|
+
Callback when file is closed, automatically upload the content.
|
|
166
|
+
"""
|
|
167
|
+
buffer.seek(0)
|
|
168
|
+
self.client.upload_from_bytes(buffer.read(), storage_uri=path)
|
|
169
|
+
|
|
170
|
+
# Wrapping the buffer to automatically upload on close
|
|
171
|
+
return io.BufferedWriter(buffer, on_close)
|
|
172
|
+
|
|
173
|
+
def write(self, path, data, **kwargs):
|
|
174
|
+
"""
|
|
175
|
+
Write data to the file at the specified path (this could be tied to open's close).
|
|
176
|
+
"""
|
|
177
|
+
if isinstance(data, io.BytesIO):
|
|
178
|
+
data.seek(0)
|
|
179
|
+
content = data.read()
|
|
180
|
+
elif isinstance(data, str):
|
|
181
|
+
content = data.encode() # Encode to bytes
|
|
182
|
+
else:
|
|
183
|
+
raise ValueError("Unsupported data type for writing")
|
|
184
|
+
|
|
185
|
+
# Upload the content to the remote file system
|
|
186
|
+
self.client.upload_from_bytes(content, storage_uri=path)
|
|
187
|
+
|
|
188
|
+
@log_time
|
|
189
|
+
def ls(self, path, detail=True, **kwargs):
|
|
190
|
+
"""List objects at path."""
|
|
191
|
+
return self.client.list_files(path, detail=detail)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class SignedURLBufferedFile(AbstractBufferedFile):
|
|
195
|
+
"""
|
|
196
|
+
Buffered file implementation for Signed URL-based file system.
|
|
197
|
+
# TODO: Need to test this implementation
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __init__(
|
|
201
|
+
self, fs: SignedURLFileSystem, path: str, mode: str, block_size: int, **kwargs
|
|
202
|
+
):
|
|
203
|
+
"""
|
|
204
|
+
Initialize the buffered file, determining the mode (read/write).
|
|
205
|
+
"""
|
|
206
|
+
super().__init__(fs, path, mode, block_size, **kwargs)
|
|
207
|
+
self.buffer = io.BytesIO()
|
|
208
|
+
self.client = fs.client
|
|
209
|
+
|
|
210
|
+
if "r" in mode:
|
|
211
|
+
# Download the file content for reading
|
|
212
|
+
file_content = fs.client.download_to_bytes(path)
|
|
213
|
+
self.buffer.write(file_content)
|
|
214
|
+
self.buffer.seek(0) # Reset buffer after writing content
|
|
215
|
+
|
|
216
|
+
def _upload_on_close(self):
|
|
217
|
+
"""
|
|
218
|
+
Upload content back to the remote store when the file is closed.
|
|
219
|
+
"""
|
|
220
|
+
self.buffer.seek(0)
|
|
221
|
+
self.client.upload_from_bytes(self.buffer.read(), storage_uri=self.path)
|
|
222
|
+
|
|
223
|
+
def close(self):
|
|
224
|
+
"""
|
|
225
|
+
Close the file, ensuring the content is uploaded for write/append modes.
|
|
226
|
+
"""
|
|
227
|
+
if self.writable():
|
|
228
|
+
self._upload_on_close()
|
|
229
|
+
self.buffer.close()
|
|
230
|
+
super().close()
|
|
231
|
+
|
|
232
|
+
def _fetch_range(self, start, end):
|
|
233
|
+
"""
|
|
234
|
+
Fetch a specific byte range from the file. Useful for large files and range reads.
|
|
235
|
+
"""
|
|
236
|
+
self.buffer.seek(start)
|
|
237
|
+
return self.buffer.read(end - start)
|
|
238
|
+
|
|
239
|
+
def _upload_chunk(self, final=False):
|
|
240
|
+
"""
|
|
241
|
+
Upload a chunk of the file. For larger files, data may be uploaded in chunks.
|
|
242
|
+
"""
|
|
243
|
+
if final:
|
|
244
|
+
self._upload_on_close()
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import time
|
|
3
2
|
from functools import lru_cache, wraps
|
|
4
3
|
from time import monotonic_ns
|
|
@@ -7,8 +6,8 @@ from urllib.parse import urljoin, urlparse
|
|
|
7
6
|
|
|
8
7
|
from truefoundry.common.constants import (
|
|
9
8
|
API_SERVER_RELATIVE_PATH,
|
|
9
|
+
ENV_VARS,
|
|
10
10
|
MLFOUNDRY_SERVER_RELATIVE_PATH,
|
|
11
|
-
TFY_CLI_LOCAL_DEV_MODE_ENV_KEY,
|
|
12
11
|
TFY_HOST_ENV_KEY,
|
|
13
12
|
)
|
|
14
13
|
from truefoundry.pydantic_v1 import BaseSettings
|
|
@@ -41,7 +40,7 @@ _tfy_servers_config = None
|
|
|
41
40
|
def get_tfy_servers_config(base_url: str) -> _TFYServersConfig:
|
|
42
41
|
global _tfy_servers_config
|
|
43
42
|
if _tfy_servers_config is None:
|
|
44
|
-
if
|
|
43
|
+
if ENV_VARS.TFY_CLI_LOCAL_DEV_MODE:
|
|
45
44
|
_tfy_servers_config = _TFYServersConfig() # type: ignore[call-arg]
|
|
46
45
|
else:
|
|
47
46
|
_tfy_servers_config = _TFYServersConfig.from_base_url(base_url)
|
|
@@ -95,11 +94,25 @@ def validate_tfy_host(tfy_host: str) -> None:
|
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
def resolve_tfy_host(tfy_host: Optional[str] = None) -> str:
|
|
98
|
-
if not tfy_host and not
|
|
97
|
+
if not tfy_host and not ENV_VARS.TFY_HOST:
|
|
99
98
|
raise ValueError(
|
|
100
99
|
f"Either `host` should be provided using `--host <value>`, or `{TFY_HOST_ENV_KEY}` env must be set"
|
|
101
100
|
)
|
|
102
|
-
tfy_host = tfy_host or
|
|
101
|
+
tfy_host = tfy_host or ENV_VARS.TFY_HOST
|
|
103
102
|
tfy_host = tfy_host.strip("/")
|
|
104
103
|
validate_tfy_host(tfy_host)
|
|
105
104
|
return tfy_host
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def log_time(func):
|
|
108
|
+
"""Decorator to log the time taken by I/O operations."""
|
|
109
|
+
|
|
110
|
+
@wraps(func)
|
|
111
|
+
def wrapper(*args, **kwargs):
|
|
112
|
+
start_time = time.time()
|
|
113
|
+
result = func(*args, **kwargs)
|
|
114
|
+
elapsed_time = time.time() - start_time
|
|
115
|
+
print(f"{func.__name__} took {elapsed_time:.2f} seconds")
|
|
116
|
+
return result
|
|
117
|
+
|
|
118
|
+
return wrapper
|