truefoundry 0.2.10__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of truefoundry might be problematic. Click here for more details.

Files changed (112) hide show
  1. truefoundry/__init__.py +1 -0
  2. truefoundry/autodeploy/cli.py +31 -18
  3. truefoundry/deploy/__init__.py +112 -1
  4. truefoundry/deploy/auto_gen/models.py +1714 -0
  5. truefoundry/deploy/builder/__init__.py +134 -0
  6. truefoundry/deploy/builder/builders/__init__.py +22 -0
  7. truefoundry/deploy/builder/builders/dockerfile.py +57 -0
  8. truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +46 -0
  9. truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +66 -0
  10. truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +44 -0
  11. truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +158 -0
  12. truefoundry/deploy/builder/docker_service.py +168 -0
  13. truefoundry/deploy/cli/cli.py +21 -26
  14. truefoundry/deploy/cli/commands/__init__.py +18 -0
  15. truefoundry/deploy/cli/commands/apply_command.py +52 -0
  16. truefoundry/deploy/cli/commands/build_command.py +45 -0
  17. truefoundry/deploy/cli/commands/build_logs_command.py +89 -0
  18. truefoundry/deploy/cli/commands/create_command.py +75 -0
  19. truefoundry/deploy/cli/commands/delete_command.py +77 -0
  20. truefoundry/deploy/cli/commands/deploy_command.py +102 -0
  21. truefoundry/deploy/cli/commands/get_command.py +216 -0
  22. truefoundry/deploy/cli/commands/list_command.py +171 -0
  23. truefoundry/deploy/cli/commands/login_command.py +33 -0
  24. truefoundry/deploy/cli/commands/logout_command.py +20 -0
  25. truefoundry/deploy/cli/commands/logs_command.py +134 -0
  26. truefoundry/deploy/cli/commands/patch_application_command.py +81 -0
  27. truefoundry/deploy/cli/commands/patch_command.py +70 -0
  28. truefoundry/deploy/cli/commands/redeploy_command.py +41 -0
  29. truefoundry/deploy/cli/commands/terminate_comand.py +44 -0
  30. truefoundry/deploy/cli/commands/trigger_command.py +145 -0
  31. truefoundry/deploy/cli/config.py +10 -0
  32. truefoundry/deploy/cli/console.py +5 -0
  33. truefoundry/deploy/cli/const.py +12 -0
  34. truefoundry/deploy/cli/display_util.py +118 -0
  35. truefoundry/deploy/cli/util.py +129 -0
  36. truefoundry/deploy/core/__init__.py +7 -0
  37. truefoundry/deploy/core/login.py +9 -0
  38. truefoundry/deploy/core/logout.py +5 -0
  39. truefoundry/deploy/function_service/__init__.py +3 -0
  40. truefoundry/deploy/function_service/__main__.py +27 -0
  41. truefoundry/deploy/function_service/app.py +92 -0
  42. truefoundry/deploy/function_service/build.py +45 -0
  43. truefoundry/deploy/function_service/remote/__init__.py +6 -0
  44. truefoundry/deploy/function_service/remote/context.py +3 -0
  45. truefoundry/deploy/function_service/remote/method.py +67 -0
  46. truefoundry/deploy/function_service/remote/remote.py +144 -0
  47. truefoundry/deploy/function_service/route.py +137 -0
  48. truefoundry/deploy/function_service/service.py +113 -0
  49. truefoundry/deploy/function_service/utils.py +53 -0
  50. truefoundry/deploy/io/__init__.py +0 -0
  51. truefoundry/deploy/io/output_callback.py +23 -0
  52. truefoundry/deploy/io/rich_output_callback.py +27 -0
  53. truefoundry/deploy/json_util.py +7 -0
  54. truefoundry/deploy/lib/__init__.py +0 -0
  55. truefoundry/deploy/lib/auth/auth_service_client.py +181 -0
  56. truefoundry/deploy/lib/auth/credential_file_manager.py +115 -0
  57. truefoundry/deploy/lib/auth/credential_provider.py +131 -0
  58. truefoundry/deploy/lib/auth/servicefoundry_session.py +59 -0
  59. truefoundry/deploy/lib/clients/__init__.py +0 -0
  60. truefoundry/deploy/lib/clients/servicefoundry_client.py +746 -0
  61. truefoundry/deploy/lib/clients/shell_client.py +13 -0
  62. truefoundry/deploy/lib/clients/utils.py +41 -0
  63. truefoundry/deploy/lib/const.py +43 -0
  64. truefoundry/deploy/lib/dao/__init__.py +0 -0
  65. truefoundry/deploy/lib/dao/application.py +263 -0
  66. truefoundry/deploy/lib/dao/apply.py +80 -0
  67. truefoundry/deploy/lib/dao/version.py +33 -0
  68. truefoundry/deploy/lib/dao/workspace.py +71 -0
  69. truefoundry/deploy/lib/exceptions.py +26 -0
  70. truefoundry/deploy/lib/logs_utils.py +43 -0
  71. truefoundry/deploy/lib/messages.py +12 -0
  72. truefoundry/deploy/lib/model/__init__.py +0 -0
  73. truefoundry/deploy/lib/model/entity.py +400 -0
  74. truefoundry/deploy/lib/session.py +158 -0
  75. truefoundry/deploy/lib/util.py +90 -0
  76. truefoundry/deploy/lib/win32.py +129 -0
  77. truefoundry/deploy/v2/__init__.py +0 -0
  78. truefoundry/deploy/v2/lib/__init__.py +3 -0
  79. truefoundry/deploy/v2/lib/deploy.py +283 -0
  80. truefoundry/deploy/v2/lib/deploy_workflow.py +295 -0
  81. truefoundry/deploy/v2/lib/deployable_patched_models.py +86 -0
  82. truefoundry/deploy/v2/lib/models.py +53 -0
  83. truefoundry/deploy/v2/lib/patched_models.py +479 -0
  84. truefoundry/deploy/v2/lib/source.py +267 -0
  85. truefoundry/langchain/__init__.py +12 -1
  86. truefoundry/langchain/deprecated.py +302 -0
  87. truefoundry/langchain/truefoundry_chat.py +130 -0
  88. truefoundry/langchain/truefoundry_embeddings.py +171 -0
  89. truefoundry/langchain/truefoundry_llm.py +106 -0
  90. truefoundry/langchain/utils.py +85 -0
  91. truefoundry/logger.py +17 -0
  92. truefoundry/pydantic_v1.py +5 -0
  93. truefoundry/python_deploy_codegen.py +132 -0
  94. truefoundry/version.py +6 -0
  95. truefoundry/workflow/__init__.py +19 -0
  96. truefoundry/workflow/container_task.py +12 -0
  97. truefoundry/workflow/example/deploy.sh +1 -0
  98. truefoundry/workflow/example/hello_world_package/workflow.py +20 -0
  99. truefoundry/workflow/example/package/test_workflow.py +152 -0
  100. truefoundry/workflow/example/truefoundry.yaml +9 -0
  101. truefoundry/workflow/example/workflow.yaml +116 -0
  102. truefoundry/workflow/map_task.py +45 -0
  103. truefoundry/workflow/python_task.py +32 -0
  104. truefoundry/workflow/task.py +50 -0
  105. truefoundry/workflow/workflow.py +114 -0
  106. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0.dist-info}/METADATA +27 -7
  107. truefoundry-0.3.0.dist-info/RECORD +136 -0
  108. truefoundry/deploy/cli/deploy.py +0 -165
  109. truefoundry/deploy/cli/version.py +0 -6
  110. truefoundry-0.2.10.dist-info/RECORD +0 -38
  111. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0.dist-info}/WHEEL +0 -0
  112. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1 @@
