FlowerPower 0.11.6.19__py3-none-any.whl → 0.20.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/cfg/__init__.py +3 -3
- flowerpower/cfg/pipeline/__init__.py +5 -3
- flowerpower/cfg/project/__init__.py +3 -3
- flowerpower/cfg/project/job_queue.py +1 -128
- flowerpower/cli/__init__.py +5 -5
- flowerpower/cli/cfg.py +0 -3
- flowerpower/cli/job_queue.py +401 -133
- flowerpower/cli/pipeline.py +14 -413
- flowerpower/cli/utils.py +0 -1
- flowerpower/flowerpower.py +537 -28
- flowerpower/job_queue/__init__.py +5 -94
- flowerpower/job_queue/base.py +201 -3
- flowerpower/job_queue/rq/concurrent_workers/thread_worker.py +0 -3
- flowerpower/job_queue/rq/manager.py +388 -77
- flowerpower/pipeline/__init__.py +2 -0
- flowerpower/pipeline/base.py +2 -2
- flowerpower/pipeline/io.py +14 -16
- flowerpower/pipeline/manager.py +21 -642
- flowerpower/pipeline/pipeline.py +571 -0
- flowerpower/pipeline/registry.py +242 -10
- flowerpower/pipeline/visualizer.py +1 -2
- flowerpower/plugins/_io/__init__.py +8 -0
- flowerpower/plugins/mqtt/manager.py +6 -6
- flowerpower/settings/backend.py +0 -2
- flowerpower/settings/job_queue.py +1 -57
- flowerpower/utils/misc.py +0 -256
- flowerpower/utils/monkey.py +1 -83
- {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/METADATA +308 -152
- flowerpower-0.20.0.dist-info/RECORD +58 -0
- 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/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/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/utils/scheduler.py +0 -311
- flowerpower-0.11.6.19.dist-info/RECORD +0 -102
- {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/WHEEL +0 -0
- {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/entry_points.txt +0 -0
- {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/licenses/LICENSE +0 -0
- {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/top_level.txt +0 -0
@@ -1,36 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseFileWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class JsonFileWriter(BaseFileWriter, gc=False):
|
8
|
-
"""JSON file writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to JSON files.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = JsonFileWriter(df, "data.json")
|
15
|
-
writer.write()
|
16
|
-
```
|
17
|
-
"""
|
18
|
-
|
19
|
-
format: str = field(default="json")
|
20
|
-
|
21
|
-
|
22
|
-
# @attrs.define
|
23
|
-
class JsonDatasetWriter(BaseFileWriter, gc=False):
|
24
|
-
"""JSON dataset writer.
|
25
|
-
|
26
|
-
This class is responsible for writing dataframes to JSON dataset.
|
27
|
-
|
28
|
-
Examples:
|
29
|
-
```python
|
30
|
-
writer = JsonDatasetWriter([df1, df2], "json_data/")
|
31
|
-
writer.write()
|
32
|
-
```
|
33
|
-
|
34
|
-
"""
|
35
|
-
|
36
|
-
format: str = field(default="json")
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import msgspec
|
2
|
-
|
3
|
-
|
4
|
-
class MQTTWriter(msgspec.Struct):
|
5
|
-
"""MQTT writer.
|
6
|
-
|
7
|
-
This class is responsible for writing dataframes to MQTT broker.
|
8
|
-
|
9
|
-
Examples:
|
10
|
-
```python
|
11
|
-
writer = MQTTWriter(broker="localhost", port=1883, topic="data")
|
12
|
-
writer.write(df)
|
13
|
-
```
|
14
|
-
"""
|
15
|
-
|
16
|
-
broker: str
|
17
|
-
port: int = 1883
|
18
|
-
topic: str
|
19
|
-
username: str | None = None
|
20
|
-
password: str | None = None
|
21
|
-
|
22
|
-
def __post_init__(self):
|
23
|
-
pass
|
24
|
-
|
25
|
-
def write(self, data):
|
26
|
-
"""Write data to MQTT broker."""
|
27
|
-
# Implementation would go here
|
28
|
-
pass
|
@@ -1,26 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatabaseWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class MSSQLWriter(BaseDatabaseWriter, gc=False):
|
8
|
-
"""MSSQL writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to MsSQL database.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = MSSQLWriter(table_name="table", host="localhost",
|
15
|
-
port=5432, username="user", password="password",
|
16
|
-
database="database")
|
17
|
-
writer.write(df)
|
18
|
-
|
19
|
-
# or
|
20
|
-
writer = MSSQLWriter(table_name="table",
|
21
|
-
connection_string="mssql+pyodbc://user:password@localhost:5432/database")
|
22
|
-
writer.write(df)
|
23
|
-
```
|
24
|
-
"""
|
25
|
-
|
26
|
-
type_: str = field(default="mssql")
|
@@ -1,26 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatabaseWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class MySQLWriter(BaseDatabaseWriter, gc=False):
|
8
|
-
"""MySQL writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to MySQL database.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = MySQLWriter(table_name="table", host="localhost",
|
15
|
-
port=5432, username="user", password="password",
|
16
|
-
database="database")
|
17
|
-
writer.write(df)
|
18
|
-
|
19
|
-
# or
|
20
|
-
writer = MySQLWriter(table_name="table",
|
21
|
-
connection_string="mysql+pymsql://user:password@localhost:5432/database")
|
22
|
-
writer.write(df)
|
23
|
-
```
|
24
|
-
"""
|
25
|
-
|
26
|
-
type_: str = field(default="mysql")
|
@@ -1,26 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatabaseWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class OracleDBWriter(BaseDatabaseWriter, gc=False):
|
8
|
-
"""OracleDB writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to OracleDB database.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = OracleDBWriter(table_name="table", host="localhost",
|
15
|
-
port=5432, username="user", password="password",
|
16
|
-
database="database")
|
17
|
-
writer.write(df)
|
18
|
-
|
19
|
-
# or
|
20
|
-
writer = OracleDBWriter(table_name="table",
|
21
|
-
connection_string="mysql+pymsql://user:password@localhost:5432/database")
|
22
|
-
writer.write(df)
|
23
|
-
```
|
24
|
-
"""
|
25
|
-
|
26
|
-
type_: str = field(default="oracle")
|
@@ -1,36 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatasetWriter, BaseFileWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class ParquetFileWriter(BaseFileWriter, gc=False):
|
8
|
-
"""Parquet file writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to Parquet files.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = ParquetFileWriter(df, "data.parquet")
|
15
|
-
writer.write()
|
16
|
-
```
|
17
|
-
"""
|
18
|
-
|
19
|
-
format: str = field(default="parquet")
|
20
|
-
|
21
|
-
|
22
|
-
# @attrs.define
|
23
|
-
class ParquetDatasetWriter(BaseDatasetWriter, gc=False):
|
24
|
-
"""Parquet dataset writer.
|
25
|
-
|
26
|
-
This class is responsible for writing dataframes to Parquet dataset.
|
27
|
-
|
28
|
-
Examples:
|
29
|
-
```python
|
30
|
-
writer = ParquetDatasetWriter(df, "parquet_data/")
|
31
|
-
writer.write()
|
32
|
-
```
|
33
|
-
|
34
|
-
"""
|
35
|
-
|
36
|
-
format: str = field(default="parquet")
|
@@ -1,26 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatabaseWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class PostgreSQLWriter(BaseDatabaseWriter, gc=False):
|
8
|
-
"""PostgreSQL writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to PostgreSQL database.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = PostgreSQLWriter(table_name="table", host="localhost",
|
15
|
-
port=5432, username="user", password="password",
|
16
|
-
database="database")
|
17
|
-
writer.write(df)
|
18
|
-
|
19
|
-
# or
|
20
|
-
writer = PostgreSQLWriter(table_name="table",
|
21
|
-
connection_string="postgresql://user:password@localhost:5432/database")
|
22
|
-
writer.write(df)
|
23
|
-
```
|
24
|
-
"""
|
25
|
-
|
26
|
-
type_: str = field(default="postgres")
|
@@ -1,20 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatasetWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class PydalaDatasetWriter(BaseDatasetWriter, gc=False):
|
8
|
-
"""Writer for Pydala dataset.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to Pydala dataset.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = PydalaDatasetWriter(path="pydala_data/")
|
15
|
-
writer.write(df)
|
16
|
-
```
|
17
|
-
"""
|
18
|
-
|
19
|
-
format: str = field(default="parquet")
|
20
|
-
is_pydala_dataset: bool = field(default=True)
|
@@ -1,24 +0,0 @@
|
|
1
|
-
from msgspec import field
|
2
|
-
|
3
|
-
from ..base import BaseDatabaseWriter
|
4
|
-
|
5
|
-
|
6
|
-
# @attrs.define
|
7
|
-
class SQLiteWriter(BaseDatabaseWriter, gc=False):
|
8
|
-
"""SQLite writer.
|
9
|
-
|
10
|
-
This class is responsible for writing dataframes to SQLite database.
|
11
|
-
|
12
|
-
Examples:
|
13
|
-
```python
|
14
|
-
writer = SQLiteWriter(table_name="table", path="data.db")
|
15
|
-
writer.write(df)
|
16
|
-
|
17
|
-
# or
|
18
|
-
writer = SQLiteWriter(table_name="table",
|
19
|
-
connection_string="sqkite:///data.db")
|
20
|
-
writer.write(df)
|
21
|
-
```
|
22
|
-
"""
|
23
|
-
|
24
|
-
type_: str = field(default="sqlite")
|
flowerpower/utils/scheduler.py
DELETED
@@ -1,311 +0,0 @@
|
|
1
|
-
from operator import attrgetter
|
2
|
-
from typing import List
|
3
|
-
|
4
|
-
from rich.console import Console
|
5
|
-
from rich.table import Table
|
6
|
-
|
7
|
-
|
8
|
-
def humanize_crontab(minute, hour, day, month, day_of_week):
|
9
|
-
days = {
|
10
|
-
"0": "Sunday",
|
11
|
-
"sun": "Sunday",
|
12
|
-
"7": "Sunday",
|
13
|
-
"1": "Monday",
|
14
|
-
"mon": "Monday",
|
15
|
-
"2": "Tuesday",
|
16
|
-
"tue": "Tuesday",
|
17
|
-
"3": "Wednesday",
|
18
|
-
"wed": "Wednesday",
|
19
|
-
"4": "Thursday",
|
20
|
-
"thu": "Thursday",
|
21
|
-
"5": "Friday",
|
22
|
-
"fri": "Friday",
|
23
|
-
"6": "Saturday",
|
24
|
-
"sat": "Saturday",
|
25
|
-
"*": "*",
|
26
|
-
}
|
27
|
-
months = {
|
28
|
-
"1": "January",
|
29
|
-
"2": "February",
|
30
|
-
"3": "March",
|
31
|
-
"4": "April",
|
32
|
-
"5": "May",
|
33
|
-
"6": "June",
|
34
|
-
"7": "July",
|
35
|
-
"8": "August",
|
36
|
-
"9": "September",
|
37
|
-
"10": "October",
|
38
|
-
"11": "November",
|
39
|
-
"12": "December",
|
40
|
-
"*": "*",
|
41
|
-
}
|
42
|
-
|
43
|
-
def get_day_name(day_input):
|
44
|
-
day_input = str(day_input).lower().strip()
|
45
|
-
if "-" in day_input:
|
46
|
-
start, end = day_input.split("-")
|
47
|
-
return f"{days.get(start.strip(), start)}-{days.get(end.strip(), end)}"
|
48
|
-
if "," in day_input:
|
49
|
-
return ", ".join(
|
50
|
-
days.get(d.strip(), d.strip()) for d in day_input.split(",")
|
51
|
-
)
|
52
|
-
return days.get(day_input, day_input)
|
53
|
-
|
54
|
-
try:
|
55
|
-
minute, hour, day, month, day_of_week = map(
|
56
|
-
str.strip, map(str, [minute, hour, day, month, day_of_week])
|
57
|
-
)
|
58
|
-
|
59
|
-
if "/" in minute:
|
60
|
-
return f"every {minute.split('/')[1]} minutes"
|
61
|
-
if "/" in hour:
|
62
|
-
return f"every {hour.split('/')[1]} hours"
|
63
|
-
|
64
|
-
if all(x == "*" for x in [minute, hour, day, month, day_of_week]):
|
65
|
-
return "every minute"
|
66
|
-
if [minute, hour, day, month, day_of_week] == ["0", "*", "*", "*", "*"]:
|
67
|
-
return "every hour"
|
68
|
-
|
69
|
-
if (
|
70
|
-
minute == "0"
|
71
|
-
and hour != "*"
|
72
|
-
and day == "*"
|
73
|
-
and month == "*"
|
74
|
-
and day_of_week == "*"
|
75
|
-
):
|
76
|
-
return (
|
77
|
-
"every day at midnight"
|
78
|
-
if hour == "0"
|
79
|
-
else "every day at noon"
|
80
|
-
if hour == "12"
|
81
|
-
else f"every day at {hour}:00"
|
82
|
-
)
|
83
|
-
|
84
|
-
if (
|
85
|
-
minute == "0"
|
86
|
-
and hour == "0"
|
87
|
-
and day == "*"
|
88
|
-
and month == "*"
|
89
|
-
and day_of_week != "*"
|
90
|
-
):
|
91
|
-
return f"every {get_day_name(day_of_week)} at midnight"
|
92
|
-
|
93
|
-
if (
|
94
|
-
minute == "0"
|
95
|
-
and hour != "*"
|
96
|
-
and day == "*"
|
97
|
-
and month == "*"
|
98
|
-
and day_of_week != "*"
|
99
|
-
):
|
100
|
-
return (
|
101
|
-
"every weekday at {hour}:00"
|
102
|
-
if "-" in day_of_week
|
103
|
-
and "mon" in day_of_week.lower()
|
104
|
-
and "fri" in day_of_week.lower()
|
105
|
-
else f"every {get_day_name(day_of_week)} at {hour}:00"
|
106
|
-
)
|
107
|
-
|
108
|
-
if (
|
109
|
-
minute != "*"
|
110
|
-
and hour != "*"
|
111
|
-
and day == "*"
|
112
|
-
and month == "*"
|
113
|
-
and day_of_week == "*"
|
114
|
-
):
|
115
|
-
return f"every day at {hour}:{minute.zfill(2)}"
|
116
|
-
|
117
|
-
if day != "*" and month != "*" and minute == "0" and hour == "0":
|
118
|
-
return f"on day {day} of {months.get(month, month)} at midnight"
|
119
|
-
|
120
|
-
if (
|
121
|
-
minute != "*"
|
122
|
-
and hour == "*"
|
123
|
-
and day == "*"
|
124
|
-
and month == "*"
|
125
|
-
and day_of_week == "*"
|
126
|
-
):
|
127
|
-
return f"every hour at minute {minute}"
|
128
|
-
|
129
|
-
parts = []
|
130
|
-
if minute != "*":
|
131
|
-
parts.append(f"at minute {minute}")
|
132
|
-
if hour != "*":
|
133
|
-
parts.append(f"hour {hour}")
|
134
|
-
if day != "*":
|
135
|
-
parts.append(f"day {day}")
|
136
|
-
if month != "*":
|
137
|
-
parts.append(f"month {months.get(month, month)}")
|
138
|
-
if day_of_week != "*":
|
139
|
-
parts.append(f"on {get_day_name(day_of_week)}")
|
140
|
-
|
141
|
-
return f"runs {' '.join(parts)}" if parts else "every minute"
|
142
|
-
except Exception:
|
143
|
-
return f"{minute} {hour} {day} {month} {day_of_week}"
|
144
|
-
|
145
|
-
|
146
|
-
def format_trigger(trigger):
|
147
|
-
trigger_type = trigger.__class__.__name__
|
148
|
-
|
149
|
-
if trigger_type == "IntervalTrigger":
|
150
|
-
for unit in ["seconds", "minutes", "hours", "days"]:
|
151
|
-
if value := getattr(trigger, unit, None):
|
152
|
-
return f"Interval: Every {value}{unit[0]}"
|
153
|
-
return "Interval"
|
154
|
-
|
155
|
-
if trigger_type == "CronTrigger":
|
156
|
-
try:
|
157
|
-
cron_parts = dict(
|
158
|
-
part.split("=")
|
159
|
-
for part in str(trigger).strip("CronTrigger(").rstrip(")").split(", ")
|
160
|
-
)
|
161
|
-
cron_parts = {k: v.strip("'") for k, v in cron_parts.items()}
|
162
|
-
crontab = f"{cron_parts['minute']} {cron_parts['hour']} {cron_parts['day']} {cron_parts['month']} {cron_parts['day_of_week']}"
|
163
|
-
human_readable = humanize_crontab(
|
164
|
-
**{
|
165
|
-
k: cron_parts[k]
|
166
|
-
for k in ["minute", "hour", "day", "month", "day_of_week"]
|
167
|
-
}
|
168
|
-
)
|
169
|
-
return f"Cron: {human_readable} ({crontab})"
|
170
|
-
except Exception:
|
171
|
-
return f"Cron: {str(trigger)}"
|
172
|
-
|
173
|
-
if trigger_type == "DateTrigger":
|
174
|
-
return f"Date: Once at {trigger.run_date.strftime('%Y-%m-%d %H:%M:%S')}"
|
175
|
-
|
176
|
-
return f"{trigger_type}: {str(trigger)}"
|
177
|
-
|
178
|
-
|
179
|
-
def display_schedules(schedules: List):
|
180
|
-
console = Console()
|
181
|
-
total_width = console.width - 10
|
182
|
-
|
183
|
-
width_ratios = {
|
184
|
-
"id": 0.20,
|
185
|
-
"task": 0.10,
|
186
|
-
"trigger": 0.25,
|
187
|
-
"name": 0.15,
|
188
|
-
"run_args": 0.15,
|
189
|
-
"next_fire": 0.08,
|
190
|
-
"last_fire": 0.08,
|
191
|
-
"paused": 0.01,
|
192
|
-
}
|
193
|
-
|
194
|
-
widths = {k: max(10, int(total_width * ratio)) for k, ratio in width_ratios.items()}
|
195
|
-
|
196
|
-
table = Table(
|
197
|
-
show_header=True,
|
198
|
-
header_style="bold magenta",
|
199
|
-
width=total_width,
|
200
|
-
row_styles=["", "dim"],
|
201
|
-
border_style="blue",
|
202
|
-
show_lines=True,
|
203
|
-
)
|
204
|
-
|
205
|
-
for col, style, width in [
|
206
|
-
("ID", "dim", widths["id"]),
|
207
|
-
("Task", "cyan", widths["task"]),
|
208
|
-
("Trigger", "blue", widths["trigger"]),
|
209
|
-
("Name", "yellow", widths["name"]),
|
210
|
-
("Run Args", "yellow", widths["run_args"]),
|
211
|
-
("Next Fire Time", "green", widths["next_fire"]),
|
212
|
-
("Last Fire Time", "red", widths["last_fire"]),
|
213
|
-
("Paused", "bold", widths["paused"]),
|
214
|
-
]:
|
215
|
-
table.add_column(col, style=style, width=width)
|
216
|
-
|
217
|
-
for schedule in sorted(schedules, key=attrgetter("next_fire_time")):
|
218
|
-
table.add_row(
|
219
|
-
schedule.id,
|
220
|
-
schedule.task_id.split(":")[-1],
|
221
|
-
format_trigger(schedule.trigger),
|
222
|
-
(
|
223
|
-
str(schedule.args[1])
|
224
|
-
if schedule.args and len(schedule.args) > 1
|
225
|
-
else "None"
|
226
|
-
),
|
227
|
-
"\n".join(f"{k}: {v}" for k, v in (schedule.kwargs or {}).items())
|
228
|
-
or "None",
|
229
|
-
(
|
230
|
-
schedule.next_fire_time.strftime("%Y-%m-%d %H:%M:%S")
|
231
|
-
if schedule.next_fire_time
|
232
|
-
else "Never"
|
233
|
-
),
|
234
|
-
(
|
235
|
-
schedule.last_fire_time.strftime("%Y-%m-%d %H:%M:%S")
|
236
|
-
if schedule.last_fire_time
|
237
|
-
else "Never"
|
238
|
-
),
|
239
|
-
"✓" if schedule.paused else "✗",
|
240
|
-
)
|
241
|
-
|
242
|
-
console.print(table)
|
243
|
-
|
244
|
-
|
245
|
-
def display_tasks(tasks):
|
246
|
-
console = Console()
|
247
|
-
table = Table(title="Tasks")
|
248
|
-
|
249
|
-
widths = {"id": 50, "executor": 15, "max_jobs": 15, "misfire": 20}
|
250
|
-
|
251
|
-
for col, style, width in [
|
252
|
-
("ID", "cyan", widths["id"]),
|
253
|
-
("Job Executor", "blue", widths["executor"]),
|
254
|
-
("Max Running Jobs", "yellow", widths["max_jobs"]),
|
255
|
-
("Misfire Grace Time", "green", widths["misfire"]),
|
256
|
-
]:
|
257
|
-
table.add_column(col, style=style, width=width)
|
258
|
-
|
259
|
-
for task in sorted(tasks, key=attrgetter("id")):
|
260
|
-
table.add_row(
|
261
|
-
task.id,
|
262
|
-
str(task.job_executor),
|
263
|
-
str(task.max_running_jobs or "None"),
|
264
|
-
str(task.misfire_grace_time or "None"),
|
265
|
-
)
|
266
|
-
|
267
|
-
console.print(table)
|
268
|
-
|
269
|
-
|
270
|
-
def display_jobs(jobs):
|
271
|
-
console = Console()
|
272
|
-
table = Table(title="Jobs")
|
273
|
-
|
274
|
-
widths = {
|
275
|
-
"id": 10,
|
276
|
-
"task_id": 40,
|
277
|
-
"args": 20,
|
278
|
-
"kwargs": 20,
|
279
|
-
"schedule": 15,
|
280
|
-
"created": 25,
|
281
|
-
"status": 15,
|
282
|
-
}
|
283
|
-
|
284
|
-
for col, style, width in [
|
285
|
-
("ID", "cyan", widths["id"]),
|
286
|
-
("Task ID", "blue", widths["task_id"]),
|
287
|
-
("Args", "yellow", widths["args"]),
|
288
|
-
("Kwargs", "yellow", widths["kwargs"]),
|
289
|
-
("Schedule ID", "green", widths["schedule"]),
|
290
|
-
("Created At", "magenta", widths["created"]),
|
291
|
-
("Status", "red", widths["status"]),
|
292
|
-
]:
|
293
|
-
table.add_column(col, style=style, width=width)
|
294
|
-
|
295
|
-
for job in sorted(jobs, key=attrgetter("id")):
|
296
|
-
status = "Running" if job.acquired_by else "Pending"
|
297
|
-
table.add_row(
|
298
|
-
str(job.id),
|
299
|
-
job.task_id,
|
300
|
-
str(job.args if job.args else "None"),
|
301
|
-
(
|
302
|
-
"\n".join(f"{k}: {v}" for k, v in job.kwargs.items())
|
303
|
-
if job.kwargs
|
304
|
-
else "None"
|
305
|
-
),
|
306
|
-
str(job.schedule_id or "None"),
|
307
|
-
job.created_at.strftime("%Y-%m-%d %H:%M:%S"),
|
308
|
-
status,
|
309
|
-
)
|
310
|
-
|
311
|
-
console.print(table)
|
@@ -1,102 +0,0 @@
|
|
1
|
-
flowerpower/__init__.py,sha256=LO27AXn-YcsQ0cbytUJAMPs8cFLo1bQwV47N-f_tous,571
|
2
|
-
flowerpower/flowerpower.py,sha256=ISR-0PtGa4hkhIJ-f1-xPp8WlSmsuwRVTnf5mZEMtDw,13752
|
3
|
-
flowerpower/mqtt.py,sha256=ztsbPG4zvyqjiWsbG4dpxtYsxEz_ESw4n7tUdzkeqlM,337
|
4
|
-
flowerpower/cfg/__init__.py,sha256=2RVEX962cVkd5KjXfW3DPhMd6BO56wAsvEQCEa2i__Q,8849
|
5
|
-
flowerpower/cfg/base.py,sha256=W1_trbWUs9d56T06QHR5YlSLMbf7GnvtL6lQNAujJcY,4709
|
6
|
-
flowerpower/cfg/pipeline/__init__.py,sha256=jfvOWFqLamccPEBAow_GNaqa-iSfg5gopdz4PLxRGfA,9169
|
7
|
-
flowerpower/cfg/pipeline/adapter.py,sha256=PuXEAl6YbluoRj5jdoABD8xHPstgHsKJUIDs2HJBgRk,2517
|
8
|
-
flowerpower/cfg/pipeline/run.py,sha256=v6xumlVYoqbQWIPwSIch9r8Z7IDGsSnBnW6-Oy0dhVk,2058
|
9
|
-
flowerpower/cfg/pipeline/schedule.py,sha256=viw1Gd8pKq73Yw2-Tm9074YHP_yB5RPl9pYaqI8VDqI,2450
|
10
|
-
flowerpower/cfg/project/__init__.py,sha256=7QwrkaaGzw9xMIp_2uVj-E3sf-LYn-urIWC0DkTNc74,5346
|
11
|
-
flowerpower/cfg/project/adapter.py,sha256=zIBwelSoQJ277_SA506tYEVSf0kEPJODaggocYm5rK4,2044
|
12
|
-
flowerpower/cfg/project/job_queue.py,sha256=vj4kW86MXnqmew_r9GRTZZwfnSj_Ui586fX1Q-n6qTI,10369
|
13
|
-
flowerpower/cli/__init__.py,sha256=ys6uxRJyunYUAZYTtLkNYKqRdOG02A2YmXw_beDEib0,5730
|
14
|
-
flowerpower/cli/cfg.py,sha256=B9yV6g9bTGRXOR1PewQTxf_XfcYbcsE3GeLAxlbE2qc,1530
|
15
|
-
flowerpower/cli/job_queue.py,sha256=wnPiuOZJTNiscG7-YkyHadfnB729uuPYCkYrRGXLCRI,37153
|
16
|
-
flowerpower/cli/mqtt.py,sha256=GM5d6bzG01THZd7SwXFAC3j0cait642eXT50P3R22vk,6281
|
17
|
-
flowerpower/cli/pipeline.py,sha256=60P6u_QOSgp0jJXEMxazEEo5Sh7-SWFo-Kkuaz21YuI,37845
|
18
|
-
flowerpower/cli/utils.py,sha256=nDSSj_1nlYlMmj252kRZeohhFqHv9yvdgDEduQCyWOc,5152
|
19
|
-
flowerpower/fs/__init__.py,sha256=uZaPXErEfQqQRbKRIjkB9yiygd45X5_psYn9-VVrBTQ,910
|
20
|
-
flowerpower/fs/base.py,sha256=TqgqBsaFj13O1NpAr8kHuGJ9CTlaSWViMB8Ai_iuCjs,22761
|
21
|
-
flowerpower/fs/ext.py,sha256=7Ue70LL-ktGH_A_bi_nyI0P1WY_fboY5HqdPpqh8a6c,70604
|
22
|
-
flowerpower/fs/storage_options.py,sha256=msq5TpxAU8tcE_Bxjw6SyxaFa75UjdYnR4-O9U2wmbk,48034
|
23
|
-
flowerpower/job_queue/__init__.py,sha256=a25hIqv2xoFKb4JZlyUukS0ppZ9-2sJKH3XAvbk3rlk,10788
|
24
|
-
flowerpower/job_queue/base.py,sha256=YwLunDQSyqkSU_vJ69C5SSybJeJP1bAiZ3teUtOchxA,13640
|
25
|
-
flowerpower/job_queue/apscheduler/__init__.py,sha256=TXiUTu_j2v7DJPi57POnGHkePTLPUXXJ0so50SPPtp0,235
|
26
|
-
flowerpower/job_queue/apscheduler/manager.py,sha256=NZeegRf16Gyq1qo_ZxhcNAdRIS0MrbtHQadlf-_tIsI,35766
|
27
|
-
flowerpower/job_queue/apscheduler/setup.py,sha256=e8NGs6I4IrtnsrQMkXTJ8bSI7iCaI5swgpFqAWnkbqA,19669
|
28
|
-
flowerpower/job_queue/apscheduler/trigger.py,sha256=kStQO_ipAn2xBbX3fSg4X3ORNOulalRyOhKBb0lkSAg,5111
|
29
|
-
flowerpower/job_queue/apscheduler/utils.py,sha256=2zJ_xmLXpvXUQNF1XS2Gqm3Ogo907ctZ50GtvQB_rhE,9354
|
30
|
-
flowerpower/job_queue/apscheduler/_setup/datastore.py,sha256=oV8pw7x0dZBDxhR54d-Y2O9hVanxhBuZbUNpxcizxak,3490
|
31
|
-
flowerpower/job_queue/apscheduler/_setup/eventbroker.py,sha256=qh8v9vAc-3v4e66wdXyrVZyIxFyqmOpzwKkolE8mVko,2872
|
32
|
-
flowerpower/job_queue/rq/__init__.py,sha256=VCGpAzd8K3GLHb8A-wFevNKj2xF23K7J7ykad7giVks,193
|
33
|
-
flowerpower/job_queue/rq/_trigger.py,sha256=w1WKs_8nd9d4e_Y25yuG0vV2N4A58rWZz8RUORJepH0,1134
|
34
|
-
flowerpower/job_queue/rq/manager.py,sha256=k3vL6w7hJYTN44mU9M4vsSt_f1iauIn_Zbu23riOUNs,57365
|
35
|
-
flowerpower/job_queue/rq/setup.py,sha256=nCJlWJzfcgf7iwqTPQPk6ZQOe9p-KUmC3lfMrYrC-Lc,5332
|
36
|
-
flowerpower/job_queue/rq/utils.py,sha256=QjyNhSM1_gMZkV2cO8eR99XeEji4AMwpxE1TANaRgTg,2009
|
37
|
-
flowerpower/job_queue/rq/concurrent_workers/gevent_worker.py,sha256=X8rKfSbuITpWiwCyNqN-WVeodBkafFuj-zvbZb7z6lw,7511
|
38
|
-
flowerpower/job_queue/rq/concurrent_workers/thread_worker.py,sha256=M_jjci-pypEsbHe-gCQS6jmJBrA-Tb7W19sEWi6htFU,7801
|
39
|
-
flowerpower/pipeline/__init__.py,sha256=xbEn_RN0vVNqLZMSFOCdV41ggUkYrghFVJYd_EC0C44,75
|
40
|
-
flowerpower/pipeline/base.py,sha256=CO2PsOACRHFd8-g-0BUTc1ZMVdaBnhQftJda7HDxPZI,3305
|
41
|
-
flowerpower/pipeline/io.py,sha256=8Mlw4G7ehHHZEk4Qui-HcKBM3tBF4FuqUbjfNxK09iU,15963
|
42
|
-
flowerpower/pipeline/job_queue.py,sha256=hl38-0QZCH5wujUf0qIqYznIPDLsJAoNDcOD7YGVQ6s,26114
|
43
|
-
flowerpower/pipeline/manager.py,sha256=KVpOclUEUAETUNJamJJGuKt3oxCaLitQgxWxkE1q028,74460
|
44
|
-
flowerpower/pipeline/registry.py,sha256=6ngmHyKyQsxvIO4qRYxljedY0BE1wE3lpfksEGOzjNs,18963
|
45
|
-
flowerpower/pipeline/runner.py,sha256=dsSVYixFXqlxFk8EJfT4wV_7IwgkXq0ErwH_yf_NGS8,25654
|
46
|
-
flowerpower/pipeline/visualizer.py,sha256=amjMrl5NetErE198HzZBPWVZBi_t5jj9ydxWpuNLoTI,5013
|
47
|
-
flowerpower/plugins/io/base.py,sha256=6jL6b_kaM_UGyP_3YKLjHfz66xNAAZH1sp36JZyQz8g,97270
|
48
|
-
flowerpower/plugins/io/metadata.py,sha256=PCrepLilXRWKDsB5BKFF_-OFs712s1zBeitW-84lDLQ,7005
|
49
|
-
flowerpower/plugins/io/helpers/datetime.py,sha256=1WBUg2ywcsodJQwoF6JiIGc9yhVobvE2IErWp4i95m4,10649
|
50
|
-
flowerpower/plugins/io/helpers/polars.py,sha256=2U0XMIDGWr7b7GcD7Qc0v-tSdZz_IiNo1Ws5kSOju6U,29359
|
51
|
-
flowerpower/plugins/io/helpers/pyarrow.py,sha256=uFaradEOTReqiDGQy5QyXCC1hY4_Vp_R-3FoosaUJBY,19070
|
52
|
-
flowerpower/plugins/io/helpers/sql.py,sha256=BPIxjarKF3p93EdtUu-md8KislE9q8IWNSeZ5toFU6U,7298
|
53
|
-
flowerpower/plugins/io/loader/__init__.py,sha256=MKH42nvVokaWas0wFgX1yrpU5iLpvHjRqqF-KzwLHCg,780
|
54
|
-
flowerpower/plugins/io/loader/csv.py,sha256=Q5bmcbbr530sT1kQ2YiJwvsMUPqi0VcZWsLOygmzRyI,827
|
55
|
-
flowerpower/plugins/io/loader/deltatable.py,sha256=YNPOIKRrThbJmksV8dr-iXrQqD7qVjV4dRG7xfGBqqU,6747
|
56
|
-
flowerpower/plugins/io/loader/duckdb.py,sha256=FOrDVJvImkEe3o4Qc1X7D6r9uUzHxfaml-tVdbFCaC0,468
|
57
|
-
flowerpower/plugins/io/loader/json.py,sha256=Z8hPxiPsv_9PpaCXki4qDX70G95wGL-tGd7ALC2LtZ0,739
|
58
|
-
flowerpower/plugins/io/loader/mqtt.py,sha256=0bjGW4ZkrFp3ouWbH1E0yeTUKRhYTFWdQOvTrONPz8Y,5098
|
59
|
-
flowerpower/plugins/io/loader/mssql.py,sha256=RfptbTjerPXq3Pye7S-_70D0jlEWPcJpSTyyqD7BTRM,807
|
60
|
-
flowerpower/plugins/io/loader/mysql.py,sha256=e1a4Yq3-mJlmxdEvzPaMZxGMrrm58_1zo_xzU_5m8HM,807
|
61
|
-
flowerpower/plugins/io/loader/oracle.py,sha256=zHFsKIjdRnYZprjrr8svfyODK1ugSZKUqhSWBMfAMPY,823
|
62
|
-
flowerpower/plugins/io/loader/parquet.py,sha256=UUpZmhdDOK8ZI7CMPKThNxDUc_6tFz3DbGZSexO3hDI,787
|
63
|
-
flowerpower/plugins/io/loader/postgres.py,sha256=1rjo0K5oYaXYu3i62bw-5Avuovc2ikI8MezySqK7GFw,835
|
64
|
-
flowerpower/plugins/io/loader/pydala.py,sha256=iCvHQCYAisrxZIaQzZrzTmWaND_LzamuMEOpxQFUdC4,420
|
65
|
-
flowerpower/plugins/io/loader/sqlite.py,sha256=CCI2bPLMVYUOg7mxy54sbR15qwvKRGL8r_982jARUig,609
|
66
|
-
flowerpower/plugins/io/saver/__init__.py,sha256=RWcUdrcmi2JR4mb77jPZd-lSG5rQBIqS7Pl4vbPfUes,780
|
67
|
-
flowerpower/plugins/io/saver/csv.py,sha256=i_kZvuco5joBaBfidplWglQsNqO7v873j_Xo5f78S5M,736
|
68
|
-
flowerpower/plugins/io/saver/deltatable.py,sha256=9UWXkmbMvomFe8jWop5GRA9hyfhiAFWZbSNROXngWHQ,7040
|
69
|
-
flowerpower/plugins/io/saver/duckdb.py,sha256=NpnoO5CffrNcCUPH_4KH4RFei8T40sHgjYySm0n1pV8,415
|
70
|
-
flowerpower/plugins/io/saver/json.py,sha256=19a0K3aNQQxtSjskv4G6_5XfiFBoZnHGZAd_W3UgFSs,734
|
71
|
-
flowerpower/plugins/io/saver/mqtt.py,sha256=vIlnRSMwPzyZzGbvi9TBX4j4Qn1iSbgUbrMU2giJSCU,573
|
72
|
-
flowerpower/plugins/io/saver/mssql.py,sha256=_ZyO2wq1hjRb-Wnz3lZLLpaI1gMM3IH4ItkU-4PeZSE,740
|
73
|
-
flowerpower/plugins/io/saver/mysql.py,sha256=7rSyRhRDMJZFNEsqope39uxBCbNqhr03X-QmwvLAzXU,740
|
74
|
-
flowerpower/plugins/io/saver/oracle.py,sha256=lli9uO0z4FhKIbrziKFz0x6Gug-jSay7pclsywIGYsc,756
|
75
|
-
flowerpower/plugins/io/saver/parquet.py,sha256=3xhYInpXCgA3yg5NYxH4yfcZKpaRCEAXtVKTbJxh5LA,784
|
76
|
-
flowerpower/plugins/io/saver/postgres.py,sha256=Pur9y2edErJMHheUOUGJn4L-lUoPLp0tFScDCNITzuQ,766
|
77
|
-
flowerpower/plugins/io/saver/pydala.py,sha256=v8MGw_NRwriw6JFTUlMy-uMg9Jsx2iylbEX60GfXhh4,475
|
78
|
-
flowerpower/plugins/io/saver/sqlite.py,sha256=_7USGGQIjkAvtFFv4xYTJ79IzqMnv8PfzC18T_TDPLA,575
|
79
|
-
flowerpower/plugins/mqtt/__init__.py,sha256=B35HETcaAmtqgAjMeohy79oLcsj0T_dRRjmyHMG5Qq4,253
|
80
|
-
flowerpower/plugins/mqtt/cfg.py,sha256=4F9ow0wEjSnU8UaWmJYGszkU0ZY2du2nHmGHXRVsC70,484
|
81
|
-
flowerpower/plugins/mqtt/manager.py,sha256=WJIKu_0wfrxph_L0AjV-7RYVFtie2cOmdVGjjlr5DIA,37197
|
82
|
-
flowerpower/settings/__init__.py,sha256=g1JKxxQKgBSbghzhCvEPOgD4ofjCGJdWCf8T0husyMQ,178
|
83
|
-
flowerpower/settings/backend.py,sha256=jb4H3DXil5uN4BDo3ipqP6-1Hpnrm6qvIZQWiHZcDXg,4994
|
84
|
-
flowerpower/settings/executor.py,sha256=vNF383g1gMGkq_CXUzateGMNcJZig-vHkVVb0Hi_b74,249
|
85
|
-
flowerpower/settings/general.py,sha256=RxY6PGF_L8ApFlLPHulZ2I8_-aHYqOj63fUu9kSQTjI,227
|
86
|
-
flowerpower/settings/hamilton.py,sha256=GVzWKz3B-wy07etY1mNUstEa4DFrQ_lM2cjE0qG_6qw,623
|
87
|
-
flowerpower/settings/job_queue.py,sha256=wrehB9Suwks9y5Gvfg-cex6SQOoeFfSwZDxdKNmKhcA,2972
|
88
|
-
flowerpower/settings/logging.py,sha256=xzoiM-87WGduC-RJu8RfyeweHGTM7SnHXHQPbxKweLE,67
|
89
|
-
flowerpower/settings/retry.py,sha256=W3AAVSxmTUAeeSbzRGA37RxqtKKyUdi2MkwDzCsXP94,181
|
90
|
-
flowerpower/utils/callback.py,sha256=sGYSrEbnl0xfRa1X-mA-om3erpH7pmpsWdyPQ9HpU7E,6736
|
91
|
-
flowerpower/utils/logging.py,sha256=QO1Q3pv-m3mK2xT_VbkjTsomFnDeuqBmRuOtoxaowgg,864
|
92
|
-
flowerpower/utils/misc.py,sha256=SK913FEYmOjS7GfSQ8oXNFiQ7owrH70fxp952vN5aWg,17099
|
93
|
-
flowerpower/utils/monkey.py,sha256=VPl3yimoWhwD9kI05BFsjNvtyQiDyLfY4Q85Bb6Ma0w,2903
|
94
|
-
flowerpower/utils/open_telemetry.py,sha256=fQWJWbIQFtKIxMBjAWeF12NGnqT0isO3A3j-DSOv_vE,949
|
95
|
-
flowerpower/utils/scheduler.py,sha256=2zJ_xmLXpvXUQNF1XS2Gqm3Ogo907ctZ50GtvQB_rhE,9354
|
96
|
-
flowerpower/utils/templates.py,sha256=ouyEeSDqa9PjW8c32fGpcINlpC0WToawRFZkMPtwsLE,1591
|
97
|
-
flowerpower-0.11.6.19.dist-info/licenses/LICENSE,sha256=9AkLexxrmr0aBgSHiqxpJk9wgazpP1CTJyiDyr56J9k,1063
|
98
|
-
flowerpower-0.11.6.19.dist-info/METADATA,sha256=VxG71IX4OkwdmSHjonWdTYw5Qk2YU4b0GmRr6NYiCY0,21613
|
99
|
-
flowerpower-0.11.6.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
100
|
-
flowerpower-0.11.6.19.dist-info/entry_points.txt,sha256=61X11i5a2IwC9LBiP20XCDl5zMOigGCjMCx17B7bDbQ,52
|
101
|
-
flowerpower-0.11.6.19.dist-info/top_level.txt,sha256=VraH4WtEUfSxs5L-rXwDQhzQb9eLHTUtgvmFZ2dAYnA,12
|
102
|
-
flowerpower-0.11.6.19.dist-info/RECORD,,
|
File without changes
|
File without changes
|