tinyfan 0.2.4__tar.gz → 0.2.5__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.
Files changed (58) hide show
  1. {tinyfan-0.2.4 → tinyfan-0.2.5}/PKG-INFO +1 -1
  2. {tinyfan-0.2.4 → tinyfan-0.2.5}/pyproject.toml +1 -1
  3. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/argo_typing.py +17 -1
  4. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/codegen.py +15 -11
  5. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/test_codegen.py +18 -1
  6. {tinyfan-0.2.4 → tinyfan-0.2.5}/uv.lock +1 -1
  7. {tinyfan-0.2.4 → tinyfan-0.2.5}/.github/workflows/publish.yml +0 -0
  8. {tinyfan-0.2.4 → tinyfan-0.2.5}/.gitignore +0 -0
  9. {tinyfan-0.2.4 → tinyfan-0.2.5}/.python-version +0 -0
  10. {tinyfan-0.2.4 → tinyfan-0.2.5}/README.md +0 -0
  11. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/README.md +0 -0
  12. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/configmap.yaml +0 -0
  13. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/configs.py +0 -0
  14. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/getting-started.py +0 -0
  15. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/.python-version +0 -0
  16. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/Dockerfile +0 -0
  17. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/README.md +0 -0
  18. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/pyproject.toml +0 -0
  19. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/src/tinyfan_examples_packaged/__init__.py +0 -0
  20. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/packaged/src/tinyfan_examples_packaged/asset.py +0 -0
  21. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/resource.py +0 -0
  22. {tinyfan-0.2.4 → tinyfan-0.2.5}/examples/secret.yaml +0 -0
  23. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/__init__.py +0 -0
  24. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/cli.py +0 -0
  25. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/config.py +0 -0
  26. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/dagviz.py +0 -0
  27. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/flow.py +0 -0
  28. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/flowrundata.py +0 -0
  29. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/py.typed +0 -0
  30. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/resources/__init__.py +0 -0
  31. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/resources/base.py +0 -0
  32. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/stores/__init__.py +0 -0
  33. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/stores/base.py +0 -0
  34. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/stores/bigquery.py +0 -0
  35. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/stores/gcs_pickle.py +0 -0
  36. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/stores/naive.py +0 -0
  37. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/__init__.py +0 -0
  38. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/embed.py +0 -0
  39. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/exjson.py +0 -0
  40. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/merge.py +0 -0
  41. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/typing.py +0 -0
  42. {tinyfan-0.2.4 → tinyfan-0.2.5}/src/tinyfan/utils/yaml.py +0 -0
  43. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/__init__.py +0 -0
  44. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/codegen_samples/directory/__init__.py +0 -0
  45. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/codegen_samples/directory/asset.py +0 -0
  46. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/codegen_samples/directory/asset2.py +0 -0
  47. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/codegen_samples/singlefile.py +0 -0
  48. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/conftest.py +0 -0
  49. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/helpers.py +0 -0
  50. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/openapi2jsonschema.py +0 -0
  51. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/test_config.py +0 -0
  52. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/test_decorators.py +0 -0
  53. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/__init__.py +0 -0
  54. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/embed_samples/directory/__init__.py +0 -0
  55. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/embed_samples/directory/dep.py +0 -0
  56. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/embed_samples/singlefile.py +0 -0
  57. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/test_embed.py +0 -0
  58. {tinyfan-0.2.4 → tinyfan-0.2.5}/tests/utils/test_exjson.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tinyfan
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: Tiny Argo Workflows python devkit
5
5
  Project-URL: Documentation, https://github.com/eunchuldev/tinyfan#readme
6
6
  Project-URL: Issues, https://github.com/eunchuldev/tinyfan/issues
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tinyfan"
3
- version = "0.2.4"
3
+ version = "0.2.5"
4
4
  description = 'Tiny Argo Workflows python devkit'
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -93,6 +93,22 @@ class EnvVar(TypedDict):
93
93
  valueFrom: NotRequired[EnvVarSource]
94
94
 
95
95
 
96
+ class ConfigMapEnvSource(TypedDict, total=False):
97
+ name: str
98
+ optional: bool
99
+
100
+
101
+ class SecretEnvSource(TypedDict, total=False):
102
+ name: str
103
+ optional: bool
104
+
105
+
106
+ class EnvFromSource(TypedDict, total=False):
107
+ configMapRef: ConfigMapEnvSource
108
+ secretRef: SecretEnvSource
109
+ prefix: str
110
+
111
+
96
112
  class Lifecycle(TypedDict, total=False):
97
113
  postStart: LifecycleHandler
98
114
  preStop: LifecycleHandler
@@ -183,7 +199,7 @@ class ScriptTemplate(TypedDict, total=False):
183
199
  args: list[str]
184
200
  command: list[str]
185
201
  env: list[EnvVar]
186
- envFrom: list[EnvVar]
202
+ envFrom: list[EnvFromSource]
187
203
  image: str
188
204
  imagePullPolicy: str
189
205
  lifecycle: Lifecycle
@@ -117,11 +117,11 @@ class AssetNode:
117
117
 
118
118
  def relatives(self, result: set[Self] | None = None) -> set[Self]:
119
119
  if result is None:
