FlowerPower 0.11.6.20__py3-none-any.whl → 0.21.0__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 -6
- flowerpower/cfg/__init__.py +7 -14
- flowerpower/cfg/base.py +29 -25
- flowerpower/cfg/pipeline/__init__.py +8 -6
- flowerpower/cfg/pipeline/_schedule.py +32 -0
- flowerpower/cfg/pipeline/adapter.py +0 -5
- flowerpower/cfg/pipeline/builder.py +377 -0
- flowerpower/cfg/pipeline/run.py +36 -0
- flowerpower/cfg/project/__init__.py +11 -24
- flowerpower/cfg/project/adapter.py +0 -12
- flowerpower/cli/__init__.py +2 -21
- flowerpower/cli/cfg.py +0 -3
- flowerpower/cli/mqtt.py +0 -6
- flowerpower/cli/pipeline.py +22 -415
- flowerpower/cli/utils.py +0 -1
- flowerpower/flowerpower.py +345 -146
- flowerpower/pipeline/__init__.py +2 -0
- flowerpower/pipeline/base.py +21 -12
- flowerpower/pipeline/io.py +58 -54
- flowerpower/pipeline/manager.py +165 -726
- flowerpower/pipeline/pipeline.py +643 -0
- flowerpower/pipeline/registry.py +285 -18
- flowerpower/pipeline/visualizer.py +5 -6
- flowerpower/plugins/io/__init__.py +8 -0
- flowerpower/plugins/mqtt/__init__.py +7 -11
- flowerpower/settings/__init__.py +0 -2
- flowerpower/settings/{backend.py → _backend.py} +0 -21
- flowerpower/settings/logging.py +1 -1
- flowerpower/utils/logging.py +24 -12
- flowerpower/utils/misc.py +17 -256
- flowerpower/utils/monkey.py +1 -83
- flowerpower-0.21.0.dist-info/METADATA +463 -0
- flowerpower-0.21.0.dist-info/RECORD +44 -0
- flowerpower/cfg/pipeline/schedule.py +0 -74
- flowerpower/cfg/project/job_queue.py +0 -238
- flowerpower/cli/job_queue.py +0 -1061
- flowerpower/fs/__init__.py +0 -29
- flowerpower/fs/base.py +0 -662
- flowerpower/fs/ext.py +0 -2143
- flowerpower/fs/storage_options.py +0 -1420
- flowerpower/job_queue/__init__.py +0 -294
- flowerpower/job_queue/apscheduler/__init__.py +0 -11
- flowerpower/job_queue/apscheduler/_setup/datastore.py +0 -110
- flowerpower/job_queue/apscheduler/_setup/eventbroker.py +0 -93
- flowerpower/job_queue/apscheduler/manager.py +0 -1051
- flowerpower/job_queue/apscheduler/setup.py +0 -554
- flowerpower/job_queue/apscheduler/trigger.py +0 -169
- flowerpower/job_queue/apscheduler/utils.py +0 -311
- flowerpower/job_queue/base.py +0 -413
- flowerpower/job_queue/rq/__init__.py +0 -10
- flowerpower/job_queue/rq/_trigger.py +0 -37
- flowerpower/job_queue/rq/concurrent_workers/gevent_worker.py +0 -226
- flowerpower/job_queue/rq/concurrent_workers/thread_worker.py +0 -231
- flowerpower/job_queue/rq/manager.py +0 -1582
- flowerpower/job_queue/rq/setup.py +0 -154
- flowerpower/job_queue/rq/utils.py +0 -69
- flowerpower/mqtt.py +0 -12
- flowerpower/pipeline/job_queue.py +0 -583
- flowerpower/pipeline/runner.py +0 -603
- flowerpower/plugins/io/base.py +0 -2520
- flowerpower/plugins/io/helpers/datetime.py +0 -298
- flowerpower/plugins/io/helpers/polars.py +0 -875
- flowerpower/plugins/io/helpers/pyarrow.py +0 -570
- flowerpower/plugins/io/helpers/sql.py +0 -202
- flowerpower/plugins/io/loader/__init__.py +0 -28
- flowerpower/plugins/io/loader/csv.py +0 -37
- flowerpower/plugins/io/loader/deltatable.py +0 -190
- flowerpower/plugins/io/loader/duckdb.py +0 -19
- flowerpower/plugins/io/loader/json.py +0 -37
- flowerpower/plugins/io/loader/mqtt.py +0 -159
- flowerpower/plugins/io/loader/mssql.py +0 -26
- flowerpower/plugins/io/loader/mysql.py +0 -26
- flowerpower/plugins/io/loader/oracle.py +0 -26
- flowerpower/plugins/io/loader/parquet.py +0 -35
- flowerpower/plugins/io/loader/postgres.py +0 -26
- flowerpower/plugins/io/loader/pydala.py +0 -19
- flowerpower/plugins/io/loader/sqlite.py +0 -23
- flowerpower/plugins/io/metadata.py +0 -244
- flowerpower/plugins/io/saver/__init__.py +0 -28
- flowerpower/plugins/io/saver/csv.py +0 -36
- flowerpower/plugins/io/saver/deltatable.py +0 -186
- flowerpower/plugins/io/saver/duckdb.py +0 -19
- flowerpower/plugins/io/saver/json.py +0 -36
- flowerpower/plugins/io/saver/mqtt.py +0 -28
- flowerpower/plugins/io/saver/mssql.py +0 -26
- flowerpower/plugins/io/saver/mysql.py +0 -26
- flowerpower/plugins/io/saver/oracle.py +0 -26
- flowerpower/plugins/io/saver/parquet.py +0 -36
- flowerpower/plugins/io/saver/postgres.py +0 -26
- flowerpower/plugins/io/saver/pydala.py +0 -20
- flowerpower/plugins/io/saver/sqlite.py +0 -24
- flowerpower/plugins/mqtt/cfg.py +0 -17
- flowerpower/plugins/mqtt/manager.py +0 -962
- flowerpower/settings/job_queue.py +0 -87
- flowerpower/utils/scheduler.py +0 -311
- flowerpower-0.11.6.20.dist-info/METADATA +0 -537
- flowerpower-0.11.6.20.dist-info/RECORD +0 -102
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/WHEEL +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.11.6.20.dist-info → flowerpower-0.21.0.dist-info}/top_level.txt +0 -0
@@ -1,238 +0,0 @@
|
|
1
|
-
import datetime as dt
|
2
|
-
import importlib
|
3
|
-
import os
|
4
|
-
|
5
|
-
import msgspec
|
6
|
-
|
7
|
-
from ... import settings
|
8
|
-
from ...settings.backend import BACKEND_PROPERTIES
|
9
|
-
from ..base import BaseConfig
|
10
|
-
|
11
|
-
|
12
|
-
class JobQueueBackendConfig(BaseConfig):
|
13
|
-
"""
|
14
|
-
Job Queue backend configuration for FlowerPower.
|
15
|
-
Inherits from BaseConfig and adapts Redis logic.
|
16
|
-
"""
|
17
|
-
|
18
|
-
type: str | None = msgspec.field(default=None)
|
19
|
-
uri: str | None = msgspec.field(default=None)
|
20
|
-
username: str | None = msgspec.field(default=None)
|
21
|
-
password: str | None = msgspec.field(default=None)
|
22
|
-
host: str | None = msgspec.field(default=None)
|
23
|
-
port: int | None = msgspec.field(default=None)
|
24
|
-
database: int | None = msgspec.field(default=None)
|
25
|
-
ssl: bool = msgspec.field(default=False)
|
26
|
-
cert_file: str | None = msgspec.field(default=None)
|
27
|
-
key_file: str | None = msgspec.field(default=None)
|
28
|
-
ca_file: str | None = msgspec.field(default=None)
|
29
|
-
verify_ssl: bool = msgspec.field(default=False)
|
30
|
-
|
31
|
-
|
32
|
-
class APSDataStoreConfig(JobQueueBackendConfig):
|
33
|
-
type: str = msgspec.field(default=settings.APS_BACKEND_DS or "memory")
|
34
|
-
username: str | None = msgspec.field(default=None)
|
35
|
-
password: str | None = msgspec.field(default=None)
|
36
|
-
host: str | None = msgspec.field(default=None)
|
37
|
-
port: int | None = msgspec.field(default=None)
|
38
|
-
database: str | None = msgspec.field(default=None)
|
39
|
-
schema: str | None = msgspec.field(default=None)
|
40
|
-
|
41
|
-
def __post_init__(self):
|
42
|
-
self.update_settings_from_env()
|
43
|
-
self.host = (
|
44
|
-
settings.APS_BACKEND_DS_HOST
|
45
|
-
or BACKEND_PROPERTIES[self.type]["default_host"]
|
46
|
-
)
|
47
|
-
self.port = (
|
48
|
-
settings.APS_BACKEND_DS_PORT
|
49
|
-
or BACKEND_PROPERTIES[self.type]["default_port"]
|
50
|
-
)
|
51
|
-
self.database = (
|
52
|
-
settings.APS_BACKEND_DS_DB
|
53
|
-
or BACKEND_PROPERTIES[self.type]["default_database"]
|
54
|
-
)
|
55
|
-
self.username = (
|
56
|
-
settings.APS_BACKEND_DS_USERNAME
|
57
|
-
or BACKEND_PROPERTIES[self.type]["default_username"]
|
58
|
-
)
|
59
|
-
self.password = (
|
60
|
-
settings.APS_BACKEND_DS_PASSWORD
|
61
|
-
or BACKEND_PROPERTIES[self.type]["default_password"]
|
62
|
-
)
|
63
|
-
|
64
|
-
def update_settings_from_env(self):
|
65
|
-
if os.getenv("FP_APS_BACKEND_DS") is not None:
|
66
|
-
settings.APS_BACKEND_DS = os.getenv("FP_APS_BACKEND_DS")
|
67
|
-
if os.getenv("FP_APS_BACKEND_DS_USERNAME") is not None:
|
68
|
-
settings.APS_BACKEND_DS_USERNAME = os.getenv("FP_APS_BACKEND_DS_USERNAME")
|
69
|
-
if os.getenv("FP_APS_BACKEND_DS_PASSWORD") is not None:
|
70
|
-
settings.APS_BACKEND_DS_PASSWORD = os.getenv("FP_APS_BACKEND_DS_PASSWORD")
|
71
|
-
if os.getenv("FP_APS_BACKEND_DS_HOST") is not None:
|
72
|
-
settings.APS_BACKEND_DS_HOST = os.getenv("FP_APS_BACKEND_DS_HOST")
|
73
|
-
if os.getenv("FP_APS_BACKEND_DS_PORT") is not None:
|
74
|
-
settings.APS_BACKEND_DS_PORT = int(os.getenv("FP_APS_BACKEND_DS_PORT"))
|
75
|
-
if os.getenv("FP_APS_BACKEND_DS_DB") is not None:
|
76
|
-
settings.APS_BACKEND_DS_DB = os.getenv("FP_APS_BACKEND_DS_DB")
|
77
|
-
|
78
|
-
|
79
|
-
class APSEventBrokerConfig(JobQueueBackendConfig):
|
80
|
-
type: str = msgspec.field(default=settings.APS_BACKEND_EB or "memory")
|
81
|
-
username: str | None = msgspec.field(default=None)
|
82
|
-
password: str | None = msgspec.field(default=None)
|
83
|
-
host: str | None = msgspec.field(default=None)
|
84
|
-
port: int | None = msgspec.field(default=None)
|
85
|
-
database: str | None = msgspec.field(default=None)
|
86
|
-
from_ds_sqla: bool = msgspec.field(
|
87
|
-
default_factory=lambda: settings.APS_BACKEND_EB == "postgresql"
|
88
|
-
and settings.APS_BACKEND_DS == "postgresql"
|
89
|
-
)
|
90
|
-
|
91
|
-
def __post_init__(self):
|
92
|
-
self.update_settings_from_env()
|
93
|
-
self.host = (
|
94
|
-
settings.APS_BACKEND_EB_HOST
|
95
|
-
or BACKEND_PROPERTIES[self.type]["default_host"]
|
96
|
-
)
|
97
|
-
self.port = (
|
98
|
-
settings.APS_BACKEND_EB_PORT
|
99
|
-
or BACKEND_PROPERTIES[self.type]["default_port"]
|
100
|
-
)
|
101
|
-
self.database = (
|
102
|
-
settings.APS_BACKEND_EB_DB
|
103
|
-
or BACKEND_PROPERTIES[self.type]["default_database"]
|
104
|
-
)
|
105
|
-
self.username = (
|
106
|
-
settings.APS_BACKEND_EB_USERNAME
|
107
|
-
or BACKEND_PROPERTIES[self.type]["default_username"]
|
108
|
-
)
|
109
|
-
self.password = (
|
110
|
-
settings.APS_BACKEND_EB_PASSWORD
|
111
|
-
or BACKEND_PROPERTIES[self.type]["default_password"]
|
112
|
-
)
|
113
|
-
|
114
|
-
def update_settings_from_env(self):
|
115
|
-
if os.getenv("FP_APS_BACKEND_EB") is not None:
|
116
|
-
settings.APS_BACKEND_EB = os.getenv("FP_APS_BACKEND_EB")
|
117
|
-
if os.getenv("FP_APS_BACKEND_EB_USERNAME") is not None:
|
118
|
-
settings.APS_BACKEND_EB_USERNAME = os.getenv("FP_APS_BACKEND_EB_USERNAME")
|
119
|
-
if os.getenv("FP_APS_BACKEND_EB_PASSWORD") is not None:
|
120
|
-
settings.APS_BACKEND_EB_PASSWORD = os.getenv("FP_APS_BACKEND_EB_PASSWORD")
|
121
|
-
if os.getenv("FP_APS_BACKEND_EB_HOST") is not None:
|
122
|
-
settings.APS_BACKEND_EB_HOST = os.getenv("FP_APS_BACKEND_EB_HOST")
|
123
|
-
if os.getenv("FP_APS_BACKEND_EB_PORT") is not None:
|
124
|
-
settings.APS_BACKEND_EB_PORT = int(os.getenv("FP_APS_BACKEND_EB_PORT"))
|
125
|
-
if os.getenv("FP_APS_BACKEND_EB_DB") is not None:
|
126
|
-
settings.APS_BACKEND_EB_DB = os.getenv("FP_APS_BACKEND_EB_DB")
|
127
|
-
|
128
|
-
|
129
|
-
class APSBackendConfig(BaseConfig):
|
130
|
-
data_store: APSDataStoreConfig = msgspec.field(default_factory=APSDataStoreConfig)
|
131
|
-
event_broker: APSEventBrokerConfig = msgspec.field(
|
132
|
-
default_factory=APSEventBrokerConfig
|
133
|
-
)
|
134
|
-
cleanup_interval: int | float | dt.timedelta = msgspec.field(
|
135
|
-
default=settings.APS_CLEANUP_INTERVAL
|
136
|
-
) # int in seconds
|
137
|
-
max_concurrent_jobs: int = msgspec.field(default=settings.APS_MAX_CONCURRENT_JOBS)
|
138
|
-
default_job_executor: str | None = msgspec.field(default=settings.EXECUTOR)
|
139
|
-
# num_workers: int | None = msgspec.field(default=settings.APS_NUM_WORKERS)
|
140
|
-
|
141
|
-
# def __post_init__(self):
|
142
|
-
# self.data_store.update_settings_from_env()
|
143
|
-
# self.event_broker.update_settings_from_env()
|
144
|
-
|
145
|
-
|
146
|
-
class RQBackendConfig(JobQueueBackendConfig):
|
147
|
-
type: str = msgspec.field(default="redis")
|
148
|
-
username: str | None = msgspec.field(default=settings.RQ_BACKEND_USERNAME)
|
149
|
-
password: str | None = msgspec.field(default=settings.RQ_BACKEND_PASSWORD)
|
150
|
-
host: str = msgspec.field(default=settings.RQ_BACKEND_HOST)
|
151
|
-
port: int = msgspec.field(default=settings.RQ_BACKEND_PORT)
|
152
|
-
database: int = msgspec.field(default=settings.RQ_BACKEND_DB)
|
153
|
-
queues: str | list[str] = msgspec.field(default_factory=lambda: settings.RQ_QUEUES)
|
154
|
-
# num_workers: int = msgspec.field(default=settings.RQ_NUM_WORKERS) # int in seconds
|
155
|
-
|
156
|
-
def update_from_settings(self):
|
157
|
-
if self.host == BACKEND_PROPERTIES[self.type]["default_host"]:
|
158
|
-
self.host = settings.RQ_BACKEND_HOST
|
159
|
-
if self.port == BACKEND_PROPERTIES[self.type]["default_port"]:
|
160
|
-
self.port = settings.RQ_BACKEND_PORT
|
161
|
-
if self.database == BACKEND_PROPERTIES[self.type]["default_database"]:
|
162
|
-
self.database = settings.RQ_BACKEND_DB
|
163
|
-
if self.username == BACKEND_PROPERTIES[self.type]["default_username"]:
|
164
|
-
self.username = settings.RQ_BACKEND_USERNAME
|
165
|
-
if self.password == BACKEND_PROPERTIES[self.type]["default_password"]:
|
166
|
-
self.password = settings.RQ_BACKEND_PASSWORD
|
167
|
-
|
168
|
-
def update_from_env(self):
|
169
|
-
if os.getenv("FP_RQ_BACKEND") is not None:
|
170
|
-
settings.RQ_BACKEND = os.getenv("FP_RQ_BACKEND")
|
171
|
-
if os.getenv("FP_RQ_BACKEND_USERNAME") is not None:
|
172
|
-
settings.RQ_BACKEND_USERNAME = os.getenv("FP_RQ_BACKEND_USERNAME")
|
173
|
-
if os.getenv("FP_RQ_BACKEND_PASSWORD") is not None:
|
174
|
-
settings.RQ_BACKEND_PASSWORD = os.getenv("FP_RQ_BACKEND_PASSWORD")
|
175
|
-
if os.getenv("FP_RQ_BACKEND_HOST") is not None:
|
176
|
-
settings.RQ_BACKEND_HOST = os.getenv("FP_RQ_BACKEND_HOST")
|
177
|
-
if os.getenv("FP_RQ_BACKEND_PORT") is not None:
|
178
|
-
settings.RQ_BACKEND_PORT = int(os.getenv("FP_RQ_BACKEND_PORT"))
|
179
|
-
if os.getenv("FP_RQ_BACKEND_DB") is not None:
|
180
|
-
settings.RQ_BACKEND_DB = int(os.getenv("FP_RQ_BACKEND_DB"))
|
181
|
-
self.update_from_settings()
|
182
|
-
|
183
|
-
def __post_init__(self):
|
184
|
-
if isinstance(self.queues, str):
|
185
|
-
self.queues = self.queues.replace(" ", "").split(",")
|
186
|
-
elif not isinstance(self.queues, list):
|
187
|
-
raise ValueError(
|
188
|
-
f"Invalid queues type: {type(self.queues)}. Must be a string or a list."
|
189
|
-
)
|
190
|
-
self.update_from_env()
|
191
|
-
|
192
|
-
|
193
|
-
class HueyBackendConfig(JobQueueBackendConfig):
|
194
|
-
pass
|
195
|
-
|
196
|
-
|
197
|
-
class JobQueueConfig(BaseConfig):
|
198
|
-
type: str | None = msgspec.field(default="rq")
|
199
|
-
backend: dict | None = msgspec.field(default=None)
|
200
|
-
num_workers: int | None = msgspec.field(default=None)
|
201
|
-
|
202
|
-
def __post_init__(self):
|
203
|
-
if self.type is not None:
|
204
|
-
self.type = self.type.lower()
|
205
|
-
if self.type == "rq":
|
206
|
-
self.backend = self.backend or RQBackendConfig()
|
207
|
-
|
208
|
-
if isinstance(self.backend, dict):
|
209
|
-
self.backend = RQBackendConfig.from_dict(self.backend)
|
210
|
-
elif isinstance(self.backend, RQBackendConfig):
|
211
|
-
pass
|
212
|
-
else:
|
213
|
-
raise ValueError(
|
214
|
-
f"Invalid backend type for RQ: {type(self.backend)}"
|
215
|
-
)
|
216
|
-
self.num_workers = self.num_workers or settings.RQ_NUM_WORKERS
|
217
|
-
|
218
|
-
elif self.type == "apscheduler":
|
219
|
-
self.backend = self.backend or APSBackendConfig()
|
220
|
-
if isinstance(self.backend, dict):
|
221
|
-
self.backend = APSBackendConfig.from_dict(self.backend)
|
222
|
-
elif isinstance(self.backend, APSBackendConfig):
|
223
|
-
pass
|
224
|
-
else:
|
225
|
-
raise ValueError(
|
226
|
-
f"Invalid backend type for APScheduler: {type(self.backend)}"
|
227
|
-
)
|
228
|
-
self.num_workers = self.num_workers or settings.APS_NUM_WORKERS
|
229
|
-
else:
|
230
|
-
raise ValueError(
|
231
|
-
f"Invalid job queue type: {self.type}. Valid types: {['rq', 'apscheduler', 'huey']}"
|
232
|
-
)
|
233
|
-
|
234
|
-
def update_type(self, type: str):
|
235
|
-
if type != self.type:
|
236
|
-
self.type = type
|
237
|
-
self.backend = None
|
238
|
-
self.__post_init__()
|