truefoundry 0.3.0rc7__tar.gz → 0.3.0rc8__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 (135) hide show
  1. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/PKG-INFO +1 -1
  2. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/pyproject.toml +1 -1
  3. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/auto_gen/models.py +21 -1
  4. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/deploy_command.py +6 -3
  5. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/patch_application_command.py +2 -0
  6. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/deploy.py +52 -1
  7. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/deploy_workflow.py +58 -5
  8. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/deployable_patched_models.py +3 -1
  9. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/__init__.py +1 -1
  10. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/example/hello_world_package/workflow.py +3 -2
  11. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/example/package/test_workflow.py +29 -8
  12. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/example/truefoundry.yaml +1 -1
  13. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/workflow.py +62 -2
  14. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/README.md +0 -0
  15. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/__init__.py +0 -0
  16. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/__init__.py +0 -0
  17. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/agents/__init__.py +0 -0
  18. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/agents/base.py +0 -0
  19. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/agents/developer.py +0 -0
  20. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/agents/project_identifier.py +0 -0
  21. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/agents/tester.py +0 -0
  22. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/cli.py +0 -0
  23. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/constants.py +0 -0
  24. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/exception.py +0 -0
  25. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/logger.py +0 -0
  26. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/__init__.py +0 -0
  27. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/ask.py +0 -0
  28. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/base.py +0 -0
  29. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/commit.py +0 -0
  30. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/docker_build.py +0 -0
  31. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/docker_run.py +0 -0
  32. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/file_type_counts.py +0 -0
  33. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/list_files.py +0 -0
  34. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/read_file.py +0 -0
  35. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/send_request.py +0 -0
  36. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/tools/write_file.py +0 -0
  37. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/utils/client.py +0 -0
  38. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/utils/diff.py +0 -0
  39. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/autodeploy/utils/pydantic_compat.py +0 -0
  40. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/cli/__init__.py +0 -0
  41. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/cli/__main__.py +0 -0
  42. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/__init__.py +0 -0
  43. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/__init__.py +0 -0
  44. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/__init__.py +0 -0
  45. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/dockerfile.py +0 -0
  46. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +0 -0
  47. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +0 -0
  48. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +0 -0
  49. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +0 -0
  50. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/builder/docker_service.py +0 -0
  51. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/__init__.py +0 -0
  52. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/cli.py +0 -0
  53. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/__init__.py +0 -0
  54. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/apply_command.py +0 -0
  55. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/build_command.py +0 -0
  56. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/build_logs_command.py +0 -0
  57. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/create_command.py +0 -0
  58. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/delete_command.py +0 -0
  59. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/get_command.py +0 -0
  60. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/list_command.py +0 -0
  61. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/login_command.py +0 -0
  62. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/logout_command.py +0 -0
  63. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/logs_command.py +0 -0
  64. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/patch_command.py +0 -0
  65. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/redeploy_command.py +0 -0
  66. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/terminate_comand.py +0 -0
  67. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/commands/trigger_command.py +0 -0
  68. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/config.py +0 -0
  69. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/console.py +0 -0
  70. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/const.py +0 -0
  71. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/display_util.py +0 -0
  72. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/cli/util.py +0 -0
  73. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/core/__init__.py +0 -0
  74. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/core/login.py +0 -0
  75. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/core/logout.py +0 -0
  76. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/__init__.py +0 -0
  77. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/__main__.py +0 -0
  78. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/app.py +0 -0
  79. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/build.py +0 -0
  80. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/remote/__init__.py +0 -0
  81. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/remote/context.py +0 -0
  82. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/remote/method.py +0 -0
  83. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/remote/remote.py +0 -0
  84. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/route.py +0 -0
  85. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/service.py +0 -0
  86. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/function_service/utils.py +0 -0
  87. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/io/__init__.py +0 -0
  88. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/io/output_callback.py +0 -0
  89. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/io/rich_output_callback.py +0 -0
  90. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/json_util.py +0 -0
  91. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/__init__.py +0 -0
  92. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/auth/auth_service_client.py +0 -0
  93. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/auth/credential_file_manager.py +0 -0
  94. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/auth/credential_provider.py +0 -0
  95. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/auth/servicefoundry_session.py +0 -0
  96. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/clients/__init__.py +0 -0
  97. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/clients/servicefoundry_client.py +0 -0
  98. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/clients/shell_client.py +0 -0
  99. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/clients/utils.py +0 -0
  100. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/const.py +0 -0
  101. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/dao/__init__.py +0 -0
  102. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/dao/application.py +0 -0
  103. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/dao/apply.py +0 -0
  104. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/dao/version.py +0 -0
  105. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/dao/workspace.py +0 -0
  106. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/exceptions.py +0 -0
  107. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/logs_utils.py +0 -0
  108. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/messages.py +0 -0
  109. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/model/__init__.py +0 -0
  110. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/model/entity.py +0 -0
  111. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/session.py +0 -0
  112. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/util.py +0 -0
  113. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/lib/win32.py +0 -0
  114. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/__init__.py +0 -0
  115. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/__init__.py +0 -0
  116. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/models.py +0 -0
  117. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/patched_models.py +0 -0
  118. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/deploy/v2/lib/source.py +0 -0
  119. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/__init__.py +0 -0
  120. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/deprecated.py +0 -0
  121. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/truefoundry_chat.py +0 -0
  122. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/truefoundry_embeddings.py +0 -0
  123. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/truefoundry_llm.py +0 -0
  124. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/langchain/utils.py +0 -0
  125. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/logger.py +0 -0
  126. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/ml/__init__.py +0 -0
  127. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/pydantic_v1.py +0 -0
  128. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/python_deploy_codegen.py +0 -0
  129. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/version.py +0 -0
  130. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/container_task.py +0 -0
  131. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/example/deploy.sh +0 -0
  132. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/example/workflow.yaml +0 -0
  133. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/map_task.py +0 -0
  134. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/python_task.py +0 -0
  135. {truefoundry-0.3.0rc7 → truefoundry-0.3.0rc8}/truefoundry/workflow/task.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truefoundry
