feldera 0.128.0__tar.gz → 0.130.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.128.0 → feldera-0.130.0}/PKG-INFO +24 -7
- {feldera-0.128.0 → feldera-0.130.0}/README.md +23 -6
- {feldera-0.128.0 → feldera-0.130.0}/feldera/pipeline.py +19 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/_httprequests.py +15 -5
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/config.py +3 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/feldera_client.py +31 -4
- {feldera-0.128.0 → feldera-0.130.0}/feldera/stats.py +3 -3
- {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/PKG-INFO +24 -7
- {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/SOURCES.txt +2 -0
- {feldera-0.128.0 → feldera-0.130.0}/pyproject.toml +1 -1
- feldera-0.130.0/tests/test_checkpoint_sync.py +320 -0
- feldera-0.130.0/tests/test_issue4457.py +57 -0
- {feldera-0.128.0 → feldera-0.130.0}/tests/test_shared_pipeline.py +11 -0
- feldera-0.130.0/tests/test_uda.py +283 -0
- feldera-0.128.0/tests/test_checkpoint_sync.py +0 -319
- {feldera-0.128.0 → feldera-0.130.0}/feldera/__init__.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/_callback_runner.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/_helpers.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/enums.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/output_handler.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/pipeline_builder.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/__init__.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/_helpers.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/errors.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/feldera_config.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/pipeline.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/sql_table.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/sql_view.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera/runtime_config.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/dependency_links.txt +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/requires.txt +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/top_level.txt +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/setup.cfg +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/tests/test_pipeline_builder.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/tests/test_shared_pipeline_stress.py +0 -0
- {feldera-0.128.0 → feldera-0.130.0}/tests/test_udf.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.130.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -28,19 +28,19 @@ Feldera Python is the Feldera SDK for Python developers.
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
pip install feldera
|
|
31
|
+
uv pip install feldera
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
### Installing from Github
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
37
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Similarly, to install from a specific branch:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
|
|
43
|
+
uv pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Replace `{BRANCH_NAME}` with the name of the branch you want to install from.
|
|
@@ -51,7 +51,18 @@ If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
# the Feldera Python SDK is present inside the python/ directory
|
|
54
|
-
|
|
54
|
+
cd python
|
|
55
|
+
# If you don't have a virtual environment, create one
|
|
56
|
+
uv venv
|
|
57
|
+
source .venv/activate
|
|
58
|
+
# Install the SDK in editable mode
|
|
59
|
+
uv pip install .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You also have to install the `pytest` module:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python3 -m pip install pytest
|
|
55
66
|
```
|
|
56
67
|
|
|
57
68
|
## Documentation
|
|
@@ -61,7 +72,7 @@ The Python SDK documentation is available at
|
|
|
61
72
|
|
|
62
73
|
To build the html documentation run:
|
|
63
74
|
|
|
64
|
-
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
75
|
+
Ensure that you have sphinx installed. If not, install it using `uv pip install sphinx`.
|
|
65
76
|
|
|
66
77
|
Then run the following commands:
|
|
67
78
|
|
|
@@ -92,7 +103,13 @@ To run tests from a specific file:
|
|
|
92
103
|
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
93
104
|
```
|
|
94
105
|
|
|
95
|
-
|
|
106
|
+
To run a specific test:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run python -m pytest tests/test_shared_pipeline.py::TestPipeline::test_adhoc_query_hash -v
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Running All Tests
|
|
96
113
|
|
|
97
114
|
The tests validate end-to-end correctness of SQL functionality. To
|
|
98
115
|
run the tests use:
|
|
@@ -5,19 +5,19 @@ Feldera Python is the Feldera SDK for Python developers.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pip install feldera
|
|
8
|
+
uv pip install feldera
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
### Installing from Github
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
14
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Similarly, to install from a specific branch:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
uv pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Replace `{BRANCH_NAME}` with the name of the branch you want to install from.
|
|
@@ -28,7 +28,18 @@ If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
# the Feldera Python SDK is present inside the python/ directory
|
|
31
|
-
|
|
31
|
+
cd python
|
|
32
|
+
# If you don't have a virtual environment, create one
|
|
33
|
+
uv venv
|
|
34
|
+
source .venv/activate
|
|
35
|
+
# Install the SDK in editable mode
|
|
36
|
+
uv pip install .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
You also have to install the `pytest` module:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python3 -m pip install pytest
|
|
32
43
|
```
|
|
33
44
|
|
|
34
45
|
## Documentation
|
|
@@ -38,7 +49,7 @@ The Python SDK documentation is available at
|
|
|
38
49
|
|
|
39
50
|
To build the html documentation run:
|
|
40
51
|
|
|
41
|
-
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
52
|
+
Ensure that you have sphinx installed. If not, install it using `uv pip install sphinx`.
|
|
42
53
|
|
|
43
54
|
Then run the following commands:
|
|
44
55
|
|
|
@@ -69,7 +80,13 @@ To run tests from a specific file:
|
|
|
69
80
|
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
70
81
|
```
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
To run a specific test:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv run python -m pytest tests/test_shared_pipeline.py::TestPipeline::test_adhoc_query_hash -v
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Running All Tests
|
|
73
90
|
|
|
74
91
|
The tests validate end-to-end correctness of SQL functionality. To
|
|
75
92
|
run the tests use:
|
|
@@ -809,6 +809,25 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
809
809
|
|
|
810
810
|
return self.client.query_as_text(self.name, query)
|
|
811
811
|
|
|
812
|
+
def query_hash(self, query: str):
|
|
813
|
+
"""
|
|
814
|
+
Executes an ad-hoc SQL query on this pipeline and returns the result
|
|
815
|
+
as a hash of the result set. This is useful for quickly checking
|
|
816
|
+
if the result set has changed without retrieving the entire result.
|
|
817
|
+
|
|
818
|
+
Note:
|
|
819
|
+
For a stable hash, the query must be deterministic which means
|
|
820
|
+
it should be sorted.
|
|
821
|
+
|
|
822
|
+
:param query: The SQL query to be executed.
|
|
823
|
+
|
|
824
|
+
:raises FelderaAPIError: If the pipeline is not in a RUNNING or PAUSED
|
|
825
|
+
state.
|
|
826
|
+
:raises FelderaAPIError: If querying a non materialized table or view.
|
|
827
|
+
:raises FelderaAPIError: If the query is invalid.
|
|
828
|
+
"""
|
|
829
|
+
return self.client.query_as_hash(self.name, query)
|
|
830
|
+
|
|
812
831
|
def execute(self, query: str):
|
|
813
832
|
"""
|
|
814
833
|
Executes an ad-hoc SQL query on the current pipeline, discarding its
|
|
@@ -57,6 +57,7 @@ class HttpRequests:
|
|
|
57
57
|
self.headers["Content-Type"] = content_type
|
|
58
58
|
|
|
59
59
|
try:
|
|
60
|
+
conn_timeout = self.config.connection_timeout
|
|
60
61
|
timeout = self.config.timeout
|
|
61
62
|
headers = self.headers
|
|
62
63
|
|
|
@@ -74,7 +75,7 @@ class HttpRequests:
|
|
|
74
75
|
if http_method.__name__ == "get":
|
|
75
76
|
request = http_method(
|
|
76
77
|
request_path,
|
|
77
|
-
timeout=timeout,
|
|
78
|
+
timeout=(conn_timeout, timeout),
|
|
78
79
|
headers=headers,
|
|
79
80
|
params=params,
|
|
80
81
|
stream=stream,
|
|
@@ -83,7 +84,7 @@ class HttpRequests:
|
|
|
83
84
|
elif isinstance(body, bytes):
|
|
84
85
|
request = http_method(
|
|
85
86
|
request_path,
|
|
86
|
-
timeout=timeout,
|
|
87
|
+
timeout=(conn_timeout, timeout),
|
|
87
88
|
headers=headers,
|
|
88
89
|
data=body,
|
|
89
90
|
params=params,
|
|
@@ -93,7 +94,7 @@ class HttpRequests:
|
|
|
93
94
|
else:
|
|
94
95
|
request = http_method(
|
|
95
96
|
request_path,
|
|
96
|
-
timeout=timeout,
|
|
97
|
+
timeout=(conn_timeout, timeout),
|
|
97
98
|
headers=headers,
|
|
98
99
|
data=json_serialize(body) if serialize else body,
|
|
99
100
|
params=params,
|
|
@@ -118,9 +119,18 @@ class HttpRequests:
|
|
|
118
119
|
time.sleep(2) # backoff, adjust as needed
|
|
119
120
|
continue
|
|
120
121
|
raise # re-raise for all other errors or if out of retries
|
|
122
|
+
except requests.exceptions.Timeout as err:
|
|
123
|
+
if attempt < max_retries:
|
|
124
|
+
logging.warning(
|
|
125
|
+
"HTTP Connection Timeout for %s, retrying (%d/%d)...",
|
|
126
|
+
path,
|
|
127
|
+
attempt + 1,
|
|
128
|
+
max_retries,
|
|
129
|
+
)
|
|
130
|
+
time.sleep(2)
|
|
131
|
+
continue
|
|
132
|
+
raise FelderaTimeoutError(str(err)) from err
|
|
121
133
|
|
|
122
|
-
except requests.exceptions.Timeout as err:
|
|
123
|
-
raise FelderaTimeoutError(str(err)) from err
|
|
124
134
|
except requests.exceptions.ConnectionError as err:
|
|
125
135
|
raise FelderaCommunicationError(str(err)) from err
|
|
126
136
|
|
|
@@ -12,6 +12,7 @@ class Config:
|
|
|
12
12
|
api_key: Optional[str] = None,
|
|
13
13
|
version: Optional[str] = None,
|
|
14
14
|
timeout: Optional[float] = None,
|
|
15
|
+
connection_timeout: Optional[float] = None,
|
|
15
16
|
requests_verify: bool = True,
|
|
16
17
|
) -> None:
|
|
17
18
|
"""
|
|
@@ -19,6 +20,7 @@ class Config:
|
|
|
19
20
|
:param api_key: The optional API key to access Feldera
|
|
20
21
|
:param version: The version of the API to use
|
|
21
22
|
:param timeout: The timeout for the HTTP requests
|
|
23
|
+
:param connection_timeout: The connection timeout for the HTTP requests
|
|
22
24
|
:param requests_verify: The `verify` parameter passed to the requests
|
|
23
25
|
library. `True` by default.
|
|
24
26
|
"""
|
|
@@ -27,4 +29,5 @@ class Config:
|
|
|
27
29
|
self.api_key: Optional[str] = api_key
|
|
28
30
|
self.version: Optional[str] = version or "v0"
|
|
29
31
|
self.timeout: Optional[float] = timeout
|
|
32
|
+
self.connection_timeout: Optional[float] = connection_timeout
|
|
30
33
|
self.requests_verify: bool = requests_verify
|
|
@@ -46,20 +46,26 @@ class FelderaClient:
|
|
|
46
46
|
url: str,
|
|
47
47
|
api_key: Optional[str] = None,
|
|
48
48
|
timeout: Optional[float] = None,
|
|
49
|
+
connection_timeout: Optional[float] = None,
|
|
49
50
|
requests_verify: bool = True,
|
|
50
51
|
) -> None:
|
|
51
52
|
"""
|
|
52
53
|
:param url: The url to Feldera API (ex: https://try.feldera.com)
|
|
53
54
|
:param api_key: The optional API key for Feldera
|
|
54
|
-
:param timeout: (optional) The amount of time in seconds that the
|
|
55
|
-
will wait for a response before timing
|
|
56
|
-
|
|
55
|
+
:param timeout: (optional) The amount of time in seconds that the
|
|
56
|
+
client will wait for a response before timing out.
|
|
57
|
+
:param connection_timeout: (optional) The amount of time in seconds that
|
|
58
|
+
the client will wait to establish connection before timing out.
|
|
57
59
|
:param requests_verify: The `verify` parameter passed to the requests
|
|
58
60
|
library. `True` by default.
|
|
59
61
|
"""
|
|
60
62
|
|
|
61
63
|
self.config = Config(
|
|
62
|
-
url,
|
|
64
|
+
url,
|
|
65
|
+
api_key,
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
connection_timeout=connection_timeout,
|
|
68
|
+
requests_verify=requests_verify,
|
|
63
69
|
)
|
|
64
70
|
self.http = HttpRequests(self.config)
|
|
65
71
|
|
|
@@ -895,6 +901,27 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
895
901
|
if chunk:
|
|
896
902
|
yield chunk.decode("utf-8")
|
|
897
903
|
|
|
904
|
+
def query_as_hash(self, pipeline_name: str, query: str) -> str:
|
|
905
|
+
"""
|
|
906
|
+
Executes an ad-hoc query on the specified pipeline and returns a hash of the result.
|
|
907
|
+
|
|
908
|
+
:param pipeline_name: The name of the pipeline to query.
|
|
909
|
+
:param query: The SQL query to be executed.
|
|
910
|
+
:return: A string containing the hash of the query result.
|
|
911
|
+
"""
|
|
912
|
+
params = {
|
|
913
|
+
"pipeline_name": pipeline_name,
|
|
914
|
+
"sql": query,
|
|
915
|
+
"format": "hash",
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
resp = self.http.get(
|
|
919
|
+
path=f"/pipelines/{pipeline_name}/query",
|
|
920
|
+
params=params,
|
|
921
|
+
stream=False,
|
|
922
|
+
)
|
|
923
|
+
return resp
|
|
924
|
+
|
|
898
925
|
def query_as_parquet(self, pipeline_name: str, query: str, path: str):
|
|
899
926
|
"""
|
|
900
927
|
Executes an ad-hoc query on the specified pipeline and saves the result to a parquet file.
|
|
@@ -26,8 +26,8 @@ class PipelineStatistics:
|
|
|
26
26
|
pipeline.inputs = [
|
|
27
27
|
InputEndpointStatus.from_dict(input) for input in d["inputs"]
|
|
28
28
|
]
|
|
29
|
-
pipeline.
|
|
30
|
-
OutputEndpointStatus
|
|
29
|
+
pipeline.outputs = [
|
|
30
|
+
OutputEndpointStatus.from_dict(output) for output in d["outputs"]
|
|
31
31
|
]
|
|
32
32
|
return pipeline
|
|
33
33
|
|
|
@@ -46,7 +46,7 @@ class GlobalPipelineMetrics:
|
|
|
46
46
|
self.rss_bytes: Optional[int] = None
|
|
47
47
|
self.cpu_msecs: Optional[int] = None
|
|
48
48
|
self.start_time: Optional[datetime] = None
|
|
49
|
-
self.incarnation_uuid: Optional[uuid] = None
|
|
49
|
+
self.incarnation_uuid: Optional[uuid.UUID] = None
|
|
50
50
|
self.storage_bytes: Optional[int] = None
|
|
51
51
|
self.storage_mb_secs: Optional[int] = None
|
|
52
52
|
self.runtime_elapsed_msecs: Optional[int] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.130.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -28,19 +28,19 @@ Feldera Python is the Feldera SDK for Python developers.
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
pip install feldera
|
|
31
|
+
uv pip install feldera
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
### Installing from Github
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
37
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Similarly, to install from a specific branch:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
|
|
43
|
+
uv pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Replace `{BRANCH_NAME}` with the name of the branch you want to install from.
|
|
@@ -51,7 +51,18 @@ If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
# the Feldera Python SDK is present inside the python/ directory
|
|
54
|
-
|
|
54
|
+
cd python
|
|
55
|
+
# If you don't have a virtual environment, create one
|
|
56
|
+
uv venv
|
|
57
|
+
source .venv/activate
|
|
58
|
+
# Install the SDK in editable mode
|
|
59
|
+
uv pip install .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You also have to install the `pytest` module:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python3 -m pip install pytest
|
|
55
66
|
```
|
|
56
67
|
|
|
57
68
|
## Documentation
|
|
@@ -61,7 +72,7 @@ The Python SDK documentation is available at
|
|
|
61
72
|
|
|
62
73
|
To build the html documentation run:
|
|
63
74
|
|
|
64
|
-
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
75
|
+
Ensure that you have sphinx installed. If not, install it using `uv pip install sphinx`.
|
|
65
76
|
|
|
66
77
|
Then run the following commands:
|
|
67
78
|
|
|
@@ -92,7 +103,13 @@ To run tests from a specific file:
|
|
|
92
103
|
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
93
104
|
```
|
|
94
105
|
|
|
95
|
-
|
|
106
|
+
To run a specific test:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv run python -m pytest tests/test_shared_pipeline.py::TestPipeline::test_adhoc_query_hash -v
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Running All Tests
|
|
96
113
|
|
|
97
114
|
The tests validate end-to-end correctness of SQL functionality. To
|
|
98
115
|
run the tests use:
|
|
@@ -25,7 +25,9 @@ feldera/rest/pipeline.py
|
|
|
25
25
|
feldera/rest/sql_table.py
|
|
26
26
|
feldera/rest/sql_view.py
|
|
27
27
|
tests/test_checkpoint_sync.py
|
|
28
|
+
tests/test_issue4457.py
|
|
28
29
|
tests/test_pipeline_builder.py
|
|
29
30
|
tests/test_shared_pipeline.py
|
|
30
31
|
tests/test_shared_pipeline_stress.py
|
|
32
|
+
tests/test_uda.py
|
|
31
33
|
tests/test_udf.py
|