feldera 0.159.0__tar.gz → 0.161.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.159.0 → feldera-0.161.0}/PKG-INFO +1 -1
  2. {feldera-0.159.0 → feldera-0.161.0}/feldera/pipeline.py +49 -0
  3. feldera-0.161.0/feldera/rest/_helpers.py +40 -0
  4. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/_httprequests.py +8 -0
  5. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/config.py +13 -9
  6. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/feldera_client.py +17 -2
  7. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/pipeline.py +1 -0
  8. {feldera-0.159.0 → feldera-0.161.0}/feldera/runtime_config.py +2 -0
  9. {feldera-0.159.0 → feldera-0.161.0}/feldera/testutils.py +2 -6
  10. {feldera-0.159.0 → feldera-0.161.0}/feldera.egg-info/PKG-INFO +1 -1
  11. {feldera-0.159.0 → feldera-0.161.0}/pyproject.toml +1 -1
  12. feldera-0.159.0/feldera/rest/_helpers.py +0 -9
  13. {feldera-0.159.0 → feldera-0.161.0}/README.md +0 -0
  14. {feldera-0.159.0 → feldera-0.161.0}/feldera/__init__.py +0 -0
  15. {feldera-0.159.0 → feldera-0.161.0}/feldera/_callback_runner.py +0 -0
  16. {feldera-0.159.0 → feldera-0.161.0}/feldera/_helpers.py +0 -0
  17. {feldera-0.159.0 → feldera-0.161.0}/feldera/enums.py +0 -0
  18. {feldera-0.159.0 → feldera-0.161.0}/feldera/output_handler.py +0 -0
  19. {feldera-0.159.0 → feldera-0.161.0}/feldera/pipeline_builder.py +0 -0
  20. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/__init__.py +0 -0
  21. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/errors.py +0 -0
  22. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/feldera_config.py +0 -0
  23. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/sql_table.py +0 -0
  24. {feldera-0.159.0 → feldera-0.161.0}/feldera/rest/sql_view.py +0 -0
  25. {feldera-0.159.0 → feldera-0.161.0}/feldera/stats.py +0 -0
  26. {feldera-0.159.0 → feldera-0.161.0}/feldera/tests/test_datafusionize.py +0 -0
  27. {feldera-0.159.0 → feldera-0.161.0}/feldera/testutils_oidc.py +0 -0
  28. {feldera-0.159.0 → feldera-0.161.0}/feldera.egg-info/SOURCES.txt +0 -0
  29. {feldera-0.159.0 → feldera-0.161.0}/feldera.egg-info/dependency_links.txt +0 -0
  30. {feldera-0.159.0 → feldera-0.161.0}/feldera.egg-info/requires.txt +0 -0
  31. {feldera-0.159.0 → feldera-0.161.0}/feldera.egg-info/top_level.txt +0 -0
  32. {feldera-0.159.0 → feldera-0.161.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: feldera
3
- Version: 0.159.0
3
+ Version: 0.161.0
4
4
  Summary: The feldera python client
5
5
  Author-email: Feldera Team <dev@feldera.com>
6
6
  License: MIT
@@ -931,6 +931,35 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
931
931
  description=description,
932
932
  )
933
933
 
934
+ def update_runtime(self):
935
+ """
936
+ Recompile a pipeline with the Feldera runtime version included in the
937
+ currently installed Feldera platform.
938
+
939
+ Use this endpoint after upgrading Feldera to rebuild pipelines that were
940
+ compiled with older platform versions. In most cases, recompilation is not
941
+ required—pipelines compiled with older versions will continue to run on the
942
+ upgraded platform.
943
+
944
+ Situations where recompilation may be necessary:
945
+ - To benefit from the latest bug fixes and performance optimizations.
946
+ - When backward-incompatible changes are introduced in Feldera. In this case,
947
+ attempting to start a pipeline compiled with an unsupported version will
948
+ result in an error.
949
+
950
+ If the pipeline is already compiled with the current platform version,
951
+ this operation is a no-op.
952
+
953
+ Note that recompiling the pipeline with a new platform version may change its
954
+ query plan. If the modified pipeline is started from an existing checkpoint,
955
+ it may require bootstrapping parts of its state from scratch. See Feldera
956
+ documentation for details on the bootstrapping process.
957
+
958
+ :raises FelderaAPIError: If the pipeline is not in a STOPPED state.
959
+ """
960
+
961
+ self.client.update_pipeline_runtime(self._inner.name)
962
+
934
963
  def storage_status(self) -> StorageStatus:
