feldera 0.99.0__tar.gz → 0.100.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.
- {feldera-0.99.0 → feldera-0.100.0}/PKG-INFO +3 -3
- {feldera-0.99.0 → feldera-0.100.0}/feldera/__init__.py +3 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/enums.py +22 -21
- {feldera-0.99.0 → feldera-0.100.0}/feldera/pipeline.py +5 -15
- {feldera-0.99.0 → feldera-0.100.0}/feldera/pipeline_builder.py +9 -3
- feldera-0.100.0/feldera/rest/_helpers.py +9 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/feldera_client.py +12 -13
- {feldera-0.99.0 → feldera-0.100.0}/feldera.egg-info/PKG-INFO +3 -3
- {feldera-0.99.0 → feldera-0.100.0}/feldera.egg-info/SOURCES.txt +1 -0
- {feldera-0.99.0 → feldera-0.100.0}/pyproject.toml +3 -3
- {feldera-0.99.0 → feldera-0.100.0}/README.md +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/_callback_runner.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/_helpers.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/output_handler.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/__init__.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/_httprequests.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/config.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/errors.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/feldera_config.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/pipeline.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/sql_table.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/rest/sql_view.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/runtime_config.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera/stats.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera.egg-info/dependency_links.txt +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera.egg-info/requires.txt +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/feldera.egg-info/top_level.txt +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/setup.cfg +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/tests/test_pipeline.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/tests/test_pipeline_builder.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/tests/test_udf.py +0 -0
- {feldera-0.99.0 → feldera-0.100.0}/tests/test_variant.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.100.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,9 +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.
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
Requires-Dist: requests
|
|
18
18
|
Requires-Dist: pandas>=2.1.2
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from feldera.rest.feldera_client import FelderaClient as FelderaClient
|
|
2
2
|
from feldera.pipeline import Pipeline as Pipeline
|
|
3
3
|
from feldera.pipeline_builder import PipelineBuilder as PipelineBuilder
|
|
4
|
+
from feldera.rest._helpers import client_version
|
|
5
|
+
|
|
6
|
+
__version__ = client_version()
|
|
4
7
|
|
|
5
8
|
import pretty_errors
|
|
6
9
|
|
|
@@ -36,27 +36,28 @@ class BuildMode(Enum):
|
|
|
36
36
|
|
|
37
37
|
class PipelineStatus(Enum):
|
|
38
38
|
"""
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
|
|
60
61
|
"""
|
|
61
62
|
|
|
62
63
|
NOT_FOUND = 0
|
|
@@ -111,9 +111,7 @@ class Pipeline:
|
|
|
111
111
|
tbl.name.lower() for tbl in pipeline.tables
|
|
112
112
|
]:
|
|
113
113
|
raise ValueError(
|
|
114
|
-
f"Cannot push to table '{
|
|
115
|
-
table_name
|
|
116
|
-
}': table with this name does not exist in the '{self.name}' pipeline"
|
|
114
|
+
f"Cannot push to table '{table_name}': table with this name does not exist in the '{self.name}' pipeline"
|
|
117
115
|
)
|
|
118
116
|
else:
|
|
119
117
|
# consider validating the schema here
|
|
@@ -308,14 +306,10 @@ class Pipeline:
|
|
|
308
306
|
elapsed = time.monotonic() - start_time
|
|
309
307
|
if elapsed > timeout_s:
|
|
310
308
|
raise TimeoutError(
|
|
311
|
-
f"timeout ({timeout_s}s) reached while waiting for pipeline '{
|
|
312
|
-
self.name
|
|
313
|
-
}' to complete"
|
|
309
|
+
f"timeout ({timeout_s}s) reached while waiting for pipeline '{self.name}' to complete"
|
|
314
310
|
)
|
|
315
311
|
logging.debug(
|
|
316
|
-
f"waiting for pipeline {self.name} to complete: elapsed time {
|
|
317
|
-
elapsed
|
|
318
|
-
}s, timeout: {timeout_s}s"
|
|
312
|
+
f"waiting for pipeline {self.name} to complete: elapsed time {elapsed}s, timeout: {timeout_s}s"
|
|
319
313
|
)
|
|
320
314
|
|
|
321
315
|
pipeline_complete: bool = self.stats().global_metrics.pipeline_complete
|
|
@@ -402,15 +396,11 @@ method or use `Pipeline.resume()` to resume a paused pipeline."""
|
|
|
402
396
|
"""
|
|
403
397
|
if idle_interval_s > timeout_s:
|
|
404
398
|
raise ValueError(
|
|
405
|
-
f"idle interval ({idle_interval_s}s) cannot be larger than timeout ({
|
|
406
|
-
timeout_s
|
|
407
|
-
}s)"
|
|
399
|
+
f"idle interval ({idle_interval_s}s) cannot be larger than timeout ({timeout_s}s)"
|
|
408
400
|
)
|
|
409
401
|
if poll_interval_s > timeout_s:
|
|
410
402
|
raise ValueError(
|
|
411
|
-
f"poll interval ({poll_interval_s}s) cannot be larger than timeout ({
|
|
412
|
-
timeout_s
|
|
413
|
-
}s)"
|
|
403
|
+
f"poll interval ({poll_interval_s}s) cannot be larger than timeout ({timeout_s}s)"
|
|
414
404
|
)
|
|
415
405
|
if poll_interval_s > idle_interval_s:
|
|
416
406
|
raise ValueError(
|
|
@@ -50,8 +50,12 @@ class PipelineBuilder:
|
|
|
50
50
|
if self.name is None or self.sql is None:
|
|
51
51
|
raise ValueError("Name and SQL are required to create a pipeline")
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
try:
|
|
54
|
+
if self.client.get_pipeline(self.name) is not None:
|
|
55
|
+
raise RuntimeError(f"Pipeline with name {self.name} already exists")
|
|
56
|
+
except FelderaAPIError as err:
|
|
57
|
+
if err.error_code != "UnknownPipelineName":
|
|
58
|
+
raise err
|
|
55
59
|
|
|
56
60
|
inner = InnerPipeline(
|
|
57
61
|
self.name,
|
|
@@ -62,7 +66,9 @@ class PipelineBuilder:
|
|
|
62
66
|
program_config={
|
|
63
67
|
"profile": self.compilation_profile.value,
|
|
64
68
|
},
|
|
65
|
-
runtime_config=
|
|
69
|
+
runtime_config=dict(
|
|
70
|
+
(k, v) for k, v in self.runtime_config.__dict__.items() if v is not None
|
|
71
|
+
),
|
|
66
72
|
)
|
|
67
73
|
|
|
68
74
|
inner = self.client.create_pipeline(inner)
|
|
@@ -11,6 +11,7 @@ from feldera.rest.feldera_config import FelderaConfig
|
|
|
11
11
|
from feldera.rest.errors import FelderaTimeoutError
|
|
12
12
|
from feldera.rest.pipeline import Pipeline
|
|
13
13
|
from feldera.rest._httprequests import HttpRequests
|
|
14
|
+
from feldera.rest._helpers import client_version
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def _validate_no_none_keys_in_map(data):
|
|
@@ -63,7 +64,13 @@ class FelderaClient:
|
|
|
63
64
|
self.http = HttpRequests(self.config)
|
|
64
65
|
|
|
65
66
|
try:
|
|
66
|
-
self.
|
|
67
|
+
config = self.get_config()
|
|
68
|
+
version = client_version()
|
|
69
|
+
if config.version != version:
|
|
70
|
+
logging.warn(
|
|
71
|
+
f"Client is on version {version} while server is at "
|
|
72
|
+
f"{config.version}. There could be incompatibilities."
|
|
73
|
+
)
|
|
67
74
|
except Exception as e:
|
|
68
75
|
logging.error(f"Failed to connect to Feldera API: {e}")
|
|
69
76
|
raise e
|
|
@@ -358,9 +365,7 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
358
365
|
time.sleep(0.1)
|
|
359
366
|
|
|
360
367
|
raise FelderaTimeoutError(
|
|
361
|
-
f"timeout error: pipeline '{pipeline_name}' did not stop in {
|
|
362
|
-
timeout_s
|
|
363
|
-
} seconds"
|
|
368
|
+
f"timeout error: pipeline '{pipeline_name}' did not stop in {timeout_s} seconds"
|
|
364
369
|
)
|
|
365
370
|
|
|
366
371
|
def clear_storage(self, pipeline_name: str, timeout_s: Optional[float] = 300):
|
|
@@ -394,9 +399,7 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
394
399
|
time.sleep(0.1)
|
|
395
400
|
|
|
396
401
|
raise FelderaTimeoutError(
|
|
397
|
-
f"timeout error: pipeline '{pipeline_name}' did not clear storage in {
|
|
398
|
-
timeout_s
|
|
399
|
-
} seconds"
|
|
402
|
+
f"timeout error: pipeline '{pipeline_name}' did not clear storage in {timeout_s} seconds"
|
|
400
403
|
)
|
|
401
404
|
|
|
402
405
|
def checkpoint_pipeline(self, pipeline_name: str) -> int:
|
|
@@ -702,9 +705,7 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
702
705
|
"""
|
|
703
706
|
|
|
704
707
|
self.http.post(
|
|
705
|
-
path=f"/pipelines/{pipeline_name}/tables/{table_name}/connectors/{
|
|
706
|
-
connector_name
|
|
707
|
-
}/pause",
|
|
708
|
+
path=f"/pipelines/{pipeline_name}/tables/{table_name}/connectors/{connector_name}/pause",
|
|
708
709
|
)
|
|
709
710
|
|
|
710
711
|
def resume_connector(
|
|
@@ -728,9 +729,7 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
728
729
|
"""
|
|
729
730
|
|
|
730
731
|
self.http.post(
|
|
731
|
-
path=f"/pipelines/{pipeline_name}/tables/{table_name}/connectors/{
|
|
732
|
-
connector_name
|
|
733
|
-
}/start",
|
|
732
|
+
path=f"/pipelines/{pipeline_name}/tables/{table_name}/connectors/{connector_name}/start",
|
|
734
733
|
)
|
|
735
734
|
|
|
736
735
|
def get_config(self) -> FelderaConfig:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.100.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,9 +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.
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
14
|
Classifier: Operating System :: OS Independent
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
Requires-Dist: requests
|
|
18
18
|
Requires-Dist: pandas>=2.1.2
|
|
@@ -6,9 +6,9 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
name = "feldera"
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
description = "The feldera python client"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.100.0"
|
|
10
10
|
license = { text = "MIT" }
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
12
|
authors = [
|
|
13
13
|
{ "name" = "Feldera Team", "email" = "dev@feldera.com" },
|
|
14
14
|
]
|
|
@@ -18,7 +18,7 @@ keywords = [
|
|
|
18
18
|
]
|
|
19
19
|
classifiers = [
|
|
20
20
|
"License :: OSI Approved :: MIT License",
|
|
21
|
-
"Programming Language :: Python :: 3.
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
22
|
"Operating System :: OS Independent",
|
|
23
23
|
]
|
|
24
24
|
dependencies = [
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|