feldera 0.172.0__tar.gz → 0.219.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.219.0/PKG-INFO +164 -0
- feldera-0.219.0/README.md +141 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/__init__.py +2 -2
- {feldera-0.172.0 → feldera-0.219.0}/feldera/pipeline.py +78 -18
- {feldera-0.172.0 → feldera-0.219.0}/feldera/pipeline_builder.py +11 -7
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/_helpers.py +1 -1
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/_httprequests.py +364 -232
- feldera-0.219.0/feldera/rest/config.py +44 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/errors.py +2 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/feldera_client.py +123 -33
- {feldera-0.172.0 → feldera-0.219.0}/feldera/testutils.py +1 -10
- feldera-0.219.0/feldera.egg-info/PKG-INFO +164 -0
- {feldera-0.172.0 → feldera-0.219.0}/pyproject.toml +4 -6
- feldera-0.172.0/PKG-INFO +0 -97
- feldera-0.172.0/README.md +0 -73
- feldera-0.172.0/feldera/rest/config.py +0 -51
- feldera-0.172.0/feldera.egg-info/PKG-INFO +0 -97
- {feldera-0.172.0 → feldera-0.219.0}/feldera/_callback_runner.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/_helpers.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/enums.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/output_handler.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/__init__.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/feldera_config.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/pipeline.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/sql_table.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/rest/sql_view.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/runtime_config.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/stats.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/tests/test_datafusionize.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera/testutils_oidc.py +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera.egg-info/SOURCES.txt +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera.egg-info/dependency_links.txt +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera.egg-info/requires.txt +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/feldera.egg-info/top_level.txt +0 -0
- {feldera-0.172.0 → feldera-0.219.0}/setup.cfg +0 -0
feldera-0.219.0/PKG-INFO
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: feldera
|
|
3
|
+
Version: 0.219.0
|
|
4
|
+
Summary: The feldera python client
|
|
5
|
+
Author-email: Feldera Team <dev@feldera.com>
|
|
6
|
+
License-Expression: 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: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Requires-Dist: pandas>=2.1.2
|
|
18
|
+
Requires-Dist: typing-extensions
|
|
19
|
+
Requires-Dist: numpy>=2.2.4
|
|
20
|
+
Requires-Dist: pretty-errors
|
|
21
|
+
Requires-Dist: ruff>=0.6.9
|
|
22
|
+
Requires-Dist: PyJWT>=2.8.0
|
|
23
|
+
|
|
24
|
+
# Feldera Python SDK
|
|
25
|
+
|
|
26
|
+
The `feldera` Python package is the Python client for the Feldera HTTP API.
|
|
27
|
+
|
|
28
|
+
The Python SDK documentation is available at: https://docs.feldera.com/python
|
|
29
|
+
|
|
30
|
+
## Getting started
|
|
31
|
+
|
|
32
|
+
### Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv pip install feldera
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Example usage
|
|
39
|
+
|
|
40
|
+
The Python client interacts with the API server of the Feldera instance.
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
# File: example.py
|
|
44
|
+
from feldera import FelderaClient, PipelineBuilder, Pipeline
|
|
45
|
+
|
|
46
|
+
# Instantiate client
|
|
47
|
+
client = FelderaClient() # Default: http://localhost:8080 without authentication
|
|
48
|
+
# client = FelderaClient(url="https://localhost:8080", api_key="apikey:...", requests_verify="/path/to/tls.crt")
|
|
49
|
+
|
|
50
|
+
# (Re)create pipeline
|
|
51
|
+
name = "example"
|
|
52
|
+
sql = """
|
|
53
|
+
CREATE TABLE t1 (i1 INT) WITH ('materialized' = 'true');
|
|
54
|
+
CREATE MATERIALIZED VIEW v1 AS SELECT * FROM t1;
|
|
55
|
+
"""
|
|
56
|
+
print("(Re)creating pipeline...")
|
|
57
|
+
pipeline = PipelineBuilder(client, name, sql).create_or_replace()
|
|
58
|
+
pipeline.start()
|
|
59
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
60
|
+
pipeline.pause()
|
|
61
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
62
|
+
pipeline.stop(force=True)
|
|
63
|
+
|
|
64
|
+
# Find existing pipeline
|
|
65
|
+
pipeline = Pipeline.get(name, client)
|
|
66
|
+
pipeline.start()
|
|
67
|
+
print(f"Pipeline status: {pipeline.status()}")
|
|
68
|
+
pipeline.stop(force=True)
|
|
69
|
+
pipeline.clear_storage()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Run using:
|
|
73
|
+
```bash
|
|
74
|
+
uv run python example.py
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Environment variables
|
|
78
|
+
|
|
79
|
+
Some default parameter values in the Python SDK can be overridden via environment variables.
|
|
80
|
+
|
|
81
|
+
**Environment variables for `FelderaClient(...)`**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
export FELDERA_HOST="https://localhost:8080" # Overrides default for `url`
|
|
85
|
+
export FELDERA_API_KEY="apikey:..." # Overrides default for `api_key`
|
|
86
|
+
|
|
87
|
+
# The following together override default for `requests_verify`
|
|
88
|
+
# export FELDERA_TLS_INSECURE="false" # If set to "1", "true" or "yes" (all case-insensitive), disables TLS certificate verification
|
|
89
|
+
# export FELDERA_HTTPS_TLS_CERT="/path/to/tls.crt" # Custom TLS certificate
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Environment variables for `PipelineBuilder(...)`**
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
export FELDERA_RUNTIME_VERSION="..." # Overrides default for `runtime_version`
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
Development assumes you have cloned the Feldera code repository.
|
|
101
|
+
|
|
102
|
+
### Installation
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd python
|
|
106
|
+
# Optional: create and activate virtual environment if you don't have one
|
|
107
|
+
uv venv
|
|
108
|
+
source .venv/bin/activate
|
|
109
|
+
# Install in editable mode
|
|
110
|
+
uv pip install -e .
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Formatting
|
|
114
|
+
|
|
115
|
+
Formatting requires the `ruff` package: `uv pip install ruff`
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd python
|
|
119
|
+
ruff check
|
|
120
|
+
ruff format
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Tests
|
|
124
|
+
|
|
125
|
+
Running the test requires the `pytest` package: `uv pip install pytest`
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# All tests
|
|
129
|
+
cd python
|
|
130
|
+
uv run python -m pytest tests/
|
|
131
|
+
|
|
132
|
+
# Specific tests directory
|
|
133
|
+
uv run python -m pytest tests/platform/
|
|
134
|
+
|
|
135
|
+
# Specific test file
|
|
136
|
+
uv run python -m pytest tests/platform/test_pipeline_crud.py
|
|
137
|
+
|
|
138
|
+
# Tip: add argument -x at the end for it to fail fast
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For further information about the tests, please see `tests/README.md`.
|
|
142
|
+
|
|
143
|
+
### Documentation
|
|
144
|
+
|
|
145
|
+
Building documentation requires the `sphinx` package: `uv pip install sphinx`
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cd python/docs
|
|
149
|
+
sphinx-apidoc -o . ../feldera
|
|
150
|
+
make html
|
|
151
|
+
make clean # Cleanup afterwards
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Installation from GitHub
|
|
155
|
+
|
|
156
|
+
Latest `main` branch:
|
|
157
|
+
```bash
|
|
158
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Different branch (replace `BRANCH_NAME`):
|
|
162
|
+
```bash
|
|
163
|
+
uv pip install git+https://github.com/feldera/feldera@BRANCH_NAME#subdirectory=python
|
|
164
|
+
```
|
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
# Tip: add argument -x at the end for it to fail fast
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For further information about the tests, please see `tests/README.md`.
|
|
119
|
+
|
|
120
|
+
### Documentation
|
|
121
|
+
|
|
122
|
+
Building documentation requires the `sphinx` package: `uv pip install sphinx`
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
cd python/docs
|
|
126
|
+
sphinx-apidoc -o . ../feldera
|
|
127
|
+
make html
|
|
128
|
+
make clean # Cleanup afterwards
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Installation from GitHub
|
|
132
|
+
|
|
133
|
+
Latest `main` branch:
|
|
134
|
+
```bash
|
|
135
|
+
uv pip install git+https://github.com/feldera/feldera#subdirectory=python
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Different branch (replace `BRANCH_NAME`):
|
|
139
|
+
```bash
|
|
140
|
+
uv pip install git+https://github.com/feldera/feldera@BRANCH_NAME#subdirectory=python
|
|
141
|
+
```
|
|
@@ -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
|
|
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import pathlib
|
|
2
3
|
import time
|
|
4
|
+
from collections import deque
|
|
3
5
|
from datetime import datetime
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import pandas
|
|
6
|
+
from threading import Event
|
|
7
|
+
from typing import Any, Callable, Dict, Generator, List, Mapping, Optional
|
|
7
8
|
from uuid import UUID
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
from threading import Event
|
|
11
|
-
from collections import deque
|
|
10
|
+
import pandas
|
|
12
11
|
|
|
13
|
-
from feldera.
|
|
12
|
+
from feldera._callback_runner import CallbackRunner
|
|
13
|
+
from feldera._helpers import chunk_dataframe, ensure_dataframe_has_columns
|
|
14
14
|
from feldera.enums import (
|
|
15
15
|
BootstrapPolicy,
|
|
16
|
-
CompletionTokenStatus,
|
|
17
|
-
PipelineFieldSelector,
|
|
18
|
-
PipelineStatus,
|
|
19
|
-
ProgramStatus,
|
|
20
16
|
CheckpointStatus,
|
|
21
|
-
|
|
22
|
-
StorageStatus,
|
|
17
|
+
CompletionTokenStatus,
|
|
23
18
|
DeploymentDesiredStatus,
|
|
24
19
|
DeploymentResourcesDesiredStatus,
|
|
25
20
|
DeploymentResourcesStatus,
|
|
26
21
|
DeploymentRuntimeDesiredStatus,
|
|
27
22
|
DeploymentRuntimeStatus,
|
|
23
|
+
PipelineFieldSelector,
|
|
24
|
+
PipelineStatus,
|
|
25
|
+
ProgramStatus,
|
|
26
|
+
StorageStatus,
|
|
27
|
+
TransactionStatus,
|
|
28
28
|
)
|
|
29
|
-
from feldera.rest.pipeline import Pipeline as InnerPipeline
|
|
30
|
-
from feldera.rest.feldera_client import FelderaClient
|
|
31
|
-
from feldera._callback_runner import CallbackRunner
|
|
32
29
|
from feldera.output_handler import OutputHandler
|
|
33
|
-
from feldera.
|
|
30
|
+
from feldera.rest.errors import FelderaAPIError
|
|
31
|
+
from feldera.rest.feldera_client import FelderaClient
|
|
32
|
+
from feldera.rest.pipeline import Pipeline as InnerPipeline
|
|
34
33
|
from feldera.rest.sql_table import SQLTable
|
|
35
34
|
from feldera.rest.sql_view import SQLView
|
|
36
35
|
from feldera.runtime_config import RuntimeConfig
|
|
@@ -826,10 +825,11 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
826
825
|
|
|
827
826
|
resp = self.client.sync_checkpoint_status(self.name)
|
|
828
827
|
success = resp.get("success")
|
|
828
|
+
periodic = resp.get("periodic")
|
|
829
829
|
|
|
830
830
|
fail = resp.get("failure") or {}
|
|
831
831
|
|
|
832
|
-
if uuid == success:
|
|
832
|
+
if uuid == success or uuid == periodic:
|
|
833
833
|
return CheckpointStatus.Success
|
|
834
834
|
|
|
835
835
|
fail = resp.get("failure") or {}
|
|
@@ -844,6 +844,26 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
844
844
|
|
|
845
845
|
return CheckpointStatus.Unknown
|
|
846
846
|
|
|
847
|
+
def last_successful_checkpoint_sync(self) -> UUID:
|
|
848
|
+
"""
|
|
849
|
+
Returns the UUID of the last successfully synced checkpoint.
|
|
850
|
+
|
|
851
|
+
:return: The UUID of the last successfully synced checkpoint.
|
|
852
|
+
"""
|
|
853
|
+
|
|
854
|
+
resp = self.client.sync_checkpoint_status(self.name)
|
|
855
|
+
success = resp.get("success")
|
|
856
|
+
periodic = resp.get("periodic")
|
|
857
|
+
|
|
858
|
+
if success is None and periodic is None:
|
|
859
|
+
raise RuntimeError("no checkpoints have been synced yet")
|
|
860
|
+
elif success is None:
|
|
861
|
+
return UUID(periodic)
|
|
862
|
+
elif periodic is None:
|
|
863
|
+
return UUID(success)
|
|
864
|
+
else:
|
|
865
|
+
return max(UUID(success), UUID(periodic))
|
|
866
|
+
|
|
847
867
|
def query(self, query: str) -> Generator[Mapping[str, Any], None, None]:
|
|
848
868
|
"""
|
|
849
869
|
Executes an ad-hoc SQL query on this pipeline and returns a generator
|
|
@@ -1337,6 +1357,7 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
1337
1357
|
stats: bool = True,
|
|
1338
1358
|
pipeline_config: bool = True,
|
|
1339
1359
|
system_config: bool = True,
|
|
1360
|
+
dataflow_graph: bool = True,
|
|
1340
1361
|
) -> bytes:
|
|
1341
1362
|
"""
|
|
1342
1363
|
Generate a support bundle containing diagnostic information from this pipeline.
|
|
@@ -1354,6 +1375,7 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
1354
1375
|
:param stats: Whether to collect stats data (default: True)
|
|
1355
1376
|
:param pipeline_config: Whether to collect pipeline configuration data (default: True)
|
|
1356
1377
|
:param system_config: Whether to collect system configuration data (default: True)
|
|
1378
|
+
:param dataflow_graph: Whether to collect dataflow graph (default: True)
|
|
1357
1379
|
:return: The support bundle as bytes (ZIP archive)
|
|
1358
1380
|
:raises FelderaAPIError: If the pipeline does not exist or if there's an error
|
|
1359
1381
|
"""
|
|
@@ -1374,6 +1396,8 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
1374
1396
|
params["pipeline_config"] = "false"
|
|
1375
1397
|
if not system_config:
|
|
1376
1398
|
params["system_config"] = "false"
|
|
1399
|
+
if not dataflow_graph:
|
|
1400
|
+
params["dataflow_graph"] = "false"
|
|
1377
1401
|
|
|
1378
1402
|
support_bundle_bytes = self.client.get_pipeline_support_bundle(
|
|
1379
1403
|
self.name, params=params
|
|
@@ -1393,6 +1417,42 @@ pipeline '{self.name}' to sync checkpoint '{uuid}'"""
|
|
|
1393
1417
|
|
|
1394
1418
|
return support_bundle_bytes
|
|
1395
1419
|
|
|
1420
|
+
def start_samply_profile(self, duration: int = 30):
|
|
1421
|
+
"""
|
|
1422
|
+
Starts profiling this pipeline using samply.
|
|
1423
|
+
|
|
1424
|
+
:param duration: The duration of the profile in seconds (default: 30)
|
|
1425
|
+
:raises FelderaAPIError: If the pipeline does not exist or if there's an error
|
|
1426
|
+
"""
|
|
1427
|
+
|
|
1428
|
+
self.client.start_samply_profile(self.name, duration)
|
|
1429
|
+
|
|
1430
|
+
def get_samply_profile(self, output_path: Optional[str] = None) -> bytes:
|
|
1431
|
+
"""
|
|
1432
|
+
Returns the gzip file of the samply profile as bytes.
|
|
1433
|
+
|
|
1434
|
+
The gzip file contains the samply profile that can be inspected by the samply tool.
|
|
1435
|
+
|
|
1436
|
+
:param output_path: Optional path to save the samply profile file. If None,
|
|
1437
|
+
the samply profile is only returned as bytes.
|
|
1438
|
+
:return: The samply profile as bytes (GZIP file)
|
|
1439
|
+
:raises FelderaAPIError: If the pipeline does not exist or if there's an error
|
|
1440
|
+
"""
|
|
1441
|
+
|
|
1442
|
+
samply_profile_bytes = self.client.get_samply_profile(self.name)
|
|
1443
|
+
|
|
1444
|
+
if output_path is not None:
|
|
1445
|
+
path = pathlib.Path(output_path)
|
|
1446
|
+
|
|
1447
|
+
if path.suffix != ".gz":
|
|
1448
|
+
path = path.with_suffix(".gz")
|
|
1449
|
+
with open(path, "wb") as f:
|
|
1450
|
+
f.write(samply_profile_bytes)
|
|
1451
|
+
|
|
1452
|
+
print(f"Samply profile written to {path}")
|
|
1453
|
+
|
|
1454
|
+
return samply_profile_bytes
|
|
1455
|
+
|
|
1396
1456
|
def generate_completion_token(self, table_name: str, connector_name: str) -> str:
|
|
1397
1457
|
"""
|
|
1398
1458
|
Returns a completion token that can be passed to :meth:`.Pipeline.completion_token_status` to
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
|
+
from feldera.enums import CompilationProfile, PipelineFieldSelector
|
|
5
|
+
from feldera.pipeline import Pipeline
|
|
6
|
+
from feldera.rest.errors import FelderaAPIError
|
|
4
7
|
from feldera.rest.feldera_client import FelderaClient
|
|
5
8
|
from feldera.rest.pipeline import Pipeline as InnerPipeline
|
|
6
|
-
from feldera.pipeline import Pipeline
|
|
7
|
-
from feldera.enums import CompilationProfile, PipelineFieldSelector
|
|
8
9
|
from feldera.runtime_config import RuntimeConfig
|
|
9
|
-
from feldera.rest.errors import FelderaAPIError
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class PipelineBuilder:
|
|
@@ -49,10 +49,11 @@ class PipelineBuilder:
|
|
|
49
49
|
"FELDERA_RUNTIME_VERSION", runtime_version
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
-
def create(self) -> Pipeline:
|
|
52
|
+
def create(self, wait: bool = True) -> Pipeline:
|
|
53
53
|
"""
|
|
54
54
|
Create the pipeline if it does not exist.
|
|
55
55
|
|
|
56
|
+
:param wait: Whether to wait for the pipeline to be created. True by default
|
|
56
57
|
:return: The created pipeline
|
|
57
58
|
"""
|
|
58
59
|
|
|
@@ -82,17 +83,20 @@ class PipelineBuilder:
|
|
|
82
83
|
runtime_config=self.runtime_config.to_dict(),
|
|
83
84
|
)
|
|
84
85
|
|
|
85
|
-
inner = self.client.create_pipeline(inner)
|
|
86
|
+
inner = self.client.create_pipeline(inner, wait=wait)
|
|
86
87
|
pipeline = Pipeline(self.client)
|
|
87
88
|
pipeline._inner = inner
|
|
88
89
|
|
|
89
90
|
return pipeline
|
|
90
91
|
|
|
91
|
-
def create_or_replace(self) -> Pipeline:
|
|
92
|
+
def create_or_replace(self, wait: bool = True) -> Pipeline:
|
|
92
93
|
"""
|
|
93
94
|
Creates a pipeline if it does not exist and replaces it if it exists.
|
|
94
95
|
|
|
95
96
|
If the pipeline exists and is running, it will be stopped and replaced.
|
|
97
|
+
|
|
98
|
+
:param wait: Whether to wait for the pipeline to be created. True by default
|
|
99
|
+
:return: The created pipeline
|
|
96
100
|
"""
|
|
97
101
|
|
|
98
102
|
if self.name is None or self.sql is None:
|
|
@@ -121,7 +125,7 @@ class PipelineBuilder:
|
|
|
121
125
|
runtime_config=self.runtime_config.to_dict(),
|
|
122
126
|
)
|
|
123
127
|
|
|
124
|
-
inner = self.client.create_or_update_pipeline(inner)
|
|
128
|
+
inner = self.client.create_or_update_pipeline(inner, wait=wait)
|
|
125
129
|
pipeline = Pipeline(self.client)
|
|
126
130
|
pipeline._inner = inner
|
|
127
131
|
|