feldera 0.153.0__tar.gz → 0.186.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.
- feldera-0.186.0/PKG-INFO +163 -0
- feldera-0.186.0/README.md +139 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/__init__.py +2 -2
- feldera-0.186.0/feldera/_callback_runner.py +95 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/_helpers.py +7 -1
- {feldera-0.153.0 → feldera-0.186.0}/feldera/enums.py +33 -13
- {feldera-0.153.0 → feldera-0.186.0}/feldera/output_handler.py +16 -4
- {feldera-0.153.0 → feldera-0.186.0}/feldera/pipeline.py +233 -117
- {feldera-0.153.0 → feldera-0.186.0}/feldera/pipeline_builder.py +11 -7
- feldera-0.186.0/feldera/rest/_helpers.py +40 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/_httprequests.py +365 -224
- feldera-0.186.0/feldera/rest/config.py +44 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/feldera_client.py +272 -124
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/pipeline.py +2 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/runtime_config.py +2 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/testutils.py +3 -16
- feldera-0.186.0/feldera.egg-info/PKG-INFO +163 -0
- {feldera-0.153.0 → feldera-0.186.0}/pyproject.toml +1 -2
- feldera-0.153.0/PKG-INFO +0 -103
- feldera-0.153.0/README.md +0 -79
- feldera-0.153.0/feldera/_callback_runner.py +0 -123
- feldera-0.153.0/feldera/rest/_helpers.py +0 -9
- feldera-0.153.0/feldera/rest/config.py +0 -47
- feldera-0.153.0/feldera.egg-info/PKG-INFO +0 -103
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/__init__.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/errors.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/feldera_config.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/sql_table.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/rest/sql_view.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/stats.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/tests/test_datafusionize.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera/testutils_oidc.py +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera.egg-info/SOURCES.txt +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera.egg-info/dependency_links.txt +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera.egg-info/requires.txt +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/feldera.egg-info/top_level.txt +0 -0
- {feldera-0.153.0 → feldera-0.186.0}/setup.cfg +0 -0
feldera-0.186.0/PKG-INFO
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feldera
|
|
3
|
+
Version: 0.186.0
|
|
4
|
+
Summary: The feldera python client
|
|
5
|
+
Author-email: Feldera Team <dev@feldera.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://www.feldera.com
|
|
8
|
+
Project-URL: Documentation, https://docs.feldera.com/python
|
|
9
|
+
Project-URL: Repository, https://github.com/feldera/feldera
|
|
10
|
+
Project-URL: Issues, https://github.com/feldera/feldera/issues
|
|
11
|
+
Keywords: feldera,python
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Requires-Dist: pandas>=2.1.2
|
|
19
|
+
Requires-Dist: typing-extensions
|
|
20
|
+
Requires-Dist: numpy>=2.2.4
|
|
21
|
+
Requires-Dist: pretty-errors
|
|
22
|
+
Requires-Dist: ruff>=0.6.9
|
|
23
|
+
Requires-Dist: PyJWT>=2.8.0
|
|
24
|
+
|
|
25
|
+
# Feldera Python SDK
|
|
26
|
+
|
|
27
|
+
The `feldera` Python package is the Python client for the Feldera HTTP API.
|
|
28
|
+
|
|
29
|
+
The Python SDK documentation is available at: https://docs.feldera.com/python
|
|
30
|
+
|
|
31
|
+
## Getting started
|
|
32
|
+
|
|
33
|
+
### Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv pip install feldera
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Example usage
|
|
40
|
+
|
|
41
|
+
The Python client interacts with the API server of the Feldera instance.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# File: example.py
|
|
45
|
+
from feldera import FelderaClient, PipelineBuilder, Pipeline
|
|
46
|
+
|
|
47
|
+
# Instantiate client
|
|
48
|
+
client = FelderaClient() # Default: http://localhost:8080 without authentication
|
|
49
|
+
# client = FelderaClient(url="https://localhost:8080", api_key="apikey:...", requests_verify="/path/to/tls.crt")
|
|
50
|
+
|
|
51
|
+
# (Re)create pipeline
|
|
52
|
+
name = "example"
|
|
53
|
+
sql = """
|
|
54
|
+
CREATE TABLE t1 (i1 INT) WITH ('materialized' = 'true');
|
|
55
|
+
CREATE MATERIALIZED VIEW v1 AS SELECT * FROM t1;
|
|
56
|
+
"""
|
|
57
|
+
print("(Re)creating pipeline...")
|
|
58
|
+
pipeline = PipelineBuilder(client, name, sql).create_or_replace()
|
|
59
|
+
pipeline.start()
|
|
60
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
61
|
+
pipeline.pause()
|
|
62
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
63
|
+
pipeline.stop(force=True)
|
|
64
|
+
|
|
65
|
+
# Find existing pipeline
|
|
66
|
+
pipeline = Pipeline.get(name, client)
|
|
67
|
+
pipeline.start()
|
|
68
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
69
|
+
pipeline.stop(force=True)
|
|
70
|
+
pipeline.clear_storage()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Run using:
|
|
74
|
+
```bash
|
|
75
|
+
uv run python example.py
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Environment variables
|
|
79
|
+
|
|
80
|
+
Some default parameter values in the Python SDK can be overridden via environment variables.
|
|
81
|
+
|
|
82
|
+
**Environment variables for `FelderaClient(...)`**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
export FELDERA_HOST="https://localhost:8080" # Overrides default for `url`
|
|
86
|
+
export FELDERA_API_KEY="apikey:..." # Overrides default for `api_key`
|
|
87
|
+
|
|
88
|
+
# The following together override default for `requests_verify`
|
|
89
|
+
# export FELDERA_TLS_INSECURE="false" # If set to "1", "true" or "yes" (all case-insensitive), disables TLS certificate verification
|
|
90
|
+
# export FELDERA_HTTPS_TLS_CERT="/path/to/tls.crt" # Custom TLS certificate
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Environment variables for `PipelineBuilder(...)`**
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
export FELDERA_RUNTIME_VERSION="..." # Overrides default for `runtime_version`
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Development
|
|
100
|
+
|
|
101
|
+
Development assumes you have cloned the Feldera code repository.
|
|
102
|
+
|
|
103
|
+
### Installation
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cd python
|
|
107
|
+
# Optional: create and activate virtual environment if you don't have one
|
|
108
|
+
uv venv
|
|
109
|
+
source .venv/bin/activate
|
|
110
|
+
# Install in editable mode
|
|
111
|
+
uv pip install -e .
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Formatting
|
|
115
|
+
|
|
116
|
+
Formatting requires the `ruff` package: `uv pip install ruff`
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cd python
|
|
120
|
+
ruff check
|
|
121
|
+
ruff format
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Tests
|
|
125
|
+
|
|
126
|
+
Running the test requires the `pytest` package: `uv pip install pytest`
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# All tests
|
|
130
|
+
cd python
|
|
131
|
+
uv run python -m pytest tests/
|
|
132
|
+
|
|
133
|
+
# Specific tests directory
|
|
134
|
+
uv run python -m pytest tests/platform/
|
|
135
|
+
|
|
136
|
+
# Specific test file
|
|
137
|
+
uv run python -m pytest tests/platform/test_pipeline_crud.py
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For further information about the tests, please see `tests/README.md`.
|
|
141
|
+
|
|
142
|
+
### Documentation
|
|
143
|
+
|
|
144
|
+
Building documentation requires the `sphinx` package: `uv pip install sphinx`
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
cd python/docs
|
|
148
|
+
sphinx-apidoc -o . ../feldera
|
|
149
|
+
make html
|
|
150
|
+
make clean # Cleanup afterwards
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Installation from GitHub
|
|
154
|
+
|
|
155
|
+
Latest `main` branch:
|
|
156
|
+
```bash
|
|
157
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Different branch (replace `BRANCH_NAME`):
|
|
161
|
+
```bash
|
|
162
|
+
uv pip install git+https://github.com/feldera/feldera@BRANCH_NAME#subdirectory=python
|
|
163
|
+
```
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Feldera Python SDK
|
|
2
|
+
|
|
3
|
+
The `feldera` Python package is the Python client for the Feldera HTTP API.
|
|
4
|
+
|
|
5
|
+
The Python SDK documentation is available at: https://docs.feldera.com/python
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
### Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv pip install feldera
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Example usage
|
|
16
|
+
|
|
17
|
+
The Python client interacts with the API server of the Feldera instance.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
# File: example.py
|
|
21
|
+
from feldera import FelderaClient, PipelineBuilder, Pipeline
|
|
22
|
+
|
|
23
|
+
# Instantiate client
|
|
24
|
+
client = FelderaClient() # Default: http://localhost:8080 without authentication
|
|
25
|
+
# client = FelderaClient(url="https://localhost:8080", api_key="apikey:...", requests_verify="/path/to/tls.crt")
|
|
26
|
+
|
|
27
|
+
# (Re)create pipeline
|
|
28
|
+
name = "example"
|
|
29
|
+
sql = """
|
|
30
|
+
CREATE TABLE t1 (i1 INT) WITH ('materialized' = 'true');
|
|
31
|
+
CREATE MATERIALIZED VIEW v1 AS SELECT * FROM t1;
|
|
32
|
+
"""
|
|
33
|
+
print("(Re)creating pipeline...")
|
|
34
|
+
pipeline = PipelineBuilder(client, name, sql).create_or_replace()
|
|
35
|
+
pipeline.start()
|
|
36
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
37
|
+
pipeline.pause()
|
|
38
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
39
|
+
pipeline.stop(force=True)
|
|
40
|
+
|
|
41
|
+
# Find existing pipeline
|
|
42
|
+
pipeline = Pipeline.get(name, client)
|
|
43
|
+
pipeline.start()
|
|
44
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
45
|
+
pipeline.stop(force=True)
|
|
46
|
+
pipeline.clear_storage()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Run using:
|
|
50
|
+
```bash
|
|
51
|
+
uv run python example.py
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Environment variables
|
|
55
|
+
|
|
56
|
+
Some default parameter values in the Python SDK can be overridden via environment variables.
|
|
57
|
+
|
|
58
|
+
**Environment variables for `FelderaClient(...)`**
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
export FELDERA_HOST="https://localhost:8080" # Overrides default for `url`
|
|
62
|
+
export FELDERA_API_KEY="apikey:..." # Overrides default for `api_key`
|
|
63
|
+
|
|
64
|
+
# The following together override default for `requests_verify`
|
|
65
|
+
# export FELDERA_TLS_INSECURE="false" # If set to "1", "true" or "yes" (all case-insensitive), disables TLS certificate verification
|
|
66
|
+
# export FELDERA_HTTPS_TLS_CERT="/path/to/tls.crt" # Custom TLS certificate
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Environment variables for `PipelineBuilder(...)`**
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export FELDERA_RUNTIME_VERSION="..." # Overrides default for `runtime_version`
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Development
|
|
76
|
+
|
|
77
|
+
Development assumes you have cloned the Feldera code repository.
|
|
78
|
+
|
|
79
|
+
### Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd python
|
|
83
|
+
# Optional: create and activate virtual environment if you don't have one
|
|
84
|
+
uv venv
|
|
85
|
+
source .venv/bin/activate
|
|
86
|
+
# Install in editable mode
|
|
87
|
+
uv pip install -e .
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Formatting
|
|
91
|
+
|
|
92
|
+
Formatting requires the `ruff` package: `uv pip install ruff`
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cd python
|
|
96
|
+
ruff check
|
|
97
|
+
ruff format
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Tests
|
|
101
|
+
|
|
102
|
+
Running the test requires the `pytest` package: `uv pip install pytest`
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# All tests
|
|
106
|
+
cd python
|
|
107
|
+
uv run python -m pytest tests/
|
|
108
|
+
|
|
109
|
+
# Specific tests directory
|
|
110
|
+
uv run python -m pytest tests/platform/
|
|
111
|
+
|
|
112
|
+
# Specific test file
|
|
113
|
+
uv run python -m pytest tests/platform/test_pipeline_crud.py
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For further information about the tests, please see `tests/README.md`.
|
|
117
|
+
|
|
118
|
+
### Documentation
|
|
119
|
+
|
|
120
|
+
Building documentation requires the `sphinx` package: `uv pip install sphinx`
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
cd python/docs
|
|
124
|
+
sphinx-apidoc -o . ../feldera
|
|
125
|
+
make html
|
|
126
|
+
make clean # Cleanup afterwards
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Installation from GitHub
|
|
130
|
+
|
|
131
|
+
Latest `main` branch:
|
|
132
|
+
```bash
|
|
133
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Different branch (replace `BRANCH_NAME`):
|
|
137
|
+
```bash
|
|
138
|
+
uv pip install git+https://github.com/feldera/feldera@BRANCH_NAME#subdirectory=python
|
|
139
|
+
```
|
|
@@ -1,9 +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
|
|
4
|
+
from feldera.rest._helpers import determine_client_version
|
|
5
5
|
|
|
6
|
-
__version__ =
|
|
6
|
+
__version__ = determine_client_version()
|
|
7
7
|
|
|
8
8
|
import pretty_errors
|
|
9
9
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from threading import Thread, Event
|
|
2
|
+
from typing import Callable, List, Optional, Mapping, Any
|
|
3
|
+
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from feldera import FelderaClient
|
|
6
|
+
from feldera._helpers import dataframe_from_response
|
|
7
|
+
from feldera.enums import PipelineFieldSelector
|
|
8
|
+
from feldera.rest.sql_table import SQLTable
|
|
9
|
+
from feldera.rest.sql_view import SQLView
|
|
10
|
+
from feldera.rest.pipeline import Pipeline
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CallbackRunner(Thread):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
client: FelderaClient,
|
|
17
|
+
pipeline_name: str,
|
|
18
|
+
view_name: str,
|
|
19
|
+
callback: Callable[[pd.DataFrame, int], None],
|
|
20
|
+
exception_callback: Callable[[BaseException], None],
|
|
21
|
+
event: Event,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
:param client: The :class:`.FelderaClient` to use.
|
|
25
|
+
:param pipeline_name: The name of the current pipeline.
|
|
26
|
+
:param view_name: The name of the view we are listening to.
|
|
27
|
+
:param callback: The callback function to call on the data we receive.
|
|
28
|
+
:param exception_callback: The callback function to call when an exception occurs.
|
|
29
|
+
:param event: The event to wait for before starting the callback runner.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
super().__init__()
|
|
33
|
+
self.daemon = True
|
|
34
|
+
self.client: FelderaClient = client
|
|
35
|
+
self.pipeline_name: str = pipeline_name
|
|
36
|
+
self.view_name: str = view_name
|
|
37
|
+
self.callback: Callable[[pd.DataFrame, int], None] = callback
|
|
38
|
+
self.exception_callback: Callable[[BaseException], None] = exception_callback
|
|
39
|
+
self.event: Event = event
|
|
40
|
+
|
|
41
|
+
self.pipeline: Pipeline = self.client.get_pipeline(
|
|
42
|
+
self.pipeline_name, PipelineFieldSelector.ALL
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
view_schema = None
|
|
46
|
+
|
|
47
|
+
schemas: List[SQLTable | SQLView] = self.pipeline.tables + self.pipeline.views
|
|
48
|
+
for schema in schemas:
|
|
49
|
+
if schema.name == self.view_name:
|
|
50
|
+
view_schema = schema
|
|
51
|
+
break
|
|
52
|
+
|
|
53
|
+
if view_schema is None:
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"Table or View {self.view_name} not found in the pipeline schema."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
self.schema: SQLTable | SQLView = view_schema
|
|
59
|
+
|
|
60
|
+
def to_callback(self, chunk: Mapping[str, Any]):
|
|
61
|
+
data: Optional[list[Mapping[str, Any]]] = chunk.get("json_data")
|
|
62
|
+
seq_no: Optional[int] = chunk.get("sequence_number")
|
|
63
|
+
if data is not None and seq_no is not None:
|
|
64
|
+
self.callback(dataframe_from_response([data], self.schema.fields), seq_no)
|
|
65
|
+
|
|
66
|
+
def run(self):
|
|
67
|
+
"""
|
|
68
|
+
The main loop of the thread. Listens for data and calls the callback function on each chunk of data received.
|
|
69
|
+
|
|
70
|
+
:meta private:
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
gen_obj = self.client.listen_to_pipeline(
|
|
75
|
+
self.pipeline_name,
|
|
76
|
+
self.view_name,
|
|
77
|
+
format="json",
|
|
78
|
+
case_sensitive=self.schema.case_sensitive,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
iterator = gen_obj()
|
|
82
|
+
|
|
83
|
+
# Trigger the HTTP call
|
|
84
|
+
chunk = next(iterator)
|
|
85
|
+
|
|
86
|
+
# Unblock the main thread
|
|
87
|
+
self.event.set()
|
|
88
|
+
|
|
89
|
+
self.to_callback(chunk)
|
|
90
|
+
|
|
91
|
+
for chunk in iterator:
|
|
92
|
+
self.to_callback(chunk)
|
|
93
|
+
|
|
94
|
+
except BaseException as e:
|
|
95
|
+
self.exception_callback(e)
|
|
@@ -2,6 +2,7 @@ import uuid
|
|
|
2
2
|
|
|
3
3
|
import pandas as pd
|
|
4
4
|
from decimal import Decimal
|
|
5
|
+
from typing import Mapping, Any
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def sql_type_to_pandas_type(sql_type: str):
|
|
@@ -60,9 +61,14 @@ def ensure_dataframe_has_columns(df: pd.DataFrame):
|
|
|
60
61
|
)
|
|
61
62
|
|
|
62
63
|
|
|
63
|
-
def dataframe_from_response(
|
|
64
|
+
def dataframe_from_response(
|
|
65
|
+
buffer: list[list[Mapping[str, Any]]], fields: list[Mapping[str, Any]]
|
|
66
|
+
):
|
|
64
67
|
"""
|
|
65
68
|
Converts the response from Feldera to a pandas DataFrame.
|
|
69
|
+
|
|
70
|
+
:param buffer: A buffer of a list of JSON formatted output of the view you are listening to.
|
|
71
|
+
:param fields: The schema (list of fields) of the view you are listening to.
|
|
66
72
|
"""
|
|
67
73
|
|
|
68
74
|
pd_schema = {}
|
|
@@ -122,12 +122,13 @@ class DeploymentRuntimeStatus(Enum):
|
|
|
122
122
|
|
|
123
123
|
UNAVAILABLE = 0
|
|
124
124
|
STANDBY = 1
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
125
|
+
AWAITINGAPPROVAL = 2
|
|
126
|
+
INITIALIZING = 3
|
|
127
|
+
BOOTSTRAPPING = 4
|
|
128
|
+
REPLAYING = 5
|
|
129
|
+
PAUSED = 6
|
|
130
|
+
RUNNING = 7
|
|
131
|
+
SUSPENDED = 8
|
|
131
132
|
|
|
132
133
|
@staticmethod
|
|
133
134
|
def from_str(value):
|
|
@@ -149,13 +150,14 @@ class PipelineStatus(Enum):
|
|
|
149
150
|
PROVISIONING = 2
|
|
150
151
|
UNAVAILABLE = 3
|
|
151
152
|
STANDBY = 4
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
AWAITINGAPPROVAL = 5
|
|
154
|
+
INITIALIZING = 6
|
|
155
|
+
BOOTSTRAPPING = 7
|
|
156
|
+
REPLAYING = 8
|
|
157
|
+
PAUSED = 9
|
|
158
|
+
RUNNING = 10
|
|
159
|
+
SUSPENDED = 11
|
|
160
|
+
STOPPING = 12
|
|
159
161
|
|
|
160
162
|
@staticmethod
|
|
161
163
|
def from_str(value):
|
|
@@ -344,3 +346,21 @@ class PipelineFieldSelector(Enum):
|
|
|
344
346
|
|
|
345
347
|
STATUS = "status"
|
|
346
348
|
"""Select only the fields required to know the status of a pipeline."""
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
class BootstrapPolicy(Enum):
|
|
352
|
+
AWAIT_APPROVAL = "await_approval"
|
|
353
|
+
ALLOW = "allow"
|
|
354
|
+
REJECT = "reject"
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
class CompletionTokenStatus(Enum):
|
|
358
|
+
COMPLETE = "complete"
|
|
359
|
+
"""
|
|
360
|
+
Feldera has completed processing all inputs represented by this token.
|
|
361
|
+
"""
|
|
362
|
+
|
|
363
|
+
IN_PROGRESS = "inprogress"
|
|
364
|
+
"""
|
|
365
|
+
Feldera is still processing the inputs represented by this token.
|
|
366
|
+
"""
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
|
+
|
|
2
3
|
from typing import Optional
|
|
4
|
+
from threading import Event
|
|
3
5
|
|
|
4
|
-
from queue import Queue
|
|
5
6
|
from feldera import FelderaClient
|
|
6
7
|
from feldera._callback_runner import CallbackRunner
|
|
7
8
|
|
|
@@ -12,7 +13,6 @@ class OutputHandler:
|
|
|
12
13
|
client: FelderaClient,
|
|
13
14
|
pipeline_name: str,
|
|
14
15
|
view_name: str,
|
|
15
|
-
queue: Optional[Queue],
|
|
16
16
|
):
|
|
17
17
|
"""
|
|
18
18
|
Initializes the output handler, but doesn't start it.
|
|
@@ -22,17 +22,26 @@ class OutputHandler:
|
|
|
22
22
|
self.client: FelderaClient = client
|
|
23
23
|
self.pipeline_name: str = pipeline_name
|
|
24
24
|
self.view_name: str = view_name
|
|
25
|
-
self.queue: Optional[Queue] = queue
|
|
26
25
|
self.buffer: list[pd.DataFrame] = []
|
|
26
|
+
self.exception: Optional[BaseException] = None
|
|
27
|
+
self.event = Event()
|
|
27
28
|
|
|
28
29
|
# the callback that is passed to the `CallbackRunner`
|
|
29
30
|
def callback(df: pd.DataFrame, _: int):
|
|
30
31
|
if not df.empty:
|
|
31
32
|
self.buffer.append(df)
|
|
32
33
|
|
|
34
|
+
def exception_callback(exception: BaseException):
|
|
35
|
+
self.exception = exception
|
|
36
|
+
|
|
33
37
|
# sets up the callback runner
|
|
34
38
|
self.handler = CallbackRunner(
|
|
35
|
-
self.client,
|
|
39
|
+
self.client,
|
|
40
|
+
self.pipeline_name,
|
|
41
|
+
self.view_name,
|
|
42
|
+
callback,
|
|
43
|
+
exception_callback,
|
|
44
|
+
self.event,
|
|
36
45
|
)
|
|
37
46
|
|
|
38
47
|
def start(self):
|
|
@@ -41,6 +50,7 @@ class OutputHandler:
|
|
|
41
50
|
"""
|
|
42
51
|
|
|
43
52
|
self.handler.start()
|
|
53
|
+
_ = self.event.wait()
|
|
44
54
|
|
|
45
55
|
def to_pandas(self, clear_buffer: bool = True):
|
|
46
56
|
"""
|
|
@@ -49,6 +59,8 @@ class OutputHandler:
|
|
|
49
59
|
:param clear_buffer: Whether to clear the buffer after getting the output.
|
|
50
60
|
"""
|
|
51
61
|
|
|
62
|
+
if self.exception is not None:
|
|
63
|
+
raise self.exception
|
|
52
64
|
if len(self.buffer) == 0:
|
|
53
65
|
return pd.DataFrame()
|
|
54
66
|
res = pd.concat(self.buffer, ignore_index=True)
|