935
964
  """
936
965
  Return the storage status of the pipeline.
@@ -951,6 +980,18 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
951
980
  self.refresh(PipelineFieldSelector.STATUS)
952
981
  return ProgramStatus.from_value(self._inner.program_status)
953
982
 
983
+ def testing_force_update_platform_version(self, platform_version: str):
984
+ """
985
+ Used to simulate a pipeline compiled with a different platform version than the one currently in use.
986
+ This is useful for testing platform upgrade behavior without actually upgrading Feldera.
987
+
988
+ This method is only available when Feldera runs with the "testing" unstable feature enabled.
989
+ """
990
+
991
+ self.client.testing_force_update_platform_version(
992
+ name=self._inner.name, platform_version=platform_version
993
+ )
994
+
954
995
  def program_status_since(self) -> datetime:
955
996
  """
956
997
  Return the timestamp when the current program status was set.
@@ -959,6 +1000,14 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
959
1000
  self.refresh(PipelineFieldSelector.STATUS)
960
1001
  return datetime.fromisoformat(self._inner.program_status_since)
961
1002
 
1003
+ def platform_version(self) -> str:
1004
+ """
1005
+ Return the Feldera platform witch which the program was compiled.
1006
+ """
1007
+
1008
+ self.refresh(PipelineFieldSelector.STATUS)
1009
+ return self._inner.platform_version
1010
+
962
1011
  def udf_rust(self) -> str:
963
1012
  """
964
1013
  Return the Rust code for UDFs.
@@ -0,0 +1,40 @@
1
+ import logging
2
+ import os
3
+
4
+
5
+ def client_version() -> str:
6
+ from importlib.metadata import version, PackageNotFoundError
7
+
8
+ try:
9
+ version = version("feldera")
10
+ except PackageNotFoundError:
11
+ version = "unknown"
12
+
13
+ return version
14
+
15
+
16
+ def requests_verify_from_env() -> str | bool:
17
+ env_feldera_tls_insecure = os.environ.get("FELDERA_TLS_INSECURE")
18
+ FELDERA_HTTPS_TLS_CERT = os.environ.get("FELDERA_HTTPS_TLS_CERT")
19
+
20
+ if env_feldera_tls_insecure is not None and FELDERA_HTTPS_TLS_CERT is not None:
21
+ logging.warning(
22
+ "environment variables FELDERA_HTTPS_TLS_CERT and "
23
+ "FELDERA_TLS_INSECURE both are set."
24
+ "\nFELDERA_HTTPS_TLS_CERT takes priority."
25
+ )
26
+
27
+ if env_feldera_tls_insecure is None:
28
+ FELDERA_TLS_INSECURE = False
29
+ else:
30
+ FELDERA_TLS_INSECURE = env_feldera_tls_insecure.strip().lower() in (
31
+ "1",
32
+ "true",
33
+ "yes",
34
+ )
35
+
36
+ requests_verify = not FELDERA_TLS_INSECURE
37
+ if FELDERA_HTTPS_TLS_CERT is not None:
38
+ requests_verify = FELDERA_HTTPS_TLS_CERT
39
+
40
+ return requests_verify
@@ -56,6 +56,8 @@ class HttpRequests:
56
56
  """
57
57
  self.headers["Content-Type"] = content_type
58
58
 
59
+ prev_resp: Optional[requests.Response] = None
60
+
59
61
  try:
60
62
  conn_timeout = self.config.connection_timeout
61
63
  timeout = self.config.timeout
@@ -102,6 +104,8 @@ class HttpRequests:
102
104
  verify=self.requests_verify,
