feldera 0.96.0__tar.gz → 0.99.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.

Potentially problematic release.


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

Files changed (32) hide show
  1. {feldera-0.96.0 → feldera-0.99.0}/PKG-INFO +24 -6
  2. {feldera-0.96.0 → feldera-0.99.0}/README.md +21 -2
  3. feldera-0.99.0/feldera/enums.py +277 -0
  4. {feldera-0.96.0 → feldera-0.99.0}/feldera/pipeline.py +154 -133
  5. {feldera-0.96.0 → feldera-0.99.0}/feldera/pipeline_builder.py +4 -1
  6. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/feldera_client.py +58 -37
  7. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/pipeline.py +1 -0
  8. feldera-0.99.0/feldera/stats.py +149 -0
  9. {feldera-0.96.0 → feldera-0.99.0}/feldera.egg-info/PKG-INFO +24 -6
  10. {feldera-0.96.0 → feldera-0.99.0}/feldera.egg-info/SOURCES.txt +1 -0
  11. {feldera-0.96.0 → feldera-0.99.0}/pyproject.toml +3 -4
  12. {feldera-0.96.0 → feldera-0.99.0}/tests/test_pipeline.py +30 -8
  13. {feldera-0.96.0 → feldera-0.99.0}/tests/test_pipeline_builder.py +59 -89
  14. {feldera-0.96.0 → feldera-0.99.0}/tests/test_udf.py +2 -2
  15. {feldera-0.96.0 → feldera-0.99.0}/tests/test_variant.py +1 -1
  16. feldera-0.96.0/feldera/enums.py +0 -260
  17. {feldera-0.96.0 → feldera-0.99.0}/feldera/__init__.py +0 -0
  18. {feldera-0.96.0 → feldera-0.99.0}/feldera/_callback_runner.py +0 -0
  19. {feldera-0.96.0 → feldera-0.99.0}/feldera/_helpers.py +0 -0
  20. {feldera-0.96.0 → feldera-0.99.0}/feldera/output_handler.py +0 -0
  21. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/__init__.py +0 -0
  22. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/_httprequests.py +0 -0
  23. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/config.py +0 -0
  24. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/errors.py +0 -0
  25. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/feldera_config.py +0 -0
  26. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/sql_table.py +0 -0
  27. {feldera-0.96.0 → feldera-0.99.0}/feldera/rest/sql_view.py +0 -0
  28. {feldera-0.96.0 → feldera-0.99.0}/feldera/runtime_config.py +0 -0
  29. {feldera-0.96.0 → feldera-0.99.0}/feldera.egg-info/dependency_links.txt +0 -0
  30. {feldera-0.96.0 → feldera-0.99.0}/feldera.egg-info/requires.txt +0 -0
  31. {feldera-0.96.0 → feldera-0.99.0}/feldera.egg-info/top_level.txt +0 -0
  32. {feldera-0.96.0 → feldera-0.99.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: feldera
3
- Version: 0.96.0
3
+ Version: 0.99.0
4
4
  Summary: The feldera python client
5
5
  Author-email: Feldera Team <dev@feldera.com>
6
6
  License: MIT
@@ -10,10 +10,9 @@ Project-URL: Repository, https://github.com/feldera/feldera
10
10
  Project-URL: Issues, https://github.com/feldera/feldera/issues
11
11
  Keywords: feldera,python
12
12
  Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
15
14
  Classifier: Operating System :: OS Independent
16
- Requires-Python: >=3.10
15
+ Requires-Python: >=3.12
17
16
  Description-Content-Type: text/markdown
18
17
  Requires-Dist: requests
19
18
  Requires-Dist: pandas>=2.1.2
@@ -81,6 +80,8 @@ To run unit tests:
81
80
  (cd python && python3 -m unittest)
82
81
  ```
83
82
 
83
+ > ⚠️ Running the unit tests will **delete all existing pipelines**.
84
+
84
85
  The following command runs end-to-end tests. You'll need a pipeline
85
86
  manager running at `http://localhost:8080`. For the pipeline builder
86
87
  tests, you'll also need a broker available at `localhost:9092` and
@@ -88,13 +89,13 @@ tests, you'll also need a broker available at `localhost:9092` and
88
89
  set the environment variables listed in `python/tests/__init__.py`.)
