1
- import datetime
2
1
import importlib
3
2
import inspect
4
- import os
5
3
import pkgutil
6
4
import sys
7
5
from typing import Set
8
6
9
- import boto3
10
7
import setuptools
11
8
import typer
12
- from botocore .exceptions import ClientError
13
9
14
- from butterfree .configs import environment
15
- from butterfree .configs .logger import __logger
16
- from butterfree .migrations .database_migration import ALLOWED_DATABASE
10
+ from butterfree ._cli import cli_logger
17
11
from butterfree .pipelines import FeatureSetPipeline
18
12
19
- app = typer .Typer (help = "Apply the automatic migrations in a database." )
20
-
21
- logger = __logger ("migrate" , True )
13
+ app = typer .Typer ()
22
14
23
15
24
16
def __find_modules (path : str ) -> Set [str ]:
@@ -40,19 +32,18 @@ def __find_modules(path: str) -> Set[str]:
40
32
41
33
42
34
def __fs_objects (path : str ) -> Set [FeatureSetPipeline ]:
43
- logger .info (f"Looking for python modules under { path } ..." )
35
+ cli_logger .info (f"Looking for python modules under { path } ..." )
44
36
modules = __find_modules (path )
45
37
if not modules :
46
- logger .error (f"Path: { path } not found!" )
47
38
return set ()
48
39
49
- logger .info (f"Importing modules..." )
40
+ cli_logger .info (f"Importing modules..." )
50
41
package = "." .join (path .strip ("/" ).split ("/" ))
51
42
imported = set (
52
43
importlib .import_module (f".{ name } " , package = package ) for name in modules
53
44
)
54
45
55
- logger .info (f"Scanning modules..." )
46
+ cli_logger .info (f"Scanning modules..." )
56
47
content = {
57
48
module : set (
58
49
filter (
@@ -88,91 +79,17 @@ def __fs_objects(path: str) -> Set[FeatureSetPipeline]:
88
79
89
80
instances .add (value )
90
81
91
- logger .info ("Creating instances..." )
82
+ cli_logger .info ("Creating instances..." )
92
83
return set (value () for value in instances )
93
84
94
85
95
86
PATH = typer .Argument (
96
87
..., help = "Full or relative path to where feature set pipelines are being defined." ,
97
88
)
98
89
99
- GENERATE_LOGS = typer .Option (
100
- False , help = "To generate the logs in local file 'logging.json'."
101
- )
102
-
103
- DEBUG_MODE = typer .Option (
104
- False ,
105
- help = "To view the queries resulting from the migration, DON'T apply the migration." ,
106
- )
107
-
108
90
109
- class Migrate :
110
- """Execute migration operations in a Database based on pipeline Writer.
111
-
112
- Attributes:
113
- pipelines: list of Feature Set Pipelines to use to migration.
114
- """
115
-
116
- def __init__ (self , pipelines : Set [FeatureSetPipeline ],) -> None :
117
- self .pipelines = pipelines
118
-
119
- def _send_logs_to_s3 (self , file_local : bool , debug_mode : bool ) -> None :
120
- """Send all migration logs to S3."""
121
- file_name = "../logging.json"
122
-
123
- if not file_local and os .path .exists (file_name ):
124
- s3_client = boto3 .client ("s3" )
125
-
126
- timestamp = datetime .datetime .now ()
127
-
128
- if debug_mode :
129
- object_name = (
130
- f"logs/migrate-debug-mode/"
131
- f"{ timestamp .strftime ('%Y-%m-%d' )} "
132
- f"/logging-{ timestamp .strftime ('%H:%M:%S' )} .json"
133
- )
134
- else :
135
- object_name = (
136
- f"logs/migrate/"
137
- f"{ timestamp .strftime ('%Y-%m-%d' )} "
138
- f"/logging-{ timestamp .strftime ('%H:%M:%S' )} .json"
139
- )
140
- bucket = environment .get_variable ("FEATURE_STORE_S3_BUCKET" )
141
-
142
- try :
143
- s3_client .upload_file (
144
- file_name ,
145
- bucket ,
146
- object_name ,
147
- ExtraArgs = {"ACL" : "bucket-owner-full-control" },
148
- )
149
- except ClientError :
150
- raise
151
-
152
- os .remove (file_name )
153
- elif os .path .exists (file_name ):
154
- print ("Logs written to ../logging.json" )
155
- else :
156
- print ("No logs were generated." )
157
-
158
- def run (self , generate_logs : bool = False , debug_mode : bool = False ) -> None :
159
- """Construct and apply the migrations."""
160
- for pipeline in self .pipelines :
161
- for writer in pipeline .sink .writers :
162
- db = writer .db_config .database
163
- if db == "cassandra" :
164
- migration = ALLOWED_DATABASE [db ]
165
- migration .apply_migration (pipeline .feature_set , writer , debug_mode )
166
- else :
167
- logger .warning (f"Butterfree not supporting { db } Migrations yet." )
168
-
169
- self ._send_logs_to_s3 (generate_logs , debug_mode )
170
-
171
-
172
- @app .command ("apply" )
173
- def migrate (
174
- path : str = PATH , generate_logs : bool = GENERATE_LOGS , debug_mode : bool = DEBUG_MODE
175
- ) -> Set [FeatureSetPipeline ]:
91
+ @app .callback ()
92
+ def migrate (path : str = PATH ) -> Set [FeatureSetPipeline ]:
176
93
"""Scan and run database migrations for feature set pipelines defined under PATH.
177
94
178
95
Butterfree will scan a given path for classes that inherit from its
@@ -183,6 +100,5 @@ def migrate(
183
100
All pipelines must be under python modules inside path, so we can dynamically
184
101
import and instantiate them.
185
102
"""
186
- pipe_set = __fs_objects (path )
187
- Migrate (pipe_set ).run (generate_logs , debug_mode )
188
- return pipe_set
103
+ # TODO call the Migration actor with all feature set pipeline objects
104
+ return __fs_objects (path )
0 commit comments