103
105
  )
104
106
 
107
+ prev_resp = request
108
+
105
109
  try:
106
110
  resp = self.__validate(request, stream=stream)
107
111
  logging.debug("got response: %s", str(resp))
@@ -134,6 +138,10 @@ class HttpRequests:
134
138
  except requests.exceptions.ConnectionError as err:
135
139
  raise FelderaCommunicationError(str(err)) from err
136
140
 
141
+ raise FelderaAPIError(
142
+ "Max retries exceeded, couldn't successfully connect to Feldera", prev_resp
143
+ )
144
+
137
145
  def get(
138
146
  self,
139
147
  path: str,
@@ -1,5 +1,7 @@
1
1
  from typing import Optional
2
2
  import os
3
+ from feldera.rest._helpers import requests_verify_from_env
4
+ import logging
3
5
 
4
6
 
5
7
  class Config:
@@ -14,7 +16,7 @@ class Config:
14
16
  version: Optional[str] = None,
15
17
  timeout: Optional[float] = None,
16
18
  connection_timeout: Optional[float] = None,
17
- requests_verify: bool | str = True,
19
+ requests_verify: Optional[bool | str] = None,
18
20
  ) -> None:
19
21
  """
20
22
  :param url: The url to the Feldera API (ex: https://try.feldera.com)
@@ -23,7 +25,10 @@ class Config:
23
25
  :param timeout: The timeout for the HTTP requests
24
26
  :param connection_timeout: The connection timeout for the HTTP requests
25
27
  :param requests_verify: The `verify` parameter passed to the requests
26
- library. `True` by default.
28
+ library. `True` by default. Can also be set using environment
29
+ variables `FELDERA_TLS_INSECURE` to disable TLS and
30
+ `FELDERA_HTTPS_TLS_CERT` to set the certificate path. The latter
31
+ takes priority.
27
32
  """
28
33
 
29
34
  BASE_URL = (
@@ -37,11 +42,10 @@ class Config:
37
42
  self.version: Optional[str] = version or "v0"
38
43
  self.timeout: Optional[float] = timeout
39
44
  self.connection_timeout: Optional[float] = connection_timeout
45
+ env_verify = requests_verify_from_env()
46
+ self.requests_verify: bool | str = (
47
+ requests_verify if requests_verify is not None else env_verify
48
+ )
40
49
 
41
- FELDERA_TLS_INSECURE = True if os.environ.get("FELDERA_TLS_INSECURE") else False
42
- FELDERA_HTTPS_TLS_CERT = os.environ.get("FELDERA_HTTPS_TLS_CERT")
43
- requests_verify = not FELDERA_TLS_INSECURE
44
- if requests_verify and FELDERA_HTTPS_TLS_CERT is not None:
45
- requests_verify = FELDERA_HTTPS_TLS_CERT
46
-
47
- self.requests_verify: bool | str = requests_verify
50
+ if self.requests_verify is False:
51
+ logging.warning("TLS verification is disabled.")
@@ -49,7 +49,7 @@ class FelderaClient:
49
49
  api_key: Optional[str] = None,
50
50
  timeout: Optional[float] = None,
51
51
  connection_timeout: Optional[float] = None,
52
- requests_verify: bool | str = True,
52
+ requests_verify: Optional[bool | str] = None,
53
53
  ) -> None:
54
54
  """
55
55
  :param url: The url to Feldera API (ex: https://try.feldera.com). If
@@ -185,7 +185,7 @@ class FelderaClient:
185
185
  elapsed = time.monotonic() - start_time
186
186
  if elapsed > timeout_s:
187
187
  raise TimeoutError(
188
- f"Timed out waiting for pipeline {pipeline_name} to"
188
+ f"Timed out waiting for pipeline {pipeline_name} to "
189
189
  f"transition to '{state}' state"
190
190
  )
191
191
 
@@ -287,6 +287,21 @@ Reason: The pipeline is in a STOPPED state due to the following error:
287
287
  },
288
288
  )
289
289
 
290
+ def testing_force_update_platform_version(self, name: str, platform_version: str):
291
+ self.http.post(
292
+ path=f"/pipelines/{name}/testing",
293
+ params={"set_platform_version": platform_version},
294
+ )
295
+
296
+ def update_pipeline_runtime(self, name: str):
297
+ """
298
+ Recompile a pipeline with the Feldera runtime version included in the currently installed Feldera platform.
299
+
300
+ :param name: The name of the pipeline
301
+ """
302
+
303
+ self.http.post(path=f"/pipelines/{name}/update_runtime")
304
+
290
305
  def delete_pipeline(self, name: str):
291
306
  """