89
90
 
90
91
  ```bash
91
- (cd python/tests && python3 -m pytest .)
92
+ (cd python && python3 -m pytest tests)
92
93
  ```
93
94
 
94
95
  To run tests from a specific file:
95
96
 
96
97
  ```bash
97
- (cd python/tests && python3 -m unittest ./tests/path-to-file.py)
98
+ (cd python && python3 -m unittest ./tests/path-to-file.py)
98
99
  ```
99
100
 
100
101
  To run the aggregate tests use:
@@ -103,3 +104,20 @@ To run the aggregate tests use:
103
104
  cd python
104
105
  PYTHONPATH=`pwd` python3 ./tests/aggregate_tests/main.py
105
106
  ```
107
+
108
+ ## Linting and formatting
109
+
110
+ Use [Ruff] to run the lint checks that will be executed by the
111
+ precommit hook when a PR is submitted:
112
+
113
+ ```bash
114
+ ruff check python/
115
+ ```
116
+
117
+ To reformat the code in the same way as the precommit hook:
118
+
119
+ ```bash
120
+ ruff format
121
+ ```
122
+
123
+ [Ruff]: https://github.com/astral-sh/ruff
@@ -57,6 +57,8 @@ To run unit tests:
57
57
  (cd python && python3 -m unittest)
58
58
  ```
59
59
 
60
+ > ⚠️ Running the unit tests will **delete all existing pipelines**.
61
+
60
62
  The following command runs end-to-end tests. You'll need a pipeline
61
63
  manager running at `http://localhost:8080`. For the pipeline builder
62
64
  tests, you'll also need a broker available at `localhost:9092` and
@@ -64,13 +66,13 @@ tests, you'll also need a broker available at `localhost:9092` and
64
66
  set the environment variables listed in `python/tests/__init__.py`.)
65
67
 
66
68
  ```bash
67
- (cd python/tests && python3 -m pytest .)
69
+ (cd python && python3 -m pytest tests)
68
70
  ```
69
71
 
70
72
  To run tests from a specific file:
71
73
 
72
74
  ```bash
73
- (cd python/tests && python3 -m unittest ./tests/path-to-file.py)
75
+ (cd python && python3 -m unittest ./tests/path-to-file.py)
74
76
  ```
75
77
 
76
78
  To run the aggregate tests use:
@@ -79,3 +81,20 @@ To run the aggregate tests use:
79
81
  cd python
80
82
  PYTHONPATH=`pwd` python3 ./tests/aggregate_tests/main.py