3
- Version: 0.3.0rc7
3
+ Version: 0.3.0rc8
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "truefoundry"
3
- version = "0.3.0rc7"
3
+ version = "0.3.0rc8"
4
4
  description = "Truefoundry CLI"
5
5
  authors = ["Abhishek Choudhary <abhishek@truefoundry.com>"]
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: application.json
3
- # timestamp: 2024-07-19T06:56:20+00:00
3
+ # timestamp: 2024-07-24T13:42:02+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1317,6 +1317,10 @@ class BaseWorkbenchInput(BaseModel):
1317
1317
  )
1318
1318
  service_account: Optional[str] = Field(None, description="+sort=10113")
1319
1319
  kustomize: Optional[Kustomize] = None
1320
+ workspace_fqn: Optional[str] = Field(
1321
+ None,
1322
+ description="+label=Workspace FQN\n+docs=Fully qualified name of the workspace\n+uiType=Hidden",
1323
+ )
1320
1324
 
1321
1325
 
1322
1326
  class Build(BaseModel):
@@ -1458,6 +1462,10 @@ class Helm(BaseModel):
1458
1462
  )
1459
1463
  kustomize: Optional[Kustomize] = None
1460
1464
  ignoreDifferences: Optional[List[Dict[str, Any]]] = None
1465
+ workspace_fqn: Optional[str] = Field(
1466
+ None,
1467
+ description="+label=Workspace FQN\n+docs=Fully qualified name of the workspace\n+uiType=Hidden",
1468
+ )
1461
1469
 
1462
1470
 
1463
1471
  class Job(BaseModel):
@@ -1509,6 +1517,10 @@ class Job(BaseModel):
1509
1517
  )
