tinyfan 0.3.0__tar.gz → 0.5.0__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.
- {tinyfan-0.3.0 → tinyfan-0.5.0}/.gitignore +4 -0
- tinyfan-0.5.0/PKG-INFO +194 -0
- tinyfan-0.5.0/README.md +142 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/configs.py +1 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/getting-started.py +2 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/src/tinyfan_examples_packaged/asset.py +2 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/pyproject.toml +2 -2
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/__init__.py +10 -10
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/argo_typing.py +1 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/cli.py +2 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/codegen.py +213 -114
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/config.py +15 -11
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/dagviz.py +7 -6
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/flow.py +12 -10
- tinyfan-0.5.0/src/tinyfan/flowrundata.py +84 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/resources/base.py +2 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/stores/base.py +5 -5
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/stores/naive.py +3 -2
- tinyfan-0.5.0/src/tinyfan/utils/embed.py +171 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/utils/exjson.py +3 -4
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/utils/merge.py +5 -4
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/codegen_samples/directory/asset2.py +1 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/conftest.py +5 -9
- tinyfan-0.5.0/tests/helpers.py +21 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/openapi2jsonschema.py +12 -21
- tinyfan-0.5.0/tests/test_codegen.py +565 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/test_config.py +35 -6
- tinyfan-0.5.0/tests/test_flowrundata.py +122 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/test_gcs_pickle_store.py +4 -3
- tinyfan-0.5.0/tests/utils/test_embed.py +242 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/utils/test_exjson.py +2 -1
- {tinyfan-0.3.0 → tinyfan-0.5.0}/uv.lock +7 -6
- tinyfan-0.3.0/PKG-INFO +0 -112
- tinyfan-0.3.0/README.md +0 -61
- tinyfan-0.3.0/src/tinyfan/flowrundata.py +0 -25
- tinyfan-0.3.0/src/tinyfan/utils/embed.py +0 -129
- tinyfan-0.3.0/tests/helpers.py +0 -21
- tinyfan-0.3.0/tests/test_codegen.py +0 -190
- tinyfan-0.3.0/tests/utils/test_embed.py +0 -55
- {tinyfan-0.3.0 → tinyfan-0.5.0}/.github/workflows/publish.yml +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/.python-version +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/README.md +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/configmap.yaml +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/.python-version +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/Dockerfile +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/README.md +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/pyproject.toml +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/packaged/src/tinyfan_examples_packaged/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/resource.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/examples/secret.yaml +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/py.typed +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/resources/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/stores/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/stores/bigquery.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/stores/gcs_pickle.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/utils/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/utils/typing.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/src/tinyfan/utils/yaml.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/codegen_samples/directory/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/codegen_samples/directory/asset.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/codegen_samples/singlefile.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/test_decorators.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/utils/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/utils/embed_samples/directory/__init__.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/utils/embed_samples/directory/dep.py +0 -0
- {tinyfan-0.3.0 → tinyfan-0.5.0}/tests/utils/embed_samples/singlefile.py +0 -0
tinyfan-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tinyfan
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Tiny Argo Workflows python devkit
|
|
5
|
+
Project-URL: Documentation, https://github.com/eunchuldev/tinyfan#readme
|
|
6
|
+
Project-URL: Issues, https://github.com/eunchuldev/tinyfan/issues
|
|
7
|
+
Project-URL: Source, https://github.com/eunchuldev/tinyfan
|
|
8
|
+
Author-email: eunchuldev <eunchulsong@gmail.com>
|
|
9
|
+
Keywords: argo-workflow,pipeline,tinyfan,workflow
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Requires-Dist: croniter>=6.2.4
|
|
16
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
17
|
+
Requires-Dist: typer-slim>=0.24.0
|
|
18
|
+
Requires-Dist: tzdata
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Requires-Dist: google-cloud-bigquery[pandas]; extra == 'all'
|
|
21
|
+
Requires-Dist: google-cloud-storage; extra == 'all'
|
|
22
|
+
Requires-Dist: networkx; extra == 'all'
|
|
23
|
+
Requires-Dist: pandas; extra == 'all'
|
|
24
|
+
Requires-Dist: pyarrow; extra == 'all'
|
|
25
|
+
Provides-Extra: bigquery
|
|
26
|
+
Requires-Dist: google-cloud-bigquery[pandas]; extra == 'bigquery'
|
|
27
|
+
Requires-Dist: pandas; extra == 'bigquery'
|
|
28
|
+
Requires-Dist: pyarrow; extra == 'bigquery'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: google-cloud-bigquery[pandas]; extra == 'dev'
|
|
31
|
+
Requires-Dist: google-cloud-storage; extra == 'dev'
|
|
32
|
+
Requires-Dist: jsonpatch>=1; extra == 'dev'
|
|
33
|
+
Requires-Dist: jsonschema[format]; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.14; extra == 'dev'
|
|
35
|
+
Requires-Dist: networkx; extra == 'dev'
|
|
36
|
+
Requires-Dist: pandas; extra == 'dev'
|
|
37
|
+
Requires-Dist: pyarrow; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=8.3.3; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
40
|
+
Requires-Dist: types-croniter; extra == 'dev'
|
|
41
|
+
Requires-Dist: types-jsonschema; extra == 'dev'
|
|
42
|
+
Requires-Dist: types-networkx; extra == 'dev'
|
|
43
|
+
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
44
|
+
Provides-Extra: gcs
|
|
45
|
+
Requires-Dist: google-cloud-storage; extra == 'gcs'
|
|
46
|
+
Provides-Extra: pandas
|
|
47
|
+
Requires-Dist: pandas; extra == 'pandas'
|
|
48
|
+
Requires-Dist: pyarrow; extra == 'pandas'
|
|
49
|
+
Provides-Extra: viz
|
|
50
|
+
Requires-Dist: networkx; extra == 'viz'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# Tinyfan
|
|
54
|
+
|
|
55
|
+
Tinyfan: Minimalist Data Pipeline Kit - Generate Argo Workflows with Python
|
|
56
|
+
|
|
57
|
+
# Features
|
|
58
|
+
|
|
59
|
+
* Generate Argo Workflows manifests from Python data pipeline definitions.
|
|
60
|
+
* Ease of Use and highly extendable
|
|
61
|
+
* Intuitive data model abstraction: let Argo handle orchestration—we focus on the data.
|
|
62
|
+
* Argo Workflows is notably lightweight and powerful – and so are we!
|
|
63
|
+
* Enhanced DevOps Experience: easly testable, Cloud Native and GitOps-ready.
|
|
64
|
+
|
|
65
|
+
# Our Goal
|
|
66
|
+
|
|
67
|
+
* **Minimize mental overhead** when building data pipelines.
|
|
68
|
+
|
|
69
|
+
# Not Our Goal
|
|
70
|
+
|
|
71
|
+
* **Full-featured orchestration framework:** We don't aim to be a battery-powered, comprehensive data pipeline orchestration solution.
|
|
72
|
+
No databases, web servers, or controllers—just a data pipeline compiler. Let's Algo Workflows handle all the complexity.
|
|
73
|
+
|
|
74
|
+
# Installation
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
# Requires Python 3.10+
|
|
78
|
+
pipx install tinyfan
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
# Tiny Example
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
# main.py
|
|
85
|
+
|
|
86
|
+
# Asset definitions
|
|
87
|
+
|
|
88
|
+
from tinyfan import asset
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@asset(schedule="*/3 * * * *")
|
|
92
|
+
def world() -> str:
|
|
93
|
+
return "world"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@asset()
|
|
97
|
+
def greeting(world: str):
|
|
98
|
+
print("hello " + world)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```shell
|
|
102
|
+
# Apply the changes to argo workflow
|
|
103
|
+
|
|
104
|
+
tinyfan main.py | kubectl apply -f -
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
For a package, pass its directory or import name. Tinyfan statically discovers
|
|
108
|
+
modules containing `@asset`, so unrelated submodules are not executed during
|
|
109
|
+
manifest generation. Modules imported by an asset module (for example, a shared
|
|
110
|
+
`Flow` definition) are loaded normally.
|
|
111
|
+
|
|
112
|
+
```shell
|
|
113
|
+
tinyfan src/my_package
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Automatic package discovery requires statically recognizable Tinyfan `@asset`
|
|
117
|
+
decorators. Dynamic asset registration and custom decorator wrappers are not
|
|
118
|
+
automatically discovered.
|
|
119
|
+
|
|
120
|
+
# Embedded source
|
|
121
|
+
|
|
122
|
+
Embedded workflows unpack their source into temporary directories, so package
|
|
123
|
+
data works with both `importlib.resources` and paths relative to `__file__`.
|
|
124
|
+
Use `Path(__file__).parent` to locate data; the working directory is unchanged.
|
|
125
|
+
|
|
126
|
+
Regular packages include their files and subdirectories, including extensionless
|
|
127
|
+
data files. Embedding a nested module includes its top-level package. Standalone
|
|
128
|
+
scripts include their containing directory so sibling imports and data files are
|
|
129
|
+
available; keep scripts in a directory containing only files intended for the
|
|
130
|
+
workflow. Git metadata, `.venv`/`venv`, Python bytecode, and common tool caches are
|
|
131
|
+
excluded by default. Scripts execute as modules, preserving `__file__`, future
|
|
132
|
+
imports, and runtime annotations; `if __name__ == "__main__"` blocks do not run.
|
|
133
|
+
|
|
134
|
+
The embedding utilities accept `includes` and `excludes` glob patterns relative
|
|
135
|
+
to the bundled directory (the top-level package for nested modules). Excluding a
|
|
136
|
+
directory excludes its contents. Bundled imports take precedence over installed
|
|
137
|
+
copies that have not already been imported. Temporary files are cleaned up on
|
|
138
|
+
normal process exit, and unchanged source produces identical bundle bytes.
|
|
139
|
+
|
|
140
|
+
Embedding does not resolve third-party dependencies or copy distribution metadata
|
|
141
|
+
such as `.dist-info`. Install dependencies in the container image, including
|
|
142
|
+
packages that need native libraries or `importlib.metadata`. Import-name embedding
|
|
143
|
+
of a standalone module includes only its `.py` file; use a script path or regular
|
|
144
|
+
package for accompanying data. Native libraries and namespace-package import
|
|
145
|
+
names are rejected; use regular packages with `__init__.py`. Keep embedded source
|
|
146
|
+
and data small because generated workflows carry them in an environment variable.
|
|
147
|
+
|
|
148
|
+
# Runtime metadata
|
|
149
|
+
|
|
150
|
+
Generated workflows read runtime metadata from the reserved `tinyfan-rundata`
|
|
151
|
+
input artifact at `/tmp/tinyfan/input.json`. Parent metadata is transported as
|
|
152
|
+
base64-encoded JSON, preserving datetime values and literal text through Argo
|
|
153
|
+
parameter substitution. Asset functions and store APIs still receive ordinary
|
|
154
|
+
Python values.
|
|
155
|
+
|
|
156
|
+
After upgrading, regenerate and apply all workflow manifests together. The
|
|
157
|
+
internal `rundata` output parameter now contains base64-encoded JSON, written to
|
|
158
|
+
`/tmp/tinyfan/rundata.b64`; it is not compatible with the previous plain JSON
|
|
159
|
+
transport. For packaged workflows, update the Tinyfan version in the container
|
|
160
|
+
image as well.
|
|
161
|
+
|
|
162
|
+
Intervals are calculated at runtime from the triggering workflow's cron schedule,
|
|
163
|
+
timezone, and `workflow.scheduledTime`. If the workflow parameter `cronScheduleTime`
|
|
164
|
+
is present, it takes precedence, supporting the timestamp supplied by
|
|
165
|
+
`argo cron backfill` with its default `--argname`. Both RFC 3339 timestamps and the
|
|
166
|
+
alpha CLI's Go-style timestamps (for example, `2026-03-09 00:00:00 -0400 EDT`)
|
|
167
|
+
are accepted. Invalid or empty supplied values fail instead of falling back.
|
|
168
|
+
The interval runs from the previous
|
|
169
|
+
scheduled occurrence (inclusive) to the current one (exclusive), regardless of
|
|
170
|
+
task delays or retries. Month lengths and leap years are calendar-based; missing
|
|
171
|
+
DST times are skipped and repeated times are distinct occurrences.
|
|
172
|
+
`data_interval_start` and `data_interval_end` are timezone-aware datetimes in the
|
|
173
|
+
schedule's timezone. `ds` is the local start date and `ts` is its ISO timestamp
|
|
174
|
+
including the UTC offset. All tasks in a workflow use that workflow's interval.
|
|
175
|
+
|
|
176
|
+
Embedded workflows include croniter's required runtime modules and timezone data
|
|
177
|
+
for the configured zones; no runtime download is needed. Regenerate manifests
|
|
178
|
+
after timezone-data updates. Packaged images must install Tinyfan's dependencies,
|
|
179
|
+
including croniter 6.2.4 or newer and `tzdata`.
|
|
180
|
+
|
|
181
|
+
Backfill CLI compatibility is version-dependent: use a version supporting
|
|
182
|
+
`spec.schedules` and the configured timezone. Older alpha implementations, such
|
|
183
|
+
as Argo 3.7.0, only read the legacy `spec.schedule` field. Tinyfan does not add a
|
|
184
|
+
duplicate `cronScheduleTime` default argument because the CLI appends it itself.
|
|
185
|
+
|
|
186
|
+
# Real World Example (still tiny though!)
|
|
187
|
+
|
|
188
|
+
Comming soon
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# License
|
|
193
|
+
|
|
194
|
+
This project is licensed under the MIT License.
|
tinyfan-0.5.0/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Tinyfan
|
|
2
|
+
|
|
3
|
+
Tinyfan: Minimalist Data Pipeline Kit - Generate Argo Workflows with Python
|
|
4
|
+
|
|
5
|
+
# Features
|
|
6
|
+
|
|
7
|
+
* Generate Argo Workflows manifests from Python data pipeline definitions.
|
|
8
|
+
* Ease of Use and highly extendable
|
|
9
|
+
* Intuitive data model abstraction: let Argo handle orchestration—we focus on the data.
|
|
10
|
+
* Argo Workflows is notably lightweight and powerful – and so are we!
|
|
11
|
+
* Enhanced DevOps Experience: easly testable, Cloud Native and GitOps-ready.
|
|
12
|
+
|
|
13
|
+
# Our Goal
|
|
14
|
+
|
|
15
|
+
* **Minimize mental overhead** when building data pipelines.
|
|
16
|
+
|
|
17
|
+
# Not Our Goal
|
|
18
|
+
|
|
19
|
+
* **Full-featured orchestration framework:** We don't aim to be a battery-powered, comprehensive data pipeline orchestration solution.
|
|
20
|
+
No databases, web servers, or controllers—just a data pipeline compiler. Let's Algo Workflows handle all the complexity.
|
|
21
|
+
|
|
22
|
+
# Installation
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
# Requires Python 3.10+
|
|
26
|
+
pipx install tinyfan
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
# Tiny Example
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
# main.py
|
|
33
|
+
|
|
34
|
+
# Asset definitions
|
|
35
|
+
|
|
36
|
+
from tinyfan import asset
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@asset(schedule="*/3 * * * *")
|
|
40
|
+
def world() -> str:
|
|
41
|
+
return "world"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@asset()
|
|
45
|
+
def greeting(world: str):
|
|
46
|
+
print("hello " + world)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
# Apply the changes to argo workflow
|
|
51
|
+
|
|
52
|
+
tinyfan main.py | kubectl apply -f -
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For a package, pass its directory or import name. Tinyfan statically discovers
|
|
56
|
+
modules containing `@asset`, so unrelated submodules are not executed during
|
|
57
|
+
manifest generation. Modules imported by an asset module (for example, a shared
|
|
58
|
+
`Flow` definition) are loaded normally.
|
|
59
|
+
|
|
60
|
+
```shell
|
|
61
|
+
tinyfan src/my_package
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Automatic package discovery requires statically recognizable Tinyfan `@asset`
|
|
65
|
+
decorators. Dynamic asset registration and custom decorator wrappers are not
|
|
66
|
+
automatically discovered.
|
|
67
|
+
|
|
68
|
+
# Embedded source
|
|
69
|
+
|
|
70
|
+
Embedded workflows unpack their source into temporary directories, so package
|
|
71
|
+
data works with both `importlib.resources` and paths relative to `__file__`.
|
|
72
|
+
Use `Path(__file__).parent` to locate data; the working directory is unchanged.
|
|
73
|
+
|
|
74
|
+
Regular packages include their files and subdirectories, including extensionless
|
|
75
|
+
data files. Embedding a nested module includes its top-level package. Standalone
|
|
76
|
+
scripts include their containing directory so sibling imports and data files are
|
|
77
|
+
available; keep scripts in a directory containing only files intended for the
|
|
78
|
+
workflow. Git metadata, `.venv`/`venv`, Python bytecode, and common tool caches are
|
|
79
|
+
excluded by default. Scripts execute as modules, preserving `__file__`, future
|
|
80
|
+
imports, and runtime annotations; `if __name__ == "__main__"` blocks do not run.
|
|
81
|
+
|
|
82
|
+
The embedding utilities accept `includes` and `excludes` glob patterns relative
|
|
83
|
+
to the bundled directory (the top-level package for nested modules). Excluding a
|
|
84
|
+
directory excludes its contents. Bundled imports take precedence over installed
|
|
85
|
+
copies that have not already been imported. Temporary files are cleaned up on
|
|
86
|
+
normal process exit, and unchanged source produces identical bundle bytes.
|
|
87
|
+
|
|
88
|
+
Embedding does not resolve third-party dependencies or copy distribution metadata
|
|
89
|
+
such as `.dist-info`. Install dependencies in the container image, including
|
|
90
|
+
packages that need native libraries or `importlib.metadata`. Import-name embedding
|
|
91
|
+
of a standalone module includes only its `.py` file; use a script path or regular
|
|
92
|
+
package for accompanying data. Native libraries and namespace-package import
|
|
93
|
+
names are rejected; use regular packages with `__init__.py`. Keep embedded source
|
|
94
|
+
and data small because generated workflows carry them in an environment variable.
|
|
95
|
+
|
|
96
|
+
# Runtime metadata
|
|
97
|
+
|
|
98
|
+
Generated workflows read runtime metadata from the reserved `tinyfan-rundata`
|
|
99
|
+
input artifact at `/tmp/tinyfan/input.json`. Parent metadata is transported as
|
|
100
|
+
base64-encoded JSON, preserving datetime values and literal text through Argo
|
|
101
|
+
parameter substitution. Asset functions and store APIs still receive ordinary
|
|
102
|
+
Python values.
|
|
103
|
+
|
|
104
|
+
After upgrading, regenerate and apply all workflow manifests together. The
|
|
105
|
+
internal `rundata` output parameter now contains base64-encoded JSON, written to
|
|
106
|
+
`/tmp/tinyfan/rundata.b64`; it is not compatible with the previous plain JSON
|
|
107
|
+
transport. For packaged workflows, update the Tinyfan version in the container
|
|
108
|
+
image as well.
|
|
109
|
+
|
|
110
|
+
Intervals are calculated at runtime from the triggering workflow's cron schedule,
|
|
111
|
+
timezone, and `workflow.scheduledTime`. If the workflow parameter `cronScheduleTime`
|
|
112
|
+
is present, it takes precedence, supporting the timestamp supplied by
|
|
113
|
+
`argo cron backfill` with its default `--argname`. Both RFC 3339 timestamps and the
|
|
114
|
+
alpha CLI's Go-style timestamps (for example, `2026-03-09 00:00:00 -0400 EDT`)
|
|
115
|
+
are accepted. Invalid or empty supplied values fail instead of falling back.
|
|
116
|
+
The interval runs from the previous
|
|
117
|
+
scheduled occurrence (inclusive) to the current one (exclusive), regardless of
|
|
118
|
+
task delays or retries. Month lengths and leap years are calendar-based; missing
|
|
119
|
+
DST times are skipped and repeated times are distinct occurrences.
|
|
120
|
+
`data_interval_start` and `data_interval_end` are timezone-aware datetimes in the
|
|
121
|
+
schedule's timezone. `ds` is the local start date and `ts` is its ISO timestamp
|
|
122
|
+
including the UTC offset. All tasks in a workflow use that workflow's interval.
|
|
123
|
+
|
|
124
|
+
Embedded workflows include croniter's required runtime modules and timezone data
|
|
125
|
+
for the configured zones; no runtime download is needed. Regenerate manifests
|
|
126
|
+
after timezone-data updates. Packaged images must install Tinyfan's dependencies,
|
|
127
|
+
including croniter 6.2.4 or newer and `tzdata`.
|
|
128
|
+
|
|
129
|
+
Backfill CLI compatibility is version-dependent: use a version supporting
|
|
130
|
+
`spec.schedules` and the configured timezone. Older alpha implementations, such
|
|
131
|
+
as Argo 3.7.0, only read the legacy `spec.schedule` field. Tinyfan does not add a
|
|
132
|
+
duplicate `cronScheduleTime` default argument because the CLI appends it itself.
|
|
133
|
+
|
|
134
|
+
# Real World Example (still tiny though!)
|
|
135
|
+
|
|
136
|
+
Comming soon
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# License
|
|
141
|
+
|
|
142
|
+
This project is licensed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tinyfan"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
description = 'Tiny Argo Workflows python devkit'
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -12,7 +12,7 @@ classifiers = [
|
|
|
12
12
|
"Programming Language :: Python :: 3.12",
|
|
13
13
|
"Typing :: Typed",
|
|
14
14
|
]
|
|
15
|
-
dependencies = ["croniter>=6", "pyyaml>=6.0.3", "typer-slim>=0.24.0"]
|
|
15
|
+
dependencies = ["croniter>=6.2.4", "pyyaml>=6.0.3", "typer-slim>=0.24.0", "tzdata"]
|
|
16
16
|
|
|
17
17
|
[project.scripts]
|
|
18
18
|
tinyfan = "tinyfan.cli:main"
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .config import ConfigMapKeyRef, ConfigMapRef, SecretKeyRef, SecretRef, cli_arg
|
|
2
|
+
from .flow import Asset, Flow, asset
|
|
3
|
+
from .resources.base import ResourceBase
|
|
2
4
|
from .stores.base import StoreBase
|
|
3
5
|
from .stores.naive import NaiveStore
|
|
4
|
-
from .config import ConfigMapRef, ConfigMapKeyRef, SecretRef, SecretKeyRef, cli_arg
|
|
5
|
-
from .resources.base import ResourceBase
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
|
-
"Flow",
|
|
9
8
|
"Asset",
|
|
10
|
-
"asset",
|
|
11
|
-
"StoreBase",
|
|
12
|
-
"NaiveStore",
|
|
13
|
-
"ConfigMapRef",
|
|
14
9
|
"ConfigMapKeyRef",
|
|
15
|
-
"
|
|
10
|
+
"ConfigMapRef",
|
|
11
|
+
"Flow",
|
|
12
|
+
"NaiveStore",
|
|
13
|
+
"ResourceBase",
|
|
16
14
|
"SecretKeyRef",
|
|
15
|
+
"SecretRef",
|
|
16
|
+
"StoreBase",
|
|
17
|
+
"asset",
|
|
17
18
|
"cli_arg",
|
|
18
|
-
"ResourceBase",
|
|
19
19
|
]
|