juturna 1.0.2__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 (95) hide show
  1. juturna-1.0.2/LICENSE +21 -0
  2. juturna-1.0.2/PKG-INFO +172 -0
  3. juturna-1.0.2/README.md +131 -0
  4. juturna-1.0.2/juturna/__init__.py +24 -0
  5. juturna-1.0.2/juturna/__main__.py +30 -0
  6. juturna-1.0.2/juturna/cli/_cli_utils.py +23 -0
  7. juturna-1.0.2/juturna/cli/commands/__init__.py +35 -0
  8. juturna-1.0.2/juturna/cli/commands/_common_pipe_parser.py +27 -0
  9. juturna-1.0.2/juturna/cli/commands/_create_tools.py +74 -0
  10. juturna-1.0.2/juturna/cli/commands/_juturna_config_creator.py +521 -0
  11. juturna-1.0.2/juturna/cli/commands/_juturna_service.py +102 -0
  12. juturna-1.0.2/juturna/cli/commands/_node_stub.py +94 -0
  13. juturna-1.0.2/juturna/cli/commands/_validation_tools.py +112 -0
  14. juturna-1.0.2/juturna/cli/commands/basic_config.template +3 -0
  15. juturna-1.0.2/juturna/cli/commands/basic_node.template +65 -0
  16. juturna-1.0.2/juturna/cli/commands/create.py +40 -0
  17. juturna-1.0.2/juturna/cli/commands/launch.py +90 -0
  18. juturna-1.0.2/juturna/cli/commands/serve.py +83 -0
  19. juturna-1.0.2/juturna/cli/commands/stub.py +55 -0
  20. juturna-1.0.2/juturna/cli/commands/validate.py +252 -0
  21. juturna-1.0.2/juturna/components/__init__.py +12 -0
  22. juturna-1.0.2/juturna/components/_buffer.py +80 -0
  23. juturna-1.0.2/juturna/components/_component_builder.py +129 -0
  24. juturna-1.0.2/juturna/components/_mapper.py +197 -0
  25. juturna-1.0.2/juturna/components/_message.py +190 -0
  26. juturna-1.0.2/juturna/components/_node.py +427 -0
  27. juturna-1.0.2/juturna/components/_pipeline.py +232 -0
  28. juturna-1.0.2/juturna/components/_pipeline_manager.py +173 -0
  29. juturna-1.0.2/juturna/components/_resource_broker.py +17 -0
  30. juturna-1.0.2/juturna/components/_synchronisers.py +11 -0
  31. juturna-1.0.2/juturna/hub/__init__.py +10 -0
  32. juturna-1.0.2/juturna/hub/__main__.py +72 -0
  33. juturna-1.0.2/juturna/hub/_gh_utils.py +70 -0
  34. juturna-1.0.2/juturna/hub/_utils.py +193 -0
  35. juturna-1.0.2/juturna/meta/__init__.py +20 -0
  36. juturna-1.0.2/juturna/meta/_constants.py +28 -0
  37. juturna-1.0.2/juturna/names/__init__.py +10 -0
  38. juturna-1.0.2/juturna/names/_component_status.py +23 -0
  39. juturna-1.0.2/juturna/names/_pipeline_status.py +9 -0
  40. juturna-1.0.2/juturna/names/_service_status.py +13 -0
  41. juturna-1.0.2/juturna/nodes/__init__.py +8 -0
  42. juturna-1.0.2/juturna/nodes/sink/__init__.py +10 -0
  43. juturna-1.0.2/juturna/nodes/sink/_notifier_http/config.toml +6 -0
  44. juturna-1.0.2/juturna/nodes/sink/_notifier_http/notifier_http.py +83 -0
  45. juturna-1.0.2/juturna/nodes/sink/_notifier_udp/README.md +8 -0
  46. juturna-1.0.2/juturna/nodes/sink/_notifier_udp/config.toml +10 -0
  47. juturna-1.0.2/juturna/nodes/sink/_notifier_udp/notifier_udp.py +121 -0
  48. juturna-1.0.2/juturna/nodes/sink/_notifier_udp/requirements.txt +0 -0
  49. juturna-1.0.2/juturna/nodes/sink/_notifier_websocket/config.toml +4 -0
  50. juturna-1.0.2/juturna/nodes/sink/_notifier_websocket/notifier_websocket.py +59 -0
  51. juturna-1.0.2/juturna/nodes/sink/_videostream_ffmpeg/config.toml +12 -0
  52. juturna-1.0.2/juturna/nodes/sink/_videostream_ffmpeg/ffmpeg_launcher_h264.sh.template +18 -0
  53. juturna-1.0.2/juturna/nodes/sink/_videostream_ffmpeg/ffmpeg_launcher_vp8-dump.sh.template +14 -0
  54. juturna-1.0.2/juturna/nodes/sink/_videostream_ffmpeg/ffmpeg_launcher_vp8.sh.template +22 -0
  55. juturna-1.0.2/juturna/nodes/sink/_videostream_ffmpeg/videostream_ffmpeg.py +113 -0
  56. juturna-1.0.2/juturna/nodes/source/__init__.py +10 -0
  57. juturna-1.0.2/juturna/nodes/source/_audio_file/audio_file.py +162 -0
  58. juturna-1.0.2/juturna/nodes/source/_audio_file/config.toml +6 -0
  59. juturna-1.0.2/juturna/nodes/source/_audio_rtp/audio_rtp.py +367 -0
  60. juturna-1.0.2/juturna/nodes/source/_audio_rtp/config.toml +11 -0
  61. juturna-1.0.2/juturna/nodes/source/_audio_rtp/ffmpeg_launcher.sh.template +9 -0
  62. juturna-1.0.2/juturna/nodes/source/_audio_rtp/remote_source.sdp.template +9 -0
  63. juturna-1.0.2/juturna/nodes/source/_json_http/README.md +11 -0
  64. juturna-1.0.2/juturna/nodes/source/_json_http/config.toml +5 -0
  65. juturna-1.0.2/juturna/nodes/source/_json_http/json_http.py +212 -0
  66. juturna-1.0.2/juturna/nodes/source/_json_http/requirements.txt +0 -0
  67. juturna-1.0.2/juturna/nodes/source/_json_websocket/README.md +14 -0
  68. juturna-1.0.2/juturna/nodes/source/_json_websocket/config.toml +5 -0
  69. juturna-1.0.2/juturna/nodes/source/_json_websocket/json_websocket.py +107 -0
  70. juturna-1.0.2/juturna/nodes/source/_json_websocket/requirements.txt +0 -0
  71. juturna-1.0.2/juturna/nodes/source/_video_file/README.md +8 -0
  72. juturna-1.0.2/juturna/nodes/source/_video_file/config.toml +6 -0
  73. juturna-1.0.2/juturna/nodes/source/_video_file/ffmpeg_launcher.sh.template +10 -0
  74. juturna-1.0.2/juturna/nodes/source/_video_file/requirements.txt +0 -0
  75. juturna-1.0.2/juturna/nodes/source/_video_file/video_file.py +131 -0
  76. juturna-1.0.2/juturna/nodes/source/_video_rtp/config.toml +9 -0
  77. juturna-1.0.2/juturna/nodes/source/_video_rtp/ffmpeg_launcher.sh.template +8 -0
  78. juturna-1.0.2/juturna/nodes/source/_video_rtp/remote_source.sdp.template +9 -0
  79. juturna-1.0.2/juturna/nodes/source/_video_rtp/video_rtp.py +168 -0
  80. juturna-1.0.2/juturna/payloads/__init__.py +22 -0
  81. juturna-1.0.2/juturna/payloads/_generics.py +29 -0
  82. juturna-1.0.2/juturna/payloads/_payloads.py +108 -0
  83. juturna-1.0.2/juturna/utils/__init__.py +6 -0
  84. juturna-1.0.2/juturna/utils/jt_utils/__init__.py +3 -0
  85. juturna-1.0.2/juturna/utils/jt_utils/_get_env_var.py +31 -0
  86. juturna-1.0.2/juturna/utils/log_utils/__init__.py +12 -0
  87. juturna-1.0.2/juturna/utils/log_utils/_formatters.py +72 -0
  88. juturna-1.0.2/juturna/utils/log_utils/_log_helper.py +62 -0
  89. juturna-1.0.2/juturna/utils/net_utils/__init__.py +10 -0
  90. juturna-1.0.2/juturna/utils/net_utils/_port_scanner.py +22 -0
  91. juturna-1.0.2/juturna/utils/net_utils/_rtp_client.py +96 -0
  92. juturna-1.0.2/juturna/utils/net_utils/_rtp_datagram.py +61 -0
  93. juturna-1.0.2/juturna/utils/proc_utils/__init__.py +6 -0
  94. juturna-1.0.2/juturna/utils/proc_utils/_trx_utils.py +64 -0
  95. juturna-1.0.2/pyproject.toml +88 -0