1510
1518
  labels: Optional[Dict[str, str]] = Field(None, description="+label=Labels")
1511
1519
  kustomize: Optional[Kustomize] = None
1520
+ workspace_fqn: Optional[str] = Field(
1521
+ None,
1522
+ description="+label=Workspace FQN\n+docs=Fully qualified name of the workspace\n+uiType=Hidden",
1523
+ )
1512
1524
 
1513
1525
 
1514
1526
  class KafkaInputConfig(BaseModel):
@@ -1680,6 +1692,10 @@ class Volume(BaseModel):
1680
1692
  description="+sort=2\n+label=Volume Config\n+message=Volume Configuration, can be either Dynamically provisioned or statically provisioned.",
1681
1693
  )
1682
1694
  volume_browser: Optional[VolumeBrowser] = None
1695
+ workspace_fqn: Optional[str] = Field(
1696
+ None,
1697
+ description="+label=Workspace FQN\n+docs=Fully qualified name of the workspace\n+uiType=Hidden",
1698
+ )
1683
1699
 
1684
1700
 
1685
1701
  class WorkerConfig(BaseModel):
@@ -1729,6 +1745,10 @@ class BaseService(BaseModel):
1729
1745
  kustomize: Optional[Kustomize] = None
1730
1746
  liveness_probe: Optional[HealthProbe] = None
1731
1747
  readiness_probe: Optional[HealthProbe] = None
1748
+ workspace_fqn: Optional[str] = Field(
1749
+ None,
1750
+ description="+label=Workspace FQN\n+docs=Fully qualified name of the workspace\n+uiType=Hidden",
1751
+ )
1732
1752
 
1733
1753
 
1734
1754
  class FlyteLaunchPlan(BaseModel):
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import sys
3
+ from typing import Optional
3
4
 
4
5
  import rich_click as click
5
6
  import yaml
@@ -9,6 +10,7 @@ from click.exceptions import ClickException
9
10
  from truefoundry.autodeploy.cli import cli as autodeploy_cli
10
11
  from truefoundry.autodeploy.exception import InvalidRequirementsException
11
12
  from truefoundry.deploy.cli.const import GROUP_CLS
13
+ from truefoundry.deploy.cli.util import handle_exception_wrapper
12
14
 
13
15
 
14
16
  def _get_default_spec_file():
@@ -41,8 +43,8 @@ def _get_default_spec_file():
41
43
  "-w",
42
44
  "--workspace-fqn",
43
45
  "--workspace_fqn",
44
- required=True,
45
- help="FQN of the Workspace to deploy to",
46
+ default=None,
47
+ help="FQN of the Workspace to deploy to. If not provided, the Workspace FQN will be read from the deployment spec if available.",
46
48
  )
47
49
  @click.option(
48
50
  "--wait/--no-wait",
@@ -52,7 +54,8 @@ def _get_default_spec_file():
52
54
  default=True,
53
55
  help="Wait and tail the deployment progress",
54
56
  )
55
- def deploy_command(file: str, workspace_fqn: str, wait: bool):
57
+ @handle_exception_wrapper
58
+ def deploy_command(file: str, workspace_fqn: Optional[str], wait: bool):
56
59
  from truefoundry.deploy.lib.auth.servicefoundry_session import ServiceFoundrySession
57
60
  from truefoundry.deploy.v2.lib.deployable_patched_models import Application
58
61
 
@@ -4,6 +4,7 @@ import rich_click as click
4
4
  import yaml
5
5
 
6
6
  from truefoundry.deploy.cli.const import GROUP_CLS
7
+ from truefoundry.deploy.cli.util import handle_exception_wrapper
7
8
  from truefoundry.deploy.lib.dao import application as application_lib
8
9
 
9
10
 
@@ -44,6 +45,7 @@ from truefoundry.deploy.lib.dao import application as application_lib
44
45
  default=True,
45
46
  help="Wait and tail the deployment progress",
46
47
  )
48
+ @handle_exception_wrapper
47
49
  def patch_application_command(
48
50
  patch_file: str, application_fqn: str, patch: str, wait: bool
49
51
  ):
@@ -191,10 +191,61 @@ def _warn_when_gpu_selected_without_cuda(component: Component):
191
191
  )
192
192
 
193
193
 
194
+ def _resolve_workspace_fqn(
195
+ component: Component, workspace_fqn: Optional[str] = None
196
+ ) -> str:
197
+ if not workspace_fqn:
198
+ if hasattr(component, "workspace_fqn") and component.workspace_fqn:
199
+ resolved_workspace_fqn = component.workspace_fqn
200
+ else:
201
+ raise ValueError(
202
+ f"""\
203
+ No Workspace FQN was provided or mentioned in the spec.
204
+ Either add a `workspace_fqn` to your yaml spec as
205
+
206
+ ```
207
+ name: {getattr(component, 'name', 'my-app')}
208
+ type: {getattr(component, 'type', 'undefined')}
209
+ ...
210
+ workspace_fqn: <your workspace fqn>
211
+ ```
212
+
213
+ or Python deployment spec as
214
+
215
+ ```
216
+ app = {component.__class__.__name__}(
217
+ name='{getattr(component, 'name', 'my-app')}',
218
+ ...
219
+ workspace_fqn='<your workspace fqn>'
220
+ )
221
+ ```
222
+
223
+ or pass it explicitly using `--workspace-fqn` argument on CLI.
224
+ """
225
+ )
226
+ else:
227
+ if (
228
+ hasattr(component, "workspace_fqn")
229
+ and component.workspace_fqn
230
+ and component.workspace_fqn != workspace_fqn
231
+ ):
232
+ logger.warning(
233
+ f"`workspace_fqn` set in the deployment spec doesn't match the provided `workspace_fqn` argument {component.workspace_fqn!r} \n"
234
+ f"Using `workspace_fqn`: {workspace_fqn!r} "
235
+ )
236
+ resolved_workspace_fqn = workspace_fqn
237
+
238
+ return resolved_workspace_fqn
239
+
240
+
194
241
  def deploy_component(
195
- component: Component, workspace_fqn: str, wait: bool = True
242
+ component: Component, workspace_fqn: Optional[str] = None, wait: bool = True
196
243
  ) -> Deployment:
197
244
  _warn_when_gpu_selected_without_cuda(component=component)
245
+ workspace_fqn = _resolve_workspace_fqn(
246
+ component=component, workspace_fqn=workspace_fqn
247
+ )
248
+ component.workspace_fqn = workspace_fqn
198
249
  workspace_id = get_workspace_by_fqn(workspace_fqn).id
