feldera 0.100.0__tar.gz → 0.101.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.100.0 → feldera-0.101.0}/PKG-INFO +45 -16
- feldera-0.101.0/README.md +129 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/_callback_runner.py +8 -7
- {feldera-0.100.0 → feldera-0.101.0}/feldera/pipeline.py +5 -2
- {feldera-0.100.0 → feldera-0.101.0}/feldera/pipeline_builder.py +2 -2
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/feldera_client.py +2 -2
- {feldera-0.100.0 → feldera-0.101.0}/feldera/runtime_config.py +9 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera.egg-info/PKG-INFO +45 -16
- {feldera-0.100.0 → feldera-0.101.0}/feldera.egg-info/SOURCES.txt +3 -3
- {feldera-0.100.0 → feldera-0.101.0}/pyproject.toml +1 -1
- feldera-0.101.0/tests/test_pipeline_builder.py +53 -0
- feldera-0.101.0/tests/test_shared_pipeline0.py +593 -0
- feldera-0.101.0/tests/test_shared_pipeline1.py +72 -0
- {feldera-0.100.0 → feldera-0.101.0}/tests/test_udf.py +0 -1
- feldera-0.100.0/README.md +0 -100
- feldera-0.100.0/tests/test_pipeline.py +0 -263
- feldera-0.100.0/tests/test_pipeline_builder.py +0 -1199
- feldera-0.100.0/tests/test_variant.py +0 -102
- {feldera-0.100.0 → feldera-0.101.0}/feldera/__init__.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/_helpers.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/enums.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/output_handler.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/__init__.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/_helpers.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/_httprequests.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/config.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/errors.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/feldera_config.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/pipeline.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/sql_table.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/rest/sql_view.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera/stats.py +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera.egg-info/dependency_links.txt +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera.egg-info/requires.txt +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/feldera.egg-info/top_level.txt +0 -0
- {feldera-0.100.0 → feldera-0.101.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.101.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -54,10 +54,11 @@ If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
|
54
54
|
pip install python/
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
Checkout the docs [here](./feldera/__init__.py) for an example on how to use the SDK.
|
|
58
|
-
|
|
59
57
|
## Documentation
|
|
60
58
|
|
|
59
|
+
The Python SDK documentation is available at
|
|
60
|
+
[Feldera Python SDK Docs](https://docs.feldera.com/python).
|
|
61
|
+
|
|
61
62
|
To build the html documentation run:
|
|
62
63
|
|
|
63
64
|
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
@@ -77,27 +78,23 @@ To clean the build, run `make clean`.
|
|
|
77
78
|
To run unit tests:
|
|
78
79
|
|
|
79
80
|
```bash
|
|
80
|
-
|
|
81
|
+
cd python && python3 -m pytest tests/
|
|
81
82
|
```
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
tests, you'll also need a broker available at `localhost:9092` and
|
|
88
|
-
(from the pipelines) `redpanda:19092`. (To change those locations,
|
|
89
|
-
set the environment variables listed in `python/tests/__init__.py`.)
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
(cd python && python3 -m pytest tests)
|
|
93
|
-
```
|
|
84
|
+
- This will detect and run all test files that match the pattern `test_*.py` or
|
|
85
|
+
`*_test.py`.
|
|
86
|
+
- By default, the tests expect a running Feldera instance at `http://localhost:8080`.
|
|
87
|
+
To override the default endpoint, set the `FELDERA_BASE_URL` environment variable.
|
|
94
88
|
|
|
95
89
|
To run tests from a specific file:
|
|
96
90
|
|
|
97
91
|
```bash
|
|
98
|
-
(cd python && python3 -m
|
|
92
|
+
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
99
93
|
```
|
|
100
94
|
|
|
95
|
+
#### Running Aggregate Tests
|
|
96
|
+
|
|
97
|
+
The aggregate tests validate end-to-end correctness of SQL functionality.
|
|
101
98
|
To run the aggregate tests use:
|
|
102
99
|
|
|
103
100
|
```bash
|
|
@@ -105,6 +102,38 @@ cd python
|
|
|
105
102
|
PYTHONPATH=`pwd` python3 ./tests/aggregate_tests/main.py
|
|
106
103
|
```
|
|
107
104
|
|
|
105
|
+
### Reducing Compilation Cycles
|
|
106
|
+
|
|
107
|
+
To reduce redundant compilation cycles during testing:
|
|
108
|
+
|
|
109
|
+
* **Inherit from `SharedTestPipeline`** instead of `unittest.TestCase`.
|
|
110
|
+
* **Define DDLs** (e.g., `CREATE TABLE`, `CREATE VIEW`) in the **docstring** of each test method.
|
|
111
|
+
* All DDLs from all test functions in the class are combined and compiled into a single pipeline.
|
|
112
|
+
* If a table or view is already defined in one test, it can be used directly in others without redefinition.
|
|
113
|
+
* Ensure that all table and view names are unique within the class.
|
|
114
|
+
* Use `@enterprise_only` on tests that require Enterprise features. Their DDLs will be skipped on OSS builds.
|
|
115
|
+
* Use `self.set_runtime_config(...)` to override the default pipeline config.
|
|
116
|
+
* Reset it at the end using `self.reset_runtime_config()`.
|
|
117
|
+
* Access the shared pipeline via `self.pipeline`.
|
|
118
|
+
|
|
119
|
+
#### Example
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from tests.shared_test_pipeline import SharedTestPipeline
|
|
123
|
+
|
|
124
|
+
class TestAverage(SharedTestPipeline):
|
|
125
|
+
def test_average(self):
|
|
126
|
+
"""
|
|
127
|
+
CREATE TABLE students(id INT, name STRING);
|
|
128
|
+
CREATE MATERIALIZED VIEW v AS SELECT * FROM students;
|
|
129
|
+
"""
|
|
130
|
+
...
|
|
131
|
+
self.pipeline.start()
|
|
132
|
+
self.pipeline.input_pandas("students", df)
|
|
133
|
+
self.pipeline.wait_for_completion(True)
|
|
134
|
+
...
|
|
135
|
+
```
|
|
136
|
+
|
|
108
137
|
## Linting and formatting
|
|
109
138
|
|
|
110
139
|
Use [Ruff] to run the lint checks that will be executed by the
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Feldera Python SDK
|
|
2
|
+
|
|
3
|
+
Feldera Python is the Feldera SDK for Python developers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install feldera
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Installing from Github
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Similarly, to install from a specific branch:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
$ pip install git+https://github.com/feldera/feldera@{BRANCH_NAME}#subdirectory=python
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Replace `{BRANCH_NAME}` with the name of the branch you want to install from.
|
|
24
|
+
|
|
25
|
+
### Installing from Local Directory
|
|
26
|
+
|
|
27
|
+
If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# the Feldera Python SDK is present inside the python/ directory
|
|
31
|
+
pip install python/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
The Python SDK documentation is available at
|
|
37
|
+
[Feldera Python SDK Docs](https://docs.feldera.com/python).
|
|
38
|
+
|
|
39
|
+
To build the html documentation run:
|
|
40
|
+
|
|
41
|
+
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
42
|
+
|
|
43
|
+
Then run the following commands:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd docs
|
|
47
|
+
sphinx-apidoc -o . ../feldera
|
|
48
|
+
make html
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To clean the build, run `make clean`.
|
|
52
|
+
|
|
53
|
+
## Testing
|
|
54
|
+
|
|
55
|
+
To run unit tests:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd python && python3 -m pytest tests/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- This will detect and run all test files that match the pattern `test_*.py` or
|
|
62
|
+
`*_test.py`.
|
|
63
|
+
- By default, the tests expect a running Feldera instance at `http://localhost:8080`.
|
|
64
|
+
To override the default endpoint, set the `FELDERA_BASE_URL` environment variable.
|
|
65
|
+
|
|
66
|
+
To run tests from a specific file:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Running Aggregate Tests
|
|
73
|
+
|
|
74
|
+
The aggregate tests validate end-to-end correctness of SQL functionality.
|
|
75
|
+
To run the aggregate tests use:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cd python
|
|
79
|
+
PYTHONPATH=`pwd` python3 ./tests/aggregate_tests/main.py
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Reducing Compilation Cycles
|
|
83
|
+
|
|
84
|
+
To reduce redundant compilation cycles during testing:
|
|
85
|
+
|
|
86
|
+
* **Inherit from `SharedTestPipeline`** instead of `unittest.TestCase`.
|
|
87
|
+
* **Define DDLs** (e.g., `CREATE TABLE`, `CREATE VIEW`) in the **docstring** of each test method.
|
|
88
|
+
* All DDLs from all test functions in the class are combined and compiled into a single pipeline.
|
|
89
|
+
* If a table or view is already defined in one test, it can be used directly in others without redefinition.
|
|
90
|
+
* Ensure that all table and view names are unique within the class.
|
|
91
|
+
* Use `@enterprise_only` on tests that require Enterprise features. Their DDLs will be skipped on OSS builds.
|
|
92
|
+
* Use `self.set_runtime_config(...)` to override the default pipeline config.
|
|
93
|
+
* Reset it at the end using `self.reset_runtime_config()`.
|
|
94
|
+
* Access the shared pipeline via `self.pipeline`.
|
|
95
|
+
|
|
96
|
+
#### Example
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from tests.shared_test_pipeline import SharedTestPipeline
|
|
100
|
+
|
|
101
|
+
class TestAverage(SharedTestPipeline):
|
|
102
|
+
def test_average(self):
|
|
103
|
+
"""
|
|
104
|
+
CREATE TABLE students(id INT, name STRING);
|
|
105
|
+
CREATE MATERIALIZED VIEW v AS SELECT * FROM students;
|
|
106
|
+
"""
|
|
107
|
+
...
|
|
108
|
+
self.pipeline.start()
|
|
109
|
+
self.pipeline.input_pandas("students", df)
|
|
110
|
+
self.pipeline.wait_for_completion(True)
|
|
111
|
+
...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Linting and formatting
|
|
115
|
+
|
|
116
|
+
Use [Ruff] to run the lint checks that will be executed by the
|
|
117
|
+
precommit hook when a PR is submitted:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ruff check python/
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
To reformat the code in the same way as the precommit hook:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
ruff format
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
[Ruff]: https://github.com/astral-sh/ruff
|
|
@@ -54,12 +54,12 @@ class CallbackRunner(Thread):
|
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
# by default, we assume that the pipeline has been started
|
|
57
|
-
ack
|
|
57
|
+
ack = _CallbackRunnerInstruction.PipelineStarted
|
|
58
58
|
|
|
59
59
|
# if there is Queue, we wait for the instruction to start the pipeline
|
|
60
60
|
# this means that we are listening to the pipeline before running it, therefore, all data should be received
|
|
61
61
|
if self.queue:
|
|
62
|
-
ack
|
|
62
|
+
ack = self.queue.get()
|
|
63
63
|
|
|
64
64
|
match ack:
|
|
65
65
|
# if the pipeline has actually been started, we start a listener
|
|
@@ -77,11 +77,12 @@ class CallbackRunner(Thread):
|
|
|
77
77
|
|
|
78
78
|
for chunk in gen_obj:
|
|
79
79
|
chunk: dict = chunk
|
|
80
|
-
data: list[dict] = chunk.get("json_data")
|
|
81
|
-
seq_no: int = chunk.get("sequence_number")
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
data: Optional[list[dict]] = chunk.get("json_data")
|
|
81
|
+
seq_no: Optional[int] = chunk.get("sequence_number")
|
|
82
|
+
if data is not None and seq_no is not None:
|
|
83
|
+
self.callback(
|
|
84
|
+
dataframe_from_response([data], self.schema), seq_no
|
|
85
|
+
)
|
|
85
86
|
|
|
86
87
|
if self.queue:
|
|
87
88
|
try:
|
|
@@ -473,10 +473,13 @@ metrics"""
|
|
|
473
473
|
pipeline to stop.
|
|
474
474
|
"""
|
|
475
475
|
|
|
476
|
-
|
|
477
|
-
for _, queue in
|
|
476
|
+
for view_queue in self.views_tx:
|
|
477
|
+
for _, queue in view_queue.items():
|
|
478
478
|
# sends a message to the callback runner to stop listening
|
|
479
479
|
queue.put(_CallbackRunnerInstruction.RanToCompletion)
|
|
480
|
+
|
|
481
|
+
if len(self.views_tx) > 0:
|
|
482
|
+
for view_name, queue in self.views_tx.pop().items():
|
|
480
483
|
# block until the callback runner has been stopped
|
|
481
484
|
queue.join()
|
|
482
485
|
|
|
@@ -2,7 +2,7 @@ from feldera.rest.feldera_client import FelderaClient
|
|
|
2
2
|
from feldera.rest.pipeline import Pipeline as InnerPipeline
|
|
3
3
|
from feldera.pipeline import Pipeline
|
|
4
4
|
from feldera.enums import CompilationProfile
|
|
5
|
-
from feldera.runtime_config import RuntimeConfig
|
|
5
|
+
from feldera.runtime_config import RuntimeConfig
|
|
6
6
|
from feldera.rest.errors import FelderaAPIError
|
|
7
7
|
|
|
8
8
|
|
|
@@ -29,7 +29,7 @@ class PipelineBuilder:
|
|
|
29
29
|
udf_toml: str = "",
|
|
30
30
|
description: str = "",
|
|
31
31
|
compilation_profile: CompilationProfile = CompilationProfile.OPTIMIZED,
|
|
32
|
-
runtime_config: RuntimeConfig = RuntimeConfig(
|
|
32
|
+
runtime_config: RuntimeConfig = RuntimeConfig.default(),
|
|
33
33
|
):
|
|
34
34
|
self.client: FelderaClient = client
|
|
35
35
|
self.name: str | None = name
|
|
@@ -454,11 +454,11 @@ Reason: The pipeline is in a STOPPED state due to the following error:
|
|
|
454
454
|
pipeline_name: str,
|
|
455
455
|
table_name: str,
|
|
456
456
|
format: str,
|
|
457
|
-
data: list[list | str | dict] | dict,
|
|
457
|
+
data: list[list | str | dict] | dict | str,
|
|
458
458
|
array: bool = False,
|
|
459
459
|
force: bool = False,
|
|
460
460
|
update_format: str = "raw",
|
|
461
|
-
json_flavor: str = None,
|
|
461
|
+
json_flavor: Optional[str] = None,
|
|
462
462
|
serialize: bool = True,
|
|
463
463
|
):
|
|
464
464
|
"""
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from typing import Optional, Any, Mapping
|
|
2
3
|
|
|
3
4
|
|
|
@@ -72,6 +73,7 @@ class RuntimeConfig:
|
|
|
72
73
|
clock_resolution_usecs: Optional[int] = None,
|
|
73
74
|
provisioning_timeout_secs: Optional[int] = None,
|
|
74
75
|
resources: Optional[Resources] = None,
|
|
76
|
+
runtime_version: Optional[str] = None,
|
|
75
77
|
):
|
|
76
78
|
self.workers = workers
|
|
77
79
|
self.tracing = tracing
|
|
@@ -81,6 +83,9 @@ class RuntimeConfig:
|
|
|
81
83
|
self.min_batch_size_records = min_batch_size_records
|
|
82
84
|
self.clock_resolution_usecs = clock_resolution_usecs
|
|
83
85
|
self.provisioning_timeout_secs = provisioning_timeout_secs
|
|
86
|
+
self.runtime_version = runtime_version or os.environ.get(
|
|
87
|
+
"FELDERA_RUNTIME_VERSION"
|
|
88
|
+
)
|
|
84
89
|
if resources is not None:
|
|
85
90
|
self.resources = resources.__dict__
|
|
86
91
|
if isinstance(storage, bool):
|
|
@@ -88,6 +93,10 @@ class RuntimeConfig:
|
|
|
88
93
|
if isinstance(storage, Storage):
|
|
89
94
|
self.storage = storage.__dict__
|
|
90
95
|
|
|
96
|
+
@staticmethod
|
|
97
|
+
def default() -> "RuntimeConfig":
|
|
98
|
+
return RuntimeConfig(resources=Resources())
|
|
99
|
+
|
|
91
100
|
@classmethod
|
|
92
101
|
def from_dict(cls, d: Mapping[str, Any]):
|
|
93
102
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feldera
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.101.0
|
|
4
4
|
Summary: The feldera python client
|
|
5
5
|
Author-email: Feldera Team <dev@feldera.com>
|
|
6
6
|
License: MIT
|
|
@@ -54,10 +54,11 @@ If you have cloned the Feldera repo, you can install the python SDK as follows:
|
|
|
54
54
|
pip install python/
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
Checkout the docs [here](./feldera/__init__.py) for an example on how to use the SDK.
|
|
58
|
-
|
|
59
57
|
## Documentation
|
|
60
58
|
|
|
59
|
+
The Python SDK documentation is available at
|
|
60
|
+
[Feldera Python SDK Docs](https://docs.feldera.com/python).
|
|
61
|
+
|
|
61
62
|
To build the html documentation run:
|
|
62
63
|
|
|
63
64
|
Ensure that you have sphinx installed. If not, install it using `pip install sphinx`.
|
|
@@ -77,27 +78,23 @@ To clean the build, run `make clean`.
|
|
|
77
78
|
To run unit tests:
|
|
78
79
|
|
|
79
80
|
```bash
|
|
80
|
-
|
|
81
|
+
cd python && python3 -m pytest tests/
|
|
81
82
|
```
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
tests, you'll also need a broker available at `localhost:9092` and
|
|
88
|
-
(from the pipelines) `redpanda:19092`. (To change those locations,
|
|
89
|
-
set the environment variables listed in `python/tests/__init__.py`.)
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
(cd python && python3 -m pytest tests)
|
|
93
|
-
```
|
|
84
|
+
- This will detect and run all test files that match the pattern `test_*.py` or
|
|
85
|
+
`*_test.py`.
|
|
86
|
+
- By default, the tests expect a running Feldera instance at `http://localhost:8080`.
|
|
87
|
+
To override the default endpoint, set the `FELDERA_BASE_URL` environment variable.
|
|
94
88
|
|
|
95
89
|
To run tests from a specific file:
|
|
96
90
|
|
|
97
91
|
```bash
|
|
98
|
-
(cd python && python3 -m
|
|
92
|
+
(cd python && python3 -m pytest ./tests/path-to-file.py)
|
|
99
93
|
```
|
|
100
94
|
|
|
95
|
+
#### Running Aggregate Tests
|
|
96
|
+
|
|
97
|
+
The aggregate tests validate end-to-end correctness of SQL functionality.
|
|
101
98
|
To run the aggregate tests use:
|
|
102
99
|
|
|
103
100
|
```bash
|
|
@@ -105,6 +102,38 @@ cd python
|
|
|
105
102
|
PYTHONPATH=`pwd` python3 ./tests/aggregate_tests/main.py
|
|
106
103
|
```
|
|
107
104
|
|
|
105
|
+
### Reducing Compilation Cycles
|
|
106
|
+
|
|
107
|
+
To reduce redundant compilation cycles during testing:
|
|
108
|
+
|
|
109
|
+
* **Inherit from `SharedTestPipeline`** instead of `unittest.TestCase`.
|
|
110
|
+
* **Define DDLs** (e.g., `CREATE TABLE`, `CREATE VIEW`) in the **docstring** of each test method.
|
|
111
|
+
* All DDLs from all test functions in the class are combined and compiled into a single pipeline.
|
|
112
|
+
* If a table or view is already defined in one test, it can be used directly in others without redefinition.
|
|
113
|
+
* Ensure that all table and view names are unique within the class.
|
|
114
|
+
* Use `@enterprise_only` on tests that require Enterprise features. Their DDLs will be skipped on OSS builds.
|
|
115
|
+
* Use `self.set_runtime_config(...)` to override the default pipeline config.
|
|
116
|
+
* Reset it at the end using `self.reset_runtime_config()`.
|
|
117
|
+
* Access the shared pipeline via `self.pipeline`.
|
|
118
|
+
|
|
119
|
+
#### Example
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from tests.shared_test_pipeline import SharedTestPipeline
|
|
123
|
+
|
|
124
|
+
class TestAverage(SharedTestPipeline):
|
|
125
|
+
def test_average(self):
|
|
126
|
+
"""
|
|
127
|
+
CREATE TABLE students(id INT, name STRING);
|
|
128
|
+
CREATE MATERIALIZED VIEW v AS SELECT * FROM students;
|
|
129
|
+
"""
|
|
130
|
+
...
|
|
131
|
+
self.pipeline.start()
|
|
132
|
+
self.pipeline.input_pandas("students", df)
|
|
133
|
+
self.pipeline.wait_for_completion(True)
|
|
134
|
+
...
|
|
135
|
+
```
|
|
136
|
+
|
|
108
137
|
## Linting and formatting
|
|
109
138
|
|
|
110
139
|
Use [Ruff] to run the lint checks that will be executed by the
|
|
@@ -24,7 +24,7 @@ feldera/rest/feldera_config.py
|
|
|
24
24
|
feldera/rest/pipeline.py
|
|
25
25
|
feldera/rest/sql_table.py
|
|
26
26
|
feldera/rest/sql_view.py
|
|
27
|
-
tests/test_pipeline.py
|
|
28
27
|
tests/test_pipeline_builder.py
|
|
29
|
-
tests/
|
|
30
|
-
tests/
|
|
28
|
+
tests/test_shared_pipeline0.py
|
|
29
|
+
tests/test_shared_pipeline1.py
|
|
30
|
+
tests/test_udf.py
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from tests import TEST_CLIENT
|
|
3
|
+
from feldera import PipelineBuilder
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestPipelineBuilder(unittest.TestCase):
|
|
7
|
+
def test_connector_orchestration(self):
|
|
8
|
+
sql = """
|
|
9
|
+
CREATE TABLE numbers (
|
|
10
|
+
num INT
|
|
11
|
+
) WITH (
|
|
12
|
+
'connectors' = '[
|
|
13
|
+
{
|
|
14
|
+
"name": "c1",
|
|
15
|
+
"paused": true,
|
|
16
|
+
"transport": {
|
|
17
|
+
"name": "datagen",
|
|
18
|
+
"config": {"plan": [{ "rate": 1, "fields": { "num": { "range": [0, 10], "strategy": "uniform" } } }]}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
]'
|
|
22
|
+
);
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name = "test_connector_orchestration"
|
|
26
|
+
|
|
27
|
+
pipeline = PipelineBuilder(TEST_CLIENT, name, sql=sql).create_or_replace()
|
|
28
|
+
pipeline.start()
|
|
29
|
+
|
|
30
|
+
pipeline.resume_connector("numbers", "c1")
|
|
31
|
+
stats = TEST_CLIENT.get_pipeline_stats(name)
|
|
32
|
+
c1_status = next(
|
|
33
|
+
item["paused"]
|
|
34
|
+
for item in stats["inputs"]
|
|
35
|
+
if item["endpoint_name"] == "numbers.c1"
|
|
36
|
+
)
|
|
37
|
+
assert not c1_status
|
|
38
|
+
|
|
39
|
+
pipeline.pause_connector("numbers", "c1")
|
|
40
|
+
stats = TEST_CLIENT.get_pipeline_stats(name)
|
|
41
|
+
c2_status = next(
|
|
42
|
+
item["paused"]
|
|
43
|
+
for item in stats["inputs"]
|
|
44
|
+
if item["endpoint_name"] == "numbers.c1"
|
|
45
|
+
)
|
|
46
|
+
assert c2_status
|
|
47
|
+
|
|
48
|
+
pipeline.stop(force=True)
|
|
49
|
+
pipeline.clear_storage()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
unittest.main()
|