dataflow-core 2.0.3__tar.gz → 2.0.6__tar.gz
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.
Potentially problematic release.
This version of dataflow-core might be problematic. Click here for more details.
- dataflow-core-2.0.6/PKG-INFO +10 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/README.md +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/__init__.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/dataflowairflowauthenticator.py +14 -52
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/dataflowhubauthenticator.py +0 -0
- dataflow-core-2.0.6/authenticator/dataflowsupersetauthenticator.py +48 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/__init__.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/configuration.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/models/__init__.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/models/database.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/models/session.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/authenticator/package/models/user.py +0 -0
- dataflow-core-2.0.6/dataflow/__init__.py +1 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow/configuration.py +0 -0
- dataflow-core-2.0.6/dataflow/dataflow.py +127 -0
- {dataflow_core-2.0.3/dataflow → dataflow-core-2.0.6/dataflow/models}/__init__.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow/models/database.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow/models/session.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow/models/user.py +0 -0
- {dataflow_core-2.0.3/dataflow/models → dataflow-core-2.0.6/dataflow/utils}/__init__.py +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow/utils/aws_secrets_manager.py +0 -0
- dataflow-core-2.0.6/dataflow_core.egg-info/PKG-INFO +10 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow_core.egg-info/SOURCES.txt +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow_core.egg-info/dependency_links.txt +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow_core.egg-info/entry_points.txt +1 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow_core.egg-info/requires.txt +1 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/dataflow_core.egg-info/top_level.txt +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/setup.cfg +0 -0
- {dataflow_core-2.0.3 → dataflow-core-2.0.6}/setup.py +7 -4
- dataflow_core-2.0.3/PKG-INFO +0 -10
- dataflow_core-2.0.3/authenticator/dataflowsupersetauthenticator.py +0 -57
- dataflow_core-2.0.3/dataflow/dataflow.py +0 -93
- dataflow_core-2.0.3/dataflow/utils/__init__.py +0 -0
- dataflow_core-2.0.3/dataflow_core.egg-info/PKG-INFO +0 -10
|
File without changes
|
|
File without changes
|
|
@@ -1,34 +1,19 @@
|
|
|
1
|
-
from .package.configuration import ConfigurationManager
|
|
2
1
|
from .package.models.database import DatabaseManager
|
|
3
|
-
from .
|
|
4
|
-
user as m_user,
|
|
5
|
-
session as m_session
|
|
6
|
-
)
|
|
2
|
+
from dataflow.dataflow import Dataflow
|
|
7
3
|
|
|
8
4
|
from typing import Any, Callable
|
|
9
5
|
from airflow.www.security import FabAirflowSecurityManagerOverride
|
|
6
|
+
from airflow.configuration import conf
|
|
10
7
|
|
|
11
8
|
class DataflowAirflowAuthenticator(FabAirflowSecurityManagerOverride):
|
|
12
9
|
def __init__(self, wsgi_app: Callable) -> None:
|
|
13
10
|
self.wsgi_app = wsgi_app
|
|
11
|
+
self.dataflow = Dataflow()
|
|
12
|
+
self.airflow_database_url = conf.get("database", "sql_alchemy_conn")
|
|
14
13
|
|
|
15
|
-
# Dataflow database configuration
|
|
16
|
-
self.dataflow_config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
|
|
17
|
-
self.dataflow_database_url = self.dataflow_config.get_config_value('database', 'database_url')
|
|
18
|
-
|
|
19
|
-
self.dataflow_db_instance = DatabaseManager(self.dataflow_database_url)
|
|
20
|
-
self.dataflow_db = next(self.dataflow_db_instance.get_session())
|
|
21
|
-
|
|
22
|
-
# Airflow database configuration
|
|
23
|
-
self.airflow_config = ConfigurationManager('airflow.cfg')
|
|
24
|
-
self.airflow_database_url = self.airflow_config.get_config_value('database', 'sql_alchemy_conn')
|
|
25
|
-
|
|
26
14
|
self.airflow_db_instance = DatabaseManager(self.airflow_database_url)
|
|
27
15
|
self.airflow_db = next(self.airflow_db_instance.get_session())
|
|
28
16
|
|
|
29
|
-
m_user.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
30
|
-
m_session.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
31
|
-
|
|
32
17
|
def __call__(self, environ: dict, start_response: Callable) -> Any:
|
|
33
18
|
|
|
34
19
|
path = environ.get('PATH_INFO', '')
|
|
@@ -51,39 +36,28 @@ class DataflowAirflowAuthenticator(FabAirflowSecurityManagerOverride):
|
|
|
51
36
|
user_session_id = user_session_id.split('=')[1]
|
|
52
37
|
|
|
53
38
|
# Retrieving user details
|
|
54
|
-
user_data = self.
|
|
39
|
+
user_data = self.dataflow.auth(user_session_id)
|
|
55
40
|
|
|
56
41
|
if user_data is None:
|
|
57
42
|
raise Exception("No user found for the dataflow_session id")
|
|
58
43
|
|
|
59
|
-
user = self.find_user(user_data
|
|
44
|
+
user = self.find_user(user_data["user_name"])
|
|
60
45
|
|
|
61
46
|
if not user:
|
|
62
|
-
user_role = self.find_role(user_data
|
|
63
|
-
user = self.add_user(
|
|
47
|
+
user_role = self.find_role(user_data["role"].title())
|
|
48
|
+
user = self.add_user(
|
|
49
|
+
username=user_data["user_name"],
|
|
50
|
+
first_name=user_data.get("first_name", ""),
|
|
51
|
+
last_name=user_data.get("last_name", ""),
|
|
52
|
+
email=user_data.get("email", ""),
|
|
53
|
+
role=user_role
|
|
54
|
+
)
|
|
64
55
|
|
|
65
56
|
environ['REMOTE_USER'] = user.username
|
|
66
|
-
self.write_user_id(user_data.user_id)
|
|
67
57
|
return self.wsgi_app(environ, start_response)
|
|
68
58
|
|
|
69
59
|
except Exception as e:
|
|
70
60
|
return self.wsgi_app(environ, start_response)
|
|
71
|
-
|
|
72
|
-
def not_none(self, value):
|
|
73
|
-
return value if value is not None else ""
|
|
74
|
-
|
|
75
|
-
def find_dataflow_user(self, user_session_id):
|
|
76
|
-
"""Find user by session_id in dataflow database."""
|
|
77
|
-
query = self.dataflow_db.query(m_session.Session_table)
|
|
78
|
-
session = query.filter(m_session.Session_table.session_id == user_session_id).first()
|
|
79
|
-
if session is None:
|
|
80
|
-
return None
|
|
81
|
-
|
|
82
|
-
user_data = self.dataflow_db.query(m_user.User).filter(m_user.User.user_id == session.user_id).first()
|
|
83
|
-
if user_data is None:
|
|
84
|
-
return None
|
|
85
|
-
|
|
86
|
-
return user_data
|
|
87
61
|
|
|
88
62
|
def find_user(self, username=None):
|
|
89
63
|
"""Find user by username or email."""
|
|
@@ -106,16 +80,4 @@ class DataflowAirflowAuthenticator(FabAirflowSecurityManagerOverride):
|
|
|
106
80
|
self.airflow_db.add(user)
|
|
107
81
|
self.airflow_db.commit()
|
|
108
82
|
return user
|
|
109
|
-
|
|
110
|
-
def write_user_id(self, user_id):
|
|
111
|
-
"""
|
|
112
|
-
Write the given user_id to a file named dataflow_user_id.txt.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
user_id (str): The user ID to be written to the file.
|
|
116
|
-
"""
|
|
117
|
-
file_name = 'dataflow_user_id.txt'
|
|
118
|
-
with open(file_name, 'w') as file:
|
|
119
|
-
file.write(str(user_id))
|
|
120
|
-
|
|
121
83
|
|
|
File without changes
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from flask import redirect, request
|
|
2
|
+
from flask_appbuilder.security.views import AuthDBView
|
|
3
|
+
from superset.security import SupersetSecurityManager
|
|
4
|
+
from flask_appbuilder.security.views import expose
|
|
5
|
+
from flask_login import login_user
|
|
6
|
+
from .package.configuration import ConfigurationManager
|
|
7
|
+
from .package.models.database import DatabaseManager
|
|
8
|
+
from .package.models import (
|
|
9
|
+
user as m_user,
|
|
10
|
+
session as m_session
|
|
11
|
+
)
|
|
12
|
+
from dataflow.dataflow import Dataflow
|
|
13
|
+
|
|
14
|
+
class CustomAuthDBView(AuthDBView):
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self.dataflow = Dataflow()
|
|
17
|
+
|
|
18
|
+
@expose('/login/', methods=['GET'])
|
|
19
|
+
def login(self):
|
|
20
|
+
try:
|
|
21
|
+
session_id = request.cookies.get('dataflow_session')
|
|
22
|
+
|
|
23
|
+
user_details = self.dataflow.auth(session_id)
|
|
24
|
+
user = self.appbuilder.sm.find_user(username=user_details['user_name'])
|
|
25
|
+
if user:
|
|
26
|
+
login_user(user, remember=False)
|
|
27
|
+
else:
|
|
28
|
+
user = self.appbuilder.sm.add_user(
|
|
29
|
+
username=user_details['user_name'],
|
|
30
|
+
first_name=user_details.get("first_name", ""),
|
|
31
|
+
last_name=user_details.get("last_name", ""),
|
|
32
|
+
email=user_details.get("email", ""),
|
|
33
|
+
role=self.appbuilder.sm.find_role('Admin'),
|
|
34
|
+
password=""
|
|
35
|
+
)
|
|
36
|
+
if user:
|
|
37
|
+
login_user(user, remember=False)
|
|
38
|
+
|
|
39
|
+
return redirect(self.appbuilder.get_url_for_index)
|
|
40
|
+
|
|
41
|
+
except Exception as e:
|
|
42
|
+
return super().login()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CustomSecurityManager(SupersetSecurityManager):
|
|
46
|
+
authdbview = CustomAuthDBView
|
|
47
|
+
def __init__(self, appbuilder):
|
|
48
|
+
super(CustomSecurityManager, self).__init__(appbuilder)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .dataflow import Dataflow
|
|
File without changes
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import os, requests
|
|
2
|
+
from .models.database import DatabaseManager
|
|
3
|
+
from sqlalchemy.inspection import inspect
|
|
4
|
+
from .utils.aws_secrets_manager import SecretsManagerClient
|
|
5
|
+
import json, asyncio, pkg_resources
|
|
6
|
+
from authenticator.package.configuration import ConfigurationManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Dataflow:
|
|
10
|
+
def __init__(self):
|
|
11
|
+
self.secrets_manager = SecretsManagerClient('us-east-1')
|
|
12
|
+
|
|
13
|
+
def auth(self, session_id: str):
|
|
14
|
+
"""Retrieve user information from the auth API."""
|
|
15
|
+
try:
|
|
16
|
+
dataflow_config = ConfigurationManager('/dataflow/app/auth_config/dataflow_auth.cfg')
|
|
17
|
+
auth_api = dataflow_config.get_config_value('auth', 'ui_auth_api')
|
|
18
|
+
response = requests.get(
|
|
19
|
+
auth_api,
|
|
20
|
+
cookies={"dataflow_session": session_id, "jupyterhub-hub-login": ""}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if response.status_code != 200:
|
|
24
|
+
return response.json()
|
|
25
|
+
|
|
26
|
+
user_data = response.json()
|
|
27
|
+
user_dict = {
|
|
28
|
+
"user_name": user_data["user_name"],
|
|
29
|
+
"first_name": user_data["first_name"],
|
|
30
|
+
"last_name": user_data["last_name"] if user_data.get("last_name") else "",
|
|
31
|
+
"email": user_data["email"],
|
|
32
|
+
"role": user_data["role"]
|
|
33
|
+
}
|
|
34
|
+
return user_dict
|
|
35
|
+
|
|
36
|
+
except Exception as e:
|
|
37
|
+
return e
|
|
38
|
+
|
|
39
|
+
def variable(self, variable_name: str):
|
|
40
|
+
"""Get variable value from secrets manager."""
|
|
41
|
+
try:
|
|
42
|
+
host_name = os.environ["HOSTNAME"]
|
|
43
|
+
user_name = host_name.replace("jupyter-","")
|
|
44
|
+
|
|
45
|
+
vault_path = "variables"
|
|
46
|
+
variable_data = self.secrets_manager.get_secret_by_key(vault_path, user_name, variable_name)
|
|
47
|
+
return variable_data['value']
|
|
48
|
+
|
|
49
|
+
except Exception as e:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def connection(self, conn_id: str):
|
|
53
|
+
"""Get connection details from secrets manager."""
|
|
54
|
+
try:
|
|
55
|
+
host_name = os.environ["HOSTNAME"]
|
|
56
|
+
user_name=host_name.replace("jupyter-","")
|
|
57
|
+
|
|
58
|
+
vault_path = "connections"
|
|
59
|
+
secret = self.secrets_manager.get_secret_by_key(vault_path, user_name, conn_id)
|
|
60
|
+
|
|
61
|
+
conn_type = secret['conn_type'].lower()
|
|
62
|
+
username = secret['login']
|
|
63
|
+
password = secret.get('password', '')
|
|
64
|
+
host = secret['host']
|
|
65
|
+
port = secret['port']
|
|
66
|
+
database = secret.get('schemas', '')
|
|
67
|
+
|
|
68
|
+
user_info = f"{username}:{password}@" if password else f"{username}@"
|
|
69
|
+
db_info = f"/{database}" if database else ""
|
|
70
|
+
|
|
71
|
+
connection_string = f"{conn_type}://{user_info}{host}:{port}{db_info}"
|
|
72
|
+
|
|
73
|
+
extra = secret.get('extra', '')
|
|
74
|
+
if extra:
|
|
75
|
+
try:
|
|
76
|
+
extra_params = json.loads(extra)
|
|
77
|
+
if extra_params:
|
|
78
|
+
extra_query = "&".join(f"{key}={value}" for key, value in extra_params.items())
|
|
79
|
+
connection_string += f"?{extra_query}"
|
|
80
|
+
except json.JSONDecodeError:
|
|
81
|
+
# If 'extra' is not valid JSON, skip adding extra parameters
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
connection_instance = DatabaseManager(connection_string)
|
|
85
|
+
return next(connection_instance.get_session())
|
|
86
|
+
|
|
87
|
+
except Exception as e:
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
async def create_env(self, env_name, py_version, py_requirements, status, env_version=None):
|
|
91
|
+
"""
|
|
92
|
+
Creates a conda environment at the specified path and installs libraries in one command.
|
|
93
|
+
"""
|
|
94
|
+
config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
|
|
95
|
+
status = status.lower()
|
|
96
|
+
if status == "published":
|
|
97
|
+
env_base_path = config.get_config_value('paths', 'published_env_path')
|
|
98
|
+
conda_env_path = os.path.join(env_base_path, env_name)
|
|
99
|
+
else:
|
|
100
|
+
env_base_path = config.get_config_value('paths', 'drafts_env_path')
|
|
101
|
+
conda_env_path = os.path.join(env_base_path, env_name, f"{env_name}_v{env_version}")
|
|
102
|
+
try:
|
|
103
|
+
if not os.path.exists(conda_env_path):
|
|
104
|
+
os.makedirs(conda_env_path, exist_ok=True)
|
|
105
|
+
|
|
106
|
+
py_requirements = ",".join(py_requirements)
|
|
107
|
+
|
|
108
|
+
script_path = pkg_resources.resource_filename('dataflow', 'scripts/create_environment.sh')
|
|
109
|
+
|
|
110
|
+
# Make the script executable
|
|
111
|
+
os.chmod(script_path, 0o755)
|
|
112
|
+
|
|
113
|
+
# Prepare command with arguments
|
|
114
|
+
command = ["bash", script_path, py_requirements, conda_env_path, py_version]
|
|
115
|
+
|
|
116
|
+
process = await asyncio.create_subprocess_exec(
|
|
117
|
+
*command,
|
|
118
|
+
stdout=asyncio.subprocess.PIPE,
|
|
119
|
+
stderr=asyncio.subprocess.PIPE
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
return process
|
|
123
|
+
except OSError as e:
|
|
124
|
+
print(f"OS error while creating {conda_env_path}: {e}")
|
|
125
|
+
except Exception as e:
|
|
126
|
+
print(f"Unexpected error while creating {conda_env_path}: {e}")
|
|
127
|
+
return {"error": str(e)}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,15 +2,18 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="dataflow-core",
|
|
5
|
-
version="2.0.
|
|
6
|
-
packages=find_packages(
|
|
5
|
+
version="2.0.6",
|
|
6
|
+
packages=find_packages(include=["dataflow", "dataflow.*", "authenticator", "authenticator.*"]),
|
|
7
7
|
include_package_data=True,
|
|
8
|
-
package_data={
|
|
8
|
+
package_data={
|
|
9
|
+
"dataflow": ["scripts/*.sh"],
|
|
10
|
+
},
|
|
9
11
|
install_requires=[
|
|
10
12
|
'sqlalchemy',
|
|
11
13
|
'boto3',
|
|
12
14
|
'psycopg2-binary',
|
|
13
|
-
'pymysql'
|
|
15
|
+
'pymysql',
|
|
16
|
+
'requests'
|
|
14
17
|
],
|
|
15
18
|
author="Dataflow",
|
|
16
19
|
author_email="",
|
dataflow_core-2.0.3/PKG-INFO
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
from flask import redirect, request
|
|
2
|
-
from flask_appbuilder.security.views import AuthDBView
|
|
3
|
-
from superset.security import SupersetSecurityManager
|
|
4
|
-
from flask_appbuilder.security.views import expose
|
|
5
|
-
from flask_login import login_user
|
|
6
|
-
from .package.configuration import ConfigurationManager
|
|
7
|
-
from .package.models.database import DatabaseManager
|
|
8
|
-
from .package.models import (
|
|
9
|
-
user as m_user,
|
|
10
|
-
session as m_session
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
class CustomAuthDBView(AuthDBView):
|
|
14
|
-
def __init__(self):
|
|
15
|
-
self.dataflow_config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
|
|
16
|
-
self.dataflow_database_url = self.dataflow_config.get_config_value('database', 'database_url')
|
|
17
|
-
self.dataflow_db_instance = DatabaseManager(self.dataflow_database_url)
|
|
18
|
-
self.dataflow_db = next(self.dataflow_db_instance.get_session())
|
|
19
|
-
m_user.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
20
|
-
m_session.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
21
|
-
|
|
22
|
-
def _get_user_id_from_session(self, session_id):
|
|
23
|
-
query = self.dataflow_db.query(m_session.Session_table).filter(m_session.Session_table.session_id == session_id).first()
|
|
24
|
-
return query.user_id if query!=None else None
|
|
25
|
-
|
|
26
|
-
def _get_user_details_from_user_table(self, user_id):
|
|
27
|
-
user_details = self.dataflow_db.query(m_user.User).filter(m_user.User.user_id == user_id).first()
|
|
28
|
-
return user_details if user_details!=None else None
|
|
29
|
-
|
|
30
|
-
def not_none(self, value):
|
|
31
|
-
return value if value is not None else ""
|
|
32
|
-
|
|
33
|
-
@expose('/login/', methods=['GET'])
|
|
34
|
-
def login(self):
|
|
35
|
-
try:
|
|
36
|
-
session_id = request.cookies.get('dataflow_session')
|
|
37
|
-
|
|
38
|
-
user_id = self._get_user_id_from_session(session_id)
|
|
39
|
-
user_details = self._get_user_details_from_user_table(user_id)
|
|
40
|
-
user = self.appbuilder.sm.find_user(username=user_details.user_name)
|
|
41
|
-
if user:
|
|
42
|
-
login_user(user, remember=False)
|
|
43
|
-
else:
|
|
44
|
-
user = self.appbuilder.sm.add_user(username=self.not_none(user_details.user_name), first_name=self.not_none(user_details.first_name), last_name=self.not_none(user_details.last_name), email=self.not_none(user_details.email), role=self.appbuilder.sm.find_role('Admin'), password=self.not_none(user_details.password))
|
|
45
|
-
if user:
|
|
46
|
-
login_user(user, remember=False)
|
|
47
|
-
|
|
48
|
-
return redirect(self.appbuilder.get_url_for_index)
|
|
49
|
-
|
|
50
|
-
except Exception as e:
|
|
51
|
-
return super().login()
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class CustomSecurityManager(SupersetSecurityManager):
|
|
55
|
-
authdbview = CustomAuthDBView
|
|
56
|
-
def __init__(self, appbuilder):
|
|
57
|
-
super(CustomSecurityManager, self).__init__(appbuilder)
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from .configuration import ConfigurationManager
|
|
3
|
-
from .models import (
|
|
4
|
-
session as m_session,
|
|
5
|
-
user as m_user,
|
|
6
|
-
)
|
|
7
|
-
from .models.database import DatabaseManager
|
|
8
|
-
from sqlalchemy.inspection import inspect
|
|
9
|
-
from .utils.aws_secrets_manager import SecretsManagerClient
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Dataflow:
|
|
14
|
-
def __init__(self):
|
|
15
|
-
self.dataflow_config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
|
|
16
|
-
self.dataflow_database_url = self.dataflow_config.get_config_value('database', 'database_url')
|
|
17
|
-
|
|
18
|
-
self.dataflow_db_instance = DatabaseManager(self.dataflow_database_url)
|
|
19
|
-
self.dataflow_db = next(self.dataflow_db_instance.get_session())
|
|
20
|
-
|
|
21
|
-
self.secrets_manager = SecretsManagerClient('us-east-1')
|
|
22
|
-
|
|
23
|
-
m_user.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
24
|
-
m_session.Base.metadata.create_all(bind=self.dataflow_db_instance.get_engine())
|
|
25
|
-
|
|
26
|
-
def auth(self, session_id: str):
|
|
27
|
-
"""Find user by session_id in dataflow database."""
|
|
28
|
-
try:
|
|
29
|
-
query = self.dataflow_db.query(m_session.Session_table)
|
|
30
|
-
session = query.filter(m_session.Session_table.session_id == session_id).first()
|
|
31
|
-
if session is None:
|
|
32
|
-
return False
|
|
33
|
-
|
|
34
|
-
user_data = self.dataflow_db.query(m_user.User).filter(m_user.User.user_id == session.user_id).first()
|
|
35
|
-
if user_data is None:
|
|
36
|
-
return False
|
|
37
|
-
|
|
38
|
-
user_dict = {"user_name": user_data.user_name, "name": f"{user_data.first_name} {user_data.last_name}", "email": user_data.email, "role": user_data.role}
|
|
39
|
-
return user_dict
|
|
40
|
-
|
|
41
|
-
except Exception as e:
|
|
42
|
-
return False
|
|
43
|
-
|
|
44
|
-
def variable(self, variable_name: str):
|
|
45
|
-
"""Get variable value from secrets manager."""
|
|
46
|
-
try:
|
|
47
|
-
host_name = os.environ["HOSTNAME"]
|
|
48
|
-
user_name = host_name.replace("jupyter-","")
|
|
49
|
-
|
|
50
|
-
vault_path = "variables"
|
|
51
|
-
variable_data = self.secrets_manager.get_secret_by_key(vault_path, user_name, variable_name)
|
|
52
|
-
return variable_data['value']
|
|
53
|
-
|
|
54
|
-
except Exception as e:
|
|
55
|
-
return None
|
|
56
|
-
|
|
57
|
-
def connection(self, conn_id: str):
|
|
58
|
-
"""Get connection details from secrets manager."""
|
|
59
|
-
try:
|
|
60
|
-
host_name = os.environ["HOSTNAME"]
|
|
61
|
-
user_name=host_name.replace("jupyter-","")
|
|
62
|
-
|
|
63
|
-
vault_path = "connections"
|
|
64
|
-
secret = self.secrets_manager.get_secret_by_key(vault_path, user_name, conn_id)
|
|
65
|
-
|
|
66
|
-
conn_type = secret['conn_type'].lower()
|
|
67
|
-
username = secret['login']
|
|
68
|
-
password = secret.get('password', '')
|
|
69
|
-
host = secret['host']
|
|
70
|
-
port = secret['port']
|
|
71
|
-
database = secret.get('schemas', '')
|
|
72
|
-
|
|
73
|
-
user_info = f"{username}:{password}@" if password else f"{username}@"
|
|
74
|
-
db_info = f"/{database}" if database else ""
|
|
75
|
-
|
|
76
|
-
connection_string = f"{conn_type}://{user_info}{host}:{port}{db_info}"
|
|
77
|
-
|
|
78
|
-
extra = secret.get('extra', '')
|
|
79
|
-
if extra:
|
|
80
|
-
try:
|
|
81
|
-
extra_params = json.loads(extra)
|
|
82
|
-
if extra_params:
|
|
83
|
-
extra_query = "&".join(f"{key}={value}" for key, value in extra_params.items())
|
|
84
|
-
connection_string += f"?{extra_query}"
|
|
85
|
-
except json.JSONDecodeError:
|
|
86
|
-
# If 'extra' is not valid JSON, skip adding extra parameters
|
|
87
|
-
pass
|
|
88
|
-
|
|
89
|
-
connection_instance = DatabaseManager(connection_string)
|
|
90
|
-
return next(connection_instance.get_session())
|
|
91
|
-
|
|
92
|
-
except Exception as e:
|
|
93
|
-
return None
|
|
File without changes
|