199
250
  updated_component = _handle_if_local_source(
200
251
  component=component, workspace_fqn=workspace_fqn
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import sys
3
3
  from pathlib import Path
4
- from typing import List, Union
4
+ from typing import List, Optional, Union
5
5
 
6
6
  from flytekit.configuration import Image as FlytekitImage
7
7
  from flytekit.configuration import ImageConfig, SerializationSettings
@@ -22,6 +22,10 @@ from truefoundry.deploy.v2.lib.source import (
22
22
  )
23
23
  from truefoundry.logger import logger
24
24
  from truefoundry.pydantic_v1 import ValidationError
25
+ from truefoundry.workflow.workflow import (
26
+ TRUEFOUNDRY_LAUNCH_PLAN_NAME,
27
+ execution_config_store,
28
+ )
25
29
 
26
30
 
27
31
  def _handle_code_upload_for_workflow(
@@ -38,7 +42,7 @@ def _handle_code_upload_for_workflow(
38
42
 
39
43
  # this function does validation that num_workflows = 1, this also validates task_config is passed correctly.
40
44
  # This is verified by pydantic but doing it here also as error messages are not clear in pydantic
41
- def _validate_workflow_entities(
45
+ def _validate_workflow_entities( # noqa: C901
42
46
  workflow_entities: List[Union[FlyteWorkflowSpec, FlyteLaunchPlan, FlyteTaskSpec]],
43
47
  ):
44
48
  workflow_objs = []
@@ -57,9 +61,9 @@ def _validate_workflow_entities(
57
61
  raise ValueError(
58
62
  f"Workflow file must have exactly one workflow object. Found {len(workflow_objs)}"
59
63
  )
60
- if len(launch_plans) != 1:
64
+ if len(launch_plans) > 2:
61
65
  raise ValueError(
62
- f"Workflow file must have exactly one launch plan. Found {len(launch_plans)}"
66
+ f"Workflow file must have exactly one launch plan. Found {len(launch_plans) - 1}"
63
67
  )
64
68
 
65
69
  error_message_to_use_truefoundry_decorators = """Invalid task definition for task: {}, Please use valid truefoundry decorator/class and pass task_config for tasks.
@@ -85,6 +89,19 @@ def _validate_workflow_entities(
85
89
  )
86
90
  ) from None
87
91
 
92
+ # validate that all inputs have default values for cron workflows
93
+ for launch_plan in launch_plans:
94
+ if (
95
+ execution_config_store.get(launch_plan.spec.workflow_id.name)
96
+ and launch_plan.id.name == TRUEFOUNDRY_LAUNCH_PLAN_NAME
97
+ ):
98
+ workflow_inputs = launch_plan.spec.default_inputs.parameters
99
+ for input in workflow_inputs:
100
+ if workflow_inputs[input].required:
101
+ raise ValueError(
102
+ f"All inputs must have default for a cron workflow. Input {input} is required in workflow but default value is not provided"
103
+ )
104
+
88
105
 
89
106
  def _get_relative_package_path_from_filepath(
90
107
  project_root_path: str, filepath: str
@@ -130,6 +147,23 @@ def _generate_manifest_for_workflow(
130
147
 
131
148
  workflow.flyte_entities = []
132
149
  for entity in workflow_entities:
150
+ if isinstance(entity, FlyteLaunchPlan):
151
+ workflow_name = entity.spec.workflow_id.name
152
+
153
+ # this is the case when someone has a cron schedule. and this line is for handling default launch plan in this case.
154
+ if (
155
+ execution_config_store.get(workflow_name)
156
+ and workflow_name == entity.id.name
157
+ ):
158
+ continue
159
+ # this is the case when someone does not have a cron schedule. and this line is for handling default launch plan in this case.
160
+ elif entity.id.name == workflow_name:
161
+ entity._id._name = TRUEFOUNDRY_LAUNCH_PLAN_NAME
162
+ # this the case when some workflow doesn't have cron schedule, neither it is default launch plan
163
+ elif entity.id.name != TRUEFOUNDRY_LAUNCH_PLAN_NAME:
164
+ raise ValueError(
165
+ f"Creating launch plans is not allowed. Found launch plan with name {entity.id.name}"
166
+ )
133
167
  message_dict = MessageToDict(entity.to_flyte_idl())
134
168
  # proto message to dict conversion converts all int to float. so we need this hack
135
169
  if (
@@ -148,10 +182,29 @@ def _generate_manifest_for_workflow(
148
182
  auto_gen_models.Workflow.validate({**workflow.dict()})
149
183
 
150
184
 
185
+ def _validate_workspace_fqn(
186
+ workflow: auto_gen_models.Workflow,
187
+ workspace_fqn: Optional[str] = None,
188
+ ):
189
+ if not workspace_fqn:
190
+ raise ValueError(
191
+ "No Workspace FQN was provided. "
192
+ "Pass it explicitly using `--workspace-fqn` argument on CLI or `workspace_fqn` argument of `deploy_workflow`."
193
+ )
194
+
195
+
151
196
  def deploy_workflow(
152
- workflow: auto_gen_models.Workflow, workspace_fqn: str, wait: bool = True
197
+ workflow: auto_gen_models.Workflow,
198
+ workspace_fqn: str,
199
+ wait: bool = True,
153
200
  ) -> Deployment:
154
201
  _generate_manifest_for_workflow(workflow)
202
+ _validate_workspace_fqn(workflow, workspace_fqn)
203
+
204
+ # we need to rest the execution config store as it is a global variable and we don't want to keep the cron execution config for next workflow
205
+ # this is only needed for notebook environment
206
+ execution_config_store.reset()
207
+
155
208
  workspace_id = get_workspace_by_fqn(workspace_fqn).id
156
209
 
157
210
  logger.info(
@@ -67,7 +67,9 @@ class Application(models.Application, DeployablePatchedModelBase):
67
67
  from truefoundry.deploy.v2.lib.deploy_workflow import deploy_workflow
68
68
 
69
69
  return deploy_workflow(
70
- workflow=self.__root__, workspace_fqn=workspace_fqn, wait=wait
70
+ workflow=self.__root__,
71
+ workspace_fqn=workspace_fqn,
72
+ wait=wait,
71
73
  )
72
74
  else:
73
75
  return deploy_component(
@@ -16,4 +16,4 @@ from truefoundry.workflow.container_task import ContainerTask
16
16
  from truefoundry.workflow.map_task import map_task
17
17
  from truefoundry.workflow.python_task import PythonFunctionTask
18
18
  from truefoundry.workflow.task import task
19
- from truefoundry.workflow.workflow import workflow
19
+ from truefoundry.workflow.workflow import ExecutionConfig, workflow
@@ -5,8 +5,9 @@ from truefoundry.workflow import PythonTaskConfig, TaskPythonBuild, task, workfl
5
5
  task_config=PythonTaskConfig(
6
6
  image=TaskPythonBuild(
7
7
  python_version="3.9",
8
- pip_packages=["flytekit==1.10.3"],
9
- )
8
+ pip_packages=["truefoundry[workflow]==0.3.0rc7"],
9
+ ),
10
+ service_account="tfy-flyte-dataplane-devtest-s3",
10
11
  )
11
12
  )
12
13
  def say_hello() -> str:
@@ -1,12 +1,13 @@
1
1
  import os
2
2
  from functools import partial
3
3
  from pathlib import Path
4
- from typing import List, Tuple
4
+ from typing import List, Optional, Tuple
5
5
 
6
6
  from truefoundry.deploy import Image, NvidiaGPU, Resources
7
7
  from truefoundry.workflow import (
8
8
  ContainerTask,
9
9
  ContainerTaskConfig,
10
+ ExecutionConfig,
10
11
  FlyteDirectory,
11
12
  PythonTaskConfig,
12
13
  TaskPythonBuild,
@@ -19,15 +20,17 @@ from truefoundry.workflow import (
19
20
  cpu_task_config = PythonTaskConfig(
20
21
  image=TaskPythonBuild(
21
22
  python_version="3.9",
22
- pip_packages=["flytekit==1.10.3"],
23
+ pip_packages=["truefoundry[workflow]==0.3.0rc7"],
23
24
  ),
24
25
  resources=Resources(cpu_request=0.45),
26
+ service_account="tfy-flyte-dataplane-devtest-s3",
25
27
  )
26
28
 
27
29
 
28
30
  # figure out naming
29
31
  @task(task_config=cpu_task_config)
30
32
  def should_train_tokenizer(tokenizer: str) -> bool:
33
+ print("Should train tokenizer")
31
34
  return not bool(tokenizer)
32
35
 
33
36
 
@@ -38,6 +41,7 @@ def should_train_tokenizer(tokenizer: str) -> bool:
38
41
  # cache_version="1.0",
39
42
  )
40
43
  def train_tokenizer() -> str:
44
+ print("Training tokenizer")
41
45
  return "trained_tokenizer"
42
46
 
43
47
 
@@ -45,7 +49,7 @@ def train_tokenizer() -> str:
45
49
  task_config=PythonTaskConfig(
46
50
  image=TaskPythonBuild(
47
51
  python_version="3.9",
48
- pip_packages=["flytekit==1.10.3", "pynvml==11.5.0"],
52
+ pip_packages=["truefoundry[workflow]==0.3.0rc7", "pynvml==11.5.0"],
49
53
  cuda_version="11.5-cudnn8",
50
54
  ),
51
55
  env={
@@ -53,17 +57,17 @@ def train_tokenizer() -> str:
53
57
  "NVIDIA_VISIBLE_DEVICES": "all",
54
58
  },
55
59
  resources=Resources(cpu_request=0.45, devices=[NvidiaGPU(name="T4", count=1)]),
60
+ service_account="tfy-flyte-dataplane-devtest-s3",
56
61
  ),
57
62
  )
58
63
  def train_model(tokenizer: str) -> Tuple[FlyteDirectory, str]:
64
+ print("Training model")
59
65
  import flytekit
60
- from package.test_workflow import random
61
66
  from pynvml import nvmlDeviceGetCount, nvmlInit
62
67
 
63
68
  nvmlInit()
64
69
  assert nvmlDeviceGetCount() > 0
65
70
 
66
- random.random()
67
71
  working_dir = flytekit.current_context().working_directory
68
72
  local_dir = Path(os.path.join(working_dir, "csv_files"))
69
73
  local_dir.mkdir(exist_ok=True)
@@ -76,6 +80,7 @@ def train_model(tokenizer: str) -> Tuple[FlyteDirectory, str]:
76
80
 
77
81
  @task(task_config=cpu_task_config)
78
82
  def get_validation_data() -> List[str]:
83
+ print("Getting validation data")
79
84
  return ["foo", "bar", "baz"]
80
85
 
81
86
 
@@ -89,6 +94,7 @@ def validate_model(model: FlyteDirectory, tokenizer: str, validation_data: str)
89
94
 
90
95
  @task(task_config=cpu_task_config)
91
96
  def all_good(validations: List[bool]) -> bool:
97
+ print("Validations", validations)
92
98
  return all(validations)
93
99
 
94
100
 
@@ -97,18 +103,33 @@ echo = ContainerTask(
97
103
  task_config=ContainerTaskConfig(
98
104
  image=Image(
99
105
  image_uri="bash:4.1",
100
- )
106
+ command=["echo", "hello"],
107
+ ),
108
+ service_account="tfy-flyte-dataplane-devtest-s3",
101
109
  ),
102
110
  )
103
111
 
104
112
 
105
113
  @task(task_config=cpu_task_config)
106
114
  def random(tokenizer: str) -> Tuple[FlyteDirectory, str]:
115
+ print(tokenizer)
107
116
  return FlyteDirectory(path=""), "random"
108
117
 
109
118
 
110
- @workflow
111
- def train(tokenizer: str = "") -> bool:
119
+ @workflow(
120
+ execution_configs=[
121
+ ExecutionConfig(
122
+ schedule="*/10 * * * *",
123
+ )
124
+ ]
125
+ )
126
+ def train(
127
+ tokenizer: str = "",
128
+ test_v2: str = "",
129
+ optional_var: Optional[str] = "",
130
+ default_v: Optional[str] = "hello1",
131
+ default_v2: str = "hello2",
132
+ ) -> bool:
112
133
  stt = should_train_tokenizer(tokenizer=tokenizer)
113
134
  model, t = (
114
135
  conditional("train_tokenizer")
@@ -1,5 +1,5 @@
1
1
  type: workflow
2
- name: my-test-workflow5
2
+ name: my-test-workflow9
3
3
  source:
4
4
  type: local
5
5
  local_build: false
@@ -1,6 +1,8 @@
1
- from typing import Any, Callable, Optional, Union
1
+ from typing import Any, Callable, Dict, List, Optional, Union
2
2
 
3
3
  from flytekit.core.base_task import Task
4
+ from flytekit.core.launch_plan import LaunchPlan
5
+ from flytekit.core.schedule import CronSchedule
4
6
  from flytekit.core.workflow import (
5
7
  FuncOut,
6
8
  PythonFunctionWorkflow,
@@ -8,11 +10,39 @@ from flytekit.core.workflow import (
8
10
  )
9
11
  from flytekit.core.workflow import workflow as flytekit_workflow
10
12
 
13
+ from truefoundry.pydantic_v1 import BaseModel
14
+
15
+ TRUEFOUNDRY_LAUNCH_PLAN_NAME = "default"
16
+
17
+
18
+ class ExecutionConfig(BaseModel):
19
+ # I am not using job's Schedule here because:
20
+ # 1. flyte accepts schedule only as a string
21
+ # 2. flyte doesn't support setting concurrency policy
22
+ schedule: str
23
+
24
+
25
+ class ExecutionConfigStore(BaseModel):
26
+ execution_config_map: Dict[str, ExecutionConfig] = {}
27
+
28
+ def reset(self):
29
+ self.execution_config_map = {}
30
+
31
+ def get(self, key: str) -> Optional[ExecutionConfig]:
32
+ return self.execution_config_map.get(key)
33
+
34
+ def set(self, key: str, value: ExecutionConfig):
35
+ self.execution_config_map[key] = value
36
+
37
+
38
+ execution_config_store = ExecutionConfigStore()
39
+
11
40
 
12
41
  def workflow(
13
42
  _workflow_function: Optional[Callable[..., Any]] = None,
14
43
  failure_policy: Optional[WorkflowFailurePolicy] = None,
15
44
  on_failure: Optional[Task] = None,
45
+ execution_configs: Optional[List[ExecutionConfig]] = None,
16
46
  ) -> Union[
17
47
  Callable[[Callable[..., FuncOut]], PythonFunctionWorkflow],
18
48
  PythonFunctionWorkflow,
@@ -47,8 +77,38 @@ def workflow(
47
77
  :param on_failure: Invoke this workflow or task on failure. The Workflow / task has to match the signature of
48
78
  the current workflow, with an additional parameter called `error` Error
49
79
  """
50
- return flytekit_workflow(
80
+ if _workflow_function is None:
81
+
82
+ def wrapper(func: Callable[..., Any]) -> Any:
83
+ return workflow(
84
+ _workflow_function=func,
85
+ failure_policy=failure_policy,
86
+ on_failure=on_failure,
87
+ execution_configs=execution_configs,
88
+ )
89
+
90
+ return wrapper
91
+
92
+ workflow_object = flytekit_workflow(
51
93
  _workflow_function,
52
94
  failure_policy=failure_policy,
53
95
  on_failure=on_failure,
54
96
  )
97
+ execution_configs = execution_configs or []
98
+ if len(execution_configs) > 1:
99
+ raise ValueError("Only one cron execution config is allowed per workflow")
100
+
101
+ if execution_configs:
102
+ execution_config = execution_configs[0]
103
+ # flyte maintains this in-memory and uses it while serialization
104
+ LaunchPlan.get_or_create(
105
+ workflow=workflow_object,
106
+ name=TRUEFOUNDRY_LAUNCH_PLAN_NAME,
107
+ schedule=CronSchedule(schedule=execution_config.schedule),
108
+ )
109
+ function_module = _workflow_function.__module__
110
+ function_name = _workflow_function.__name__
111
+ function_path = f"{function_module}.{function_name}"
112
+ execution_config_store.set(function_path, execution_config)
113
+
114
+ return workflow_object
File without changes