81
83
  ```
84
+
85
+ ## Linting and formatting
86
+
87
+ Use [Ruff] to run the lint checks that will be executed by the
88
+ precommit hook when a PR is submitted:
89
+
90
+ ```bash
91
+ ruff check python/
92
+ ```
93
+
94
+ To reformat the code in the same way as the precommit hook:
95
+
96
+ ```bash
97
+ ruff format
98
+ ```
99
+
100
+ [Ruff]: https://github.com/astral-sh/ruff
@@ -0,0 +1,277 @@
1
+ from enum import Enum
2
+ from typing import Optional
3
+
4
+
5
+ class CompilationProfile(Enum):
6
+ """
7
+ The compilation profile to use when compiling the program.
8
+ """
9
+
10
+ SERVER_DEFAULT = None
11
+ """
12
+ The compiler server default compilation profile.
13
+ """
14
+
15
+ DEV = "dev"
16
+ """
17
+ The development compilation profile.
18
+ """
19
+
20
+ UNOPTIMIZED = "unoptimized"
21
+ """
22
+ The unoptimized compilation profile.
23
+ """
24
+
25
+ OPTIMIZED = "optimized"
26
+ """
27
+ The optimized compilation profile, the default for this API.
28
+ """
29
+
30
+
31
+ class BuildMode(Enum):
32
+ CREATE = 1
33
+ GET = 2
34
+ GET_OR_CREATE = 3
35
+
36
+
37
+ class PipelineStatus(Enum):
38
+ """
39
+ Represents the state that this pipeline is currently in.
40
+
41
+ .. code-block:: text
42
+
43
+ Stopped ◄─────────── Stopping ◄───── All states can transition
44
+ │ ▲ to Stopping by either:
45
+ /start or /pause │ │ (1) user calling /stop?force=true, or;
46
+ ▼ │ (2) pipeline encountering a fatal
47
+ ⌛Provisioning Suspending resource or runtime error,
48
+ │ ▲ having the system call /stop?force=true
49
+ ▼ │ /stop effectively
50
+ ⌛Initializing ─────────────┤ ?force=false
51
+ │ │
52
+ ┌─────────┼────────────────────┴─────┐
53
+ │ ▼ │
54
+ │ Paused ◄──────► Unavailable │
55
+ │ │ ▲ ▲ │
56
+ │ /start │ │ /pause │ │
57
+ │ ▼ │ │ │
58
+ │ Running ◄─────────────┘ │
59
+ └────────────────────────────────────┘
60
+ """
61
+
62
+ NOT_FOUND = 0
63
+ """
64
+ The pipeline has not been created yet.
65
+ """
66
+
67
+ STOPPED = 1
68
+ """
69
+ The pipeline has not (yet) been started or has been stopped either
70
+ manually by the user or automatically by the system due to a
71
+ resource or runtime error.
72
+
73
+ The pipeline remains in this state until:
74
+
75
+ 1. The user starts it via `/start` or `/pause`, transitioning to `PROVISIONING`.
76
+ 2. Early start fails (e.g., compilation failure), transitioning to `STOPPING`.
77
+ """
78
+
79
+ PROVISIONING = 2
80
+ """
81
+ Compute (and optionally storage) resources needed for running the pipeline
82
+ are being provisioned.
83
+
84
+ The pipeline remains in this state until:
85
+
86
+ 1. Resources are provisioned successfully, transitioning to `INITIALIZING`.
87
+ 2. Provisioning fails or times out, transitioning to `STOPPING`.
88
+ 3. The user cancels the pipeline via `/stop`, transitioning to `STOPPING`.
89
+ """
90
+
91
+ INITIALIZING = 3
92
+ """
93
+ The pipeline is initializing its internal state and connectors.
94
+
95
+ The pipeline remains in this state until:
96
+
97
+ 1. Initialization succeeds, transitioning to `PAUSED`.
98
+ 2. Initialization fails or times out, transitioning to `STOPPING`.
99
+ 3. The user suspends the pipeline via `/suspend`, transitioning to `SUSPENDING`.
100
+ 4. The user stops the pipeline via `/stop`, transitioning to `STOPPING`.
101
+ """
102
+
103
+ PAUSED = 4
104
+ """
105
+ The pipeline is initialized but data processing is paused.
106
+
107
+ The pipeline remains in this state until:
108
+
109
+ 1. The user starts it via `/start`, transitioning to `RUNNING`.
110
+ 2. A runtime error occurs, transitioning to `STOPPING`.
111
+ 3. The user suspends it via `/suspend`, transitioning to `SUSPENDING`.
112
+ 4. The user stops it via `/stop`, transitioning to `STOPPING`.
113
+ """
114
+
115
+ RUNNING = 5
116
+ """
117
+ The pipeline is processing data.
118
+
119
+ The pipeline remains in this state until:
120
+
121
+ 1. The user pauses it via `/pause`, transitioning to `PAUSED`.
122
+ 2. A runtime error occurs, transitioning to `STOPPING`.
123
+ 3. The user suspends it via `/suspend`, transitioning to `SUSPENDING`.
124
+ 4. The user stops it via `/stop`, transitioning to `STOPPING`.
125
+ """
126
+
127
+ UNAVAILABLE = 6
128
+ """
129
+ The pipeline was initialized at least once but is currently unreachable
130
+ or not ready.
131
+
132
+ The pipeline remains in this state until:
133
+
134
+ 1. A successful status check transitions it back to `PAUSED` or `RUNNING`.
135
+ 2. A runtime error occurs, transitioning to `STOPPING`.
136
+ 3. The user suspends it via `/suspend`, transitioning to `SUSPENDING`.
137
+ 4. The user stops it via `/stop`, transitioning to `STOPPING`.
138
+
139
+ Note: While in this state, `/start` or `/pause` express desired state but
140
+ are only applied once the pipeline becomes reachable.
141
+ """
142
+
143
+ SUSPENDING = 7
144
+ """
145
+ The pipeline is being suspended to storage.
146
+
147
+ The pipeline remains in this state until:
148
+
149
+ 1. Suspension succeeds, transitioning to `STOPPING`.
150
+ 2. A runtime error occurs, transitioning to `STOPPING`.
151
+ """
152
+
153
+ STOPPING = 8
154
+ """
155
+ The pipeline's compute resources are being scaled down to zero.
156
+
157
+ The pipeline remains in this state until deallocation completes,
158
+ transitioning to `STOPPED`.
159
+ """
160
+
161
+ @staticmethod
162
+ def from_str(value):
163
+ for member in PipelineStatus:
164
+ if member.name.lower() == value.lower():
165
+ return member
166
+ raise ValueError(f"Unknown value '{value}' for enum {PipelineStatus.__name__}")
167
+
168
+ def __eq__(self, other):
169
+ return self.value == other.value
170
+
171
+
172
+ class ProgramStatus(Enum):
173
+ Pending = 1
174
+ CompilingSql = 2
175
+ SqlCompiled = 3
176
+ CompilingRust = 4
177
+ Success = 5
178
+ SqlError = 6
179
+ RustError = 7
180
+ SystemError = 8
181
+
182
+ def __init__(self, value):
183
+ self.error: Optional[dict] = None
184
+ self._value_ = value
185
+
186
+ @staticmethod
187
+ def from_value(value):
188
+ error = None
189
+ if isinstance(value, dict):
190
+ error = value
191
+ value = list(value.keys())[0]
192
+
193
+ for member in ProgramStatus:
194
+ if member.name.lower() == value.lower():
195
+ member.error = error
196
+ return member
197
+ raise ValueError(f"Unknown value '{value}' for enum {ProgramStatus.__name__}")
198
+
199
+ def __eq__(self, other):
200
+ return self.value == other.value
201
+
202
+ def __str__(self):
203
+ return self.name + (f": ({self.error})" if self.error else "")
204
+
205
+ def get_error(self) -> Optional[dict]:
206
+ """
207
+ Returns the compilation error, if any.
208
+ """
209
+
210
+ return self.error
211
+
212
+
213
+ class CheckpointStatus(Enum):
214
+ Success = 1
215
+ Failure = 2
216
+ InProgress = 3
217
+ Unknown = 4
218
+
219
+ def __init__(self, value):
220
+ self.error: Optional[str] = None
221
+ self._value_ = value
222
+
223
+ def __eq__(self, other):
224
+ return self.value == other.value
225
+
226
+ def get_error(self) -> Optional[str]:
227
+ """
228
+ Returns the error, if any.
229
+ """
230
+
231
+ return self.error
232
+
233
+
234
+ class StorageStatus(Enum):
235
+ """
236
+ Represents the current storage usage status of the pipeline.
237
+ """
238
+
239
+ CLEARED = 0
240
+ """
241
+ The pipeline has not been started before, or the user has cleared storage.
242
+
243
+ In this state, the pipeline has no storage resources bound to it.
244
+ """
245
+
246
+ INUSE = 1
247
+ """
248
+ The pipeline was (attempted to be) started before, transitioning from `STOPPED`
249
+ to `PROVISIONING`, which caused the storage status to become `INUSE`.
250
+
251
+ Being in the `INUSE` state restricts certain edits while the pipeline is `STOPPED`.
252
+
253
+ The pipeline remains in this state until the user invokes `/clear`, transitioning
254
+ it to `CLEARING`.
255
+ """
256
+
257
+ CLEARING = 2
258
+ """
259
+ The pipeline is in the process of becoming unbound from its storage resources.
260
+
261
+ If storage resources are configured to be deleted upon clearing, their deletion
262
+ occurs before transitioning to `CLEARED`. Otherwise, no actual work is required,
263
+ and the transition happens immediately.
264
+
265
+ If storage is not deleted during clearing, the responsibility to manage or delete
266
+ those resources lies with the user.
267
+ """
268
+
269
+ @staticmethod
270
+ def from_str(value):
271
+ for member in StorageStatus:
272
+ if member.name.lower() == value.lower():
273
+ return member
274
+ raise ValueError(f"Unknown value '{value}' for enum {StorageStatus.__name__}")
275
+
276
+ def __eq__(self, other):
277
+ return self.value == other.value