truefoundry 0.3.0rc8__tar.gz → 0.3.0rc10__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.0rc10}/PKG-INFO +3 -2
  2. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/pyproject.toml +3 -2
  3. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/__init__.py +2 -9
  4. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/auto_gen/models.py +31 -191
  5. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/__init__.py +2 -4
  6. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +7 -5
  7. truefoundry-0.3.0rc10/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +66 -0
  8. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/cli.py +2 -0
  9. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/trigger_command.py +58 -0
  10. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/clients/servicefoundry_client.py +6 -0
  11. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/dao/application.py +20 -0
  12. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/deploy_workflow.py +73 -6
  13. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/patched_models.py +0 -36
  14. truefoundry-0.3.0rc10/truefoundry/version.py +6 -0
  15. truefoundry-0.3.0rc8/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +0 -51
  16. truefoundry-0.3.0rc8/truefoundry/version.py +0 -4
  17. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/README.md +0 -0
  18. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/__init__.py +0 -0
  19. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/__init__.py +0 -0
  20. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/agents/__init__.py +0 -0
  21. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/agents/base.py +0 -0
  22. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/agents/developer.py +0 -0
  23. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
  24. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/agents/tester.py +0 -0
  25. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/cli.py +0 -0
  26. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/constants.py +0 -0
  27. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/exception.py +0 -0
  28. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/logger.py +0 -0
  29. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/__init__.py +0 -0
  30. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/ask.py +0 -0
  31. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/base.py +0 -0
  32. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/commit.py +0 -0
  33. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/docker_build.py +0 -0
  34. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/docker_run.py +0 -0
  35. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
  36. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/list_files.py +0 -0
  37. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/read_file.py +0 -0
  38. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/send_request.py +0 -0
  39. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/tools/write_file.py +0 -0
  40. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/utils/client.py +0 -0
  41. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/utils/diff.py +0 -0
  42. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
  43. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/cli/__init__.py +0 -0
  44. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/cli/__main__.py +0 -0
  45. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/builders/__init__.py +0 -0
  46. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
  47. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
  48. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -0
  49. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/builder/docker_service.py +0 -0
  50. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/__init__.py +0 -0
  51. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/__init__.py +0 -0
  52. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
  53. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/build_command.py +0 -0
  54. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
  55. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/create_command.py +0 -0
  56. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
  57. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/deploy_command.py +0 -0
  58. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/get_command.py +0 -0
  59. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/list_command.py +0 -0
  60. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/login_command.py +0 -0
  61. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
  62. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
  63. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/patch_application_command.py +0 -0
  64. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
  65. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
  66. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
  67. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/config.py +0 -0
  68. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/console.py +0 -0
  69. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/const.py +0 -0
  70. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/display_util.py +0 -0
  71. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/cli/util.py +0 -0
  72. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/core/__init__.py +0 -0
  73. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/core/login.py +0 -0
  74. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/core/logout.py +0 -0
  75. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/__init__.py +0 -0
  76. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/__main__.py +0 -0
  77. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/app.py +0 -0
  78. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/build.py +0 -0
  79. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
  80. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/remote/context.py +0 -0
  81. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/remote/method.py +0 -0
  82. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/remote/remote.py +0 -0
  83. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/route.py +0 -0
  84. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/service.py +0 -0
  85. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/function_service/utils.py +0 -0
  86. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/io/__init__.py +0 -0
  87. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/io/output_callback.py +0 -0
  88. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/io/rich_output_callback.py +0 -0
  89. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/json_util.py +0 -0
  90. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/__init__.py +0 -0
  91. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/auth/auth_service_client.py +0 -0
  92. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/auth/credential_file_manager.py +0 -0
  93. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/auth/credential_provider.py +0 -0
  94. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
  95. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/clients/__init__.py +0 -0
  96. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/clients/shell_client.py +0 -0
  97. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/clients/utils.py +0 -0
  98. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/const.py +0 -0
  99. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/dao/__init__.py +0 -0
  100. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/dao/apply.py +0 -0
  101. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/dao/version.py +0 -0
  102. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/dao/workspace.py +0 -0
  103. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/exceptions.py +0 -0
  104. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/logs_utils.py +0 -0
  105. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/messages.py +0 -0
  106. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/model/__init__.py +0 -0
  107. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/model/entity.py +0 -0
  108. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/session.py +0 -0
  109. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/util.py +0 -0
  110. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/lib/win32.py +0 -0
  111. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/__init__.py +0 -0
  112. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/__init__.py +0 -0
  113. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/deploy.py +0 -0
  114. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/deployable_patched_models.py +0 -0
  115. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/models.py +0 -0
  116. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/deploy/v2/lib/source.py +0 -0
  117. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/__init__.py +0 -0
  118. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/deprecated.py +0 -0
  119. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/truefoundry_chat.py +0 -0
  120. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
  121. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/truefoundry_llm.py +0 -0
  122. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/langchain/utils.py +0 -0
  123. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/logger.py +0 -0
  124. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/ml/__init__.py +0 -0
  125. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/pydantic_v1.py +0 -0
  126. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/python_deploy_codegen.py +0 -0
  127. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/__init__.py +0 -0
  128. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/container_task.py +0 -0
  129. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/example/deploy.sh +0 -0
  130. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/example/hello_world_package/workflow.py +0 -0
  131. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/example/package/test_workflow.py +0 -0
  132. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/example/truefoundry.yaml +0 -0
  133. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/example/workflow.yaml +0 -0
  134. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/map_task.py +0 -0
  135. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/python_task.py +0 -0
  136. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/truefoundry/workflow/task.py +0 -0
  137. {truefoundry-0.3.0rc8 → truefoundry-0.3.0rc10}/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.0rc10
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com
@@ -24,7 +24,7 @@ Requires-Dist: flytekit (==1.12.2) ; extra == "workflow"
24
24
  Requires-Dist: gitignorefile (>=1.1.2,<1.2.0)
