ml-analytics-tools 0.2.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.
- ml_analytics/__init__.py +53 -0
- ml_analytics/aws_auth.py +169 -0
- ml_analytics/cli.py +58 -0
- ml_analytics/data_connector.py +2615 -0
- ml_analytics/gsheet_connector.py +1646 -0
- ml_analytics/model_manager.py +1208 -0
- ml_analytics/model_tools.py +990 -0
- ml_analytics/s3_connector.py +1381 -0
- ml_analytics/slack_connector.py +637 -0
- ml_analytics/tunnel_manager.py +277 -0
- ml_analytics/utils.py +673 -0
- ml_analytics_tools-0.2.0.dist-info/METADATA +231 -0
- ml_analytics_tools-0.2.0.dist-info/RECORD +17 -0
- ml_analytics_tools-0.2.0.dist-info/WHEEL +5 -0
- ml_analytics_tools-0.2.0.dist-info/entry_points.txt +4 -0
- ml_analytics_tools-0.2.0.dist-info/licenses/LICENSE +21 -0
- ml_analytics_tools-0.2.0.dist-info/top_level.txt +1 -0
ml_analytics/__init__.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ML Analytics Tools Package
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from dotenv import load_dotenv
|
|
6
|
+
|
|
7
|
+
from .aws_auth import ensure_aws_authenticated, ensure_aws_sso_login
|
|
8
|
+
from .data_connector import DataConnector
|
|
9
|
+
from .gsheet_connector import GSheet
|
|
10
|
+
from .model_manager import ModelManager
|
|
11
|
+
from .s3_connector import S3Connector
|
|
12
|
+
from .slack_connector import SlackConnector
|
|
13
|
+
from .utils import (
|
|
14
|
+
execute_sql_scripts,
|
|
15
|
+
find_project_root,
|
|
16
|
+
get_credential_value,
|
|
17
|
+
get_logger,
|
|
18
|
+
get_sql_files,
|
|
19
|
+
load_sql_query,
|
|
20
|
+
log_and_raise_error,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Automatically load .env file when the package is imported
|
|
24
|
+
logger = get_logger("ml_analytics")
|
|
25
|
+
try:
|
|
26
|
+
project_root = find_project_root()
|
|
27
|
+
env_file = project_root / ".env"
|
|
28
|
+
if env_file.exists():
|
|
29
|
+
if load_dotenv(env_file, override=True):
|
|
30
|
+
logger.info(".env file loaded successfully.")
|
|
31
|
+
else:
|
|
32
|
+
logger.info("Failed to load .env file.")
|
|
33
|
+
else:
|
|
34
|
+
logger.info("No .env file present in project root.")
|
|
35
|
+
except Exception:
|
|
36
|
+
logger.info("No .env file loaded.")
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"DataConnector",
|
|
40
|
+
"ensure_aws_authenticated",
|
|
41
|
+
"ensure_aws_sso_login",
|
|
42
|
+
"execute_sql_scripts",
|
|
43
|
+
"find_project_root",
|
|
44
|
+
"get_credential_value",
|
|
45
|
+
"get_logger",
|
|
46
|
+
"get_sql_files",
|
|
47
|
+
"GSheet",
|
|
48
|
+
"load_sql_query",
|
|
49
|
+
"log_and_raise_error",
|
|
50
|
+
"ModelManager",
|
|
51
|
+
"S3Connector",
|
|
52
|
+
"SlackConnector",
|
|
53
|
+
]
|
ml_analytics/aws_auth.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AWS authentication utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from .utils import get_logger
|
|
9
|
+
|
|
10
|
+
logger = get_logger("aws_auth")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _do_sso_login(profile: str = None) -> bool:
|
|
14
|
+
"""
|
|
15
|
+
Performs the interactive SSO login flow.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
profile : str, optional
|
|
20
|
+
AWS profile name to use.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
bool
|
|
25
|
+
True if login successful, False otherwise.
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
logger.info("AWS SSO login required - starting authentication...")
|
|
29
|
+
login_cmd = ["aws", "sso", "login"]
|
|
30
|
+
if profile:
|
|
31
|
+
login_cmd.extend(["--profile", profile])
|
|
32
|
+
|
|
33
|
+
# Redirect stdout to stderr so user sees prompts but eval doesn't execute them
|
|
34
|
+
login_result = subprocess.run(login_cmd, stdout=sys.stderr, timeout=300)
|
|
35
|
+
|
|
36
|
+
if login_result.returncode == 0:
|
|
37
|
+
logger.info("✓ AWS SSO login successful")
|
|
38
|
+
return True
|
|
39
|
+
else:
|
|
40
|
+
logger.error("✗ AWS SSO login failed")
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
except subprocess.TimeoutExpired:
|
|
44
|
+
logger.error("AWS SSO login timed out")
|
|
45
|
+
return False
|
|
46
|
+
except FileNotFoundError:
|
|
47
|
+
logger.error("AWS CLI not found. Please install AWS CLI.")
|
|
48
|
+
return False
|
|
49
|
+
except Exception as e:
|
|
50
|
+
logger.error(f"Error during AWS SSO login: {e}")
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def ensure_aws_sso_login(profile: str = None, force: bool = False) -> bool:
|
|
55
|
+
"""
|
|
56
|
+
Ensures AWS SSO is authenticated. If not, prompts user to login.
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
profile : str, optional
|
|
61
|
+
AWS profile name to use. If None, uses default profile.
|
|
62
|
+
force : bool, optional
|
|
63
|
+
If True, skip the cached credential check and force a fresh SSO login.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
bool
|
|
68
|
+
True if authenticated successfully, False otherwise.
|
|
69
|
+
"""
|
|
70
|
+
if force:
|
|
71
|
+
return _do_sso_login(profile)
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
# Check if already logged in by attempting to get caller identity
|
|
75
|
+
cmd = ["aws", "sts", "get-caller-identity"]
|
|
76
|
+
if profile:
|
|
77
|
+
cmd.extend(["--profile", profile])
|
|
78
|
+
|
|
79
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
|
|
80
|
+
|
|
81
|
+
if result.returncode == 0:
|
|
82
|
+
# Already authenticated - don't log to reduce noise
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
# Not logged in, attempt SSO login
|
|
86
|
+
return _do_sso_login(profile)
|
|
87
|
+
|
|
88
|
+
except subprocess.TimeoutExpired:
|
|
89
|
+
logger.error("AWS SSO login timed out")
|
|
90
|
+
return False
|
|
91
|
+
except FileNotFoundError:
|
|
92
|
+
logger.error("AWS CLI not found. Please install AWS CLI.")
|
|
93
|
+
return False
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.error(f"Error during AWS SSO login: {e}")
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def ensure_aws_authenticated(sso_profile: str = None, print_exports: bool = False) -> bool:
|
|
100
|
+
"""
|
|
101
|
+
Convenience function that ensures AWS SSO is authenticated.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
sso_profile : str, optional
|
|
106
|
+
AWS SSO profile to use
|
|
107
|
+
print_exports : bool, optional
|
|
108
|
+
Kept for backward-compatible CLI calls. No shell exports are required.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
bool
|
|
113
|
+
True if AWS SSO authentication succeeded, False otherwise.
|
|
114
|
+
|
|
115
|
+
Example
|
|
116
|
+
-------
|
|
117
|
+
>>> from ml_analytics.aws_auth import ensure_aws_authenticated
|
|
118
|
+
>>> ensure_aws_authenticated()
|
|
119
|
+
"""
|
|
120
|
+
del print_exports
|
|
121
|
+
logger.info("Ensuring AWS authentication...")
|
|
122
|
+
|
|
123
|
+
if not ensure_aws_sso_login(sso_profile):
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
logger.info("✓ AWS authentication complete")
|
|
127
|
+
return True
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def run_uv_command(command: str) -> bool:
|
|
131
|
+
"""
|
|
132
|
+
Runs a UV command and returns whether it succeeded.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
command : str
|
|
137
|
+
The UV command to run (e.g., "uv sync", "uv add package")
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
bool
|
|
142
|
+
True if the command executed successfully, False otherwise.
|
|
143
|
+
|
|
144
|
+
Example
|
|
145
|
+
-------
|
|
146
|
+
>>> from ml_analytics.aws_auth import run_uv_command
|
|
147
|
+
>>> run_uv_command("uv sync")
|
|
148
|
+
"""
|
|
149
|
+
try:
|
|
150
|
+
logger.info(f"Running UV command: {command}")
|
|
151
|
+
result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=300)
|
|
152
|
+
|
|
153
|
+
if result.returncode == 0:
|
|
154
|
+
logger.info("✓ UV command completed successfully")
|
|
155
|
+
if result.stdout:
|
|
156
|
+
print(result.stdout)
|
|
157
|
+
return True
|
|
158
|
+
else:
|
|
159
|
+
logger.error(f"✗ UV command failed: {result.stderr}")
|
|
160
|
+
if result.stderr:
|
|
161
|
+
print(result.stderr)
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
except subprocess.TimeoutExpired:
|
|
165
|
+
logger.error(f"UV command timed out: {command}")
|
|
166
|
+
return False
|
|
167
|
+
except Exception as e:
|
|
168
|
+
logger.error(f"Error running UV command '{command}': {e}")
|
|
169
|
+
return False
|
ml_analytics/cli.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for ml-analytics-tools
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from .aws_auth import ensure_aws_authenticated, ensure_aws_sso_login
|
|
8
|
+
from .utils import get_logger
|
|
9
|
+
|
|
10
|
+
logger = get_logger("ml_analytics_cli")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def aws_auth_command():
|
|
14
|
+
"""
|
|
15
|
+
CLI command to authenticate with AWS SSO.
|
|
16
|
+
Can be run as: ml-analytics-auth
|
|
17
|
+
"""
|
|
18
|
+
try:
|
|
19
|
+
if ensure_aws_authenticated(print_exports=True):
|
|
20
|
+
return 0
|
|
21
|
+
else:
|
|
22
|
+
print("Authentication failed", file=sys.stderr)
|
|
23
|
+
return 1
|
|
24
|
+
except KeyboardInterrupt:
|
|
25
|
+
print("Cancelled", file=sys.stderr)
|
|
26
|
+
return 130
|
|
27
|
+
except Exception as e:
|
|
28
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
29
|
+
return 1
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def aws_sso_command():
|
|
33
|
+
"""
|
|
34
|
+
CLI command to authenticate with AWS SSO only.
|
|
35
|
+
Can be run as: ml-analytics-sso
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
if ensure_aws_sso_login():
|
|
39
|
+
return 0
|
|
40
|
+
else:
|
|
41
|
+
print("SSO login failed", file=sys.stderr)
|
|
42
|
+
return 1
|
|
43
|
+
except KeyboardInterrupt:
|
|
44
|
+
print("Cancelled", file=sys.stderr)
|
|
45
|
+
return 130
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
48
|
+
return 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
"""Main entry point for CLI commands."""
|
|
53
|
+
# This is a placeholder for potential future CLI expansion
|
|
54
|
+
aws_auth_command()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
sys.exit(main())
|