dagex 2026.8__cp39-cp39-manylinux_2_34_x86_64.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.
dagex/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ from .dagex import *
2
+
3
+ __doc__ = dagex.__doc__
4
+ if hasattr(dagex, "__all__"):
5
+ __all__ = dagex.__all__
@@ -0,0 +1,259 @@
1
+ Metadata-Version: 2.1
2
+ Name: dagex
3
+ Version: 2026.8
4
+ Summary: A pure Rust DAG executor supporting implicit node connections, branching, and config sweeps
5
+ Keywords: dag,graph,execution,pipeline,workflow
6
+ Home-Page: https://github.com/briday1/dagex
7
+ Author: briday1 <your-email@example.com>
8
+ Author-email: briday1 <your-email@example.com>
9
+ License: MIT
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
12
+ Project-URL: Source Code, https://github.com/briday1/dagex
13
+
14
+ # dagex
15
+
16
+ A pure Rust DAG (Directed Acyclic Graph) executor with Python bindings for building and executing computational pipelines.
17
+
18
+ ## Features
19
+
20
+ - **Implicit Node Connections**: Nodes automatically connect based on execution order
21
+ - **Parallel Branching**: Create fan-out execution paths with `.branch()`
22
+ - **Configuration Variants**: Use `.variant()` to create parameter sweeps
23
+ - **Mermaid Visualization**: Generate diagrams with `.to_mermaid()`
24
+ - **Parallel Execution**: Execute independent branches concurrently
25
+ - **Native Performance**: Rust-powered execution with Python convenience
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install dagex
31
+ ```
32
+
33
+ No Rust toolchain required - prebuilt wheels are available for all major platforms.
34
+
35
+ ## Quick Start
36
+
37
+ ### Basic Pipeline
38
+
39
+ ```python
40
+ import dagex
41
+
42
+ def data_source(inputs, variant_params):
43
+ """Generate initial data"""
44
+ return {"value": 42}
45
+
46
+ def multiply(inputs, variant_params):
47
+ """Process the data"""
48
+ val = inputs.get("x", 0)
49
+ return {"doubled": val * 2}
50
+
51
+ # Create graph
52
+ graph = dagex.Graph()
53
+
54
+ # Add nodes
55
+ graph.add(
56
+ function=data_source,
57
+ label="DataSource",
58
+ inputs=None,
59
+ outputs=[("value", "data")]
60
+ )
61
+
62
+ graph.add(
63
+ function=multiply,
64
+ label="Multiply",
65
+ inputs=[("data", "x")],
66
+ outputs=[("doubled", "result")]
67
+ )
68
+
69
+ # Build and execute
70
+ dag = graph.build()
71
+ context = dag.execute()
72
+
73
+ print(f"Result: {context['result']}") # Output: Result: 84
74
+ ```
75
+
76
+ ### Parallel Branching
77
+
78
+ Create multiple parallel processing paths:
79
+
80
+ ```python
81
+ import dagex
82
+ import time
83
+
84
+ def source(inputs, variant_params):
85
+ return {"data": 100}
86
+
87
+ def branch_a(inputs, variant_params):
88
+ time.sleep(0.1) # Simulate work
89
+ return {"result_a": inputs["x"] * 2}
90
+
91
+ def branch_b(inputs, variant_params):
92
+ time.sleep(0.1) # Simulate work
93
+ return {"result_b": inputs["x"] * 3}
94
+
95
+ def branch_c(inputs, variant_params):
96
+ time.sleep(0.1) # Simulate work
97
+ return {"result_c": inputs["x"] + 50}
98
+
99
+ graph = dagex.Graph()
100
+
101
+ # Source node
102
+ graph.add(source, label="Source", outputs=[("data", "shared_data")])
103
+
104
+ # Create parallel branches
105
+ graph.branch()
106
+ graph.add(branch_a, label="BranchA", inputs=[("shared_data", "x")], outputs=[("result_a", "a")])
107
+
108
+ graph.branch()
109
+ graph.add(branch_b, label="BranchB", inputs=[("shared_data", "x")], outputs=[("result_b", "b")])
110
+
111
+ graph.branch()
112
+ graph.add(branch_c, label="BranchC", inputs=[("shared_data", "x")], outputs=[("result_c", "c")])
113
+
114
+ dag = graph.build()
115
+ result = dag.execute(parallel=True)
116
+
117
+ print(f"Branch A (100*2): {result['a']}") # 200
118
+ print(f"Branch B (100*3): {result['b']}") # 300
119
+ print(f"Branch C (100+50): {result['c']}") # 150
120
+ ```
121
+
122
+ ### Visualization
123
+
124
+ Generate Mermaid diagrams to visualize your pipeline:
125
+
126
+ ```python
127
+ print(dag.to_mermaid())
128
+ ```
129
+
130
+ Output:
131
+ ```mermaid
132
+ graph TD
133
+ 0["Source"]
134
+ 1["BranchA"]
135
+ 2["BranchB"]
136
+ 3["BranchC"]
137
+ 0 -->|shared_data → x| 1
138
+ 0 -->|shared_data → x| 2
139
+ 0 -->|shared_data → x| 3
140
+ style 1 fill:#e1f5ff
141
+ style 2 fill:#e1f5ff
142
+ style 3 fill:#e1f5ff
143
+ ```
144
+
145
+ ## Working with NumPy Arrays
146
+
147
+ dagex seamlessly handles NumPy arrays and complex numbers:
148
+
149
+ ```python
150
+ import dagex
151
+ import numpy as np
152
+
153
+ def generate_signal(inputs, variant_params):
154
+ """Generate a complex signal"""
155
+ samples = 256
156
+ t = np.linspace(0, 1, samples)
157
+ signal = np.exp(2j * np.pi * 10 * t) # 10 Hz complex exponential
158
+ return {
159
+ "signal": signal, # numpy array passed directly
160
+ "num_samples": samples
161
+ }
162
+
163
+ def process_signal(inputs, variant_params):
164
+ """Process with FFT"""
165
+ signal = np.array(inputs["signal"], dtype=complex)
166
+ spectrum = np.fft.fft(signal)
167
+ magnitude = np.abs(spectrum)
168
+ peak_freq = np.argmax(magnitude)
169
+
170
+ return {
171
+ "spectrum": spectrum,
172
+ "peak_frequency": int(peak_freq)
173
+ }
174
+
175
+ graph = dagex.Graph()
176
+
177
+ graph.add(
178
+ generate_signal,
179
+ label="GenerateSignal",
180
+ outputs=[("signal", "sig"), ("num_samples", "n")]
181
+ )
182
+
183
+ graph.add(
184
+ process_signal,
185
+ label="ProcessSignal",
186
+ inputs=[("sig", "signal")],
187
+ outputs=[("spectrum", "spec"), ("peak_frequency", "peak")]
188
+ )
189
+
190
+ dag = graph.build()
191
+ result = dag.execute()
192
+
193
+ print(f"Peak frequency bin: {result['peak']}")
194
+ ```
195
+
196
+ ### Data Types
197
+
198
+ dagex supports any Python data type:
199
+
200
+ - **Primitives**: int, float, str, bool
201
+ - **Complex numbers**: Built-in `complex` and `numpy.complex128`
202
+ - **Collections**: list, dict, tuple
203
+ - **NumPy arrays**: All dtypes including complex arrays
204
+ - **Custom objects**: Any Python object can be passed through the graph
205
+
206
+ The framework doesn't impose type restrictions - your node functions determine what data flows through the pipeline.
207
+
208
+ ## API Reference
209
+
210
+ ### Graph
211
+
212
+ - `Graph()` - Create a new graph builder
213
+ - `graph.add(function, label=None, inputs=None, outputs=None)` - Add a node
214
+ - `function`: Callable with signature `(inputs: dict, variant_params: dict) -> dict`
215
+ - `label`: Optional node name (str)
216
+ - `inputs`: List of `(broadcast_var, node_input_var)` tuples
217
+ - `outputs`: List of `(node_output_var, broadcast_var)` tuples
218
+ - `graph.branch(subgraph=None)` - Create a parallel branch
219
+ - `graph.build()` - Build the DAG and return a `Dag` object
220
+
221
+ ### Dag
222
+
223
+ - `dag.execute(parallel=False, max_threads=None)` - Execute the graph
224
+ - `parallel`: Enable parallel execution of independent nodes
225
+ - `max_threads`: Limit concurrent threads (None = unlimited)
226
+ - Returns: `dict` with all broadcast variables
227
+ - `dag.to_mermaid()` - Generate Mermaid diagram (str)
228
+
229
+ ## Examples
230
+
231
+ The package includes several example scripts:
232
+
233
+ - **`python_demo.py`** - Basic pipeline construction
234
+ - **`python_comprehensive_demo.py`** - Multiple pipeline patterns
235
+ - **`python_parallel_demo.py`** - Parallel execution examples
236
+ - **`python_data_types_demo.py`** - Working with various data types
237
+ - **`python_radar_demo.py`** - Signal processing pipeline with NumPy
238
+
239
+ Find them in the [examples/py directory](https://github.com/briday1/dagex/tree/main/examples/py) on GitHub.
240
+
241
+ ## Performance Notes
242
+
243
+ - The DAG executor is written in Rust for performance
244
+ - Python functions are called from Rust with proper GIL handling
245
+ - Parallel execution releases the GIL during graph traversal
246
+ - For CPU-bound Python code, use libraries like NumPy that release the GIL internally
247
+ - Best performance gains with parallel execution of I/O-bound or NumPy-based operations
248
+
249
+ ## License
250
+
251
+ MIT License - see [LICENSE](https://github.com/briday1/dagex/blob/main/LICENSE) for details.
252
+
253
+ ## Links
254
+
255
+ - **GitHub**: https://github.com/briday1/dagex
256
+ - **Documentation**: https://docs.rs/dagex
257
+ - **PyPI**: https://pypi.org/project/dagex
258
+ - **Crates.io**: https://crates.io/crates/dagex
259
+
@@ -0,0 +1,5 @@
1
+ dagex-2026.8.dist-info/METADATA,sha256=FgXIpmz2KypSjb4HvPP6UsWxTy5I2LHPd0sen3SEscI,7099
2
+ dagex-2026.8.dist-info/WHEEL,sha256=QYlBbBRQuscZ0pEURJuEhuWwfV3--mdvcM36TkptLNA,106
3
+ dagex/__init__.py,sha256=uHbe0OdI2RMIcYORKDaI9JvEPcs3Iqxzy3Z5gpiCOiM,103
4
+ dagex/dagex.cpython-39-x86_64-linux-gnu.so,sha256=G4b0efZJlr_eNLQCrCYIk4xQ-cyre9dS-1CPDMboB8Y,871624
5
+ dagex-2026.8.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.2.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp39-cp39-manylinux_2_34_x86_64