120
- result = set[Self]([self])
121
- for o in self.parents + self.children:
122
- if o not in result:
123
- result.add(o)
124
- o.relatives(result)
120
+ result = {self}
121
+ for node in self.parents + self.children:
122
+ if node not in result:
123
+ result.add(node)
124
+ node.relatives(result)
125
125
  return result
126
126
 
127
127
 
@@ -142,18 +142,23 @@ class AssetTree:
142
142
  | set(inspect.get_annotations(FlowRunData).keys())
143
143
  )
144
144
  unknown_names = [n for n in func_param_names if n not in known_names]
145
- if len(unknown_names) > 0:
145
+ if unknown_names:
146
146
  raise Exception(
147
147
  f"unknown asset args: {', '.join('`' + n + '`' for n in unknown_names)} from asset `{node.asset.name}`"
148
148
  )
149
149
 
150
150
  params_ids = set(name for name in func_param_names if name in self.flow.assets)
151
151
  if node.asset.depends is not None:
152
+ assert re.match(VALID_DEPENDS_REGEXP, node.asset.depends)
152
153
  depends_ids = set(re.findall(EXTRACT_DEPENDS_REGEXP, node.asset.depends))
153
154
  node.parents = [self.nodes[n] for n in depends_ids.union(params_ids)]
154
- node.asset.depends = f"({node.asset.depends}) && {' && '.join(params_ids - depends_ids)}".replace(
155
- "_", "-"
156
- )
155
+ new_ids = params_ids - depends_ids
156
+ if new_ids:
157
+ if len(depends_ids) > 1:
158
+ node.asset.depends = f"({node.asset.depends}) && {' && '.join(new_ids)}".replace("_", "-")
159
+ else:
160
+ node.asset.depends = f"{node.asset.depends} && {' && '.join(new_ids)}".replace("_", "-")
161
+ assert re.match(VALID_DEPENDS_REGEXP, node.asset.depends)
157
162
  for p in node.parents:
158
163
  p.children.append(node)
159
164
  else:
@@ -189,10 +194,9 @@ class AssetTree:
189
194
 
190
195
  from .dagviz import dagviz
191
196
 
192
- relatives_by_schedules = self.relatives_by_schedules()
193
197
  g: nx.DiGraph = nx.DiGraph()
194
198
  g.add_node(self.flow.name, bullet="■")
195
- for (tz, schedule), relatives in relatives_by_schedules.items():
199
+ for (tz, schedule), relatives in self.relatives_by_schedules().items():
196
200
  schedule_node_name = schedule + f" ({tz})"
197
201
  g.add_node(schedule_node_name, bullet="○")
198
202
  g.add_edge(self.flow.name, schedule_node_name)
@@ -21,6 +21,14 @@ def sample_flow() -> Generator:
21
21
  def asset2(asset1: str): # type: ignore
22
22
  print("asset1 says: " + asset1)
23
23
 
24
+ @asset(flow=flow, depends="asset1 && asset2")
25
+ def asset3(asset1: str): # type: ignore
26
+ print("asset1 says: " + asset1)
27
+
28
+ @asset(flow=flow, depends="asset2")
29
+ def asset4(asset1: str): # type: ignore
30
+ print("asset1 says: " + asset1)
31
+
24
32
  yield flow
25
33
  FLOW_REGISTER.clear()
26
34
 
@@ -132,9 +140,18 @@ def test_codegen_directory(validate_crds):
132
140
  def test_rundata_data_interval(sample_flow):
133
141
  tree = AssetTree(sample_flow)
134
142
  node = list(tree.nodes.values())[0]
135
- # rundatatmpl = node.rundatatmpl("0 * * * * *")
136
143
  daily = node.rundatatmpl("@daily")
137
144
  assert (
138
145
  daily
139
146
  == """{"ds": "{{=sprig.date('2006-01-02', sprig.dateModify('-86400.0s', sprig.toDate('2006-01-02T15:04:05Z07:00', workflow.scheduledTime)))}}", "ts": "{{=sprig.dateModify('-86400.0s', sprig.toDate('2006-01-02T15:04:05Z07:00', workflow.scheduledTime))}}", "data_interval_start": {"__tinyfan_datetime__": "{{=sprig.dateModify('-86400.0s', sprig.toDate('2006-01-02T15:04:05Z07:00', workflow.scheduledTime))}}"}, "data_interval_end": {"__tinyfan_datetime__": "{{workflow.scheduledTime}}"}, "parents": {}, "asset_name": "asset1", "flow_name": "test", "module_name": "tests.test_codegen"}"""
140
147
  )
148
+
149
+
150
+ def test_depends(sample_flow):
151
+ tree = AssetTree(sample_flow)
152
+ assert [node.asset.depends for node in tree.nodes.values()] == [
153
+ "",
154
+ "asset1",
155
+ "asset1 && asset2",
156
+ "asset2 && asset1",
157
+ ]
@@ -784,7 +784,7 @@ wheels = [
784
784
 
785
785
  [[package]]
786
786
  name = "tinyfan"
787
- version = "0.2.4"
787
+ version = "0.2.5"
788
788
  source = { editable = "." }
789
789
  dependencies = [
790
790
  { name = "croniter" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes