truefoundry 0.3.0rc8__tar.gz → 0.3.0rc9__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.3.0rc8 → truefoundry-0.3.0rc9}/PKG-INFO +2 -1
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/pyproject.toml +2 -1
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/__init__.py +1 -9
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/auto_gen/models.py +31 -191
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/__init__.py +2 -4
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +7 -5
- truefoundry-0.3.0rc9/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +66 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deploy_workflow.py +73 -6
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/patched_models.py +0 -36
- truefoundry-0.3.0rc9/truefoundry/version.py +6 -0
- truefoundry-0.3.0rc8/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +0 -51
- truefoundry-0.3.0rc8/truefoundry/version.py +0 -4
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/README.md +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/base.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/developer.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/tester.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/cli.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/constants.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/exception.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/logger.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/ask.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/base.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/commit.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/docker_build.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/docker_run.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/list_files.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/read_file.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/send_request.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/write_file.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/client.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/diff.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/cli/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/cli/__main__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/docker_service.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/cli.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/build_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/create_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/deploy_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/get_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/list_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/login_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/patch_application_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/trigger_command.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/config.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/console.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/const.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/display_util.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/util.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/login.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/logout.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/__main__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/app.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/build.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/context.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/method.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/remote.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/route.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/service.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/utils.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/output_callback.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/rich_output_callback.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/json_util.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/auth_service_client.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/credential_file_manager.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/credential_provider.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/servicefoundry_client.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/shell_client.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/utils.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/const.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/application.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/apply.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/version.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/workspace.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/exceptions.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/logs_utils.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/messages.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/model/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/model/entity.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/session.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/util.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/win32.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deploy.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deployable_patched_models.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/models.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/source.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/deprecated.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_chat.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_llm.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/utils.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/logger.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/ml/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/pydantic_v1.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/python_deploy_codegen.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/__init__.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/container_task.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/deploy.sh +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/hello_world_package/workflow.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/package/test_workflow.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/truefoundry.yaml +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/workflow.yaml +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/map_task.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/python_task.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/task.py +0 -0
- {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: truefoundry
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.0rc9
|
|
4
4
|
Summary: Truefoundry CLI
|
|
5
5
|
Author: Abhishek Choudhary
|
|
6
6
|
Author-email: abhishek@truefoundry.com
|
|
@@ -34,6 +34,7 @@ Requires-Dist: python-dotenv (>=1.0.1,<1.1.0)
|
|
|
34
34
|
Requires-Dist: python-socketio[client] (>=5.5.2,<6.0.0)
|
|
35
35
|
Requires-Dist: questionary (>=1.10.0,<2.0.0)
|
|
36
36
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
37
|
+
Requires-Dist: requirements-parser (>=0.10.2,<0.11.0)
|
|
37
38
|
Requires-Dist: rich (>=13.7.1,<14.0.0)
|
|
38
39
|
Requires-Dist: rich-click (>=1.2.1,<2.0.0)
|
|
39
40
|
Requires-Dist: tqdm (>=4.0.0,<5.0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "truefoundry"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.0rc9"
|
|
4
4
|
description = "Truefoundry CLI"
|
|
5
5
|
authors = ["Abhishek Choudhary <abhishek@truefoundry.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -29,6 +29,7 @@ python-socketio = {version = ">=5.5.2,<6.0.0", extras = ["client"]}
|
|
|
29
29
|
PyYAML = ">=6.0.0,<7.0.0"
|
|
30
30
|
questionary = ">=1.10.0,<2.0.0"
|
|
31
31
|
requests = ">=2.31.0,<3.0.0"
|
|
32
|
+
requirements-parser = "^0.10.2"
|
|
32
33
|
rich = ">=13.7.1,<14.0.0"
|
|
33
34
|
rich-click = ">=1.2.1,<2.0.0"
|
|
34
35
|
tqdm = ">=4.0.0,<5.0.0"
|
|
@@ -6,6 +6,7 @@ from truefoundry.deploy.auto_gen.models import (
|
|
|
6
6
|
Kustomize,
|
|
7
7
|
ParamType,
|
|
8
8
|
Protocol,
|
|
9
|
+
WorkbenchImage,
|
|
9
10
|
)
|
|
10
11
|
from truefoundry.deploy.lib.dao.application import (
|
|
11
12
|
delete_application,
|
|
@@ -56,14 +57,10 @@ from truefoundry.deploy.v2.lib.patched_models import (
|
|
|
56
57
|
BlueGreen,
|
|
57
58
|
Build,
|
|
58
59
|
Canary,
|
|
59
|
-
CodeserverImage,
|
|
60
60
|
CoreNATSOutputConfig,
|
|
61
61
|
CPUUtilizationMetric,
|
|
62
62
|
CronMetric,
|
|
63
63
|
CUDAVersion,
|
|
64
|
-
CustomCodeserverImage,
|
|
65
|
-
CustomNotebookImage,
|
|
66
|
-
CustomSSHServerImage,
|
|
67
64
|
DockerFileBuild,
|
|
68
65
|
DynamicVolumeConfig,
|
|
69
66
|
Endpoint,
|
|
@@ -104,15 +101,10 @@ from truefoundry.deploy.v2.lib.patched_models import (
|
|
|
104
101
|
SQSInputConfig,
|
|
105
102
|
SQSOutputConfig,
|
|
106
103
|
SQSQueueMetricConfig,
|
|
107
|
-
SSHServerImage,
|
|
108
104
|
StaticVolumeConfig,
|
|
109
105
|
StringDataMount,
|
|
110
106
|
TPUType,
|
|
111
107
|
TruefoundryArtifactSource,
|
|
112
|
-
TruefoundryImageBase,
|
|
113
|
-
TruefoundryImageCuda1180,
|
|
114
|
-
TruefoundryImageCuda1211,
|
|
115
|
-
TruefoundryImageFull,
|
|
116
108
|
VolumeBrowser,
|
|
117
109
|
VolumeMount,
|
|
118
110
|
WorkerConfig,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: application.json
|
|
3
|
-
# timestamp: 2024-
|
|
3
|
+
# timestamp: 2024-08-09T07:42:58+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -125,6 +125,13 @@ class AsyncProcessorSidecar(BaseModel):
|
|
|
125
125
|
)
|
|
126
126
|
|
|
127
127
|
|
|
128
|
+
class Autoshutdown(BaseModel):
|
|
129
|
+
wait_time: conint(ge=0) = Field(
|
|
130
|
+
300,
|
|
131
|
+
description="+label=Wait Time\n+usage=The period to wait after the last received request before scaling the replicas to 0",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
128
135
|
class BaseAutoscaling(BaseModel):
|
|
129
136
|
min_replicas: conint(ge=0) = Field(
|
|
130
137
|
1,
|
|
@@ -138,10 +145,6 @@ class BaseAutoscaling(BaseModel):
|
|
|
138
145
|
30,
|
|
139
146
|
description="+label=Polling Interval\n+usage=This is the interval to check each trigger on.",
|
|
140
147
|
)
|
|
141
|
-
cooldown_period: conint(ge=0) = Field(
|
|
142
|
-
300,
|
|
143
|
-
description="+label=Cooldown Period\n+usage=The period to wait after the last trigger reported active before scaling the resource back to 0.",
|
|
144
|
-
)
|
|
145
148
|
|
|
146
149
|
|
|
147
150
|
class BasicAuthCreds(BaseModel):
|
|
@@ -197,26 +200,6 @@ class CanaryStep(BaseModel):
|
|
|
197
200
|
)
|
|
198
201
|
|
|
199
202
|
|
|
200
|
-
class CodeserverImage(BaseModel):
|
|
201
|
-
"""
|
|
202
|
-
+usage=Codeserver with persistent environment (Python 3.11.6)
|
|
203
|
-
"""
|
|
204
|
-
|
|
205
|
-
type: constr(regex=r"^codeserver$") = Field(..., description="+value=codeserver")
|
|
206
|
-
enable_sudo: bool = Field(
|
|
207
|
-
True,
|
|
208
|
-
description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
|
|
209
|
-
)
|
|
210
|
-
apt_packages: Optional[List[str]] = Field(
|
|
211
|
-
None,
|
|
212
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
213
|
-
)
|
|
214
|
-
docker_registry: Optional[str] = Field(
|
|
215
|
-
None,
|
|
216
|
-
description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
|
|
220
203
|
class CronMetric(BaseModel):
|
|
221
204
|
type: Literal["cron"] = Field(..., description="+value=cron")
|
|
222
205
|
desired_replicas: Optional[conint(ge=1)] = Field(
|
|
@@ -237,60 +220,6 @@ class CronMetric(BaseModel):
|
|
|
237
220
|
)
|
|
238
221
|
|
|
239
222
|
|
|
240
|
-
class CustomCodeserverImage(BaseModel):
|
|
241
|
-
"""
|
|
242
|
-
+usage=User supplied docker image URI for vscode server
|
|
243
|
-
"""
|
|
244
|
-
|
|
245
|
-
type: constr(regex=r"^customcodeserver$") = Field(
|
|
246
|
-
..., description="+value=customcodeserver"
|
|
247
|
-
)
|
|
248
|
-
image_uri: str = Field(
|
|
249
|
-
...,
|
|
250
|
-
description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
|
|
251
|
-
)
|
|
252
|
-
docker_registry: Optional[str] = Field(
|
|
253
|
-
None,
|
|
254
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
class CustomNotebookImage(BaseModel):
|
|
259
|
-
"""
|
|
260
|
-
+usage=User supplied docker image URI for jupyter notebook
|
|
261
|
-
"""
|
|
262
|
-
|
|
263
|
-
type: constr(regex=r"^customnotebook$") = Field(
|
|
264
|
-
..., description="+value=customnotebook"
|
|
265
|
-
)
|
|
266
|
-
image_uri: str = Field(
|
|
267
|
-
...,
|
|
268
|
-
description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
|
|
269
|
-
)
|
|
270
|
-
docker_registry: Optional[str] = Field(
|
|
271
|
-
None,
|
|
272
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
class CustomSSHServerImage(BaseModel):
|
|
277
|
-
"""
|
|
278
|
-
+usage=User supplied docker image URI for ssh server
|
|
279
|
-
"""
|
|
280
|
-
|
|
281
|
-
type: constr(regex=r"^custom-ssh-server$") = Field(
|
|
282
|
-
..., description="+value=custom-ssh-server"
|
|
283
|
-
)
|
|
284
|
-
image_uri: str = Field(
|
|
285
|
-
...,
|
|
286
|
-
description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
|
|
287
|
-
)
|
|
288
|
-
docker_registry: Optional[str] = Field(
|
|
289
|
-
None,
|
|
290
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
|
|
294
223
|
class DockerFileBuild(BaseModel):
|
|
295
224
|
"""
|
|
296
225
|
+docs=Describes that we are using a dockerfile to build our image
|
|
@@ -976,22 +905,6 @@ class SQSQueueMetricConfig(BaseModel):
|
|
|
976
905
|
)
|
|
977
906
|
|
|
978
907
|
|
|
979
|
-
class SSHServerImage(BaseModel):
|
|
980
|
-
"""
|
|
981
|
-
+usage=Ssh Server with persistent environment (Python 3.11.6)
|
|
982
|
-
"""
|
|
983
|
-
|
|
984
|
-
type: constr(regex=r"^ssh-server$") = Field(..., description="+value=ssh-server")
|
|
985
|
-
apt_packages: Optional[List[str]] = Field(
|
|
986
|
-
None,
|
|
987
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
988
|
-
)
|
|
989
|
-
docker_registry: Optional[str] = Field(
|
|
990
|
-
None,
|
|
991
|
-
description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
992
|
-
)
|
|
993
|
-
|
|
994
|
-
|
|
995
908
|
class ConcurrencyPolicy(str, Enum):
|
|
996
909
|
"""
|
|
997
910
|
+usage=Choose whether to allow this job to run while another instance of the job is running, or to replace the currently running instance. Allow
|
|
@@ -1149,86 +1062,6 @@ class TruefoundryArtifactSource(BaseModel):
|
|
|
1149
1062
|
)
|
|
1150
1063
|
|
|
1151
1064
|
|
|
1152
|
-
class TruefoundryImageBase(BaseModel):
|
|
1153
|
-
"""
|
|
1154
|
-
+usage=JupyterLab with persistent python environment (Python 3.11.6)
|
|
1155
|
-
"""
|
|
1156
|
-
|
|
1157
|
-
type: constr(regex=r"^truefoundrybase$") = Field(
|
|
1158
|
-
..., description="+value=truefoundrybase"
|
|
1159
|
-
)
|
|
1160
|
-
enable_sudo: bool = Field(
|
|
1161
|
-
True,
|
|
1162
|
-
description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
|
|
1163
|
-
)
|
|
1164
|
-
apt_packages: Optional[List[str]] = Field(
|
|
1165
|
-
None,
|
|
1166
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
1167
|
-
)
|
|
1168
|
-
docker_registry: Optional[str] = Field(
|
|
1169
|
-
None,
|
|
1170
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
1171
|
-
)
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
class TruefoundryImageCuda1180(BaseModel):
|
|
1175
|
-
"""
|
|
1176
|
-
+usage=JupyterLab with persistent python environment (Python 3.11.6, Cuda 11.8.0)
|
|
1177
|
-
"""
|
|
1178
|
-
|
|
1179
|
-
type: constr(regex=r"^truefoundrycuda1180$") = Field(
|
|
1180
|
-
..., description="+value=truefoundrycuda1180"
|
|
1181
|
-
)
|
|
1182
|
-
apt_packages: Optional[List[str]] = Field(
|
|
1183
|
-
None,
|
|
1184
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
1185
|
-
)
|
|
1186
|
-
docker_registry: Optional[str] = Field(
|
|
1187
|
-
None,
|
|
1188
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
1189
|
-
)
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
class TruefoundryImageCuda1211(BaseModel):
|
|
1193
|
-
"""
|
|
1194
|
-
+usage=JupyterLab with persistent python environment (Python 3.11.6, Cuda 12.1.1)
|
|
1195
|
-
"""
|
|
1196
|
-
|
|
1197
|
-
type: constr(regex=r"^truefoundrycuda1211$") = Field(
|
|
1198
|
-
..., description="+value=truefoundrycuda1211"
|
|
1199
|
-
)
|
|
1200
|
-
apt_packages: Optional[List[str]] = Field(
|
|
1201
|
-
None,
|
|
1202
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
1203
|
-
)
|
|
1204
|
-
docker_registry: Optional[str] = Field(
|
|
1205
|
-
None,
|
|
1206
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
1207
|
-
)
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
class TruefoundryImageFull(BaseModel):
|
|
1211
|
-
"""
|
|
1212
|
-
+usage=JupyterLab + Tensorflow 2.15.0 and Pytorch 2.1.1 with persistent environment (Python 3.11.6)
|
|
1213
|
-
"""
|
|
1214
|
-
|
|
1215
|
-
type: constr(regex=r"^truefoundryfull$") = Field(
|
|
1216
|
-
..., description="+value=truefoundryfull"
|
|
1217
|
-
)
|
|
1218
|
-
enable_sudo: bool = Field(
|
|
1219
|
-
True,
|
|
1220
|
-
description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
|
|
1221
|
-
)
|
|
1222
|
-
apt_packages: Optional[List[str]] = Field(
|
|
1223
|
-
None,
|
|
1224
|
-
description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
|
|
1225
|
-
)
|
|
1226
|
-
docker_registry: Optional[str] = Field(
|
|
1227
|
-
None,
|
|
1228
|
-
description="+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
1229
|
-
)
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
1065
|
class VolumeBrowser(BaseModel):
|
|
1233
1066
|
"""
|
|
1234
1067
|
+label=Volume Browser
|
|
@@ -1265,6 +1098,25 @@ class VolumeMount(BaseModel):
|
|
|
1265
1098
|
)
|
|
1266
1099
|
|
|
1267
1100
|
|
|
1101
|
+
class WorkbenchImage(BaseModel):
|
|
1102
|
+
"""
|
|
1103
|
+
+usage=Workbench Image with persistent environment (Python 3.11.6)
|
|
1104
|
+
"""
|
|
1105
|
+
|
|
1106
|
+
image_uri: str = Field(
|
|
1107
|
+
...,
|
|
1108
|
+
description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
|
|
1109
|
+
)
|
|
1110
|
+
build_script: Optional[constr(min_length=1, max_length=1024)] = Field(
|
|
1111
|
+
None,
|
|
1112
|
+
description="+label=Build Script\n+usage=The build script to run when building the image.\nThis will be executed as the last step in the docker build process as the root user (RUN DEBIAN_FRONTEND=noninteractive bash -ex build_script.sh)\n+placeholder=Enter the build script",
|
|
1113
|
+
)
|
|
1114
|
+
docker_registry: Optional[str] = Field(
|
|
1115
|
+
None,
|
|
1116
|
+
description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
|
|
1117
|
+
)
|
|
1118
|
+
|
|
1119
|
+
|
|
1268
1120
|
class ArtifactsDownload(BaseModel):
|
|
1269
1121
|
"""
|
|
1270
1122
|
+docs=Describes the configuration for the artifacts cache
|
|
@@ -1365,9 +1217,7 @@ class Codeserver(BaseWorkbenchInput):
|
|
|
1365
1217
|
"""
|
|
1366
1218
|
|
|
1367
1219
|
type: constr(regex=r"^codeserver$") = Field(..., description="+value=Code Server")
|
|
1368
|
-
image:
|
|
1369
|
-
..., description="+usage=Pick a codeserver image to deploy\n+sort=2"
|
|
1370
|
-
)
|
|
1220
|
+
image: WorkbenchImage
|
|
1371
1221
|
auth: Optional[BasicAuthCreds] = None
|
|
1372
1222
|
|
|
1373
1223
|
|
|
@@ -1627,16 +1477,7 @@ class Notebook(BaseWorkbenchInput):
|
|
|
1627
1477
|
"""
|
|
1628
1478
|
|
|
1629
1479
|
type: constr(regex=r"^notebook$") = Field(..., description="+value=notebook")
|
|
1630
|
-
image:
|
|
1631
|
-
TruefoundryImageBase,
|
|
1632
|
-
TruefoundryImageFull,
|
|
1633
|
-
CustomNotebookImage,
|
|
1634
|
-
TruefoundryImageCuda1180,
|
|
1635
|
-
TruefoundryImageCuda1211,
|
|
1636
|
-
] = Field(
|
|
1637
|
-
...,
|
|
1638
|
-
description="+usage=Changes made to the root directory `/` will not be persisted across notebook restarts\n+sort=2",
|
|
1639
|
-
)
|
|
1480
|
+
image: WorkbenchImage
|
|
1640
1481
|
auth: Optional[BasicAuthCreds] = None
|
|
1641
1482
|
cull_timeout: conint(ge=5) = Field(
|
|
1642
1483
|
30,
|
|
@@ -1672,9 +1513,7 @@ class SSHServer(BaseWorkbenchInput):
|
|
|
1672
1513
|
"""
|
|
1673
1514
|
|
|
1674
1515
|
type: constr(regex=r"^ssh-server$") = Field(..., description="+value=SSH Server")
|
|
1675
|
-
image:
|
|
1676
|
-
..., description="+usage=Pick a ssh server image to deploy\n+sort=2"
|
|
1677
|
-
)
|
|
1516
|
+
image: WorkbenchImage
|
|
1678
1517
|
ssh_public_key: str = Field(
|
|
1679
1518
|
...,
|
|
1680
1519
|
description="+label: SSH Public Key\n+usage=Add Your SSH Public Key, this will be used to authenticate you to the SSH Server. You can find it using `cat ~/.ssh/id_rsa.pub`\n+sort=4",
|
|
@@ -1776,6 +1615,7 @@ class Service(BaseService):
|
|
|
1776
1615
|
1,
|
|
1777
1616
|
description="+label=Replicas\n+usage=Deploy multiple instances of your pods to distribute incoming traffic across them, ensuring effective load balancing.\n+icon=fa-clone\n+sort=4",
|
|
1778
1617
|
)
|
|
1618
|
+
auto_shutdown: Optional[Autoshutdown] = None
|
|
1779
1619
|
allow_interception: bool = Field(
|
|
1780
1620
|
False,
|
|
1781
1621
|
description="+label=Allow intercepts\n+usage=Whether to allow intercepts to be applied for this service.\nThis would inject an additional sidecar in each pod of the service. Not recommended on production",
|
|
@@ -10,19 +10,17 @@ from truefoundry.deploy.builder.builders import get_builder
|
|
|
10
10
|
from truefoundry.deploy.builder.builders.tfy_notebook_buildpack.dockerfile_template import (
|
|
11
11
|
NotebookImageBuild,
|
|
12
12
|
)
|
|
13
|
-
from truefoundry.pydantic_v1 import BaseModel
|
|
13
|
+
from truefoundry.pydantic_v1 import BaseModel, Field
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class _BuildConfig(BaseModel):
|
|
17
|
-
# I cannot use Field(discriminator="build_config_type") here as
|
|
18
|
-
# build_config_type in the build configs is not a Literal.
|
|
19
17
|
__root__: Union[
|
|
20
18
|
DockerFileBuild,
|
|
21
19
|
PythonBuild,
|
|
22
20
|
NotebookImageBuild,
|
|
23
21
|
TaskPythonBuild,
|
|
24
22
|
TaskDockerFileBuild,
|
|
25
|
-
]
|
|
23
|
+
] = Field(discriminator="type")
|
|
26
24
|
|
|
27
25
|
|
|
28
26
|
def build(
|
|
@@ -13,18 +13,19 @@ __all__ = ["generate_dockerfile_content", "build"]
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def _convert_to_dockerfile_build_config(
|
|
16
|
-
build_configuration: NotebookImageBuild,
|
|
17
|
-
dockerfile_path: str,
|
|
16
|
+
build_configuration: NotebookImageBuild, local_dir: str
|
|
18
17
|
) -> DockerFileBuild:
|
|
19
18
|
dockerfile_content = generate_dockerfile_content(
|
|
20
|
-
build_configuration=build_configuration
|
|
19
|
+
build_configuration=build_configuration,
|
|
20
|
+
local_dir=local_dir,
|
|
21
21
|
)
|
|
22
|
+
dockerfile_path = os.path.join(local_dir, "Dockerfile")
|
|
22
23
|
with open(dockerfile_path, "w", encoding="utf8") as fp:
|
|
23
24
|
fp.write(dockerfile_content)
|
|
24
|
-
|
|
25
25
|
return DockerFileBuild(
|
|
26
26
|
type="dockerfile",
|
|
27
27
|
dockerfile_path=dockerfile_path,
|
|
28
|
+
build_context_path=local_dir,
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
|
|
@@ -35,7 +36,8 @@ def build(
|
|
|
35
36
|
):
|
|
36
37
|
with TemporaryDirectory() as local_dir:
|
|
37
38
|
docker_build_configuration = _convert_to_dockerfile_build_config(
|
|
38
|
-
build_configuration,
|
|
39
|
+
build_configuration,
|
|
40
|
+
local_dir=local_dir,
|
|
39
41
|
)
|
|
40
42
|
dockerfile.build(
|
|
41
43
|
tag=tag,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import os
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
from mako.template import Template
|
|
6
|
+
|
|
7
|
+
from truefoundry.pydantic_v1 import BaseModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NotebookImageBuild(BaseModel):
|
|
11
|
+
type: Literal["tfy-notebook-buildpack"] = "tfy-notebook-buildpack"
|
|
12
|
+
base_image_uri: str
|
|
13
|
+
build_script: Optional[str] = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
DOCKERFILE_TEMPLATE = Template(
|
|
17
|
+
"""
|
|
18
|
+
FROM ${base_image_uri}
|
|
19
|
+
USER root
|
|
20
|
+
|
|
21
|
+
% if build_script_docker_commands is not None:
|
|
22
|
+
${build_script_docker_commands}
|
|
23
|
+
% endif
|
|
24
|
+
|
|
25
|
+
USER $NB_UID
|
|
26
|
+
"""
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def generate_build_script_docker_commands(
|
|
31
|
+
build_script: Optional[str], local_dir: str
|
|
32
|
+
) -> Optional[str]:
|
|
33
|
+
if not build_script:
|
|
34
|
+
return None
|
|
35
|
+
build_script_path = None
|
|
36
|
+
if build_script:
|
|
37
|
+
# we add build script's hash to the file name to ensure docker cache invalidation
|
|
38
|
+
script_hash = hashlib.sha256(build_script.encode("utf-8")).hexdigest()
|
|
39
|
+
build_script_path = os.path.join(local_dir, f"build-script-{script_hash}.sh")
|
|
40
|
+
with open(build_script_path, "w") as fp:
|
|
41
|
+
fp.write(build_script)
|
|
42
|
+
build_script_path = os.path.relpath(build_script_path, local_dir)
|
|
43
|
+
run_build_script_command = f"""\
|
|
44
|
+
COPY {build_script_path} /tmp/user-build-script.sh
|
|
45
|
+
RUN mkdir -p /var/log/ && DEBIAN_FRONTEND=noninteractive bash -ex /tmp/user-build-script.sh 2>&1 | tee /var/log/user-build-script-output.log
|
|
46
|
+
"""
|
|
47
|
+
return run_build_script_command
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def generate_dockerfile_content(
|
|
51
|
+
build_configuration: NotebookImageBuild, local_dir: str
|
|
52
|
+
) -> str:
|
|
53
|
+
build_script_docker_commands = generate_build_script_docker_commands(
|
|
54
|
+
build_script=build_configuration.build_script,
|
|
55
|
+
local_dir=local_dir,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
template_args = {
|
|
59
|
+
"base_image_uri": build_configuration.base_image_uri,
|
|
60
|
+
"build_script_docker_commands": build_script_docker_commands,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
template = DOCKERFILE_TEMPLATE
|
|
64
|
+
|
|
65
|
+
dockerfile_content = template.render(**template_args)
|
|
66
|
+
return dockerfile_content
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import List, Optional, Union
|
|
4
|
+
from typing import Dict, List, Optional, Union
|
|
5
5
|
|
|
6
|
+
import requirements
|
|
7
|
+
from flytekit.configuration import (
|
|
8
|
+
SERIALIZED_CONTEXT_ENV_VAR,
|
|
9
|
+
ImageConfig,
|
|
10
|
+
SerializationSettings,
|
|
11
|
+
)
|
|
6
12
|
from flytekit.configuration import Image as FlytekitImage
|
|
7
|
-
from flytekit.configuration import ImageConfig, SerializationSettings
|
|
8
13
|
from flytekit.models.launch_plan import LaunchPlan as FlyteLaunchPlan
|
|
9
14
|
from flytekit.tools.repo import serialize as serialize_workflow
|
|
10
15
|
from flytekit.tools.translator import TaskSpec as FlyteTaskSpec
|
|
@@ -40,14 +45,60 @@ def _handle_code_upload_for_workflow(
|
|
|
40
45
|
return new_workflow
|
|
41
46
|
|
|
42
47
|
|
|
48
|
+
def _is_tfy_workflow_package(package: requirements.parser.Requirement) -> bool:
|
|
49
|
+
return package.name == "truefoundry" and "workflow" in package.extras
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _is_tfy_wf_present_in_pip_packages_or_requirements_file(
|
|
53
|
+
pip_packages: List[str],
|
|
54
|
+
project_root_path: str,
|
|
55
|
+
requirements_path: Optional[str] = None,
|
|
56
|
+
) -> bool:
|
|
57
|
+
for package in pip_packages:
|
|
58
|
+
parsed_package = requirements.parser.Requirement.parse(package)
|
|
59
|
+
if _is_tfy_workflow_package(parsed_package):
|
|
60
|
+
return True
|
|
61
|
+
if requirements_path:
|
|
62
|
+
requirements_file_absolute_path = os.path.join(
|
|
63
|
+
project_root_path, requirements_path
|
|
64
|
+
)
|
|
65
|
+
if not os.path.exists(requirements_file_absolute_path):
|
|
66
|
+
raise FileNotFoundError(
|
|
67
|
+
f"requirements file not found at {requirements_file_absolute_path}. requirements file path should be relative to project root path."
|
|
68
|
+
)
|
|
69
|
+
with open(requirements_file_absolute_path, "r") as file:
|
|
70
|
+
for package in requirements.parse(file):
|
|
71
|
+
if _is_tfy_workflow_package(package):
|
|
72
|
+
return True
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _is_tfy_wf_present_in_task_python_build(
|
|
77
|
+
task_image_spec: Dict, project_root_path: str
|
|
78
|
+
) -> bool:
|
|
79
|
+
pip_packages = task_image_spec["pip_packages"] or []
|
|
80
|
+
requirements_path = task_image_spec.get("requirements_path")
|
|
81
|
+
return _is_tfy_wf_present_in_pip_packages_or_requirements_file(
|
|
82
|
+
pip_packages=pip_packages,
|
|
83
|
+
project_root_path=project_root_path,
|
|
84
|
+
requirements_path=requirements_path,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _is_dynamic_task(flyte_task: FlyteTaskSpec) -> bool:
|
|
89
|
+
envs: Dict[str:str] = flyte_task.template.container.env or {}
|
|
90
|
+
return SERIALIZED_CONTEXT_ENV_VAR in envs.keys()
|
|
91
|
+
|
|
92
|
+
|
|
43
93
|
# this function does validation that num_workflows = 1, this also validates task_config is passed correctly.
|
|
44
94
|
# This is verified by pydantic but doing it here also as error messages are not clear in pydantic
|
|
45
95
|
def _validate_workflow_entities( # noqa: C901
|
|
46
96
|
workflow_entities: List[Union[FlyteWorkflowSpec, FlyteLaunchPlan, FlyteTaskSpec]],
|
|
97
|
+
project_root_path: str,
|
|
47
98
|
):
|
|
48
|
-
workflow_objs = []
|
|
49
|
-
launch_plans = []
|
|
50
|
-
tasks = []
|
|
99
|
+
workflow_objs: List[FlyteWorkflowSpec] = []
|
|
100
|
+
launch_plans: List[FlyteLaunchPlan] = []
|
|
101
|
+
tasks: List[FlyteTaskSpec] = []
|
|
51
102
|
for entity in workflow_entities:
|
|
52
103
|
if isinstance(entity, FlyteWorkflowSpec):
|
|
53
104
|
workflow_objs.append(entity)
|
|
@@ -73,13 +124,25 @@ def _validate_workflow_entities( # noqa: C901
|
|
|
73
124
|
`PythonTaskConfig`, or `ContainerTaskConfig`. You can import these using:
|
|
74
125
|
`from truefoundry.workflow import PythonTaskConfig, ContainerTaskConfig`
|
|
75
126
|
"""
|
|
127
|
+
tasks_without_truefoundry_worflow_package = []
|
|
76
128
|
for task in tasks:
|
|
129
|
+
if _is_dynamic_task(task):
|
|
130
|
+
raise ValueError("Dynamic workflows are not supported yet.")
|
|
77
131
|
if not task.template.custom:
|
|
78
132
|
raise ValueError(
|
|
79
133
|
error_message_to_use_truefoundry_decorators.format(
|
|
80
134
|
task.template.id.name
|
|
81
135
|
)
|
|
82
136
|
)
|
|
137
|
+
task_image_spec = task.template.custom["truefoundry"]["image"]
|
|
138
|
+
if task_image_spec["type"] == "task-python-build":
|
|
139
|
+
is_tfy_wf_present_in_task_python_build = (
|
|
140
|
+
_is_tfy_wf_present_in_task_python_build(
|
|
141
|
+
task_image_spec=task_image_spec, project_root_path=project_root_path
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
if not is_tfy_wf_present_in_task_python_build:
|
|
145
|
+
tasks_without_truefoundry_worflow_package.append(task.template.id.name)
|
|
83
146
|
try:
|
|
84
147
|
auto_gen_models.FlyteTaskCustom.validate(task.template.custom)
|
|
85
148
|
except ValidationError:
|
|
@@ -88,6 +151,10 @@ def _validate_workflow_entities( # noqa: C901
|
|
|
88
151
|
task.template.id.name
|
|
89
152
|
)
|
|
90
153
|
) from None
|
|
154
|
+
if len(tasks_without_truefoundry_worflow_package) > 0:
|
|
155
|
+
raise ValueError(
|
|
156
|
+
rf"truefoundry\[workflow] package is required dependency to run workflows, add it in pip_packages for tasks: {', '.join(tasks_without_truefoundry_worflow_package)}"
|
|
157
|
+
)
|
|
91
158
|
|
|
92
159
|
# validate that all inputs have default values for cron workflows
|
|
93
160
|
for launch_plan in launch_plans:
|
|
@@ -143,7 +210,7 @@ def _generate_manifest_for_workflow(
|
|
|
143
210
|
workflow_entities = serialize_workflow(
|
|
144
211
|
pkgs=[package_path], settings=settings, local_source_root=source_absolute_path
|
|
145
212
|
)
|
|
146
|
-
_validate_workflow_entities(workflow_entities)
|
|
213
|
+
_validate_workflow_entities(workflow_entities, source_absolute_path)
|
|
147
214
|
|
|
148
215
|
workflow.flyte_entities = []
|
|
149
216
|
for entity in workflow_entities:
|
|
@@ -330,18 +330,6 @@ class Endpoint(models.Endpoint, PatchedModelBase):
|
|
|
330
330
|
pass
|
|
331
331
|
|
|
332
332
|
|
|
333
|
-
class TruefoundryImageBase(models.TruefoundryImageBase, PatchedModelBase):
|
|
334
|
-
type: Literal["truefoundrybase"] = "truefoundrybase"
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
class TruefoundryImageFull(models.TruefoundryImageFull, PatchedModelBase):
|
|
338
|
-
type: Literal["truefoundryfull"] = "truefoundryfull"
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
class CodeserverImage(models.CodeserverImage, PatchedModelBase):
|
|
342
|
-
type: Literal["codeserver"] = "codeserver"
|
|
343
|
-
|
|
344
|
-
|
|
345
333
|
class HelmRepo(models.HelmRepo, PatchedModelBase):
|
|
346
334
|
type: Literal["helm-repo"] = "helm-repo"
|
|
347
335
|
|
|
@@ -442,10 +430,6 @@ class ArtifactsDownload(models.ArtifactsDownload, PatchedModelBase):
|
|
|
442
430
|
pass
|
|
443
431
|
|
|
444
432
|
|
|
445
|
-
class CustomNotebookImage(models.CustomNotebookImage, PatchedModelBase):
|
|
446
|
-
type: Literal["customnotebook"] = "customnotebook"
|
|
447
|
-
|
|
448
|
-
|
|
449
433
|
class NvidiaGPU(models.NvidiaGPU, PatchedModelBase):
|
|
450
434
|
type: Literal["nvidia_gpu"] = "nvidia_gpu"
|
|
451
435
|
name: Optional[Union[GPUType, constr(regex=r"^tpu-[a-z\d\-]+$")]] = None
|
|
@@ -469,26 +453,6 @@ class GcpTPU(models.GcpTPU, PatchedModelBase):
|
|
|
469
453
|
name: Union[TPUType, Literal[r"tpu-[a-z\d\-]+"]]
|
|
470
454
|
|
|
471
455
|
|
|
472
|
-
class CustomCodeserverImage(models.CustomCodeserverImage, PatchedModelBase):
|
|
473
|
-
type: Literal["customcodeserver"] = "customcodeserver"
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
class CustomSSHServerImage(models.CustomSSHServerImage, PatchedModelBase):
|
|
477
|
-
type: Literal["custom-ssh-server"] = "custom-ssh-server"
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
class SSHServerImage(models.SSHServerImage, PatchedModelBase):
|
|
481
|
-
type: Literal["ssh-server"] = "ssh-server"
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
class TruefoundryImageCuda1180(models.TruefoundryImageCuda1180, PatchedModelBase):
|
|
485
|
-
type: Literal["truefoundrycuda1180"] = "truefoundrycuda1180"
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
class TruefoundryImageCuda1211(models.TruefoundryImageCuda1211, PatchedModelBase):
|
|
489
|
-
type: Literal["truefoundrycuda1211"] = "truefoundrycuda1211"
|
|
490
|
-
|
|
491
|
-
|
|
492
456
|
class DynamicVolumeConfig(models.DynamicVolumeConfig, PatchedModelBase):
|
|
493
457
|
type: Literal["dynamic"] = "dynamic"
|
|
494
458
|
|