25
25
  Requires-Dist: importlib-metadata (>=6.0.1,<8.0.0)
26
26
  Requires-Dist: importlib-resources (>=5.2.0,<6.0.0)
27
- Requires-Dist: mlfoundry (==0.11.2) ; extra == "ml"
27
+ Requires-Dist: mlfoundry (==0.11.3) ; extra == "ml"
28
28
  Requires-Dist: openai (>=1.16.2,<2.0.0)
29
29
  Requires-Dist: packaging (>=20.0,<25.0)
30
30
  Requires-Dist: pydantic (>=1.10.0,<3)
@@ -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.0rc10"
4
4
  description = "Truefoundry CLI"
5
5
  authors = ["Abhishek Choudhary <abhishek@truefoundry.com>"]
6
6
  readme = "README.md"
@@ -17,7 +17,7 @@ GitPython = ">=3.1.43,<3.2.0"
17
17
  importlib-metadata = ">=6.0.1,<8.0.0"
18
18
  importlib-resources = "^5.2.0"
19
19
  Mako = "^1.1.6"
20
- mlfoundry = { version = "0.11.2", optional = true }
20
+ mlfoundry = { version = "0.11.3", optional = true }
21
21
  openai = ">=1.16.2,<2.0.0"
22
22
  packaging = ">=20.0,<25.0"
23
23
  pydantic = ">=1.10.0,<3"
@@ -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,
@@ -15,6 +16,7 @@ from truefoundry.deploy.lib.dao.application import (
15
16
  list_job_runs,
16
17
  terminate_job_run,
17
18
  trigger_job,
19
+ trigger_workflow,
18
20
  )