juturna-1.0.2/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Antonio Bevilacqua
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
juturna-1.0.2/PKG-INFO ADDED
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.3
2
+ Name: juturna
3
+ Version: 1.0.2
4
+ Summary: Juturna core library
5
+ License: MIT
6
+ Author: Antonio Bevilacqua
7
+ Author-email: b3by.in.th3.sky@gmail.com
8
+ Maintainer: Antonio Bevilacqua
9
+ Maintainer-email: b3by.in.th3.sky@gmail.com
10
+ Requires-Python: >=3.12
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Provides-Extra: dev
15
+ Provides-Extra: httpwrapper
16
+ Provides-Extra: pipebuilder
17
+ Requires-Dist: av (>=14.2.0,<15.0.0)
18
+ Requires-Dist: fastapi-cli[httpwrapper] (>=0.0.7,<0.0.8) ; extra == "httpwrapper"
19
+ Requires-Dist: fastapi[httpwrapper] (>=0.115.12,<0.116.0) ; extra == "httpwrapper"
20
+ Requires-Dist: furo[dev] (>=2025.9.25,<2026.0.0) ; extra == "dev"
21
+ Requires-Dist: numpy (==2.2.3)
22
+ Requires-Dist: prompt_toolkit[pipebuilder] (>=3.0.52,<4.0.0) ; extra == "pipebuilder"
23
+ Requires-Dist: pytest[dev] (>=8.3.5,<9.0.0) ; extra == "dev"
24
+ Requires-Dist: requests (==2.32.3)
25
+ Requires-Dist: rich[pipebuilder] (>=13.8.1,<14.0.0) ; extra == "pipebuilder"
26
+ Requires-Dist: sphinx-autoapi[dev] (>=3.6.0,<4.0.0) ; extra == "dev"
27
+ Requires-Dist: sphinx-autobuild[dev] (>=2024.10.3,<2025.0.0) ; extra == "dev"
28
+ Requires-Dist: sphinx-design[dev] (>=0.6.1,<0.7.0) ; extra == "dev"
29
+ Requires-Dist: sphinx-new-tab-link[dev] (>=0.8.0,<0.9.0) ; extra == "dev"
30
+ Requires-Dist: sphinx[dev] (>=8.2.3,<9.0.0) ; extra == "dev"
31
+ Requires-Dist: sphinxcontrib-apidoc[dev] (>=0.5.0,<0.6.0) ; extra == "dev"
32
+ Requires-Dist: sphinxcontrib-napoleon[dev] (>=0.7,<0.8) ; extra == "dev"
33
+ Requires-Dist: websockets (>=15.0.1,<16.0.0)
34
+ Project-URL: Changelog, https://github.com/meetecho/juturna/blob/main/CHANGELOG.md
35
+ Project-URL: Documentation, https://meetecho.github.io/juturna/index.html
36
+ Project-URL: Homepage, https://github.com/meetecho/juturna
37
+ Project-URL: Issues, https://github.com/meetecho/juturna/issues
38
+ Project-URL: Repository, https://github.com/meetecho/juturna
39
+ Description-Content-Type: text/markdown
40
+
41
+ # Juturna – Real-time AI Pipeline Framework
42
+ <p align="center"><img src="https://raw.githubusercontent.com/meetecho/juturna/main/docs/source/_static/img/logo_dark_alt.svg" width="30%">
43
+ <br>
44
+ <img src="https://img.shields.io/github/license/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/stars/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/forks/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/issues/meetecho/juturna?style=for-the-badge">
45
+ </p>
46
+
47
+ ## :seedling: Important to know
48
+ Juturna is actively evolving with exciting new features and improvements being
49
+ added regularly. We're using semantic versioning to clearly communicate any
50
+ breaking changes between releases, so you can upgrade with confidence. Juturna
51
+ is perfect for experimentation and prototyping today, and we're working toward
52
+ production-ready stability with each release. So, if you plan to deploy it in
53
+ production, make sure you are comfortable managing potential updates and
54
+ adjustments.
55
+
56
+ ## At a glance
57
+
58
+ **Juturna** is a data pipeline library written in Python. It is particularly
59
+ useful for fast prototyping multimedia, **real-time** data applications, as
60
+ well as exploring and testing AI models, in a modular and flexible fashion.
61
+
62
+ Among its many features, there are a few keypoints to highligh about Juturna:
63
+
64
+ * :zap: **Real-Time Streaming:** continuouusly process audio, video and
65
+ arbitrary data streams
66
+ * :electric_plug: **Modularity:** create your own nodes and share them through
67
+ the Juturna hub
68
+ * :link: **Composable workloads:** design pipelines to solve complex tasks in
69
+ minutes
70
+ * 🚀 **Parallelism & Batching:** parallel, non-blocking execution for high
71
+ throughput
72
+ * 📊 **Observability:** built-in logging and metrics support
73
+
74
+ [documentation](https://meetecho.github.io/juturna/index.html) | [contribute](https://github.com/meetecho/juturna/blob/main/CONTRIBUTING.md) | [meetecho](https://www.meetecho.com/en/)
75
+
76
+ ## Overview
77
+
78
+ A **pipeline** can simply be defined as a collection of **nodes**.
79
+
80
+ Each **node** acquires a piece of data from its parents and, after performing a
81
+ single task, provide its output to its children. In this sense, a Juturna
82
+ pipeline is nothing else but a DAG, where root nodes have an in-degree of 0
83
+ (this is not technically the case, but we’ll skip it for now), and every other
84
+ node has an in-degree of 1 or more.
85
+
86
+ An example of one of our pipelines, currently in use for live audio
87
+ transcription and summarisation is shown here.
88
+
89
+ <p align="center"><img src="https://raw.githubusercontent.com/meetecho/juturna/main/assets/img/pipeline_example.png"></p>
90
+
91
+ Whilst Juturna ships with a number of built-in nodes (mainly source and sink
92
+ nodes), you can implement your own nodes with ease, and share them so others
93
+ can use them too.
94
+
95
+ To know more about the Juturna internals, please refer to the full
96
+ documentation.
97
+
98
+ ## Installation
99
+
100
+ The following dependencies are required to use Juturna:
101
+
102
+ - ``python >= 3.12``
103
+ - system libraries ``libsm6``, ``libext6``, ``ffmpeg``
104
+
105
+ :information_source: Current Python building version is 3.12. The library still
106
+ has to be tested on Python 3.13 and later with GIL disabled.
107
+
108
+
109
+ Juturna is currently available as a opensource codebase, but not yet published
110
+ on PyPi. To install it on your system, first clone the repository, then use
111
+ pip to install it (assuming you are working in a virtual environment):
112
+
113
+ ```
114
+ (venv) $ git clone https://github.com/meetecho/juturna
115
+ (venv) $ pip install ./juturna
116
+ ```
117
+
118
+ In case you want to include all the development dependencies in the
119
+ installation, specify the ``dev`` group:
120
+
121
+ ```
122
+ (venv) $ pip install "./juturna[dev]"
123
+ ```
124
+
125
+ To include the Juturna HTTP wrapper, include the ``httpwrapper``:
126
+
127
+ ```
128
+ (venv) $ pip install "./juturna[httpwrapper]"
129
+ ```
130
+
131
+ Alternatively, you can manually install the required dependencies, and just
132
+ import the juturna module from within the repository folder:
133
+
134
+ ```
135
+ (venv) $ pip install av ffmpeg-python opencv-python numpy requests websockets
136
+ (venv) $ python
137
+ >>> import juturna as jt
138
+ ```
139
+
140
+ ### Dockerfile
141
+
142
+ In the Juturna repository you will find a Dockerfile that can be used to create
143
+ a base Juturna image. To build it, symply navigate within the repo folder and
144
+ run:
145
+
146
+ ```
147
+ $ docker build -t juturna:latest .
148
+ ```
149
+
150
+ ## Contributing
151
+
152
+ Please read [`CONTRIBUTING.md`](https://github.com/meetecho/juturna/blob/main/CONTRIBUTING.md) for:
153
+
154
+ * Branching & PR workflow
155
+ * Code style & linting
156
+ * Issue triage (TBD)
157
+ * Issue & PR templates and a Code of Conduct are provided (TBD)
158
+ * Signing CRA
159
+
160
+ ## Changelog
161
+
162
+ All notable changes are documented in [`CHANGELOG.md`](https://github.com/meetecho/juturna/blob/main/CHANGELOG.md)
163
+ following [Semantic Versioning](https://semver.org).
164
+
165
+ ## External Docs & Support
166
+
167
+ Coming soon!
168
+
169
+ ## License
170
+
171
+ Distributed under the **MIT License**. See [LICENSE](https://github.com/meetecho/juturna/blob/main/LICENSE) for details.
172
+
@@ -0,0 +1,131 @@
1
+ # Juturna – Real-time AI Pipeline Framework
2
+ <p align="center"><img src="https://raw.githubusercontent.com/meetecho/juturna/main/docs/source/_static/img/logo_dark_alt.svg" width="30%">
3
+ <br>
4
+ <img src="https://img.shields.io/github/license/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/stars/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/forks/meetecho/juturna?style=for-the-badge"> <img src="https://img.shields.io/github/issues/meetecho/juturna?style=for-the-badge">
5
+ </p>
6
+
7
+ ## :seedling: Important to know
8
+ Juturna is actively evolving with exciting new features and improvements being
9
+ added regularly. We're using semantic versioning to clearly communicate any
10
+ breaking changes between releases, so you can upgrade with confidence. Juturna
11
+ is perfect for experimentation and prototyping today, and we're working toward
12
+ production-ready stability with each release. So, if you plan to deploy it in
13
+ production, make sure you are comfortable managing potential updates and
14
+ adjustments.
15
+
16
+ ## At a glance
17
+
18
+ **Juturna** is a data pipeline library written in Python. It is particularly
19
+ useful for fast prototyping multimedia, **real-time** data applications, as
20
+ well as exploring and testing AI models, in a modular and flexible fashion.
21
+
22
+ Among its many features, there are a few keypoints to highligh about Juturna:
23
+
24
+ * :zap: **Real-Time Streaming:** continuouusly process audio, video and
25
+ arbitrary data streams
26
+ * :electric_plug: **Modularity:** create your own nodes and share them through
27
+ the Juturna hub
28
+ * :link: **Composable workloads:** design pipelines to solve complex tasks in
29
+ minutes
30
+ * 🚀 **Parallelism & Batching:** parallel, non-blocking execution for high
31
+ throughput
32
+ * 📊 **Observability:** built-in logging and metrics support
33
+
34
+ [documentation](https://meetecho.github.io/juturna/index.html) | [contribute](https://github.com/meetecho/juturna/blob/main/CONTRIBUTING.md) | [meetecho](https://www.meetecho.com/en/)
35
+
36
+ ## Overview
37
+
38
+ A **pipeline** can simply be defined as a collection of **nodes**.
39
+
40
+ Each **node** acquires a piece of data from its parents and, after performing a
41
+ single task, provide its output to its children. In this sense, a Juturna
42
+ pipeline is nothing else but a DAG, where root nodes have an in-degree of 0
43
+ (this is not technically the case, but we’ll skip it for now), and every other
44
+ node has an in-degree of 1 or more.
45
+
46
+ An example of one of our pipelines, currently in use for live audio
47
+ transcription and summarisation is shown here.
48
+
49
+ <p align="center"><img src="https://raw.githubusercontent.com/meetecho/juturna/main/assets/img/pipeline_example.png"></p>
50
+
51
+ Whilst Juturna ships with a number of built-in nodes (mainly source and sink
52
+ nodes), you can implement your own nodes with ease, and share them so others
53
+ can use them too.
54
+
55
+ To know more about the Juturna internals, please refer to the full
56
+ documentation.
57
+
58
+ ## Installation
59
+
60
+ The following dependencies are required to use Juturna:
61
+
62
+ - ``python >= 3.12``
63
+ - system libraries ``libsm6``, ``libext6``, ``ffmpeg``
64
+
65
+ :information_source: Current Python building version is 3.12. The library still
66
+ has to be tested on Python 3.13 and later with GIL disabled.
67
+
68
+
69
+ Juturna is currently available as a opensource codebase, but not yet published
70
+ on PyPi. To install it on your system, first clone the repository, then use
71
+ pip to install it (assuming you are working in a virtual environment):
72
+
73
+ ```
74
+ (venv) $ git clone https://github.com/meetecho/juturna
75
+ (venv) $ pip install ./juturna
76
+ ```
77
+
78
+ In case you want to include all the development dependencies in the
79
+ installation, specify the ``dev`` group:
80
+
81
+ ```
82
+ (venv) $ pip install "./juturna[dev]"
83
+ ```
84
+
85
+ To include the Juturna HTTP wrapper, include the ``httpwrapper``:
86
+
87
+ ```
88
+ (venv) $ pip install "./juturna[httpwrapper]"
89
+ ```
90
+
91
+ Alternatively, you can manually install the required dependencies, and just
92
+ import the juturna module from within the repository folder:
93
+
94
+ ```
95
+ (venv) $ pip install av ffmpeg-python opencv-python numpy requests websockets
96
+ (venv) $ python
97
+ >>> import juturna as jt
98
+ ```
99
+
100
+ ### Dockerfile
101
+
102
+ In the Juturna repository you will find a Dockerfile that can be used to create
103
+ a base Juturna image. To build it, symply navigate within the repo folder and
104
+ run:
105
+
106
+ ```
107
+ $ docker build -t juturna:latest .
108
+ ```
109
+
110
+ ## Contributing
111
+
112
+ Please read [`CONTRIBUTING.md`](https://github.com/meetecho/juturna/blob/main/CONTRIBUTING.md) for:
113
+
114
+ * Branching & PR workflow
115
+ * Code style & linting
116
+ * Issue triage (TBD)
117
+ * Issue & PR templates and a Code of Conduct are provided (TBD)
118
+ * Signing CRA
119
+
120
+ ## Changelog
121
+
122
+ All notable changes are documented in [`CHANGELOG.md`](https://github.com/meetecho/juturna/blob/main/CHANGELOG.md)
123
+ following [Semantic Versioning](https://semver.org).
124
+
125
+ ## External Docs & Support
126
+
127
+ Coming soon!
128
+
129
+ ## License
130
+
131
+ Distributed under the **MIT License**. See [LICENSE](https://github.com/meetecho/juturna/blob/main/LICENSE) for details.
@@ -0,0 +1,24 @@
1
+ import juturna.names as names
2
+ import juturna.components as components
3
+ import juturna.nodes as nodes
4
+ import juturna.utils as utils
5
+ import juturna.hub as hub
6
+ import juturna.meta as meta
7
+ import juturna.payloads as payloads
8
+
9
+ import juturna.utils.log_utils as log
10
+
11
+
12
+ __app_name__ = 'juturna'
13
+ __version__ = '0.1.0'
14
+
15
+ __all__ = [
16
+ 'names',
17
+ 'components',
18
+ 'nodes',
19
+ 'utils',
20
+ 'log',
21
+ 'meta',
22
+ 'hub',
23
+ 'payloads'
24
+ ]
@@ -0,0 +1,30 @@
1
+ import argparse
2
+ import sys
3
+
4
+
5
+ from juturna.cli import commands
6
+
7
+
8
+ parser = argparse.ArgumentParser(
9
+ prog='juturna',
10
+ description=(
11
+ 'Collection of simple CLI utilities to manage pipeline configuration '
12
+ 'files and pipeline lifecycles.'
13
+ ))
14
+
15
+ subparsers = parser.add_subparsers(
16
+ dest='command',
17
+ description='List of commands included in the juturna CLI')
18
+
19
+ commands.register_all(subparsers)
20
+ _ret = 0
21
+
22
+ args = parser.parse_args()
23
+
24
+ if command := args.command:
25
+ delattr(args, 'command')
26
+ _ret = commands.command(command)(args)
27
+ else:
28
+ parser.print_help()
29
+
30
+ sys.exit(_ret)
@@ -0,0 +1,23 @@
1
+ import argparse
2
+ import pathlib
3
+
4
+
5
+
6
+ def _is_file_ok(file_path: str) -> str:
7
+ if not pathlib.Path(file_path).exists():
8
+ raise argparse.ArgumentTypeError(f'{file_path} does not exists')
9
+
10
+ if not pathlib.Path(file_path).is_file():
11
+ raise argparse.ArgumentTypeError(f'{file_path} is not a file')
12
+
13
+ return file_path
14
+
15
+
16
+ def _is_dir_ok(dir_path: str) -> str:
17
+ if not pathlib.Path(dir_path).exists():
18
+ raise argparse.ArgumentTypeError(f'{dir_path} does not exists')
19
+
20
+ if not pathlib.Path(dir_path).is_dir():
21
+ raise argparse.ArgumentTypeError(f'{dir_path} is not a file')
22
+
23
+ return dir_path
@@ -0,0 +1,35 @@
1
+ """
2
+ CLI registry
3
+
4
+ Commands are registered based on whether their required modules are installed. A
5
+ command for which its module fails to be imported will not be registered, so it
6
+ will not be available in the command line.
7
+ """
8
+
9
+ import importlib
10
+
11
+
12
+ _MODULES = {
13
+ cmd: None for cmd in ['launch', 'validate', 'serve', 'create', 'stub']
14
+ }
15
+
16
+
17
+ def _safe_reg(module_name: str, subparsers):
18
+ try:
19
+ _MODULES[module_name] = importlib.import_module(
20
+ f'juturna.cli.commands.{module_name}'
21
+ )
22
+ _MODULES[module_name].setup_parser(subparsers)
23
+ except ModuleNotFoundError:
24
+ ...
25
+
26
+
27
+ def register_all(subparsers):
28
+ """Register subparsers for all modules"""
29
+ for module in _MODULES:
30
+ _safe_reg(module, subparsers)
31
+
32
+
33
+ def command(cmd_name: str):
34
+ """Return command caller function"""
35
+ return _MODULES[cmd_name]._execute
@@ -0,0 +1,27 @@
1
+ import argparse
2
+
3
+ from juturna.cli import _cli_utils
4
+
5
+
6
+ def common_parser():
7
+ parser = argparse.ArgumentParser(add_help=False)
8
+
9
+ parser.add_argument(
10
+ '--log-level',
11
+ '-l',
12
+ type=str,
13
+ default='DEBUG',
14
+ choices=['NOTSET', 'DEBUG', 'INFO', 'WARNING', 'ERROR'],
15
+ help='set log level during pipeline execution'
16
+ )
17
+
18
+ parser.add_argument(
19
+ '--config',
20
+ '-c',
21
+ required=True,
22
+ metavar='FILE',
23
+ type=_cli_utils._is_file_ok,
24
+ help='pipeline json configuration file',
25
+ )
26
+
27
+ return parser
@@ -0,0 +1,74 @@
1
+ import pathlib
2
+ import tomllib
3
+
4
+
5
+ _TYPE_MAP = {
6
+ bool: 'boolean',
7
+ int: 'integer',
8
+ float: 'float',
9
+ str: 'string',
10
+ dict: 'dictionary',
11
+ list: 'list',
12
+ }
13
+
14
+
15
+ def discover_nodes(node_folder: str) -> dict:
16
+ node_registry = dict()
17
+
18
+ folder = pathlib.Path(node_folder)
19
+
20
+ if not folder.exists():
21
+ raise FileNotFoundError(f'node folder {node_folder} does not exist')
22
+
23
+ for node_type_dir in folder.iterdir():
24
+ if not node_type_dir.is_dir():
25
+ continue
26
+
27
+ nodes = discover_node_marks(str(node_type_dir))
28
+
29
+ if nodes:
30
+ node_registry[node_type_dir.name] = nodes
31
+
32
+ return node_registry
33
+
34
+
35
+ def discover_node_marks(node_folder: str) -> dict:
36
+ folder = pathlib.Path(node_folder)
37
+ registry = dict()
38
+
39
+ marks = folder.glob('_*')
40
+
41
+ for mark_dir in filter(lambda d: d.is_dir(), marks):
42
+ mark = mark_dir.name[1:]
43
+ config_path = mark_dir / 'config.toml'
44
+
45
+ if not config_path.exists():
46
+ continue
47
+
48
+ with open(config_path, 'rb') as f:
49
+ config = tomllib.load(f)
50
+ arguments = config.get('arguments', {})
51
+
52
+ registry[mark] = {
53
+ 'arguments': {
54
+ arg_name: {
55
+ 'default': arg_value,
56
+ 'type': _TYPE_MAP.get(type(arg_value)),
57
+ }
58
+ for arg_name, arg_value in arguments.items()
59
+ }
60
+ }
61
+
62
+ return registry
63
+
64
+
65
+ def get_types(nodes: dict) -> list[str]:
66
+ return sorted(nodes.keys())
67
+
68
+
69
+ def get_marks(nodes: dict, node_type: str) -> list[str]:
70
+ return sorted(nodes.get(node_type, {}).keys())
71
+
72
+
73
+ def get_config(nodes: dict, node_type: str, node_mark: str) -> dict | None:
74
+ return nodes.get(node_type, {}).get(node_mark)