1
+ tfy deploy --workspace_fqn tfy-ctl-euwe1-devtest:nikhil-ws
@@ -0,0 +1,20 @@
1
+ from truefoundry.workflow import PythonTaskConfig, TaskPythonBuild, task, workflow
2
+
3
+
4
+ @task(
5
+ task_config=PythonTaskConfig(
6
+ image=TaskPythonBuild(
7
+ python_version="3.9",
8
+ pip_packages=["truefoundry[workflow]==0.3.0rc7"],
9
+ ),
10
+ service_account="tfy-flyte-dataplane-devtest-s3",
11
+ )
12
+ )
13
+ def say_hello() -> str:
14
+ return "Hello, World!"
15
+
16
+
17
+ @workflow
18
+ def hello_world_wf() -> str:
19
+ res = say_hello()
20
+ return res
@@ -0,0 +1,152 @@
1
+ import os
2
+ from functools import partial
3
+ from pathlib import Path
4
+ from typing import List, Optional, Tuple
5
+
6
+ from truefoundry.deploy import Image, NvidiaGPU, Resources
7
+ from truefoundry.workflow import (
8
+ ContainerTask,
9
+ ContainerTaskConfig,
10
+ ExecutionConfig,
11
+ FlyteDirectory,
12
+ PythonTaskConfig,
13
+ TaskPythonBuild,
14
+ conditional,
15
+ map_task,
16
+ task,
17
+ workflow,
18
+ )
19
+
20
+ cpu_task_config = PythonTaskConfig(
21
+ image=TaskPythonBuild(
22
+ python_version="3.9",
23
+ pip_packages=["truefoundry[workflow]==0.3.0rc7"],
24
+ ),
25
+ resources=Resources(cpu_request=0.45),
26
+ service_account="tfy-flyte-dataplane-devtest-s3",
27
+ )
28
+
29
+
30
+ # figure out naming
31
+ @task(task_config=cpu_task_config)
32
+ def should_train_tokenizer(tokenizer: str) -> bool:
33
+ print("Should train tokenizer")
34
+ return not bool(tokenizer)
35
+
36
+
37
+ @task(
38
+ task_config=cpu_task_config,
39
+ # currently we will not support the caching, but keeping here for now
40
+ # cache=True,
41
+ # cache_version="1.0",
42
+ )
43
+ def train_tokenizer() -> str:
44
+ print("Training tokenizer")
45
+ return "trained_tokenizer"
46
+
47
+
48
+ @task(
49
+ task_config=PythonTaskConfig(
50
+ image=TaskPythonBuild(
51
+ python_version="3.9",
52
+ pip_packages=["truefoundry[workflow]==0.3.0rc7", "pynvml==11.5.0"],
53
+ cuda_version="11.5-cudnn8",
54
+ ),
55
+ env={
56
+ "NVIDIA_DRIVER_CAPABILITIES": "compute,utility",
57
+ "NVIDIA_VISIBLE_DEVICES": "all",
58
+ },
59
+ resources=Resources(cpu_request=0.45, devices=[NvidiaGPU(name="T4", count=1)]),
60
+ service_account="tfy-flyte-dataplane-devtest-s3",
61
+ ),
62
+ )
63
+ def train_model(tokenizer: str) -> Tuple[FlyteDirectory, str]:
64
+ print("Training model")
65
+ import flytekit
66
+ from pynvml import nvmlDeviceGetCount, nvmlInit
67
+
68
+ nvmlInit()
69
+ assert nvmlDeviceGetCount() > 0
70
+
71
+ working_dir = flytekit.current_context().working_directory
72
+ local_dir = Path(os.path.join(working_dir, "csv_files"))
73
+ local_dir.mkdir(exist_ok=True)
74
+
75
+ with open(os.path.join(local_dir, "model"), "w", encoding="utf-8") as f:
76
+ f.write(tokenizer)
77
+
78
+ return FlyteDirectory(path=str(local_dir)), "hello"
79
+
80
+
81
+ @task(task_config=cpu_task_config)
82
+ def get_validation_data() -> List[str]:
83
+ print("Getting validation data")
84
+ return ["foo", "bar", "baz"]
85
+
86
+
87
+ @task(task_config=cpu_task_config)
88
+ def validate_model(model: FlyteDirectory, tokenizer: str, validation_data: str) -> bool:
89
+ print(validation_data)
90
+ model_path = os.path.join(model, "model")
91
+ with open(model_path, "r", encoding="utf-8") as f:
92
+ return f.read() == tokenizer
93
+
94
+
95
+ @task(task_config=cpu_task_config)
96
+ def all_good(validations: List[bool]) -> bool:
97
+ print("Validations", validations)
98
+ return all(validations)
99
+
100
+
101
+ echo = ContainerTask(
102
+ name="echo",
103
+ task_config=ContainerTaskConfig(
104
+ image=Image(
105
+ image_uri="bash:4.1",
106
+ command=["echo", "hello"],
107
+ ),
108
+ service_account="tfy-flyte-dataplane-devtest-s3",
109
+ ),
110
+ )
111
+
112
+
113
+ @task(task_config=cpu_task_config)
114
+ def random(tokenizer: str) -> Tuple[FlyteDirectory, str]:
115
+ print(tokenizer)
116
+ return FlyteDirectory(path=""), "random"
117
+
118
+
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:
133
+ stt = should_train_tokenizer(tokenizer=tokenizer)
134
+ model, t = (
135
+ conditional("train_tokenizer")
136
+ .if_(stt.is_true())
137
+ .then(train_model(tokenizer=tokenizer))
138
+ .else_()
139
+ .then(random(tokenizer=tokenizer))
140
+ )
141
+ validation_task = partial(validate_model, model=model, tokenizer=t)
142
+ validation_data = get_validation_data()
143
+ validations = map_task(
144
+ validation_task,
145
+ concurrency=2,
146
+ )(validation_data=validation_data)
147
+ echo()
148
+ return all_good(validations=validations)
149
+
150
+
151
+ if __name__ == "__main__":
152
+ train()
@@ -0,0 +1,9 @@
1
+ type: workflow
2
+ name: my-test-workflow9
3
+ source:
4
+ type: local
5
+ local_build: false
6
+ project_root_path: "./"
7
+ workflow_file_path: package/test_workflow.py
8
+ # workflow_file_path: hello_world_package/workflow.py
9
+ flyte_entities: []
@@ -0,0 +1,116 @@
1
+ type: workflow
2
+ name: my-test-workflow5
3
+ source:
4
+ type: remote
5
+ remote_uri: s3://tfy-mlfoundry-tfy-ctl-euwe1-devtest20221012173221749100000002/tfy-ctl-euwe1-devtest:nikhil-ws/my-test-workflow5/clyhb79w4013l01oyfq1iawd5/package.tar.gz
6
+ workflow_file_path: hello_world_package/workflow.py
7
+ docker_registry: docker.io/nikp-test
8
+ flyte_entities:
9
+ - template:
10
+ id:
11
+ resourceType: TASK
12
+ name: hello_world_package.workflow.say_hello
13
+ type: python-task
14
+ metadata:
15
+ runtime:
16
+ type: FLYTE_SDK
17
+ version: 1.12.2
18
+ flavor: python
19
+ retries: {}
20
+ interface:
21
+ inputs: {}
22
+ outputs:
23
+ variables:
24
+ o0:
25
+ type:
26
+ simple: STRING
27
+ description: o0
28
+ custom:
29
+ truefoundry:
30
+ type: python-task-config
31
+ image:
32
+ type: task-python-build
33
+ python_version: '3.9'
34
+ pip_packages:
35
+ - flytekit==1.10.3
36
+ resources:
37
+ cpu_request: 0.2
38
+ cpu_limit: 0.5
39
+ memory_request: 200
40
+ memory_limit: 500
41
+ ephemeral_storage_request: 1000
42
+ ephemeral_storage_limit: 2000
43
+ container:
44
+ image: ':'
45
+ args:
46
+ - pyflyte-execute
47
+ - --inputs
48
+ - '{{.input}}'
49
+ - --output-prefix
50
+ - '{{.outputPrefix}}'
51
+ - --raw-output-data-prefix
52
+ - '{{.rawOutputDataPrefix}}'
53
+ - --checkpoint-path
54
+ - '{{.checkpointOutputPrefix}}'
55
+ - --prev-checkpoint
56
+ - '{{.prevCheckpointPrefix}}'
57
+ - --resolver
58
+ - flytekit.core.python_auto_container.default_task_resolver
59
+ - --
60
+ - task-module
61
+ - hello_world_package.workflow
62
+ - task-name
63
+ - say_hello
64
+ resources: {}
65
+ description:
66
+ longDescription:
67
+ format: DESCRIPTION_FORMAT_RST
68
+ - template:
69
+ id:
70
+ resourceType: WORKFLOW
71
+ name: hello_world_package.workflow.hello_world_wf
72
+ metadata: {}
73
+ interface:
74
+ inputs: {}
75
+ outputs:
76
+ variables:
77
+ o0:
78
+ type:
79
+ simple: STRING
80
+ description: o0
81
+ nodes:
82
+ - id: n0
83
+ metadata:
84
+ name: say_hello
85
+ retries: {}
86
+ taskNode:
87
+ referenceId:
88
+ resourceType: TASK
89
+ name: hello_world_package.workflow.say_hello
90
+ overrides: {}
91
+ outputs:
92
+ - var: o0
93
+ binding:
94
+ promise:
95
+ nodeId: n0
96
+ var: o0
97
+ metadataDefaults: {}
98
+ description:
99
+ longDescription:
100
+ format: DESCRIPTION_FORMAT_RST
101
+ - id:
102
+ resourceType: LAUNCH_PLAN
103
+ name: hello_world_package.workflow.hello_world_wf
104
+ spec:
105
+ workflowId:
106
+ resourceType: WORKFLOW
107
+ name: hello_world_package.workflow.hello_world_wf
108
+ entityMetadata: {}
109
+ defaultInputs: {}
110
+ fixedInputs: {}
111
+ labels: {}
112
+ annotations: {}
113
+ rawOutputDataConfig: {}
114
+ closure:
115
+ expectedInputs: {}
116
+ expectedOutputs: {}
@@ -0,0 +1,45 @@
1
+ from typing import Optional
2
+
3
+ from flytekit import PythonFunctionTask
4
+ from flytekit.core.array_node_map_task import ArrayNodeMapTask
5
+
6
+
7
+ class TrueFoundryArrayNodeMapTask(ArrayNodeMapTask):
8
+ def __init__(self, *args, **kwargs):
9
+ super().__init__(*args, **kwargs)
10
+
11
+ def get_custom(self, settings) -> dict:
12
+ arraynode_custom_params = super().get_custom(settings)
13
+ return {
14
+ "truefoundry": self._partial.func.task_config.dict(),
15
+ **arraynode_custom_params,
16
+ }
17
+
18
+
19
+ def map_task(
20
+ task_function: PythonFunctionTask,
21
+ concurrency: Optional[int] = None,
22
+ # TODO why no min_successes?
23
+ min_success_ratio: float = 1.0,
24
+ **kwargs,
25
+ ):
26
+ """Map task that uses the ``ArrayNode`` construct..
27
+
28
+ .. important::
29
+
30
+ This is an experimental drop-in replacement for :py:func:`~flytekit.map_task`.
31
+
32
+ :param task_function: This argument is implicitly passed and represents the repeatable function
33
+ :param concurrency: If specified, this limits the number of mapped tasks than can run in parallel to the given batch
34
+ size. If the size of the input exceeds the concurrency value, then multiple batches will be run serially until
35
+ all inputs are processed. If set to 0, this means unbounded concurrency. If left unspecified, this means the
36
+ array node will inherit parallelism from the workflow
37
+ :param min_success_ratio: If specified, this determines the minimum fraction of total jobs which can complete
38
+ successfully before terminating this task and marking it successful.
39
+ """
40
+ return TrueFoundryArrayNodeMapTask(
41
+ task_function,
42
+ concurrency=concurrency,
43
+ min_success_ratio=min_success_ratio,
44
+ **kwargs,
45
+ )
@@ -0,0 +1,32 @@
1
+ from typing import Callable, Tuple, Union
2
+
3
+ from flytekit import FlyteContext, PythonFunctionTask
4
+ from flytekit.extend import Promise, TaskPlugins
5
+
6
+ from truefoundry.logger import logger
7
+ from truefoundry.workflow import PythonTaskConfig
8
+
9
+
10
+ class TrueFoundryFunctionTask(PythonFunctionTask[PythonTaskConfig]):
11
+ # Note(nikp1172) We are not creating our task type for now, we just re-use their task type for now
12
+ def __init__(
13
+ self,
14
+ task_config: PythonTaskConfig,
15
+ task_function: Callable,
16
+ **kwargs,
17
+ ):
18
+ super().__init__(task_config=task_config, task_function=task_function, **kwargs)
19
+
20
+ def local_execute(
21
+ self, ctx: FlyteContext, **kwargs
22
+ ) -> Union[Tuple[Promise], Promise, None]:
23
+ logger.warning(
24
+ "Running pod task locally. Local environment may not match pod environment which may cause issues."
25
+ )
26
+ return super().local_execute(ctx=ctx, **kwargs)
27
+
28
+ def get_custom(self, settings) -> dict:
29
+ return {"truefoundry": self._task_config.dict()}
30
+
31
+
32
+ TaskPlugins.register_pythontask_plugin(PythonTaskConfig, TrueFoundryFunctionTask)
@@ -0,0 +1,50 @@
1
+ from typing import Any, Callable, Optional, Union
2
+
3
+ from flytekit import PythonFunctionTask
4
+ from flytekit.core.task import FuncOut, T
5
+ from flytekit.core.task import task as flytekit_task
6
+
7
+ from truefoundry.workflow import PythonTaskConfig
8
+
9
+
10
+ def task(
11
+ _task_function: Optional[Callable[..., Any]] = None,
12
+ task_config: Optional[PythonTaskConfig] = None,
13
+ retries: Optional[int] = 0,
14
+ ) -> Union[
15
+ Callable[[Callable[..., FuncOut]], PythonFunctionTask[T]],
16
+ PythonFunctionTask[T],
17
+ Callable[..., FuncOut],
18
+ ]:
19
+ """
20
+ This is the decorator used to run flyte tasks in Truefoundry.
21
+
22
+ Tasks are the building blocks of workflow. They represent users code. Tasks have the following properties
23
+
24
+ * Versioned (usually tied to the git revision SHA1)
25
+ * Strong interfaces (specified inputs and outputs)
26
+ * Declarative
27
+ * Independently executable
28
+ * Unit testable
29
+
30
+ For a simple python task,
31
+
32
+ .. code-block:: python
33
+ from truefoundry.workflow import task
34
+ @task
35
+ def my_task(x: int, y: typing.Dict[str, str]) -> str:
36
+ ...
37
+
38
+ For specific task types
39
+
40
+ .. code-block:: python
41
+ from truefoundry.workflow import task, PythonTaskConfig
42
+ @task(task_config=PythonTaskConfig(), retries=2)
43
+ def my_task(x: int, y: typing.Dict[str, str]) -> str:
44
+ ...
45
+
46
+ :param _task_function: The function to be wrapped as a task. This is optional and can be used as a decorator.
47
+ :param task_config: The configuration for the task of class PythonTaskConfig. This is optional and defaults to an empty configuration.
48
+ :param retries: The number of retries for the task. This is optional and defaults to 0.
49
+ """
50
+ return flytekit_task(_task_function, task_config=task_config, retries=retries)
@@ -0,0 +1,114 @@
1
+ from typing import Any, Callable, Dict, List, Optional, Union
2
+
3
+ from flytekit.core.base_task import Task
4
+ from flytekit.core.launch_plan import LaunchPlan
5
+ from flytekit.core.schedule import CronSchedule
6
+ from flytekit.core.workflow import (
7
+ FuncOut,
8
+ PythonFunctionWorkflow,
9
+ WorkflowFailurePolicy,
10
+ )
11
+ from flytekit.core.workflow import workflow as flytekit_workflow
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
+
40
+
41
+ def workflow(
42
+ _workflow_function: Optional[Callable[..., Any]] = None,
43
+ failure_policy: Optional[WorkflowFailurePolicy] = None,
44
+ on_failure: Optional[Task] = None,
45
+ execution_configs: Optional[List[ExecutionConfig]] = None,
46
+ ) -> Union[
47
+ Callable[[Callable[..., FuncOut]], PythonFunctionWorkflow],
48
+ PythonFunctionWorkflow,
49
+ Callable[..., FuncOut],
50
+ ]:
51
+ """
52
+ This decorator declares a function to be a Flyte workflow. Workflows are declarative entities that construct a DAG
53
+ of tasks using the data flow between tasks.
54
+
55
+ Unlike a task, the function body of a workflow is evaluated at serialization-time (aka compile-time). This is
56
+ because while we can determine the entire structure of a task by looking at the function's signature, workflows need
57
+ to run through the function itself because the body of the function is what expresses the workflow structure. It's
58
+ also important to note that, local execution notwithstanding, it is not evaluated again when the workflow runs on
59
+ Flyte.
60
+ That is, workflows should not call non-Flyte entities since they are only run once (again, this is with respect to
61
+ the platform, local runs notwithstanding).
62
+
63
+ Example:
64
+
65
+ .. literalinclude:: ../../../tests/flytekit/unit/core/test_workflows.py
66
+ :pyobject: my_wf_example
67
+
68
+ Again, users should keep in mind that even though the body of the function looks like regular Python, it is
69
+ actually not. When flytekit scans the workflow function, the objects being passed around between the tasks are not
70
+ your typical Python values. So even though you may have a task ``t1() -> int``, when ``a = t1()`` is called, ``a``
71
+ will not be an integer so if you try to ``range(a)`` you'll get an error.
72
+
73
+ Please see the :ref:`user guide <cookbook:workflow>` for more usage examples.
74
+
75
+ :param _workflow_function: This argument is implicitly passed and represents the decorated function.
76
+ :param failure_policy: Use the options in flytekit.WorkflowFailurePolicy
77
+ :param on_failure: Invoke this workflow or task on failure. The Workflow / task has to match the signature of
78
+ the current workflow, with an additional parameter called `error` Error
79
+ """
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(
93
+ _workflow_function,
94
+ failure_policy=failure_policy,
95
+ on_failure=on_failure,
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
@@ -1,27 +1,47 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truefoundry
3
- Version: 0.2.10
3
+ Version: 0.3.0
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com
7
- Requires-Python: >=3.8,<3.13
7
+ Requires-Python: >=3.8.1,<3.13
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.8
10
9
  Classifier: Programming Language :: Python :: 3.9
11
10
  Classifier: Programming Language :: Python :: 3.10
12
11
  Classifier: Programming Language :: Python :: 3.11
13
12
  Classifier: Programming Language :: Python :: 3.12
14
13
  Provides-Extra: ml
15
- Requires-Dist: docker (>=7.0.0,<8.0.0)
14
+ Provides-Extra: workflow
15
+ Requires-Dist: GitPython (>=3.1.43,<3.2.0)
16
+ Requires-Dist: Mako (>=1.1.6,<2.0.0)
17
+ Requires-Dist: PyJWT (>=2.0.0,<3.0.0)
18
+ Requires-Dist: PyYAML (>=6.0.0,<7.0.0)
19
+ Requires-Dist: click (>=7.0.0,<9.0.0)
20
+ Requires-Dist: docker (>=6.1.2,<8.0.0)
21
+ Requires-Dist: fastapi (>=0.56.0,<0.200.0)
22
+ Requires-Dist: filelock (>=3.8.0,<4.0.0)
23
+ Requires-Dist: flytekit (==1.12.2) ; extra == "workflow"
16
24
  Requires-Dist: gitignorefile (>=1.1.2,<1.2.0)
17
- Requires-Dist: gitpython (>=3.1.43,<3.2.0)
18
- Requires-Dist: mlfoundry (==0.11.2) ; extra == "ml"
25
+ Requires-Dist: importlib-metadata (>=6.0.1,<8.0.0)
26
+ Requires-Dist: importlib-resources (>=5.2.0,<6.0.0)
27
+ Requires-Dist: mlfoundry (==0.11.5) ; extra == "ml"
19
28
  Requires-Dist: openai (>=1.16.2,<2.0.0)
29
+ Requires-Dist: packaging (>=20.0,<25.0)
20
30
  Requires-Dist: pydantic (>=1.10.0,<3)
31
+ Requires-Dist: pygments (>=2.12.0,<3.0.0)
32
+ Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
21
33
  Requires-Dist: python-dotenv (>=1.0.1,<1.1.0)
34
+ Requires-Dist: python-socketio[client] (>=5.5.2,<6.0.0)
35
+ Requires-Dist: questionary (>=1.10.0,<2.0.0)
22
36
  Requires-Dist: requests (>=2.31.0,<3.0.0)
37
+ Requires-Dist: requirements-parser (>=0.10.2,<0.11.0)
23
38
  Requires-Dist: rich (>=13.7.1,<14.0.0)
24
- Requires-Dist: servicefoundry (==0.10.16)
39
+ Requires-Dist: rich-click (>=1.2.1,<2.0.0)
40
+ Requires-Dist: tqdm (>=4.0.0,<5.0.0)
41
+ Requires-Dist: typing-extensions (>=3.10.0)
42
+ Requires-Dist: urllib3 (>=1.26.18,<3)
43
+ Requires-Dist: uvicorn (>=0.13.0,<0.40.0)
44
+ Requires-Dist: yq (>=3.1.0,<4.0.0)
25
45
  Description-Content-Type: text/markdown
26
46
 
27
47
  # TrueFoundry