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.

Files changed (36) hide show
  1. {feldera-0.128.0 → feldera-0.130.0}/PKG-INFO +24 -7
  2. {feldera-0.128.0 → feldera-0.130.0}/README.md +23 -6
  3. {feldera-0.128.0 → feldera-0.130.0}/feldera/pipeline.py +19 -0
  4. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/_httprequests.py +15 -5
  5. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/config.py +3 -0
  6. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/feldera_client.py +31 -4
  7. {feldera-0.128.0 → feldera-0.130.0}/feldera/stats.py +3 -3
  8. {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/PKG-INFO +24 -7
  9. {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/SOURCES.txt +2 -0
  10. {feldera-0.128.0 → feldera-0.130.0}/pyproject.toml +1 -1
  11. feldera-0.130.0/tests/test_checkpoint_sync.py +320 -0
  12. feldera-0.130.0/tests/test_issue4457.py +57 -0
  13. {feldera-0.128.0 → feldera-0.130.0}/tests/test_shared_pipeline.py +11 -0
  14. feldera-0.130.0/tests/test_uda.py +283 -0
  15. feldera-0.128.0/tests/test_checkpoint_sync.py +0 -319
  16. {feldera-0.128.0 → feldera-0.130.0}/feldera/__init__.py +0 -0
  17. {feldera-0.128.0 → feldera-0.130.0}/feldera/_callback_runner.py +0 -0
  18. {feldera-0.128.0 → feldera-0.130.0}/feldera/_helpers.py +0 -0
  19. {feldera-0.128.0 → feldera-0.130.0}/feldera/enums.py +0 -0
  20. {feldera-0.128.0 → feldera-0.130.0}/feldera/output_handler.py +0 -0
  21. {feldera-0.128.0 → feldera-0.130.0}/feldera/pipeline_builder.py +0 -0
  22. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/__init__.py +0 -0
  23. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/_helpers.py +0 -0
  24. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/errors.py +0 -0
  25. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/feldera_config.py +0 -0
  26. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/pipeline.py +0 -0
  27. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/sql_table.py +0 -0
  28. {feldera-0.128.0 → feldera-0.130.0}/feldera/rest/sql_view.py +0 -0
  29. {feldera-0.128.0 → feldera-0.130.0}/feldera/runtime_config.py +0 -0
  30. {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/dependency_links.txt +0 -0
  31. {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/requires.txt +0 -0
  32. {feldera-0.128.0 → feldera-0.130.0}/feldera.egg-info/top_level.txt +0 -0
  33. {feldera-0.128.0 → feldera-0.130.0}/setup.cfg +0 -0
  34. {feldera-0.128.0 → feldera-0.130.0}/tests/test_pipeline_builder.py +0 -0
  35. {feldera-0.128.0 → feldera-0.130.0}/tests/test_shared_pipeline_stress.py +0 -0
  36. {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.128.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
- $ pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
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
- pip install python/
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
- #### Running Tests
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
- $ pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
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
- pip install python/
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
- #### Running Tests
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 client
55
- will wait for a response before timing
56
- out.
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, api_key, timeout=timeout, requests_verify=requests_verify
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.inputs = [
30
- OutputEndpointStatus().from_dict(output) for output in d["outputs"]
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.128.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
- $ pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
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
- pip install python/
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
- #### Running Tests
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
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
  name = "feldera"
7
7
  readme = "README.md"
8
8
  description = "The feldera python client"
9
- version = "0.128.0"
9
+ version = "0.130.0"
10
10
  license = { text = "MIT" }
11
11
  requires-python = ">=3.10"
12
12
  authors = [