19
21
  from truefoundry.deploy.lib.dao.version import (
20
22
  get_version as get_application_version,
@@ -56,14 +58,10 @@ from truefoundry.deploy.v2.lib.patched_models import (
56
58
  BlueGreen,
57
59
  Build,
58
60
  Canary,
59
- CodeserverImage,
60
61
  CoreNATSOutputConfig,
61
62
  CPUUtilizationMetric,
62
63
  CronMetric,
63
64
  CUDAVersion,
64
- CustomCodeserverImage,
65
- CustomNotebookImage,
66
- CustomSSHServerImage,
67
65
  DockerFileBuild,
68
66
  DynamicVolumeConfig,
69
67
  Endpoint,
@@ -104,15 +102,10 @@ from truefoundry.deploy.v2.lib.patched_models import (
104
102
  SQSInputConfig,
105
103
  SQSOutputConfig,
106
104
  SQSQueueMetricConfig,
107
- SSHServerImage,
108
105
  StaticVolumeConfig,
109
106
  StringDataMount,
110
107
  TPUType,
111
108
  TruefoundryArtifactSource,
112
- TruefoundryImageBase,
113
- TruefoundryImageCuda1180,
114
- TruefoundryImageCuda1211,
115
- TruefoundryImageFull,
116
109
  VolumeBrowser,
117
110
  VolumeMount,
118
111
  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
@@ -13,6 +13,7 @@ from truefoundry.deploy.cli.commands import (
13
13
  get_logout_command,
14
14
  get_patch_application_command,
15
15
  get_patch_command,
16
+ get_trigger_command,
16
17
  )
17
18
  from truefoundry.deploy.cli.config import CliConfig
18
19
  from truefoundry.deploy.cli.const import GROUP_CLS
@@ -36,6 +37,7 @@ def create_truefoundry_cli():
36
37
  cli.add_command(get_deploy_command())
37
38
  cli.add_command(get_patch_application_command())
38
39
  cli.add_command(get_delete_command())
40
+ cli.add_command(get_trigger_command())
39
41
 
40
42
  if not (sys.platform.startswith("win32") or sys.platform.startswith("cygwin")):
41
43
  cli.add_command(get_patch_command())
@@ -82,6 +82,64 @@ def trigger_job(application_fqn: str, command: Optional[Sequence[str]], params):
82
82
  )
83
83
 
84
84
 
85
+ @click.command(
86
+ name="workflow",
87
+ cls=COMMAND_CLS,
88
+ context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
89
+ )
90
+ @click.option(
91
+ "--application-fqn",
92
+ "--application_fqn",
93
+ type=click.STRING,
94
+ required=True,
95
+ help="FQN of the workflow application",
96
+ )
97
+ @click.argument(
98
+ "inputs",
99
+ type=click.STRING,
100
+ nargs=-1,
101
+ required=False,
102
+ )
103
+ @handle_exception_wrapper
104
+ def trigger_workflow(application_fqn: str, inputs):
105
+ """
106
+ Trigger a Workflow on TrueFoundry
107
+
108
+ [b]tfy trigger workflow --application-fqn "my-cluster:my-workspace:my-workflow"[/]
109
+
110
+ \n
111
+ Additionally, you can pass inputs (if defined in the workflow)\n\n
112
+
113
+ Passing inputs:
114
+
115
+ [b]tfy trigger workflow --application-fqn "my-cluster:my-workspace:my-workflow" -- --input1_name input1_value --input2_name input2_value ...[/]
116
+ """
117
+ if inputs:
118
+ inputs_dict = {}
119
+ if len(inputs) % 2 != 0:
120
+ raise ClickException(
121
+ f"Found odd number of argument pairs: {inputs}. "
122
+ "Perhaps you forgot to pass a value for one of the inputs? "
123
+ "inputs for workflow should be passed in the "
124
+ "format `--input1_name input1_value --input2_name input2_value ...`"
125
+ )
126
+ for i in range(0, len(inputs), 2):
127
+ key = inputs[i]
128
+ value = inputs[i + 1]
129
+ if not key.startswith("--"):
130
+ raise ClickException(
131
+ f"Got ambiguous argument {key!r} in inputs: {inputs}. "
132
+ f"input names should be prefixed with '--' i.e. "
133
+ "inputs for workflow should be passed in the "
134
+ "format `--input1_name input1_value --input2_name input2_value ...`"
135
+ )
136
+ key = key.lstrip("-")
137
+ inputs_dict[key] = value
138
+
139
+ application.trigger_workflow(application_fqn=application_fqn, inputs=inputs)
140
+
141
+
85
142
  def get_trigger_command():
86
143
  trigger_command.add_command(trigger_job)
144
+ trigger_command.add_command(trigger_workflow)
87
145
  return trigger_command
@@ -616,6 +616,12 @@ class ServiceFoundryServiceClient:
616
616
  response = request_handling(res)
617
617
  return TriggerJobResult.parse_obj(response)
618
618
 
619
+ def trigger_workflow(self, application_id: str, inputs: Dict[str, Any]):
620
+ url = f"{self._api_server_url}/{VERSION_PREFIX}/workflow/{application_id}/executions"
621
+ res = requests.post(url, json=inputs, headers=self._get_header())
622
+ response = request_handling(res)
623
+ return response
624
+
619
625
  @check_min_cli_version
620
626
  def get_docker_registry_creds(
621
627
  self, docker_registry_fqn: str, cluster_id: str
@@ -241,3 +241,23 @@ def terminate_job_run(
241
241
  job_run_name=job_run_name,
242
242
  )
243
243
  return response
244
+
245
+
246
+ def trigger_workflow(application_fqn: str, inputs: Optional[Dict[str, Any]] = None):
247
+ inputs = inputs or {}
248
+ client = ServiceFoundryServiceClient()
249
+ _application_info = client.get_application_info_by_fqn(
250
+ application_fqn=application_fqn
251
+ )
252
+ application_info = client.get_application_info(
253
+ application_id=_application_info.applicationId
254
+ )
255
+ client.trigger_workflow(
256
+ application_id=application_info.id,
257
+ inputs=inputs,
258
+ )
259
+ logger.info(f"Started Execution for Workflow: {application_info.name}")
260
+ executions_page = (
261
+ f"{client.base_url.strip('/')}/deployments/{application_info.id}?tab=executions"
262
+ )
263
+ logger.info(f"You can check the executions at {executions_page}")