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.

Files changed (137) hide show
  1. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/PKG-INFO +2 -1
  2. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/pyproject.toml +2 -1
  3. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/__init__.py +1 -9
  4. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/auto_gen/models.py +31 -191
  5. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/__init__.py +2 -4
  6. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +7 -5
  7. truefoundry-0.3.0rc9/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +66 -0
  8. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deploy_workflow.py +73 -6
  9. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/patched_models.py +0 -36
  10. truefoundry-0.3.0rc9/truefoundry/version.py +6 -0
  11. truefoundry-0.3.0rc8/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +0 -51
  12. truefoundry-0.3.0rc8/truefoundry/version.py +0 -4
  13. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/README.md +0 -0
  14. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/__init__.py +0 -0
  15. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/__init__.py +0 -0
  16. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/__init__.py +0 -0
  17. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/base.py +0 -0
  18. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/developer.py +0 -0
  19. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
  20. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/agents/tester.py +0 -0
  21. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/cli.py +0 -0
  22. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/constants.py +0 -0
  23. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/exception.py +0 -0
  24. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/logger.py +0 -0
  25. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/__init__.py +0 -0
  26. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/ask.py +0 -0
  27. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/base.py +0 -0
  28. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/commit.py +0 -0
  29. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/docker_build.py +0 -0
  30. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/docker_run.py +0 -0
  31. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
  32. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/list_files.py +0 -0
  33. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/read_file.py +0 -0
  34. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/send_request.py +0 -0
  35. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/tools/write_file.py +0 -0
  36. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/client.py +0 -0
  37. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/diff.py +0 -0
  38. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
  39. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/cli/__init__.py +0 -0
  40. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/cli/__main__.py +0 -0
  41. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/__init__.py +0 -0
  42. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
  43. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
  44. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -0
  45. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/builder/docker_service.py +0 -0
  46. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/__init__.py +0 -0
  47. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/cli.py +0 -0
  48. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/__init__.py +0 -0
  49. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
  50. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/build_command.py +0 -0
  51. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
  52. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/create_command.py +0 -0
  53. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
  54. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/deploy_command.py +0 -0
  55. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/get_command.py +0 -0
  56. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/list_command.py +0 -0
  57. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/login_command.py +0 -0
  58. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
  59. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
  60. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/patch_application_command.py +0 -0
  61. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
  62. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
  63. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
  64. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/commands/trigger_command.py +0 -0
  65. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/config.py +0 -0
  66. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/console.py +0 -0
  67. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/const.py +0 -0
  68. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/display_util.py +0 -0
  69. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/cli/util.py +0 -0
  70. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/__init__.py +0 -0
  71. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/login.py +0 -0
  72. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/core/logout.py +0 -0
  73. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/__init__.py +0 -0
  74. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/__main__.py +0 -0
  75. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/app.py +0 -0
  76. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/build.py +0 -0
  77. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
  78. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/context.py +0 -0
  79. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/method.py +0 -0
  80. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/remote/remote.py +0 -0
  81. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/route.py +0 -0
  82. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/service.py +0 -0
  83. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/function_service/utils.py +0 -0
  84. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/__init__.py +0 -0
  85. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/output_callback.py +0 -0
  86. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/io/rich_output_callback.py +0 -0
  87. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/json_util.py +0 -0
  88. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/__init__.py +0 -0
  89. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/auth_service_client.py +0 -0
  90. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/credential_file_manager.py +0 -0
  91. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/credential_provider.py +0 -0
  92. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
  93. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/__init__.py +0 -0
  94. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/servicefoundry_client.py +0 -0
  95. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/shell_client.py +0 -0
  96. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/clients/utils.py +0 -0
  97. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/const.py +0 -0
  98. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/__init__.py +0 -0
  99. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/application.py +0 -0
  100. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/apply.py +0 -0
  101. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/version.py +0 -0
  102. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/dao/workspace.py +0 -0
  103. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/exceptions.py +0 -0
  104. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/logs_utils.py +0 -0
  105. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/messages.py +0 -0
  106. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/model/__init__.py +0 -0
  107. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/model/entity.py +0 -0
  108. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/session.py +0 -0
  109. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/util.py +0 -0
  110. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/lib/win32.py +0 -0
  111. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/__init__.py +0 -0
  112. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/__init__.py +0 -0
  113. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deploy.py +0 -0
  114. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/deployable_patched_models.py +0 -0
  115. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/models.py +0 -0
  116. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/deploy/v2/lib/source.py +0 -0
  117. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/__init__.py +0 -0
  118. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/deprecated.py +0 -0
  119. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_chat.py +0 -0
  120. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
  121. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/truefoundry_llm.py +0 -0
  122. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/langchain/utils.py +0 -0
  123. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/logger.py +0 -0
  124. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/ml/__init__.py +0 -0
  125. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/pydantic_v1.py +0 -0
  126. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/python_deploy_codegen.py +0 -0
  127. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/__init__.py +0 -0
  128. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/container_task.py +0 -0
  129. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/deploy.sh +0 -0
  130. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/hello_world_package/workflow.py +0 -0
  131. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/package/test_workflow.py +0 -0
  132. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/truefoundry.yaml +0 -0
  133. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/example/workflow.yaml +0 -0
  134. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/map_task.py +0 -0
  135. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/python_task.py +0 -0
  136. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc9}/truefoundry/workflow/task.py +0 -0
  137. {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.0rc8
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.0rc8"
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-07-24T13:42:02+00:00
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: Union[CodeserverImage, CustomCodeserverImage] = Field(
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: Union[
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: Union[SSHServerImage, CustomSSHServerImage] = Field(
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, dockerfile_path=os.path.join(local_dir, "Dockerfile")
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