truefoundry 0.12.0rc1__py3-none-any.whl → 0.12.1__py3-none-any.whl
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/common/constants.py +27 -18
- truefoundry/common/utils.py +4 -0
- truefoundry/deploy/builder/builders/dockerfile.py +4 -6
- truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +8 -4
- truefoundry/deploy/builder/builders/tfy_spark_buildpack/dockerfile_template.py +1 -7
- truefoundry/deploy/builder/builders/tfy_task_pyspark_buildpack/dockerfile_template.py +1 -11
- truefoundry/deploy/builder/utils.py +13 -0
- truefoundry/deploy/lib/util.py +102 -17
- truefoundry/deploy/v2/lib/deploy.py +4 -0
- truefoundry/deploy/v2/lib/patched_models.py +6 -30
- truefoundry/deploy/v2/lib/source.py +6 -35
- truefoundry/ml/log_types/artifacts/artifact.py +2 -0
- truefoundry/ml/log_types/artifacts/constants.py +4 -1
- truefoundry/ml/log_types/artifacts/model.py +2 -0
- truefoundry/ml/log_types/artifacts/utils.py +52 -14
- {truefoundry-0.12.0rc1.dist-info → truefoundry-0.12.1.dist-info}/METADATA +1 -1
- {truefoundry-0.12.0rc1.dist-info → truefoundry-0.12.1.dist-info}/RECORD +19 -19
- {truefoundry-0.12.0rc1.dist-info → truefoundry-0.12.1.dist-info}/WHEEL +0 -0
- {truefoundry-0.12.0rc1.dist-info → truefoundry-0.12.1.dist-info}/entry_points.txt +0 -0
truefoundry/common/constants.py
CHANGED
|
@@ -36,11 +36,16 @@ class TrueFoundrySdkEnv(BaseSettings):
|
|
|
36
36
|
# Note: Every field in this class should have a default value
|
|
37
37
|
# Never expect the user to set these values
|
|
38
38
|
|
|
39
|
+
# For local development, this enables further configuration via _TFYServersConfig
|
|
40
|
+
TFY_CLI_LOCAL_DEV_MODE: bool = False
|
|
41
|
+
|
|
39
42
|
# These two are not meant to be used directly. See the TFY_HOST and TFY_API_KEY properties below
|
|
40
43
|
TFY_HOST_: Optional[str] = Field(default=None, env=TFY_HOST_ENV_KEY)
|
|
41
44
|
TFY_API_KEY_: Optional[SecretStr] = Field(default=None, env=TFY_API_KEY_ENV_KEY)
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
##############################
|
|
47
|
+
# Internal Signed URL Server #
|
|
48
|
+
##############################
|
|
44
49
|
TFY_INTERNAL_SIGNED_URL_SERVER_HOST: Optional[str] = Field(
|
|
45
50
|
default=None, env=TFY_INTERNAL_SIGNED_URL_SERVER_HOST_ENV_KEY
|
|
46
51
|
)
|
|
@@ -55,32 +60,42 @@ class TrueFoundrySdkEnv(BaseSettings):
|
|
|
55
60
|
TFY_INTERNAL_SIGNED_URL_REQUEST_TIMEOUT: int = 3600 # default: 1 hour
|
|
56
61
|
TFY_INTERNAL_SIGNED_URL_CLIENT_LOG_LEVEL: str = "WARNING"
|
|
57
62
|
|
|
58
|
-
|
|
63
|
+
#############
|
|
64
|
+
# Artifacts #
|
|
65
|
+
#############
|
|
59
66
|
TFY_ARTIFACTS_DOWNLOAD_CHUNK_SIZE_BYTES: int = 100 * 1000 * 1000
|
|
60
67
|
TFY_ARTIFACTS_DOWNLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
|
|
61
68
|
TFY_ARTIFACTS_UPLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
|
|
62
69
|
TFY_ARTIFACTS_DISABLE_MULTIPART_UPLOAD: bool = False
|
|
63
70
|
TFY_ARTIFACTS_DOWNLOAD_FSYNC_CHUNKS: bool = False
|
|
64
71
|
|
|
65
|
-
|
|
72
|
+
#############
|
|
73
|
+
# TFY Build #
|
|
74
|
+
#############
|
|
75
|
+
# For customizing the images and packages used for builds
|
|
66
76
|
TFY_PYTHONBUILD_PYTHON_IMAGE_REPO: str = "public.ecr.aws/docker/library/python"
|
|
67
|
-
|
|
68
|
-
# TODO(gw): Use another image with more linient rate limits
|
|
69
|
-
TFY_SPARK_BUILD_SPARK_IMAGE_REPO: str = "public.ecr.aws/bitnami/spark"
|
|
70
|
-
|
|
71
|
-
TFY_TASK_PYSPARK_BUILD_SPARK_IMAGE_REPO: str = "public.ecr.aws/bitnami/spark"
|
|
72
|
-
|
|
73
|
-
# For local development, this enables futher configuration via _TFYServersConfig
|
|
74
|
-
TFY_CLI_LOCAL_DEV_MODE: bool = False
|
|
75
|
-
|
|
76
77
|
TFY_PYTHON_BUILD_PACKAGE_MANAGER: PythonPackageManager = PythonPackageManager.UV
|
|
77
78
|
TFY_PYTHON_BUILD_UV_IMAGE_REPO: str = "ghcr.io/astral-sh/uv"
|
|
78
79
|
TFY_PYTHON_BUILD_UV_IMAGE_TAG: str = "latest"
|
|
80
|
+
TFY_PYTHON_BUILD_POETRY_VERSION: str = Field(
|
|
81
|
+
default="2.0", env="TFY_PYTHON_BUILD_POETRY_VERSION"
|
|
82
|
+
)
|
|
83
|
+
TFY_PYTHON_BUILD_LATEST_POETRY_MAJOR_VERSION: int = Field(
|
|
84
|
+
default=2, env="TFY_PYTHON_BUILD_LATEST_POETRY_MAJOR_VERSION"
|
|
85
|
+
)
|
|
86
|
+
TFY_SPARK_BUILD_SPARK_IMAGE_REPO: str = "public.ecr.aws/bitnami/spark"
|
|
87
|
+
TFY_TASK_PYSPARK_BUILD_SPARK_IMAGE_REPO: str = "public.ecr.aws/bitnami/spark"
|
|
79
88
|
|
|
89
|
+
##############
|
|
90
|
+
# OpenAI API #
|
|
91
|
+
##############
|
|
80
92
|
# Global Constants for OpenAI Integration
|
|
81
93
|
OPENAI_API_KEY: Optional[str] = Field(default=None, env=OPENAI_API_KEY_KEY)
|
|
82
94
|
OPENAI_MODEL: Optional[str] = Field(default=None, env=OPENAI_MODEL_KEY)
|
|
83
95
|
|
|
96
|
+
###########
|
|
97
|
+
# TFY Ask #
|
|
98
|
+
###########
|
|
84
99
|
# Ask Command Specific Environment Variables for TrueFoundry
|
|
85
100
|
TFY_ASK_OPENAI_API_KEY: Optional[str] = Field(
|
|
86
101
|
default=None, env=TFY_ASK_OPENAI_API_KEY_KEY
|
|
@@ -94,12 +109,6 @@ class TrueFoundrySdkEnv(BaseSettings):
|
|
|
94
109
|
)
|
|
95
110
|
TFY_ASK_SYSTEM_PROMPT_NAME: str = Field(default="tfy-ask-k8s-prompt")
|
|
96
111
|
TFY_INTERNAL_ASK_CONFIG_OVERRIDE_FILE: Optional[str] = Field(default=None)
|
|
97
|
-
TFY_PYTHON_BUILD_POETRY_VERSION: str = Field(
|
|
98
|
-
default="2.0", env="TFY_PYTHON_BUILD_POETRY_VERSION"
|
|
99
|
-
)
|
|
100
|
-
TFY_PYTHON_BUILD_LATEST_POETRY_MAJOR_VERSION: int = Field(
|
|
101
|
-
default=2, env="TFY_PYTHON_BUILD_LATEST_POETRY_MAJOR_VERSION"
|
|
102
|
-
)
|
|
103
112
|
|
|
104
113
|
# This is a hack to fresh read the env vars because people can end up importing this file
|
|
105
114
|
# before setting the correct env vars. E.g. in notebook environments.
|
truefoundry/common/utils.py
CHANGED
|
@@ -210,3 +210,7 @@ def get_user_agent() -> str:
|
|
|
210
210
|
return f"truefoundry/{__version__} Python/{platform.python_version()} OS/{platform.system()}-{platform.release()} ({platform.architecture()[0]})"
|
|
211
211
|
except Exception:
|
|
212
212
|
return f"truefoundry/{__version__}"
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def get_expanded_and_absolute_path(path: str):
|
|
216
|
+
return os.path.abspath(os.path.expanduser(path))
|
|
@@ -14,22 +14,20 @@ def _get_expanded_and_absolute_path(path: str):
|
|
|
14
14
|
|
|
15
15
|
def _build_docker_image(
|
|
16
16
|
tag: str,
|
|
17
|
+
dockerfile: str,
|
|
17
18
|
path: str = ".",
|
|
18
|
-
file: Optional[str] = None,
|
|
19
19
|
build_args: Optional[Dict[str, str]] = None,
|
|
20
20
|
extra_opts: Optional[List[str]] = None,
|
|
21
21
|
):
|
|
22
|
+
dockerfile = _get_expanded_and_absolute_path(dockerfile)
|
|
22
23
|
path = _get_expanded_and_absolute_path(path)
|
|
23
24
|
|
|
24
|
-
if file:
|
|
25
|
-
file = _get_expanded_and_absolute_path(file)
|
|
26
|
-
|
|
27
25
|
build_docker_image(
|
|
28
26
|
path=path,
|
|
29
27
|
tag=tag,
|
|
30
28
|
# TODO: can we pick target platform(s) picked from cluster
|
|
31
29
|
platform="linux/amd64",
|
|
32
|
-
dockerfile=
|
|
30
|
+
dockerfile=dockerfile,
|
|
33
31
|
build_args=build_args,
|
|
34
32
|
extra_opts=extra_opts,
|
|
35
33
|
)
|
|
@@ -50,8 +48,8 @@ def build(
|
|
|
50
48
|
|
|
51
49
|
_build_docker_image(
|
|
52
50
|
tag=tag,
|
|
51
|
+
dockerfile=build_configuration.dockerfile_path,
|
|
53
52
|
path=build_configuration.build_context_path,
|
|
54
|
-
file=build_configuration.dockerfile_path,
|
|
55
53
|
build_args=build_configuration.build_args,
|
|
56
54
|
extra_opts=extra_opts,
|
|
57
55
|
)
|
|
@@ -6,6 +6,7 @@ from jinja2 import Template
|
|
|
6
6
|
from truefoundry.common.constants import ENV_VARS, PythonPackageManager
|
|
7
7
|
from truefoundry.deploy._autogen.models import UV, Pip, Poetry
|
|
8
8
|
from truefoundry.deploy.builder.utils import (
|
|
9
|
+
check_whether_poetry_toml_exists,
|
|
9
10
|
generate_apt_install_command,
|
|
10
11
|
generate_command_to_install_from_uv_lock,
|
|
11
12
|
generate_pip_install_command,
|
|
@@ -18,7 +19,6 @@ from truefoundry.deploy.v2.lib.patched_models import (
|
|
|
18
19
|
CUDAVersion,
|
|
19
20
|
PythonBuild,
|
|
20
21
|
_resolve_requirements_path,
|
|
21
|
-
check_whether_poetry_toml_exists,
|
|
22
22
|
)
|
|
23
23
|
from truefoundry.pydantic_v1 import BaseModel
|
|
24
24
|
|
|
@@ -224,6 +224,10 @@ def _build_template_context(
|
|
|
224
224
|
package_manager: str,
|
|
225
225
|
available_secrets: Set[str],
|
|
226
226
|
) -> TemplateContext:
|
|
227
|
+
if not build_configuration.python_version:
|
|
228
|
+
raise ValueError(
|
|
229
|
+
"`python_version` is required for `tfy-python-buildpack` builder"
|
|
230
|
+
)
|
|
227
231
|
# Set up package manager config secret mount
|
|
228
232
|
python_dependencies_type = python_dependencies.type
|
|
229
233
|
package_manager_config_secret_mount = ""
|
|
@@ -235,7 +239,7 @@ def _build_template_context(
|
|
|
235
239
|
)
|
|
236
240
|
|
|
237
241
|
# Configure dependencies based on type
|
|
238
|
-
if
|
|
242
|
+
if isinstance(python_dependencies, UV):
|
|
239
243
|
uv_context = _build_uv_context(
|
|
240
244
|
python_dependencies,
|
|
241
245
|
available_secrets,
|
|
@@ -252,7 +256,7 @@ def _build_template_context(
|
|
|
252
256
|
],
|
|
253
257
|
final_uv_sync_command=uv_context["final_uv_sync_command"],
|
|
254
258
|
)
|
|
255
|
-
elif
|
|
259
|
+
elif isinstance(python_dependencies, Poetry):
|
|
256
260
|
poetry_toml_exists = check_whether_poetry_toml_exists(
|
|
257
261
|
build_context_path=build_configuration.build_context_path,
|
|
258
262
|
)
|
|
@@ -271,7 +275,7 @@ def _build_template_context(
|
|
|
271
275
|
poetry_version_expression=poetry_context["poetry_version_expression"],
|
|
272
276
|
poetry_toml_exists=poetry_toml_exists,
|
|
273
277
|
)
|
|
274
|
-
elif
|
|
278
|
+
elif isinstance(python_dependencies, Pip):
|
|
275
279
|
pip_context = _build_pip_context(
|
|
276
280
|
build_configuration,
|
|
277
281
|
python_dependencies,
|
|
@@ -10,9 +10,6 @@ from truefoundry.deploy.builder.utils import (
|
|
|
10
10
|
generate_uv_pip_install_command,
|
|
11
11
|
get_available_secrets,
|
|
12
12
|
)
|
|
13
|
-
from truefoundry.deploy.v2.lib.patched_models import (
|
|
14
|
-
_resolve_requirements_path,
|
|
15
|
-
)
|
|
16
13
|
|
|
17
14
|
# TODO (chiragjn): Switch to a non-root user inside the container
|
|
18
15
|
|
|
@@ -79,10 +76,7 @@ def generate_dockerfile_content(
|
|
|
79
76
|
available_secrets = get_available_secrets(docker_build_extra_args)
|
|
80
77
|
|
|
81
78
|
# TODO (chiragjn): Handle recursive references to other requirements files e.g. `-r requirements-gpu.txt`
|
|
82
|
-
requirements_path =
|
|
83
|
-
build_context_path=build_configuration.build_context_path,
|
|
84
|
-
requirements_path=build_configuration.requirements_path,
|
|
85
|
-
)
|
|
79
|
+
requirements_path = build_configuration.requirements_path
|
|
86
80
|
requirements_destination_path = (
|
|
87
81
|
"/tmp/requirements.txt" if requirements_path else None
|
|
88
82
|
)
|
|
@@ -11,9 +11,6 @@ from truefoundry.deploy.builder.utils import (
|
|
|
11
11
|
generate_uv_pip_install_command,
|
|
12
12
|
get_available_secrets,
|
|
13
13
|
)
|
|
14
|
-
from truefoundry.deploy.v2.lib.patched_models import (
|
|
15
|
-
_resolve_requirements_path,
|
|
16
|
-
)
|
|
17
14
|
|
|
18
15
|
# TODO[GW]: Switch to a non-root user inside the container
|
|
19
16
|
_POST_PYTHON_INSTALL_TEMPLATE = """
|
|
@@ -65,17 +62,10 @@ def generate_dockerfile_content(
|
|
|
65
62
|
available_secrets = get_available_secrets(docker_build_extra_args)
|
|
66
63
|
|
|
67
64
|
# TODO (chiragjn): Handle recursive references to other requirements files e.g. `-r requirements-gpu.txt`
|
|
68
|
-
requirements_path =
|
|
69
|
-
build_context_path="",
|
|
70
|
-
requirements_path=build_configuration.requirements_path,
|
|
71
|
-
)
|
|
65
|
+
requirements_path = build_configuration.requirements_path
|
|
72
66
|
requirements_destination_path = (
|
|
73
67
|
"/tmp/requirements.txt" if requirements_path else None
|
|
74
68
|
)
|
|
75
|
-
# if not build_configuration.python_version:
|
|
76
|
-
# raise ValueError(
|
|
77
|
-
# "`python_version` is required for `tfy-python-buildpack` builder"
|
|
78
|
-
# )
|
|
79
69
|
pip_packages = get_additional_pip_packages(build_configuration) + (
|
|
80
70
|
build_configuration.pip_packages or []
|
|
81
71
|
)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import shlex
|
|
2
3
|
from typing import List, Optional, Set
|
|
3
4
|
|
|
@@ -307,3 +308,15 @@ def generate_poetry_install_command(
|
|
|
307
308
|
)
|
|
308
309
|
|
|
309
310
|
return poetry_install_cmd
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def check_whether_poetry_toml_exists(
|
|
314
|
+
build_context_path: str,
|
|
315
|
+
) -> bool:
|
|
316
|
+
required_filename = "poetry.toml"
|
|
317
|
+
possible_path = os.path.join(build_context_path, required_filename)
|
|
318
|
+
|
|
319
|
+
if os.path.isfile(possible_path):
|
|
320
|
+
return True
|
|
321
|
+
|
|
322
|
+
return False
|
truefoundry/deploy/lib/util.py
CHANGED
|
@@ -2,7 +2,13 @@ import os
|
|
|
2
2
|
import re
|
|
3
3
|
from typing import Union
|
|
4
4
|
|
|
5
|
+
from truefoundry.common.utils import get_expanded_and_absolute_path
|
|
5
6
|
from truefoundry.deploy._autogen.models import (
|
|
7
|
+
UV,
|
|
8
|
+
Build,
|
|
9
|
+
DockerFileBuild,
|
|
10
|
+
Pip,
|
|
11
|
+
Poetry,
|
|
6
12
|
PythonBuild,
|
|
7
13
|
)
|
|
8
14
|
|
|
@@ -36,31 +42,110 @@ def find_list_paths(data, parent_key="", sep="."):
|
|
|
36
42
|
return list_paths
|
|
37
43
|
|
|
38
44
|
|
|
39
|
-
def _validate_file_path(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
def _validate_file_path(
|
|
46
|
+
parent_path: str, relative_file_path: str, parent_dir_type: str
|
|
47
|
+
):
|
|
48
|
+
parent_abs = get_expanded_and_absolute_path(parent_path)
|
|
49
|
+
file_path_abs = get_expanded_and_absolute_path(
|
|
50
|
+
os.path.join(parent_abs, relative_file_path)
|
|
51
|
+
)
|
|
52
|
+
# Ensure the file path is actually inside the build context
|
|
53
|
+
outside_context = False
|
|
54
|
+
try:
|
|
55
|
+
# Use os.path.commonpath to check if file_path is inside build_context_abs
|
|
56
|
+
common_path = os.path.commonpath([parent_abs, file_path_abs])
|
|
57
|
+
outside_context = common_path != parent_abs
|
|
58
|
+
except ValueError:
|
|
59
|
+
# os.path.commonpath raises ValueError if paths are on different drives (Windows)
|
|
60
|
+
outside_context = True
|
|
61
|
+
|
|
62
|
+
if outside_context:
|
|
63
|
+
raise ValueError(
|
|
64
|
+
f"Referenced file `{relative_file_path}` is outside the {parent_dir_type} `{parent_abs}`. "
|
|
65
|
+
f"It must exist in {parent_dir_type} `{parent_abs}`."
|
|
44
66
|
)
|
|
45
67
|
|
|
68
|
+
if not os.path.exists(file_path_abs):
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Referenced file `{relative_file_path}` not found. It must exist in {parent_dir_type} `{parent_abs}`."
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def validate_dockerfile_build_paths(
|
|
75
|
+
dockerfile_build: DockerFileBuild, project_root_path: str
|
|
76
|
+
):
|
|
77
|
+
_validate_file_path(
|
|
78
|
+
parent_path=project_root_path,
|
|
79
|
+
relative_file_path=dockerfile_build.dockerfile_path,
|
|
80
|
+
parent_dir_type="project root",
|
|
81
|
+
)
|
|
82
|
+
|
|
46
83
|
|
|
47
|
-
def
|
|
84
|
+
def validate_python_build_paths(python_build: PythonBuild, build_context_path: str):
|
|
48
85
|
if not python_build.python_dependencies:
|
|
86
|
+
# Old style flat requirements file
|
|
87
|
+
if python_build.requirements_path:
|
|
88
|
+
_validate_file_path(
|
|
89
|
+
parent_path=build_context_path,
|
|
90
|
+
relative_file_path=python_build.requirements_path,
|
|
91
|
+
parent_dir_type="build context",
|
|
92
|
+
)
|
|
49
93
|
return
|
|
50
94
|
|
|
51
|
-
if not os.path.exists(source_dir):
|
|
52
|
-
raise ValueError(f"project root path {source_dir!r} of does not exist")
|
|
53
95
|
if (
|
|
54
|
-
python_build.python_dependencies
|
|
96
|
+
isinstance(python_build.python_dependencies, Pip)
|
|
55
97
|
and python_build.python_dependencies.requirements_path
|
|
56
98
|
):
|
|
57
99
|
_validate_file_path(
|
|
58
|
-
|
|
59
|
-
python_build.python_dependencies.requirements_path,
|
|
100
|
+
parent_path=build_context_path,
|
|
101
|
+
relative_file_path=python_build.python_dependencies.requirements_path,
|
|
102
|
+
parent_dir_type="build context",
|
|
103
|
+
)
|
|
104
|
+
elif isinstance(python_build.python_dependencies, UV):
|
|
105
|
+
_validate_file_path(
|
|
106
|
+
parent_path=build_context_path,
|
|
107
|
+
relative_file_path="pyproject.toml",
|
|
108
|
+
parent_dir_type="build context",
|
|
109
|
+
)
|
|
110
|
+
_validate_file_path(
|
|
111
|
+
parent_path=build_context_path,
|
|
112
|
+
relative_file_path="uv.lock",
|
|
113
|
+
parent_dir_type="build context",
|
|
114
|
+
)
|
|
115
|
+
elif isinstance(python_build.python_dependencies, Poetry):
|
|
116
|
+
_validate_file_path(
|
|
117
|
+
parent_path=build_context_path,
|
|
118
|
+
relative_file_path="pyproject.toml",
|
|
119
|
+
parent_dir_type="build context",
|
|
120
|
+
)
|
|
121
|
+
_validate_file_path(
|
|
122
|
+
parent_path=build_context_path,
|
|
123
|
+
relative_file_path="poetry.lock",
|
|
124
|
+
parent_dir_type="build context",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def validate_local_source_paths(component_name: str, build: Build):
|
|
129
|
+
source_dir = get_expanded_and_absolute_path(build.build_source.project_root_path)
|
|
130
|
+
if not os.path.exists(source_dir):
|
|
131
|
+
raise ValueError(
|
|
132
|
+
f"Project root path {source_dir!r} of component {component_name!r} does not exist"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
build_context_path = get_expanded_and_absolute_path(
|
|
136
|
+
os.path.join(source_dir, build.build_spec.build_context_path)
|
|
137
|
+
)
|
|
138
|
+
if not os.path.exists(build_context_path):
|
|
139
|
+
raise ValueError(
|
|
140
|
+
f"Build context path {build_context_path!r} "
|
|
141
|
+
f"of component {component_name!r} does not exist"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if isinstance(build.build_spec, DockerFileBuild):
|
|
145
|
+
validate_dockerfile_build_paths(
|
|
146
|
+
dockerfile_build=build.build_spec, project_root_path=source_dir
|
|
147
|
+
)
|
|
148
|
+
elif isinstance(build.build_spec, PythonBuild):
|
|
149
|
+
validate_python_build_paths(
|
|
150
|
+
python_build=build.build_spec, build_context_path=build_context_path
|
|
60
151
|
)
|
|
61
|
-
if python_build.python_dependencies.type == "uv":
|
|
62
|
-
_validate_file_path(source_dir, "uv.lock")
|
|
63
|
-
_validate_file_path(source_dir, "pyproject.toml")
|
|
64
|
-
if python_build.python_dependencies.type == "poetry":
|
|
65
|
-
_validate_file_path(source_dir, "pyproject.toml")
|
|
66
|
-
_validate_file_path(source_dir, "poetry.lock")
|
|
@@ -15,6 +15,7 @@ from truefoundry.deploy.lib.dao.workspace import get_workspace_by_fqn
|
|
|
15
15
|
from truefoundry.deploy.lib.model.entity import Deployment, DeploymentTransitionStatus
|
|
16
16
|
from truefoundry.deploy.lib.util import (
|
|
17
17
|
get_application_fqn_from_deployment_fqn,
|
|
18
|
+
validate_local_source_paths,
|
|
18
19
|
)
|
|
19
20
|
from truefoundry.deploy.v2.lib.models import BuildResponse
|
|
20
21
|
from truefoundry.deploy.v2.lib.source import (
|
|
@@ -47,6 +48,9 @@ def _handle_if_local_source(component: Component, workspace_fqn: str) -> Compone
|
|
|
47
48
|
and isinstance(component.image.build_source, autogen_models.LocalSource)
|
|
48
49
|
):
|
|
49
50
|
new_component = component.copy(deep=True)
|
|
51
|
+
validate_local_source_paths(
|
|
52
|
+
component_name=new_component.name, build=new_component.image
|
|
53
|
+
)
|
|
50
54
|
|
|
51
55
|
if new_component.image.build_source.local_build:
|
|
52
56
|
if not env_has_docker():
|
|
@@ -47,8 +47,9 @@ or set it to None if you don't want to use any requirements file.
|
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
SPECS_UPGRADE_WARNING_MESSAGE_TEMPLATE = """\
|
|
50
|
-
The `requirements_path` and `pip_packages` fields are deprecated
|
|
51
|
-
|
|
50
|
+
The `requirements_path` and `pip_packages` fields are deprecated.
|
|
51
|
+
It is recommended to use the `python_dependencies` field instead which supports pip, uv and poetry.
|
|
52
|
+
Please use the following format:
|
|
52
53
|
|
|
53
54
|
```python
|
|
54
55
|
build=Build(
|
|
@@ -106,18 +107,6 @@ def _resolve_requirements_path(
|
|
|
106
107
|
return None
|
|
107
108
|
|
|
108
109
|
|
|
109
|
-
def check_whether_poetry_toml_exists(
|
|
110
|
-
build_context_path: str,
|
|
111
|
-
) -> bool:
|
|
112
|
-
required_filename = "poetry.toml"
|
|
113
|
-
possible_path = os.path.join(build_context_path, required_filename)
|
|
114
|
-
|
|
115
|
-
if os.path.isfile(possible_path):
|
|
116
|
-
return True
|
|
117
|
-
|
|
118
|
-
return False
|
|
119
|
-
|
|
120
|
-
|
|
121
110
|
class CUDAVersion(str, enum.Enum):
|
|
122
111
|
CUDA_11_0_CUDNN8 = "11.0-cudnn8"
|
|
123
112
|
CUDA_11_1_CUDNN8 = "11.1-cudnn8"
|
|
@@ -210,7 +199,9 @@ class PythonBuild(models.PythonBuild, PatchedModelBase):
|
|
|
210
199
|
requirements_path=values.get("requirements_path"),
|
|
211
200
|
)
|
|
212
201
|
|
|
213
|
-
if
|
|
202
|
+
if (
|
|
203
|
+
values.get("requirements_path") or values.get("pip_packages")
|
|
204
|
+
) and not values.get("python_dependencies"):
|
|
214
205
|
warnings.warn(
|
|
215
206
|
SPECS_UPGRADE_WARNING_MESSAGE_TEMPLATE.format(
|
|
216
207
|
requirements_txt_path=values.get("requirements_path"),
|
|
@@ -219,27 +210,12 @@ class PythonBuild(models.PythonBuild, PatchedModelBase):
|
|
|
219
210
|
category=TrueFoundryDeprecationWarning,
|
|
220
211
|
stacklevel=2,
|
|
221
212
|
)
|
|
222
|
-
values["python_dependencies"] = Pip(
|
|
223
|
-
type="pip",
|
|
224
|
-
requirements_path=values.get("requirements_path"),
|
|
225
|
-
pip_packages=values.get("pip_packages"),
|
|
226
|
-
)
|
|
227
|
-
values.pop("pip_packages", None)
|
|
228
|
-
values.pop("requirements_path", None)
|
|
229
213
|
return values
|
|
230
214
|
|
|
231
215
|
|
|
232
216
|
class SparkBuild(models.SparkBuild, PatchedModelBase):
|
|
233
217
|
type: Literal["tfy-spark-buildpack"] = "tfy-spark-buildpack"
|
|
234
218
|
|
|
235
|
-
@root_validator
|
|
236
|
-
def validate_values(cls, values):
|
|
237
|
-
_resolve_requirements_path(
|
|
238
|
-
build_context_path=values.get("build_context_path") or "./",
|
|
239
|
-
requirements_path=values.get("requirements_path"),
|
|
240
|
-
)
|
|
241
|
-
return values
|
|
242
|
-
|
|
243
219
|
|
|
244
220
|
class SparkImageBuild(models.SparkImageBuild, PatchedModelBase):
|
|
245
221
|
type: Literal["spark-image-build"] = "spark-image-build"
|
|
@@ -9,6 +9,7 @@ import gitignorefile
|
|
|
9
9
|
from tqdm import tqdm
|
|
10
10
|
|
|
11
11
|
from truefoundry.common.types import UploadCodePackageCallable
|
|
12
|
+
from truefoundry.common.utils import get_expanded_and_absolute_path
|
|
12
13
|
from truefoundry.common.warnings import TrueFoundryDeprecationWarning
|
|
13
14
|
from truefoundry.deploy import builder
|
|
14
15
|
from truefoundry.deploy._autogen import models
|
|
@@ -21,7 +22,6 @@ from truefoundry.deploy.lib.clients.servicefoundry_client import (
|
|
|
21
22
|
ServiceFoundryServiceClient,
|
|
22
23
|
)
|
|
23
24
|
from truefoundry.deploy.lib.dao import workspace as workspace_lib
|
|
24
|
-
from truefoundry.deploy.lib.util import validate_paths
|
|
25
25
|
from truefoundry.deploy.v2.lib.patched_models import Image, RemoteSource
|
|
26
26
|
from truefoundry.logger import logger
|
|
27
27
|
|
|
@@ -142,15 +142,8 @@ def local_source_to_remote_source(
|
|
|
142
142
|
) -> RemoteSource:
|
|
143
143
|
with tempfile.TemporaryDirectory() as local_dir:
|
|
144
144
|
package_local_path = os.path.join(local_dir, "build.tar.gz")
|
|
145
|
-
source_dir =
|
|
146
|
-
|
|
147
|
-
if not os.path.exists(source_dir):
|
|
148
|
-
raise ValueError(
|
|
149
|
-
f"project root path {source_dir!r} of component {component_name!r} does not exist"
|
|
150
|
-
)
|
|
151
|
-
|
|
145
|
+
source_dir = get_expanded_and_absolute_path(local_source.project_root_path)
|
|
152
146
|
logger.info("Archiving contents of dir: %r", source_dir)
|
|
153
|
-
|
|
154
147
|
is_path_ignored = _get_callback_handler_to_ignore_file_path(source_dir)
|
|
155
148
|
_make_tarfile(
|
|
156
149
|
output_filename=package_local_path,
|
|
@@ -183,36 +176,14 @@ def local_source_to_image(
|
|
|
183
176
|
component_name: str,
|
|
184
177
|
) -> Image:
|
|
185
178
|
build = build.copy(deep=True)
|
|
186
|
-
source_dir =
|
|
187
|
-
os.path.expanduser(build.build_source.project_root_path)
|
|
188
|
-
)
|
|
189
|
-
if not os.path.exists(source_dir):
|
|
190
|
-
raise ValueError(
|
|
191
|
-
f"project root path {source_dir!r} of component {component_name!r} does not exist"
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
build.build_spec.build_context_path = os.path.join(
|
|
195
|
-
source_dir, build.build_spec.build_context_path
|
|
196
|
-
)
|
|
197
|
-
if not os.path.exists(build.build_spec.build_context_path):
|
|
198
|
-
raise ValueError(
|
|
199
|
-
f"Build context path {build.build_spec.build_context_path!r} "
|
|
200
|
-
f"of component {component_name!r} does not exist"
|
|
201
|
-
)
|
|
202
|
-
|
|
179
|
+
source_dir = get_expanded_and_absolute_path(build.build_source.project_root_path)
|
|
203
180
|
if isinstance(build.build_spec, models.DockerFileBuild):
|
|
204
181
|
build.build_spec.dockerfile_path = os.path.join(
|
|
205
182
|
source_dir, build.build_spec.dockerfile_path
|
|
206
183
|
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
f"of component {component_name!r} does not exist"
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
if isinstance(build.build_spec, models.PythonBuild):
|
|
214
|
-
validate_paths(build.build_spec, source_dir)
|
|
215
|
-
|
|
184
|
+
build.build_spec.build_context_path = os.path.join(
|
|
185
|
+
source_dir, build.build_spec.build_context_path
|
|
186
|
+
)
|
|
216
187
|
client = ServiceFoundryServiceClient()
|
|
217
188
|
|
|
218
189
|
workspace = workspace_lib.get_workspace_by_fqn(workspace_fqn=workspace_fqn)
|
|
@@ -40,6 +40,7 @@ from truefoundry.ml.log_types.artifacts.utils import (
|
|
|
40
40
|
calculate_total_size,
|
|
41
41
|
get_autogen_type,
|
|
42
42
|
set_tfy_internal_metadata,
|
|
43
|
+
set_user_artifact_metadata,
|
|
43
44
|
)
|
|
44
45
|
from truefoundry.ml.logger import logger
|
|
45
46
|
from truefoundry.ml.session import _get_api_client
|
|
@@ -458,6 +459,7 @@ def _log_artifact_version_helper(
|
|
|
458
459
|
|
|
459
460
|
metadata = metadata or {}
|
|
460
461
|
metadata = set_tfy_internal_metadata(metadata)
|
|
462
|
+
metadata = set_user_artifact_metadata(metadata)
|
|
461
463
|
|
|
462
464
|
_validate_description(description)
|
|
463
465
|
_validate_artifact_metadata(metadata)
|
|
@@ -26,7 +26,7 @@ following:
|
|
|
26
26
|
from truefoundry.ml import get_client
|
|
27
27
|
from truefoundry.ml import ModelVersion, ModelSchema, Feature, FeatureValueType, PredictionValueType
|
|
28
28
|
client = get_client()
|
|
29
|
-
model_version = ModelVersion(fqn="{fqn}")
|
|
29
|
+
model_version = ModelVersion.from_fqn(fqn="{fqn}")
|
|
30
30
|
model_version = ModelSchema(...) # or schema in dictionary format {{"features": [...], "prediction": ...}}
|
|
31
31
|
model_version.update()
|
|
32
32
|
```
|
|
@@ -36,3 +36,6 @@ ARTIFACT_METADATA_TRUEFOUNDRY_KEY = ".truefoundry"
|
|
|
36
36
|
TFY_INTERNAL_APPLICATION_ID_ENV_VAR = "TFY_INTERNAL_APPLICATION_ID"
|
|
37
37
|
TFY_INTERNAL_APPLICATION_VERSION_ENV_VAR = "TFY_INTERNAL_APPLICATION_VERSION"
|
|
38
38
|
TFY_INTERNAL_JOB_RUN_NAME_ENV_VAR = "TFY_INTERNAL_JOB_RUN_NAME"
|
|
39
|
+
TFY_ARTIFACTS_ADDITIONAL_USER_METADATA_ENV_VAR = (
|
|
40
|
+
"TFY_ARTIFACTS_ADDITIONAL_USER_METADATA"
|
|
41
|
+
)
|
|
@@ -47,6 +47,7 @@ from truefoundry.ml.log_types.artifacts.utils import (
|
|
|
47
47
|
calculate_total_size,
|
|
48
48
|
get_autogen_type,
|
|
49
49
|
set_tfy_internal_metadata,
|
|
50
|
+
set_user_artifact_metadata,
|
|
50
51
|
)
|
|
51
52
|
from truefoundry.ml.model_framework import (
|
|
52
53
|
ModelFrameworkType,
|
|
@@ -547,6 +548,7 @@ def _log_model_version( # noqa: C901
|
|
|
547
548
|
total_size = None
|
|
548
549
|
metadata = metadata or {}
|
|
549
550
|
metadata = set_tfy_internal_metadata(metadata)
|
|
551
|
+
metadata = set_user_artifact_metadata(metadata)
|
|
550
552
|
|
|
551
553
|
_validate_description(description)
|
|
552
554
|
_validate_artifact_metadata(metadata)
|
|
@@ -10,6 +10,7 @@ from truefoundry.ml.exceptions import MlFoundryException
|
|
|
10
10
|
from truefoundry.ml.log_types.artifacts.constants import (
|
|
11
11
|
ARTIFACT_METADATA_TRUEFOUNDRY_KEY,
|
|
12
12
|
DESCRIPTION_MAX_LENGTH,
|
|
13
|
+
TFY_ARTIFACTS_ADDITIONAL_USER_METADATA_ENV_VAR,
|
|
13
14
|
TFY_INTERNAL_APPLICATION_ID_ENV_VAR,
|
|
14
15
|
TFY_INTERNAL_APPLICATION_VERSION_ENV_VAR,
|
|
15
16
|
TFY_INTERNAL_JOB_RUN_NAME_ENV_VAR,
|
|
@@ -237,16 +238,8 @@ def get_autogen_type(parent_type: Type[BaseModel], field_name: str) -> Type[Base
|
|
|
237
238
|
|
|
238
239
|
|
|
239
240
|
def set_tfy_internal_metadata(metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
elif not isinstance(metadata[ARTIFACT_METADATA_TRUEFOUNDRY_KEY], dict):
|
|
243
|
-
return metadata
|
|
244
|
-
|
|
245
|
-
tfy_metadata = metadata[ARTIFACT_METADATA_TRUEFOUNDRY_KEY]
|
|
246
|
-
created_by_key = "created_by"
|
|
247
|
-
if created_by_key not in tfy_metadata:
|
|
248
|
-
tfy_metadata[created_by_key] = {}
|
|
249
|
-
elif not isinstance(tfy_metadata[created_by_key], dict):
|
|
241
|
+
tfy_metadata = metadata.setdefault(ARTIFACT_METADATA_TRUEFOUNDRY_KEY, {})
|
|
242
|
+
if not isinstance(tfy_metadata, dict):
|
|
250
243
|
return metadata
|
|
251
244
|
|
|
252
245
|
tfy_internal_metadata = {
|
|
@@ -254,8 +247,53 @@ def set_tfy_internal_metadata(metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
254
247
|
"application_version": os.environ.get(TFY_INTERNAL_APPLICATION_VERSION_ENV_VAR),
|
|
255
248
|
"job_run_name": os.environ.get(TFY_INTERNAL_JOB_RUN_NAME_ENV_VAR),
|
|
256
249
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
250
|
+
tfy_internal_metadata = {
|
|
251
|
+
k: v for k, v in tfy_internal_metadata.items() if v is not None
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if tfy_internal_metadata:
|
|
255
|
+
created_by_key = "created_by"
|
|
256
|
+
created_by_metadata = tfy_metadata.setdefault(created_by_key, {})
|
|
257
|
+
if created_by_key in tfy_metadata and not isinstance(created_by_metadata, dict):
|
|
258
|
+
return metadata
|
|
259
|
+
for key, value in tfy_internal_metadata.items():
|
|
260
|
+
if key not in created_by_metadata:
|
|
261
|
+
created_by_metadata[key] = value
|
|
262
|
+
return metadata
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _merge_dicts_recursively(
|
|
266
|
+
src: Dict[str, Any], dest: Dict[str, Any], overwrite: bool = False
|
|
267
|
+
) -> Dict[str, Any]:
|
|
268
|
+
for key, value in src.items():
|
|
269
|
+
if key not in dest:
|
|
270
|
+
dest[key] = value
|
|
271
|
+
else:
|
|
272
|
+
if isinstance(value, dict) and isinstance(dest[key], dict):
|
|
273
|
+
_merge_dicts_recursively(value, dest[key], overwrite=overwrite)
|
|
274
|
+
elif overwrite:
|
|
275
|
+
dest[key] = value
|
|
276
|
+
return dest
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def set_user_artifact_metadata(metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
280
|
+
_user_metadata = os.environ.get(TFY_ARTIFACTS_ADDITIONAL_USER_METADATA_ENV_VAR)
|
|
281
|
+
if not _user_metadata:
|
|
282
|
+
return metadata
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
user_metadata = json.loads(_user_metadata)
|
|
286
|
+
except ValueError:
|
|
287
|
+
logger.warning(
|
|
288
|
+
"Content of `TFY_ARTIFACTS_ADDITIONAL_USER_METADATA` environment variable is not valid json, cannot add to metadata"
|
|
289
|
+
)
|
|
290
|
+
return metadata
|
|
291
|
+
|
|
292
|
+
if not isinstance(user_metadata, dict):
|
|
293
|
+
logger.warning(
|
|
294
|
+
"Content of `TFY_ARTIFACTS_ADDITIONAL_USER_METADATA` environment variable is not a dictionary, cannot add to metadata"
|
|
295
|
+
)
|
|
296
|
+
return metadata
|
|
297
|
+
|
|
298
|
+
metadata = _merge_dicts_recursively(user_metadata, metadata, overwrite=False)
|
|
261
299
|
return metadata
|
|
@@ -40,7 +40,7 @@ truefoundry/cli/display_util.py,sha256=9vzN3mbQqU6OhS7qRUiMRana4PTHa4sDTA0Hn7OVj
|
|
|
40
40
|
truefoundry/cli/util.py,sha256=kEjC20-n_jwxZV9jq-78CxDk4xAySxAoYIXTxZfJzLM,5423
|
|
41
41
|
truefoundry/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
truefoundry/common/auth_service_client.py,sha256=N3YxKlx63r6cPZqbgb2lqBOPI69ShB7D7RCIq4FSCjc,7949
|
|
43
|
-
truefoundry/common/constants.py,sha256
|
|
43
|
+
truefoundry/common/constants.py,sha256=-oZRizJixgt7nKAtGoFyHN23sIbe1UqLkYVAyEYacbM,5203
|
|
44
44
|
truefoundry/common/credential_file_manager.py,sha256=1yEk1Zm2xS4G0VDFwKSZ4w0VUrcPWQ1nJnoBaz9xyKA,4251
|
|
45
45
|
truefoundry/common/credential_provider.py,sha256=_OhJ2XFlDaVsrUO-FyywxctcGGqDdC2pgcvwEKqQD0Q,4071
|
|
46
46
|
truefoundry/common/entities.py,sha256=b4R6ss06-ygDS3C4Tqa_GOq5LFKDYbt7x4Mghnfz6yo,4007
|
|
@@ -50,7 +50,7 @@ truefoundry/common/servicefoundry_client.py,sha256=2fYhdVPSvLXz5C5tosOq86JD8WM3I
|
|
|
50
50
|
truefoundry/common/session.py,sha256=d9l3TEBpqVP4mr4mTGY1qVxc815skzMlNNdw14otg34,2923
|
|
51
51
|
truefoundry/common/storage_provider_utils.py,sha256=jX9maCtWusZx63324cmPxHiGeIluZZzbDaJ1QYTIhAw,11856
|
|
52
52
|
truefoundry/common/types.py,sha256=BMJFCsR1lPJAw66IQBSvLyV4I6o_x5oj78gVsUa9si8,188
|
|
53
|
-
truefoundry/common/utils.py,sha256=
|
|
53
|
+
truefoundry/common/utils.py,sha256=SMpinsdXuAkIUXe7gBB8v-dWe1x2_VHdXTkA0btksDc,6816
|
|
54
54
|
truefoundry/common/warnings.py,sha256=xDMhR_-ZGC40Ycaj6nlFb5MYPexn8WbKCHd4FlflTXQ,705
|
|
55
55
|
truefoundry/deploy/__init__.py,sha256=g_g5_XKCZZXL3v_ycQhvn01bkMHweNqhOy1rg6vc5-k,2903
|
|
56
56
|
truefoundry/deploy/python_deploy_codegen.py,sha256=WwP6bIzFoLpF7J2Bgef2HMSIeefJ8TWtSv4hXNycEzQ,8872
|
|
@@ -58,18 +58,18 @@ truefoundry/deploy/_autogen/models.py,sha256=FwhfLrqrjFWY8Mzny2hlL2ksqDfVUMFFJsP
|
|
|
58
58
|
truefoundry/deploy/builder/__init__.py,sha256=7MEezQzxjrWpbvnONyGMqYNVVonlb8WkARob4dHzAB4,5045
|
|
59
59
|
truefoundry/deploy/builder/constants.py,sha256=aWC94kL8I8Lty9ccJwBVncsNx4ADTgPxyBxk_zur6XM,980
|
|
60
60
|
truefoundry/deploy/builder/docker_service.py,sha256=sm7GWeIqyrKaZpxskdLejZlsxcZnM3BTDJr6orvPN4E,3948
|
|
61
|
-
truefoundry/deploy/builder/utils.py,sha256=
|
|
61
|
+
truefoundry/deploy/builder/utils.py,sha256=YJVwSfzwc5OF6rDd_Gf-R1J0llARTvQ2CsauQrGP7_I,10465
|
|
62
62
|
truefoundry/deploy/builder/builders/__init__.py,sha256=Gp9NODR1E7mUjadhzIe3zzO43bBfHPeNcEDryYF2uo0,807
|
|
63
|
-
truefoundry/deploy/builder/builders/dockerfile.py,sha256=
|
|
63
|
+
truefoundry/deploy/builder/builders/dockerfile.py,sha256=PoEyWBm5NmBDIL0pAzPPt2IWXbAQTVOZ-psT5ZXxQdI,1517
|
|
64
64
|
truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py,sha256=RGWGqY8xOF7vycUPJd10N7ZzahWv24lO0anrOPtLuDU,1796
|
|
65
65
|
truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py,sha256=rQgdvKmAT9HArVW4TAG5yd2QTKRs3S5LJ9RQbc_EkHE,2518
|
|
66
66
|
truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py,sha256=CGBZvmLoYLgFI98-1ulXJU-tt90OcDFJaV4dFw-aThE,1763
|
|
67
|
-
truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=
|
|
67
|
+
truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=MGLxzrOeOr6WycqssMugmh4e44f870hP7LpRoGOT9aQ,16448
|
|
68
68
|
truefoundry/deploy/builder/builders/tfy_spark_buildpack/__init__.py,sha256=4d-1lZrR70QN2fTsAaphWNRwXGx5IG99yFs6gEp7TFE,2625
|
|
69
|
-
truefoundry/deploy/builder/builders/tfy_spark_buildpack/dockerfile_template.py,sha256=
|
|
69
|
+
truefoundry/deploy/builder/builders/tfy_spark_buildpack/dockerfile_template.py,sha256=m9NMv8tDQvYQs8v5wB9hCHdJRM7L2ct3OOcAg5l0JfQ,4193
|
|
70
70
|
truefoundry/deploy/builder/builders/tfy_spark_buildpack/tfy_execute_notebook.py,sha256=-D37Zjy2SBt3RHxonPEpR1_LR0W7vTSM1kQ1S-fdK-I,6363
|
|
71
71
|
truefoundry/deploy/builder/builders/tfy_task_pyspark_buildpack/__init__.py,sha256=9LkPTAydx8UVOfKfEqfe5t7vgnc2GuNiUafCv5jcUVw,1556
|
|
72
|
-
truefoundry/deploy/builder/builders/tfy_task_pyspark_buildpack/dockerfile_template.py,sha256=
|
|
72
|
+
truefoundry/deploy/builder/builders/tfy_task_pyspark_buildpack/dockerfile_template.py,sha256=3W8_lMIVgQFc8p9btU4wOAduiOUXB-hnnbqAQ7K5Eks,4044
|
|
73
73
|
truefoundry/deploy/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
truefoundry/deploy/cli/commands/__init__.py,sha256=qv818jxqSAygJ3h-6Ul8t-5VOgR_UrSgsVtNCl3e5G0,1408
|
|
75
75
|
truefoundry/deploy/cli/commands/apply_command.py,sha256=DmXmKVokkauyKIiJDtErTwbJ5_LvQeJbTQsG5BjyKpo,2427
|
|
@@ -101,7 +101,7 @@ truefoundry/deploy/lib/diff_utils.py,sha256=J1sAf5O4rHNHS_MOkcB0CyaeQFtU_ALI-wd-
|
|
|
101
101
|
truefoundry/deploy/lib/logs_utils.py,sha256=SQxRv3jDDmgHdOUMhlMaAPGYskybnBUMpst7QU_i_sc,1469
|
|
102
102
|
truefoundry/deploy/lib/messages.py,sha256=8424kj3kqCyDCX5Nr2WJZZ_UEutPoaSs_y2f9-O4yy8,1001
|
|
103
103
|
truefoundry/deploy/lib/session.py,sha256=fLdgR6ZDp8-hFl5NTON4ngnWLsMzGxvKtfpDOOw_7lo,4963
|
|
104
|
-
truefoundry/deploy/lib/util.py,sha256=
|
|
104
|
+
truefoundry/deploy/lib/util.py,sha256=QLED4zF_g_WE67MCrZQy1nrLcuiLwInLEqxYdLmOu90,5326
|
|
105
105
|
truefoundry/deploy/lib/win32.py,sha256=1RcvPTdlOAJ48rt8rCbE2Ufha2ztRqBAE9dueNXArrY,5009
|
|
106
106
|
truefoundry/deploy/lib/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
107
107
|
truefoundry/deploy/lib/clients/servicefoundry_client.py,sha256=JIj0Rs5PVZzXeh2QubLaVjgMJiUkfHrIMTtZMpgBmiA,27369
|
|
@@ -115,12 +115,12 @@ truefoundry/deploy/lib/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
115
115
|
truefoundry/deploy/lib/model/entity.py,sha256=eBfA4trO0jUuDy0wifiu2rB_HryZrx5Kf-tRMwIQ_9g,8716
|
|
116
116
|
truefoundry/deploy/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
117
|
truefoundry/deploy/v2/lib/__init__.py,sha256=WEiVMZXOVljzEE3tpGJil14liIn_PCDoACJ6b3tZ6sI,188
|
|
118
|
-
truefoundry/deploy/v2/lib/deploy.py,sha256=
|
|
118
|
+
truefoundry/deploy/v2/lib/deploy.py,sha256=JaLK0Mryps_2JaPB-q3NjfA0d55xsMFbIkH8VddRd_E,12873
|
|
119
119
|
truefoundry/deploy/v2/lib/deploy_workflow.py,sha256=G5BzMIbap8pgDX1eY-TITruUxQdkKhYtBmRwLL6lDeY,14342
|
|
120
120
|
truefoundry/deploy/v2/lib/deployable_patched_models.py,sha256=mUi-OjPf7bc8rzfrPLdFb79LKuDq7F36RxL4V-AXebs,6830
|
|
121
121
|
truefoundry/deploy/v2/lib/models.py,sha256=ogc1UYs1Z2nBdGSKCrde9sk8d0GxFKMkem99uqO5CmM,1148
|
|
122
|
-
truefoundry/deploy/v2/lib/patched_models.py,sha256=
|
|
123
|
-
truefoundry/deploy/v2/lib/source.py,sha256=
|
|
122
|
+
truefoundry/deploy/v2/lib/patched_models.py,sha256=gWpU7aVLVM-QFqUuekLbTO7ZJvWbaijzAuLgl1FwZC0,18345
|
|
123
|
+
truefoundry/deploy/v2/lib/source.py,sha256=nG11vrPqc2Z2bv7IMRruB-fNbSxY8jeWYNcCTEXr5s0,8622
|
|
124
124
|
truefoundry/ml/__init__.py,sha256=EEEHV7w58Krpo_W9Chd8Y3TdItfFO3LI6j6Izqc4-P8,2219
|
|
125
125
|
truefoundry/ml/constants.py,sha256=vDq72d4C9FSWqr9MMdjgTF4TuyNFApvo_6RVsSeAjB4,2837
|
|
126
126
|
truefoundry/ml/entities.py,sha256=GuwzmS7qqZJ_iz34zhla_Pg-ZNjt_3oHG2gn-LMftKk,1486
|
|
@@ -365,12 +365,12 @@ truefoundry/ml/log_types/plot.py,sha256=LDh4uy6z2P_a2oPM2lc85c0lt8utVvunohzeMawF
|
|
|
365
365
|
truefoundry/ml/log_types/pydantic_base.py,sha256=eBlw_AEyAz4iJKDP4zgJOCFWcldwQqpf7FADW1jzIQY,272
|
|
366
366
|
truefoundry/ml/log_types/utils.py,sha256=xjJ21jdPScvFmw3TbVh5NCzbzJwaqiXJyiiT4xxX1EI,335
|
|
367
367
|
truefoundry/ml/log_types/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
368
|
-
truefoundry/ml/log_types/artifacts/artifact.py,sha256=
|
|
369
|
-
truefoundry/ml/log_types/artifacts/constants.py,sha256=
|
|
368
|
+
truefoundry/ml/log_types/artifacts/artifact.py,sha256=Ra2R5BYuLhvLlxaCIwzoluZ7SrnZTSz-H8H9z_0c23E,20024
|
|
369
|
+
truefoundry/ml/log_types/artifacts/constants.py,sha256=BU4tpFQ7p3rNUkSvQXZNGRJB1QjkrQW2eRspUG9HOTs,1405
|
|
370
370
|
truefoundry/ml/log_types/artifacts/dataset.py,sha256=OgWIoT59AhMw8P01FfvUKbJ3EL6HQf_Xw8X4E3Ff5Sg,13172
|
|
371
371
|
truefoundry/ml/log_types/artifacts/general_artifact.py,sha256=yr-SQ2fhUR_sE1MB5zoHHYpGC8tizH_-t3lhsxCAULU,2747
|
|
372
|
-
truefoundry/ml/log_types/artifacts/model.py,sha256=
|
|
373
|
-
truefoundry/ml/log_types/artifacts/utils.py,sha256=
|
|
372
|
+
truefoundry/ml/log_types/artifacts/model.py,sha256=lGxj2cl0q_dgBGJTTOvIA2mUYio32x3uL-IssPa-UpU,24995
|
|
373
|
+
truefoundry/ml/log_types/artifacts/utils.py,sha256=AXSBMUjAb8hm0Wbnj6a8UZbLs5gIWNIkp1RJReNtnGM,10639
|
|
374
374
|
truefoundry/ml/log_types/image/__init__.py,sha256=fcOq8yQnNj1rkLcPeIjLXBpdA1WIeiPsXOlAAvMxx7M,76
|
|
375
375
|
truefoundry/ml/log_types/image/constants.py,sha256=wLtGEOA4T5fZHSlOXPuNDLX3lpbCtwlvGKPFk_1fah0,255
|
|
376
376
|
truefoundry/ml/log_types/image/image.py,sha256=sa0tBHdyluC8bELXY16E0HgFrUDnDBxHrteix4BFXcs,12479
|
|
@@ -387,7 +387,7 @@ truefoundry/workflow/remote_filesystem/__init__.py,sha256=LQ95ViEjJ7Ts4JcCGOxMPs
|
|
|
387
387
|
truefoundry/workflow/remote_filesystem/logger.py,sha256=em2l7D6sw7xTLDP0kQSLpgfRRCLpN14Qw85TN7ujQcE,1022
|
|
388
388
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=xcT0wQmQlgzcj0nP3tJopyFSVWT1uv3nhiTIuwfXYeg,12342
|
|
389
389
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py,sha256=nSGPZu0Gyd_jz0KsEE-7w_BmnTD8CVF1S8cUJoxaCbc,13305
|
|
390
|
-
truefoundry-0.12.
|
|
391
|
-
truefoundry-0.12.
|
|
392
|
-
truefoundry-0.12.
|
|
393
|
-
truefoundry-0.12.
|
|
390
|
+
truefoundry-0.12.1.dist-info/METADATA,sha256=vlWYE5rhOSxQxqxoaiJO-obasmN55g_pCwaQDZBZ0O8,2796
|
|
391
|
+
truefoundry-0.12.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
392
|
+
truefoundry-0.12.1.dist-info/entry_points.txt,sha256=xVjn7RMN-MW2-9f7YU-bBdlZSvvrwzhpX1zmmRmsNPU,98
|
|
393
|
+
truefoundry-0.12.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|