292
307
  Deletes a pipeline by name
@@ -57,6 +57,7 @@ class Pipeline:
57
57
  )
58
58
  self.program_status: Optional[str] = None
59
59
  self.program_status_since: Optional[str] = None
60
+ self.platform_version: Optional[str] = None
60
61
  self.program_error: Optional[dict] = None
61
62
  self.storage_status: Optional[str] = None
62
63
 
@@ -81,6 +81,7 @@ class RuntimeConfig:
81
81
  fault_tolerance_model: Optional[FaultToleranceModel] = None,
82
82
  checkpoint_interval_secs: Optional[int] = None,
83
83
  dev_tweaks: Optional[dict] = None,
84
+ logging: Optional[str] = None,
84
85
  ):
85
86
  self.workers = workers
86
87
  self.tracing = tracing
@@ -105,6 +106,7 @@ class RuntimeConfig:
105
106
  else:
106
107
  raise ValueError(f"Unknown value '{storage}' for storage")
107
108
  self.dev_tweaks = dev_tweaks
109
+ self.logging = logging
108
110
 
109
111
  @staticmethod
110
112
  def default() -> "RuntimeConfig":
@@ -13,6 +13,7 @@ from feldera.pipeline import Pipeline
13
13
  from feldera.pipeline_builder import PipelineBuilder
14
14
  from feldera.runtime_config import Resources, RuntimeConfig
15
15
  from feldera.rest import FelderaClient
16
+ from feldera.rest._helpers import requests_verify_from_env
16
17
 
17
18
  API_KEY = os.environ.get("FELDERA_API_KEY")
18
19
 
@@ -46,12 +47,7 @@ KAFKA_SERVER = os.environ.get("FELDERA_KAFKA_SERVER", "localhost:19092")
46
47
  PIPELINE_TO_KAFKA_SERVER = os.environ.get(
47
48
  "FELDERA_PIPELINE_TO_KAFKA_SERVER", "redpanda:9092"
48
49
  )
49
- FELDERA_TLS_INSECURE = True if os.environ.get("FELDERA_TLS_INSECURE") else False
50
- FELDERA_HTTPS_TLS_CERT = os.environ.get("FELDERA_HTTPS_TLS_CERT")
51
- if not FELDERA_TLS_INSECURE and FELDERA_HTTPS_TLS_CERT is not None:
52
- FELDERA_REQUESTS_VERIFY = FELDERA_HTTPS_TLS_CERT
53
- else:
54
- FELDERA_REQUESTS_VERIFY = not FELDERA_TLS_INSECURE
50
+ FELDERA_REQUESTS_VERIFY = requests_verify_from_env()
55
51
 
56
52
 
57
53
  class _LazyClient:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: feldera
3
- Version: 0.159.0
3
+ Version: 0.161.0
4
4
  Summary: The feldera python client
5
5
  Author-email: Feldera Team <dev@feldera.com>
6
6
  License: MIT
@@ -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.159.0"
9
+ version = "0.161.0"
10
10
  license = { text = "MIT" }
11
11
  requires-python = ">=3.10"
12
12
  authors = [
@@ -1,9 +0,0 @@
1
- def client_version() -> str:
2
- from importlib.metadata import version, PackageNotFoundError
3
-
4
- try:
5
- version = version("feldera")
6
- except PackageNotFoundError:
7
- version = "unknown"
8
-
9
- return version
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes