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.
Files changed (80) hide show
  1. flowerpower/cfg/__init__.py +3 -3
  2. flowerpower/cfg/pipeline/__init__.py +5 -3
  3. flowerpower/cfg/project/__init__.py +3 -3
  4. flowerpower/cfg/project/job_queue.py +1 -128
  5. flowerpower/cli/__init__.py +5 -5
  6. flowerpower/cli/cfg.py +0 -3
  7. flowerpower/cli/job_queue.py +401 -133
  8. flowerpower/cli/pipeline.py +14 -413
  9. flowerpower/cli/utils.py +0 -1
  10. flowerpower/flowerpower.py +537 -28
  11. flowerpower/job_queue/__init__.py +5 -94
  12. flowerpower/job_queue/base.py +201 -3
  13. flowerpower/job_queue/rq/concurrent_workers/thread_worker.py +0 -3
  14. flowerpower/job_queue/rq/manager.py +388 -77
  15. flowerpower/pipeline/__init__.py +2 -0
  16. flowerpower/pipeline/base.py +2 -2
  17. flowerpower/pipeline/io.py +14 -16
  18. flowerpower/pipeline/manager.py +21 -642
  19. flowerpower/pipeline/pipeline.py +571 -0
  20. flowerpower/pipeline/registry.py +242 -10
  21. flowerpower/pipeline/visualizer.py +1 -2
  22. flowerpower/plugins/_io/__init__.py +8 -0
  23. flowerpower/plugins/mqtt/manager.py +6 -6
  24. flowerpower/settings/backend.py +0 -2
  25. flowerpower/settings/job_queue.py +1 -57
  26. flowerpower/utils/misc.py +0 -256
  27. flowerpower/utils/monkey.py +1 -83
  28. {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/METADATA +308 -152
  29. flowerpower-0.20.0.dist-info/RECORD +58 -0
  30. flowerpower/fs/__init__.py +0 -29
  31. flowerpower/fs/base.py +0 -662
  32. flowerpower/fs/ext.py +0 -2143
  33. flowerpower/fs/storage_options.py +0 -1420
  34. flowerpower/job_queue/apscheduler/__init__.py +0 -11
  35. flowerpower/job_queue/apscheduler/_setup/datastore.py +0 -110
  36. flowerpower/job_queue/apscheduler/_setup/eventbroker.py +0 -93
  37. flowerpower/job_queue/apscheduler/manager.py +0 -1051
  38. flowerpower/job_queue/apscheduler/setup.py +0 -554
  39. flowerpower/job_queue/apscheduler/trigger.py +0 -169
  40. flowerpower/job_queue/apscheduler/utils.py +0 -311
  41. flowerpower/pipeline/job_queue.py +0 -583
  42. flowerpower/pipeline/runner.py +0 -603
  43. flowerpower/plugins/io/base.py +0 -2520
  44. flowerpower/plugins/io/helpers/datetime.py +0 -298
  45. flowerpower/plugins/io/helpers/polars.py +0 -875
  46. flowerpower/plugins/io/helpers/pyarrow.py +0 -570
  47. flowerpower/plugins/io/helpers/sql.py +0 -202
  48. flowerpower/plugins/io/loader/__init__.py +0 -28
  49. flowerpower/plugins/io/loader/csv.py +0 -37
  50. flowerpower/plugins/io/loader/deltatable.py +0 -190
  51. flowerpower/plugins/io/loader/duckdb.py +0 -19
  52. flowerpower/plugins/io/loader/json.py +0 -37
  53. flowerpower/plugins/io/loader/mqtt.py +0 -159
  54. flowerpower/plugins/io/loader/mssql.py +0 -26
  55. flowerpower/plugins/io/loader/mysql.py +0 -26
  56. flowerpower/plugins/io/loader/oracle.py +0 -26
  57. flowerpower/plugins/io/loader/parquet.py +0 -35
  58. flowerpower/plugins/io/loader/postgres.py +0 -26
  59. flowerpower/plugins/io/loader/pydala.py +0 -19
  60. flowerpower/plugins/io/loader/sqlite.py +0 -23
  61. flowerpower/plugins/io/metadata.py +0 -244
  62. flowerpower/plugins/io/saver/__init__.py +0 -28
  63. flowerpower/plugins/io/saver/csv.py +0 -36
  64. flowerpower/plugins/io/saver/deltatable.py +0 -186
  65. flowerpower/plugins/io/saver/duckdb.py +0 -19
  66. flowerpower/plugins/io/saver/json.py +0 -36
  67. flowerpower/plugins/io/saver/mqtt.py +0 -28
  68. flowerpower/plugins/io/saver/mssql.py +0 -26
  69. flowerpower/plugins/io/saver/mysql.py +0 -26
  70. flowerpower/plugins/io/saver/oracle.py +0 -26
  71. flowerpower/plugins/io/saver/parquet.py +0 -36
  72. flowerpower/plugins/io/saver/postgres.py +0 -26
  73. flowerpower/plugins/io/saver/pydala.py +0 -20
  74. flowerpower/plugins/io/saver/sqlite.py +0 -24
  75. flowerpower/utils/scheduler.py +0 -311
  76. flowerpower-0.11.6.19.dist-info/RECORD +0 -102
  77. {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/WHEEL +0 -0
  78. {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/entry_points.txt +0 -0
  79. {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/licenses/LICENSE +0 -0
  80. {flowerpower-0.11.6.19.dist-info → flowerpower-0.20.0.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  from pathlib import Path
2
2
 
3
3
  import msgspec
4
+ from fsspec_utils import AbstractFileSystem, BaseStorageOptions, filesystem
4
5
  from munch import Munch
5
6
 
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
@@ -77,7 +77,7 @@ class Config(BaseConfig):
77
77
  ```
78
78
  """
79
79
  if fs is None:
80
- fs = get_filesystem(
80
+ fs = filesystem(
81
81
  base_dir, cached=True, dirfs=True, storage_options=storage_options
82
82
  )
83
83
  project = ProjectConfig.load(
@@ -123,7 +123,7 @@ class Config(BaseConfig):
123
123
  ```
124
124
  """
125
125
  if fs is None and self.fs is None:
126
- self.fs = get_filesystem(
126
+ self.fs = filesystem(
127
127
  self.base_dir, cached=True, dirfs=True, **storage_options
128
128
  )
129
129
 
@@ -1,12 +1,14 @@
1
1
  import msgspec
2
2
  import yaml
3
+ from fsspec_utils import AbstractFileSystem, BaseStorageOptions, filesystem
3
4
  from hamilton.function_modifiers import source, value
4
5
  from munch import Munch, munchify
5
6
 
6
- from ...fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
7
7
  from ..base import BaseConfig
8
8
  from .adapter import AdapterConfig
9
+ from .run import ExecutorConfig as ExecutorConfig
9
10
  from .run import RunConfig
11
+ from .run import WithAdapterConfig as WithAdapterConfig
10
12
  from .schedule import ScheduleConfig
11
13
 
12
14
 
@@ -166,7 +168,7 @@ class PipelineConfig(BaseConfig):
166
168
  ```
167
169
  """
168
170
  if fs is None:
169
- fs = get_filesystem(
171
+ fs = filesystem(
170
172
  base_dir, cached=False, dirfs=True, storage_options=storage_options
171
173
  )
172
174
  if fs.exists("conf/pipelines"):
@@ -207,7 +209,7 @@ class PipelineConfig(BaseConfig):
207
209
  ```
208
210
  """
209
211
  if fs is None:
210
- fs = get_filesystem(
212
+ fs = filesystem(
211
213
  base_dir, cached=True, dirfs=True, storage_options=storage_options
212
214
  )
213
215
 
@@ -1,6 +1,6 @@
1
1
  import msgspec
2
+ from fsspec_utils import AbstractFileSystem, BaseStorageOptions, filesystem
2
3
 
3
- from ...fs import AbstractFileSystem, BaseStorageOptions, get_filesystem
4
4
  from ..base import BaseConfig
5
5
  from .adapter import AdapterConfig
6
6
  from .job_queue import JobQueueConfig
@@ -71,7 +71,7 @@ class ProjectConfig(BaseConfig):
71
71
  ```
72
72
  """
73
73
  if fs is None:
74
- fs = get_filesystem(
74
+ fs = filesystem(
75
75
  base_dir, cached=False, dirfs=True, storage_options=storage_options
76
76
  )
77
77
  if fs.exists("conf/project.yml"):
@@ -103,7 +103,7 @@ class ProjectConfig(BaseConfig):
103
103
  ```
104
104
  """
105
105
  if fs is None:
106
- fs = get_filesystem(
106
+ fs = filesystem(
107
107
  base_dir, cached=True, dirfs=True, storage_options=storage_options
108
108
  )
109
109
 
@@ -1,5 +1,3 @@
1
- import datetime as dt
2
- import importlib
3
1
  import os
4
2
 
5
3
  import msgspec
@@ -29,120 +27,6 @@ class JobQueueBackendConfig(BaseConfig):
29
27
  verify_ssl: bool = msgspec.field(default=False)
30
28
 
31
29
 
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
30
  class RQBackendConfig(JobQueueBackendConfig):
147
31
  type: str = msgspec.field(default="redis")
148
32
  username: str | None = msgspec.field(default=settings.RQ_BACKEND_USERNAME)
@@ -215,20 +99,9 @@ class JobQueueConfig(BaseConfig):
215
99
  )
216
100
  self.num_workers = self.num_workers or settings.RQ_NUM_WORKERS
217
101
 
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
102
  else:
230
103
  raise ValueError(
231
- f"Invalid job queue type: {self.type}. Valid types: {['rq', 'apscheduler', 'huey']}"
104
+ f"Invalid job queue type: {self.type}. Valid types: ['rq']"
232
105
  )
233
106
 
234
107
  def update_type(self, type: str):
@@ -18,7 +18,7 @@ app.add_typer(
18
18
  pipeline_app, name="pipeline", help="Manage and execute FlowerPower pipelines"
19
19
  )
20
20
 
21
- if importlib.util.find_spec("apscheduler") or importlib.util.find_spec("rq"):
21
+ if importlib.util.find_spec("rq"):
22
22
  from .job_queue import app as job_queue_app
23
23
 
24
24
  app.add_typer(
@@ -53,7 +53,7 @@ def init(
53
53
  "rq",
54
54
  "--job-queue-type",
55
55
  "-q",
56
- help="Job queue backend type to use (rq, apscheduler)",
56
+ help="Job queue backend type to use (rq)",
57
57
  ),
58
58
  ):
59
59
  """
@@ -69,7 +69,7 @@ def init(
69
69
  base_dir: Base directory where the project will be created. If not provided,
70
70
  the current directory's parent will be used
71
71
  storage_options: Storage options for filesystem access, as a JSON or dict string
72
- job_queue_type: Type of job queue backend to use (rq, apscheduler)
72
+ job_queue_type: Type of job queue backend to use (rq)
73
73
 
74
74
  Examples:
75
75
  # Create a project in the current directory using its name
@@ -81,8 +81,8 @@ def init(
81
81
  # Create a project in a specific location
82
82
  $ flowerpower init --name my-project --base-dir /path/to/projects
83
83
 
84
- # Create a project with APScheduler as the job queue backend
85
- $ flowerpower init --job-queue-type apscheduler
84
+ # Create a project with RQ as the job queue backend (default)
85
+ $ flowerpower init --job-queue-type rq
86
86
  """
87
87
  parsed_storage_options = {}
88
88
  if storage_options:
flowerpower/cli/cfg.py CHANGED
@@ -1,8 +1,5 @@
1
1
  import typer
2
2
 
3
- from ..cfg import Config
4
- from ..cli.utils import parse_dict_or_list_param
5
-
6
3
  app = typer.Typer(help="Config management commands")
7
4
 
8
5