FlowerPower 1.0.0b1__py3-none-any.whl → 1.0.0b3__py3-none-any.whl
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.
- flowerpower/__init__.py +2 -3
- flowerpower/cfg/__init__.py +10 -8
- flowerpower/cfg/pipeline/__init__.py +11 -7
- flowerpower/cfg/project/__init__.py +11 -8
- flowerpower/cfg/project/job_queue.py +10 -29
- flowerpower/cli/__init__.py +62 -28
- flowerpower/cli/job_queue.py +306 -123
- flowerpower/cli/mqtt.py +22 -16
- flowerpower/cli/pipeline.py +294 -114
- flowerpower/flowerpower.py +14 -8
- flowerpower/fs/__init__.py +7 -3
- flowerpower/fs/ext.py +6 -2
- flowerpower/io/base.py +17 -10
- flowerpower/io/loader/_duckdb.py +1 -0
- flowerpower/io/loader/deltatable.py +6 -2
- flowerpower/io/saver/deltatable.py +1 -2
- flowerpower/job_queue/__init__.py +16 -12
- flowerpower/job_queue/apscheduler/__init__.py +1 -1
- flowerpower/job_queue/apscheduler/manager.py +11 -6
- flowerpower/job_queue/apscheduler/utils.py +6 -4
- flowerpower/job_queue/base.py +1 -0
- flowerpower/job_queue/rq/__init__.py +1 -1
- flowerpower/job_queue/rq/manager.py +12 -3
- flowerpower/pipeline/io.py +11 -9
- flowerpower/pipeline/job_queue.py +5 -5
- flowerpower/pipeline/manager.py +35 -27
- flowerpower/pipeline/registry.py +26 -16
- flowerpower/pipeline/runner.py +3 -4
- flowerpower/plugins/mqtt/__init__.py +7 -7
- flowerpower/plugins/mqtt/cfg.py +3 -2
- flowerpower/plugins/mqtt/manager.py +25 -23
- flowerpower/utils/misc.py +6 -4
- flowerpower/utils/templates.py +1 -4
- {flowerpower-1.0.0b1.dist-info → flowerpower-1.0.0b3.dist-info}/METADATA +1 -1
- {flowerpower-1.0.0b1.dist-info → flowerpower-1.0.0b3.dist-info}/RECORD +38 -38
- {flowerpower-1.0.0b1.dist-info → flowerpower-1.0.0b3.dist-info}/WHEEL +0 -0
- {flowerpower-1.0.0b1.dist-info → flowerpower-1.0.0b3.dist-info}/entry_points.txt +0 -0
- {flowerpower-1.0.0b1.dist-info → flowerpower-1.0.0b3.dist-info}/top_level.txt +0 -0
flowerpower/__init__.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
import importlib.metadata
|
2
2
|
|
3
|
+
from .cfg import Config, PipelineConfig, ProjectConfig
|
3
4
|
from .flowerpower import init as init_project # noqa: E402
|
4
|
-
|
5
|
-
from .pipeline import PipelineManager
|
6
5
|
from .job_queue import JobQueueManager
|
7
|
-
from .
|
6
|
+
from .pipeline import PipelineManager
|
8
7
|
|
9
8
|
__version__ = importlib.metadata.version("FlowerPower")
|
10
9
|
|
flowerpower/cfg/__init__.py
CHANGED
@@ -3,7 +3,7 @@ from pathlib import Path
|
|
3
3
|
import msgspec
|
4
4
|
from munch import Munch
|
5
5
|
|
6
|
-
from ..fs import AbstractFileSystem, get_filesystem
|
6
|
+
from ..fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
|
7
7
|
from .base import BaseConfig
|
8
8
|
from .pipeline import PipelineConfig, init_pipeline_config
|
9
9
|
from .project import ProjectConfig, init_project_config
|
@@ -51,7 +51,7 @@ class Config(BaseConfig):
|
|
51
51
|
pipeline_name: str | None = None,
|
52
52
|
job_queue_type: str | None = None,
|
53
53
|
fs: AbstractFileSystem | None = None,
|
54
|
-
storage_options: dict |
|
54
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
55
55
|
):
|
56
56
|
"""Load both project and pipeline configurations.
|
57
57
|
|
@@ -77,7 +77,9 @@ class Config(BaseConfig):
|
|
77
77
|
```
|
78
78
|
"""
|
79
79
|
if fs is None:
|
80
|
-
fs = get_filesystem(
|
80
|
+
fs = get_filesystem(
|
81
|
+
base_dir, cached=True, dirfs=True, storage_options=storage_options
|
82
|
+
)
|
81
83
|
project = ProjectConfig.load(
|
82
84
|
base_dir=base_dir,
|
83
85
|
name=name,
|
@@ -105,7 +107,7 @@ class Config(BaseConfig):
|
|
105
107
|
project: bool = False,
|
106
108
|
pipeline: bool = True,
|
107
109
|
fs: AbstractFileSystem | None = None,
|
108
|
-
storage_options: dict |
|
110
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
109
111
|
):
|
110
112
|
"""Save project and/or pipeline configurations.
|
111
113
|
|
@@ -144,7 +146,7 @@ def load(
|
|
144
146
|
base_dir: str,
|
145
147
|
name: str | None = None,
|
146
148
|
pipeline_name: str | None = None,
|
147
|
-
storage_options: dict |
|
149
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
148
150
|
fs: AbstractFileSystem | None = None,
|
149
151
|
):
|
150
152
|
"""Helper function to load configuration.
|
@@ -180,7 +182,7 @@ def save(
|
|
180
182
|
project: bool = False,
|
181
183
|
pipeline: bool = True,
|
182
184
|
fs: AbstractFileSystem | None = None,
|
183
|
-
storage_options: dict |
|
185
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
184
186
|
):
|
185
187
|
"""Helper function to save configuration.
|
186
188
|
|
@@ -210,7 +212,7 @@ def init_config(
|
|
210
212
|
pipeline_name: str | None = None,
|
211
213
|
job_queue_type: str | None = None,
|
212
214
|
fs: AbstractFileSystem | None = None,
|
213
|
-
storage_options: dict |
|
215
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
214
216
|
):
|
215
217
|
"""Initialize a new configuration with both project and pipeline settings.
|
216
218
|
|
@@ -251,4 +253,4 @@ def init_config(
|
|
251
253
|
fs=fs,
|
252
254
|
storage_options=storage_options,
|
253
255
|
)
|
254
|
-
return Config(pipeline=pipeline_cfg, project=project_cfg, fs=fs, base_dir=base_dir)
|
256
|
+
return Config(pipeline=pipeline_cfg, project=project_cfg, fs=fs, base_dir=base_dir)
|
@@ -3,7 +3,7 @@ import yaml
|
|
3
3
|
from hamilton.function_modifiers import source, value
|
4
4
|
from munch import Munch, munchify
|
5
5
|
|
6
|
-
from ...fs import AbstractFileSystem, get_filesystem
|
6
|
+
from ...fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
|
7
7
|
from ..base import BaseConfig
|
8
8
|
from .adapter import AdapterConfig
|
9
9
|
from .run import RunConfig
|
@@ -144,7 +144,7 @@ class PipelineConfig(BaseConfig):
|
|
144
144
|
base_dir: str = ".",
|
145
145
|
name: str | None = None,
|
146
146
|
fs: AbstractFileSystem | None = None,
|
147
|
-
storage_options: dict |
|
147
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
148
148
|
):
|
149
149
|
"""Load pipeline configuration from a YAML file.
|
150
150
|
|
@@ -166,7 +166,9 @@ class PipelineConfig(BaseConfig):
|
|
166
166
|
```
|
167
167
|
"""
|
168
168
|
if fs is None:
|
169
|
-
fs = get_filesystem(
|
169
|
+
fs = get_filesystem(
|
170
|
+
base_dir, cached=False, dirfs=True, storage_options=storage_options
|
171
|
+
)
|
170
172
|
if fs.exists("conf/pipelines"):
|
171
173
|
if name is not None:
|
172
174
|
pipeline = PipelineConfig.from_yaml(
|
@@ -186,7 +188,7 @@ class PipelineConfig(BaseConfig):
|
|
186
188
|
name: str | None = None,
|
187
189
|
base_dir: str = ".",
|
188
190
|
fs: AbstractFileSystem | None = None,
|
189
|
-
storage_options: dict |
|
191
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
190
192
|
):
|
191
193
|
"""Save pipeline configuration to a YAML file.
|
192
194
|
|
@@ -205,7 +207,9 @@ class PipelineConfig(BaseConfig):
|
|
205
207
|
```
|
206
208
|
"""
|
207
209
|
if fs is None:
|
208
|
-
fs = get_filesystem(
|
210
|
+
fs = get_filesystem(
|
211
|
+
base_dir, cached=True, dirfs=True, storage_options=storage_options
|
212
|
+
)
|
209
213
|
|
210
214
|
fs.makedirs("conf/pipelines", exist_ok=True)
|
211
215
|
if name is not None:
|
@@ -224,7 +228,7 @@ def init_pipeline_config(
|
|
224
228
|
base_dir: str = ".",
|
225
229
|
name: str | None = None,
|
226
230
|
fs: AbstractFileSystem | None = None,
|
227
|
-
storage_options: dict |
|
231
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
228
232
|
):
|
229
233
|
"""Initialize a new pipeline configuration.
|
230
234
|
|
@@ -251,4 +255,4 @@ def init_pipeline_config(
|
|
251
255
|
base_dir=base_dir, name=name, fs=fs, storage_options=storage_options
|
252
256
|
)
|
253
257
|
pipeline.save(name=name, base_dir=base_dir, fs=fs, storage_options=storage_options)
|
254
|
-
return pipeline
|
258
|
+
return pipeline
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import msgspec
|
2
|
-
from munch import Munch
|
3
2
|
|
4
|
-
from ...fs import AbstractFileSystem, get_filesystem
|
3
|
+
from ...fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
|
5
4
|
from ..base import BaseConfig
|
6
5
|
from .adapter import AdapterConfig
|
7
6
|
from .job_queue import JobQueueConfig
|
@@ -48,7 +47,7 @@ class ProjectConfig(BaseConfig):
|
|
48
47
|
name: str | None = None,
|
49
48
|
job_queue_type: str | None = None,
|
50
49
|
fs: AbstractFileSystem | None = None,
|
51
|
-
storage_options: dict |
|
50
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
52
51
|
):
|
53
52
|
"""Load project configuration from a YAML file.
|
54
53
|
|
@@ -72,7 +71,9 @@ class ProjectConfig(BaseConfig):
|
|
72
71
|
```
|
73
72
|
"""
|
74
73
|
if fs is None:
|
75
|
-
fs = get_filesystem(
|
74
|
+
fs = get_filesystem(
|
75
|
+
base_dir, cached=False, dirfs=True, storage_options=storage_options
|
76
|
+
)
|
76
77
|
if fs.exists("conf/project.yml"):
|
77
78
|
project = ProjectConfig.from_yaml(path="conf/project.yml", fs=fs)
|
78
79
|
else:
|
@@ -87,7 +88,7 @@ class ProjectConfig(BaseConfig):
|
|
87
88
|
self,
|
88
89
|
base_dir: str = ".",
|
89
90
|
fs: AbstractFileSystem | None = None,
|
90
|
-
storage_options: dict |
|
91
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
91
92
|
):
|
92
93
|
"""Save project configuration to a YAML file.
|
93
94
|
|
@@ -102,7 +103,9 @@ class ProjectConfig(BaseConfig):
|
|
102
103
|
```
|
103
104
|
"""
|
104
105
|
if fs is None:
|
105
|
-
fs = get_filesystem(
|
106
|
+
fs = get_filesystem(
|
107
|
+
base_dir, cached=True, dirfs=True, storage_options=storage_options
|
108
|
+
)
|
106
109
|
|
107
110
|
fs.makedirs("conf", exist_ok=True)
|
108
111
|
self.to_yaml(path="conf/project.yml", fs=fs)
|
@@ -113,7 +116,7 @@ def init_project_config(
|
|
113
116
|
name: str | None = None,
|
114
117
|
job_queue_type: str | None = None,
|
115
118
|
fs: AbstractFileSystem | None = None,
|
116
|
-
storage_options: dict |
|
119
|
+
storage_options: dict | BaseStorageOptions | None = {},
|
117
120
|
):
|
118
121
|
"""Initialize a new project configuration.
|
119
122
|
|
@@ -146,4 +149,4 @@ def init_project_config(
|
|
146
149
|
storage_options=storage_options,
|
147
150
|
)
|
148
151
|
project.save(base_dir=base_dir, fs=fs, storage_options=storage_options)
|
149
|
-
return project
|
152
|
+
return project
|
@@ -6,7 +6,6 @@ from ... import settings
|
|
6
6
|
from ..base import BaseConfig
|
7
7
|
|
8
8
|
|
9
|
-
|
10
9
|
class JobQueueBackendConfig(BaseConfig):
|
11
10
|
"""
|
12
11
|
Job Queue backend configuration for FlowerPower.
|
@@ -30,39 +29,27 @@ class JobQueueBackendConfig(BaseConfig):
|
|
30
29
|
class APSDataStoreConfig(JobQueueBackendConfig):
|
31
30
|
type: str = msgspec.field(default=settings.APS_BACKEND_DS)
|
32
31
|
host: str = msgspec.field(
|
33
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS][
|
34
|
-
"default_host"
|
35
|
-
]
|
32
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS]["default_host"]
|
36
33
|
)
|
37
34
|
port: int = msgspec.field(
|
38
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS][
|
39
|
-
"default_port"
|
40
|
-
]
|
35
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS]["default_port"]
|
41
36
|
)
|
42
37
|
schema: str | None = msgspec.field(default=settings.APS_SCHEMA_DS)
|
43
38
|
username: str = msgspec.field(
|
44
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS][
|
45
|
-
"default_username"
|
46
|
-
]
|
39
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_DS]["default_username"]
|
47
40
|
)
|
48
41
|
|
49
42
|
|
50
43
|
class APSEventBrokerConfig(JobQueueBackendConfig):
|
51
44
|
type: str = msgspec.field(default=settings.APS_BACKEND_EB)
|
52
45
|
host: str = msgspec.field(
|
53
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB][
|
54
|
-
"default_host"
|
55
|
-
]
|
46
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB]["default_host"]
|
56
47
|
)
|
57
48
|
port: int = msgspec.field(
|
58
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB][
|
59
|
-
"default_port"
|
60
|
-
]
|
49
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB]["default_port"]
|
61
50
|
)
|
62
51
|
username: str = msgspec.field(
|
63
|
-
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB][
|
64
|
-
"default_username"
|
65
|
-
]
|
52
|
+
default=settings.BACKEND_PROPERTIES[settings.APS_BACKEND_EB]["default_username"]
|
66
53
|
)
|
67
54
|
from_ds_sqla: bool = msgspec.field(
|
68
55
|
default_factory=lambda: settings.APS_BACKEND_EB == "postgresql"
|
@@ -78,9 +65,7 @@ class APSBackendConfig(BaseConfig):
|
|
78
65
|
cleanup_interval: int | float | dt.timedelta = msgspec.field(
|
79
66
|
default=settings.APS_CLEANUP_INTERVAL
|
80
67
|
) # int in secods
|
81
|
-
max_concurrent_jobs: int = msgspec.field(
|
82
|
-
default=settings.APS_MAX_CONCURRENT_JOBS
|
83
|
-
)
|
68
|
+
max_concurrent_jobs: int = msgspec.field(default=settings.APS_MAX_CONCURRENT_JOBS)
|
84
69
|
default_job_executor: str | None = msgspec.field(default=settings.EXECUTOR)
|
85
70
|
num_workers: int | None = msgspec.field(default=settings.APS_NUM_WORKERS)
|
86
71
|
|
@@ -96,12 +81,8 @@ class RQBackendConfig(JobQueueBackendConfig):
|
|
96
81
|
database: int = msgspec.field(
|
97
82
|
default=settings.BACKEND_PROPERTIES["redis"]["default_database"]
|
98
83
|
)
|
99
|
-
queues: str | list[str] = msgspec.field(
|
100
|
-
|
101
|
-
)
|
102
|
-
num_workers: int = msgspec.field(
|
103
|
-
default=settings.RQ_NUM_WORKERS
|
104
|
-
) # int in secods
|
84
|
+
queues: str | list[str] = msgspec.field(default_factory=lambda: settings.RQ_QUEUES)
|
85
|
+
num_workers: int = msgspec.field(default=settings.RQ_NUM_WORKERS) # int in secods
|
105
86
|
|
106
87
|
|
107
88
|
class HueyBackendConfig(JobQueueBackendConfig):
|
@@ -129,7 +110,7 @@ class JobQueueConfig(BaseConfig):
|
|
129
110
|
)
|
130
111
|
elif self.type == "apscheduler":
|
131
112
|
if self.backend is None:
|
132
|
-
self.backend = APSBackendConfig(
|
113
|
+
self.backend = APSBackendConfig()
|
133
114
|
else:
|
134
115
|
if isinstance(self.backend, dict):
|
135
116
|
self.backend = APSBackendConfig.from_dict(self.backend)
|
flowerpower/cli/__init__.py
CHANGED
@@ -14,58 +14,82 @@ app = typer.Typer(
|
|
14
14
|
)
|
15
15
|
|
16
16
|
|
17
|
-
app.add_typer(
|
17
|
+
app.add_typer(
|
18
|
+
pipeline_app, name="pipeline", help="Manage and execute FlowerPower pipelines"
|
19
|
+
)
|
18
20
|
|
19
21
|
if importlib.util.find_spec("apscheduler") or importlib.util.find_spec("rq"):
|
20
22
|
from .job_queue import app as job_queue_app
|
21
23
|
|
22
|
-
app.add_typer(
|
24
|
+
app.add_typer(
|
25
|
+
job_queue_app,
|
26
|
+
name="job-queue",
|
27
|
+
help="Manage job queue workers and scheduled tasks",
|
28
|
+
)
|
23
29
|
|
24
30
|
if importlib.util.find_spec("paho"):
|
25
31
|
from .mqtt import app as mqtt_app
|
26
32
|
|
27
|
-
app.add_typer(
|
33
|
+
app.add_typer(
|
34
|
+
mqtt_app, name="mqtt", help="Connect pipelines to MQTT message brokers"
|
35
|
+
)
|
28
36
|
|
29
37
|
|
30
38
|
@app.command()
|
31
39
|
def init(
|
32
|
-
project_name: str = typer.Option(
|
33
|
-
|
34
|
-
|
35
|
-
|
40
|
+
project_name: str = typer.Option(
|
41
|
+
None, "--name", "-n", help="Name of the FlowerPower project to create"
|
42
|
+
),
|
43
|
+
base_dir: str = typer.Option(
|
44
|
+
None,
|
45
|
+
"--base-dir",
|
46
|
+
"-d",
|
47
|
+
help="Base directory where the project will be created",
|
48
|
+
),
|
49
|
+
storage_options: str = typer.Option(
|
50
|
+
None, "--storage-options", "-s", help="Storage options as a JSON or dict string"
|
51
|
+
),
|
52
|
+
job_queue_type: str = typer.Option(
|
53
|
+
"rq",
|
54
|
+
"--job-queue-type",
|
55
|
+
"-q",
|
56
|
+
help="Job queue backend type to use (rq, apscheduler)",
|
57
|
+
),
|
36
58
|
):
|
37
59
|
"""
|
38
60
|
Initialize a new FlowerPower project.
|
39
|
-
|
61
|
+
|
40
62
|
This command creates a new FlowerPower project with the necessary directory structure
|
41
63
|
and configuration files. If no project name is provided, the current directory name
|
42
64
|
will be used as the project name.
|
43
|
-
|
65
|
+
|
44
66
|
Args:
|
45
|
-
project_name: Name of the FlowerPower project to create. If not provided,
|
67
|
+
project_name: Name of the FlowerPower project to create. If not provided,
|
46
68
|
the current directory name will be used
|
47
69
|
base_dir: Base directory where the project will be created. If not provided,
|
48
70
|
the current directory's parent will be used
|
49
71
|
storage_options: Storage options for filesystem access, as a JSON or dict string
|
50
72
|
job_queue_type: Type of job queue backend to use (rq, apscheduler)
|
51
|
-
|
73
|
+
|
52
74
|
Examples:
|
53
75
|
# Create a project in the current directory using its name
|
54
76
|
$ flowerpower init
|
55
|
-
|
77
|
+
|
56
78
|
# Create a project with a specific name
|
57
79
|
$ flowerpower init --name my-awesome-project
|
58
|
-
|
80
|
+
|
59
81
|
# Create a project in a specific location
|
60
82
|
$ flowerpower init --name my-project --base-dir /path/to/projects
|
61
|
-
|
83
|
+
|
62
84
|
# Create a project with APScheduler as the job queue backend
|
63
85
|
$ flowerpower init --job-queue-type apscheduler
|
64
86
|
"""
|
65
87
|
parsed_storage_options = {}
|
66
88
|
if storage_options:
|
67
89
|
try:
|
68
|
-
parsed_storage_options =
|
90
|
+
parsed_storage_options = (
|
91
|
+
parse_dict_or_list_param(storage_options, "dict") or {}
|
92
|
+
)
|
69
93
|
except Exception as e:
|
70
94
|
logger.error(f"Error parsing storage options: {e}")
|
71
95
|
raise typer.Exit(code=1)
|
@@ -85,19 +109,29 @@ def init(
|
|
85
109
|
@app.command()
|
86
110
|
def ui(
|
87
111
|
port: int = typer.Option(8241, "--port", "-p", help="Port to run the UI server on"),
|
88
|
-
base_dir: str = typer.Option(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
112
|
+
base_dir: str = typer.Option(
|
113
|
+
"~/.hamilton/db", "--base-dir", "-d", help="Base directory for Hamilton UI data"
|
114
|
+
),
|
115
|
+
no_migration: bool = typer.Option(
|
116
|
+
False, "--no-migration", help="Skip running database migrations"
|
117
|
+
),
|
118
|
+
no_open: bool = typer.Option(
|
119
|
+
False, "--no-open", help="Don't automatically open the UI in a browser"
|
120
|
+
),
|
121
|
+
settings_file: str = typer.Option(
|
122
|
+
"mini", "--settings", "-s", help="Settings file to use for the UI"
|
123
|
+
),
|
124
|
+
config_file: str = typer.Option(
|
125
|
+
None, "--config", "-c", help="Configuration file to use for the UI"
|
126
|
+
),
|
93
127
|
):
|
94
128
|
"""
|
95
129
|
Start the Hamilton UI web application.
|
96
|
-
|
97
|
-
This command launches the Hamilton UI, which provides a web interface for
|
130
|
+
|
131
|
+
This command launches the Hamilton UI, which provides a web interface for
|
98
132
|
visualizing and interacting with your FlowerPower pipelines. The UI allows you
|
99
133
|
to explore pipeline execution graphs, view results, and manage jobs.
|
100
|
-
|
134
|
+
|
101
135
|
Args:
|
102
136
|
port: Port to run the UI server on
|
103
137
|
base_dir: Base directory where the UI will store its data
|
@@ -105,20 +139,20 @@ def ui(
|
|
105
139
|
no_open: Prevent automatically opening the browser
|
106
140
|
settings_file: Settings profile to use (mini, dev, prod)
|
107
141
|
config_file: Optional custom configuration file path
|
108
|
-
|
142
|
+
|
109
143
|
Examples:
|
110
144
|
# Start the UI with default settings
|
111
145
|
$ flowerpower ui
|
112
|
-
|
146
|
+
|
113
147
|
# Run the UI on a specific port
|
114
148
|
$ flowerpower ui --port 9000
|
115
|
-
|
149
|
+
|
116
150
|
# Use a custom data directory
|
117
151
|
$ flowerpower ui --base-dir ~/my-project/.hamilton-data
|
118
|
-
|
152
|
+
|
119
153
|
# Start without opening a browser
|
120
154
|
$ flowerpower ui --no-open
|
121
|
-
|
155
|
+
|
122
156
|
# Use production settings
|
123
157
|
$ flowerpower ui --settings prod
|
124
158
|
"""
|