dataflow-core 2.0.11__tar.gz → 2.1.0__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.

Files changed (57) hide show
  1. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/PKG-INFO +1 -1
  2. dataflow_core-2.1.0/authenticator/dataflowairflowauthenticator.py +58 -0
  3. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/authenticator/dataflowhubauthenticator.py +13 -19
  4. dataflow_core-2.0.11/dataflow/models/database.py → dataflow_core-2.1.0/dataflow/database_manager.py +4 -3
  5. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/dataflow.py +46 -9
  6. dataflow_core-2.1.0/dataflow/db.py +51 -0
  7. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/environment.py +1 -1
  8. dataflow_core-2.1.0/dataflow/models/__init__.py +22 -0
  9. dataflow_core-2.1.0/dataflow/models/app_types.py +10 -0
  10. dataflow_core-2.1.0/dataflow/models/blacklist_library.py +26 -0
  11. dataflow_core-2.1.0/dataflow/models/connection.py +25 -0
  12. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/models/environment.py +5 -5
  13. dataflow_core-2.1.0/dataflow/models/environment_status.py +17 -0
  14. dataflow_core-2.1.0/dataflow/models/git_ssh.py +18 -0
  15. dataflow_core-2.1.0/dataflow/models/pinned_projects.py +15 -0
  16. dataflow_core-2.1.0/dataflow/models/project_details.py +23 -0
  17. dataflow_core-2.1.0/dataflow/models/recent_project_studio.py +19 -0
  18. dataflow_core-2.1.0/dataflow/models/recent_projects.py +9 -0
  19. dataflow_core-2.1.0/dataflow/models/role.py +19 -0
  20. dataflow_core-2.1.0/dataflow/models/role_server.py +14 -0
  21. dataflow_core-2.1.0/dataflow/models/runtime.py +11 -0
  22. dataflow_core-2.1.0/dataflow/models/server_config.py +33 -0
  23. dataflow_core-2.1.0/dataflow/models/session.py +17 -0
  24. dataflow_core-2.1.0/dataflow/models/team.py +17 -0
  25. dataflow_core-2.1.0/dataflow/models/user.py +29 -0
  26. dataflow_core-2.1.0/dataflow/models/user_environment.py +16 -0
  27. dataflow_core-2.1.0/dataflow/models/user_team.py +14 -0
  28. dataflow_core-2.1.0/dataflow/models/variables.py +27 -0
  29. dataflow_core-2.1.0/dataflow/utils/get_current_user.py +35 -0
  30. dataflow_core-2.1.0/dataflow/utils/logger.py +41 -0
  31. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow_core.egg-info/PKG-INFO +1 -1
  32. dataflow_core-2.1.0/dataflow_core.egg-info/SOURCES.txt +46 -0
  33. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/setup.py +1 -1
  34. dataflow_core-2.0.11/authenticator/dataflowairflowauthenticator.py +0 -83
  35. dataflow_core-2.0.11/authenticator/package/models/__init__.py +0 -0
  36. dataflow_core-2.0.11/authenticator/package/models/database.py +0 -32
  37. dataflow_core-2.0.11/authenticator/package/models/session.py +0 -20
  38. dataflow_core-2.0.11/authenticator/package/models/user.py +0 -22
  39. dataflow_core-2.0.11/dataflow/configuration.py +0 -27
  40. dataflow_core-2.0.11/dataflow/models/__init__.py +0 -0
  41. dataflow_core-2.0.11/dataflow/utils/__init__.py +0 -0
  42. dataflow_core-2.0.11/dataflow_core.egg-info/SOURCES.txt +0 -30
  43. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/README.md +0 -0
  44. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/authenticator/__init__.py +0 -0
  45. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/authenticator/dataflowsupersetauthenticator.py +0 -0
  46. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/__init__.py +0 -0
  47. {dataflow_core-2.0.11/authenticator/package → dataflow_core-2.1.0/dataflow}/configuration.py +0 -0
  48. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/scripts/clone_environment.sh +0 -0
  49. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/scripts/create_environment.sh +0 -0
  50. {dataflow_core-2.0.11/authenticator/package → dataflow_core-2.1.0/dataflow/utils}/__init__.py +0 -0
  51. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/utils/aws_secrets_manager.py +0 -0
  52. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow/utils/json_handler.py +0 -0
  53. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow_core.egg-info/dependency_links.txt +0 -0
  54. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow_core.egg-info/entry_points.txt +0 -0
  55. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow_core.egg-info/requires.txt +0 -0
  56. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/dataflow_core.egg-info/top_level.txt +0 -0
  57. {dataflow_core-2.0.11 → dataflow_core-2.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataflow-core
3
- Version: 2.0.11
3
+ Version: 2.1.0
4
4
  Summary: Dataflow core package
5
5
  Author: Dataflow
6
6
  Author-email:
@@ -0,0 +1,58 @@
1
+ from flask import redirect, request
2
+ from flask_appbuilder.security.views import AuthDBView
3
+ from flask_appbuilder.security.views import expose
4
+ from flask_login import login_user
5
+ from airflow.www.security import FabAirflowSecurityManagerOverride
6
+ from dataflow.dataflow import Dataflow
7
+ import logging
8
+
9
+ logging.basicConfig(
10
+ level=logging.INFO,
11
+ format='%(asctime)s - %(levelname)s - %(message)s',
12
+ datefmt='%Y-%m-%d %H:%M:%S'
13
+ )
14
+ logger = logging.getLogger(__name__)
15
+
16
+ dataflow = Dataflow()
17
+
18
+ class DataflowAuthDBView(AuthDBView):
19
+ @expose('/login/', methods=['GET', 'POST'])
20
+ def login(self):
21
+ """
22
+ Override the default login method to handle custom authentication
23
+ """
24
+ try:
25
+ session_id = request.cookies.get('dataflow_session')
26
+ if not session_id:
27
+ logger.info("No session cookie found, falling back to standard login.")
28
+ return super().login()
29
+
30
+ user_details = dataflow.auth(session_id)
31
+ logger.info(f"User details retrieved for: {user_details['user_name']}")
32
+ user = self.appbuilder.sm.find_user(username=user_details['user_name'])
33
+ if user:
34
+ logger.info(f"User found: {user}")
35
+ login_user(user, remember=False)
36
+ else:
37
+ user = self.appbuilder.sm.add_user(
38
+ username=user_details['user_name'],
39
+ first_name=user_details.get("first_name", ""),
40
+ last_name=user_details.get("last_name", ""),
41
+ email=user_details.get("email", ""),
42
+ role=self.appbuilder.sm.find_role(user_details.get("base_role", "user").title())
43
+ )
44
+ logger.info(f"New user created: {user}")
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
+ logger.error(f"Login failed: {e}")
52
+ return super().login()
53
+
54
+ class DataflowAirflowAuthenticator(FabAirflowSecurityManagerOverride):
55
+ authdbview = DataflowAuthDBView
56
+
57
+ def __init__(self, appbuilder):
58
+ super().__init__(appbuilder)
@@ -1,6 +1,5 @@
1
- from .package.configuration import ConfigurationManager
2
- from .package.models.database import DatabaseManager
3
- from .package.models import (
1
+ from dataflow.db import get_db
2
+ from dataflow.models import (
4
3
  user as m_user,
5
4
  session as m_session
6
5
  )
@@ -11,15 +10,7 @@ from jupyterhub.auth import Authenticator
11
10
  class DataflowHubAuthenticator(Authenticator):
12
11
  def __init__(self, **kwargs):
13
12
  super().__init__(**kwargs)
14
-
15
- self.dataflow_config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
16
- self.database_url = self.dataflow_config.get_config_value('database', 'database_url')
17
-
18
- self.db_instance = DatabaseManager(self.database_url)
19
- self.db = next(self.db_instance.get_session())
20
-
21
- m_user.Base.metadata.create_all(bind=self.db_instance.get_engine())
22
- m_session.Base.metadata.create_all(bind=self.db_instance.get_engine())
13
+ self.db = next(get_db())
23
14
 
24
15
  def generate_session_id(self):
25
16
  return str(uuid.uuid4())
@@ -39,8 +30,8 @@ class DataflowHubAuthenticator(Authenticator):
39
30
 
40
31
  # Check if the user already has an existing session
41
32
  existing_session = (
42
- self.db.query(m_session.Session_table)
43
- .filter(m_session.Session_table.user_id == str(user.user_id))
33
+ self.db.query(m_session.Session)
34
+ .filter(m_session.Session.user_id == user.user_id)
44
35
  .first()
45
36
  )
46
37
 
@@ -50,16 +41,16 @@ class DataflowHubAuthenticator(Authenticator):
50
41
  else:
51
42
  # Generate a new session_id
52
43
  session_id = self.generate_session_id()
53
- query = self.db.query(m_session.Session_table)
54
- isSession = query.filter(m_session.Session_table.session_id == session_id).first()
44
+ query = self.db.query(m_session.Session)
45
+ isSession = query.filter(m_session.Session.session_id == session_id).first()
55
46
 
56
47
  # If session_id(uuid string) already exists in the database, generate a new one
57
48
  while isSession is not None:
58
49
  session_id = self.generate_session_id()
59
- isSession = query.filter(m_session.Session_table.session_id == session_id).first()
50
+ isSession = query.filter(m_session.Session.session_id == session_id).first()
60
51
 
61
52
  # add session_id to the database
62
- db_item = m_session.Session_table(user_id=user.user_id, session_id=session_id)
53
+ db_item = m_session.Session(user_id=user.user_id, session_id=session_id)
63
54
  self.db.add(db_item)
64
55
  self.db.commit()
65
56
  self.db.refresh(db_item)
@@ -86,4 +77,7 @@ class DataflowHubAuthenticator(Authenticator):
86
77
  return user_dict
87
78
 
88
79
  except Exception as e:
89
- return None
80
+ return None
81
+
82
+ finally:
83
+ self.db.close()
@@ -7,6 +7,7 @@ from sqlalchemy.orm import sessionmaker
7
7
  class DatabaseManager:
8
8
  def __init__(self, db_url):
9
9
  self.db_url = db_url
10
+ self.engine = self.get_engine()
10
11
 
11
12
  def get_engine(self):
12
13
  try:
@@ -17,8 +18,8 @@ class DatabaseManager:
17
18
 
18
19
  def get_session(self):
19
20
  try:
20
- engine = self.get_engine()
21
- session = sessionmaker(autocommit=False, autoflush=False, bind=engine or create_engine(self.db_url))
21
+ engine = self.engine
22
+ session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
22
23
  db = session()
23
24
  try:
24
25
  yield db
@@ -29,4 +30,4 @@ class DatabaseManager:
29
30
  raise e
30
31
 
31
32
  def get_base(self):
32
- return declarative_base()
33
+ return declarative_base()
@@ -1,8 +1,8 @@
1
1
  import os, requests
2
- from .models.database import DatabaseManager
2
+ from .database_manager import DatabaseManager
3
3
  from .utils.aws_secrets_manager import SecretsManagerClient
4
4
  import json
5
- from authenticator.package.configuration import ConfigurationManager
5
+ from .configuration import ConfigurationManager
6
6
 
7
7
 
8
8
  class Dataflow:
@@ -10,7 +10,15 @@ class Dataflow:
10
10
  self.secrets_manager = SecretsManagerClient()
11
11
 
12
12
  def auth(self, session_id: str):
13
- """Retrieve user information from the auth API."""
13
+ """
14
+ Retrieve and return user information using their session ID.
15
+
16
+ Args:
17
+ session_id (str): User's session ID from cookies
18
+
19
+ Returns:
20
+ dict: User information including username, name, email, and role
21
+ """
14
22
  try:
15
23
  dataflow_config = ConfigurationManager('/dataflow/app/auth_config/dataflow_auth.cfg')
16
24
  auth_api = dataflow_config.get_config_value('auth', 'ui_auth_api')
@@ -28,7 +36,7 @@ class Dataflow:
28
36
  "first_name": user_data["first_name"],
29
37
  "last_name": user_data["last_name"] if user_data.get("last_name") else "",
30
38
  "email": user_data["email"],
31
- "role": user_data["role"]
39
+ "role": user_data["base_role"]
32
40
  }
33
41
  return user_dict
34
42
 
@@ -37,7 +45,13 @@ class Dataflow:
37
45
 
38
46
  def variable(self, variable_name: str):
39
47
  """
40
- Get variable value from UI API.
48
+ Retrieve a Dataflow variable.
49
+
50
+ Args:
51
+ variable_name (str): Name of the variable to retrieve
52
+
53
+ Returns:
54
+ str or None: Variable value if found, None otherwise
41
55
  """
42
56
  try:
43
57
  host_name = os.environ.get("HOSTNAME", "")
@@ -87,7 +101,15 @@ class Dataflow:
87
101
  return None
88
102
 
89
103
  def secret(self, secret_name: str):
90
- """Get secret value from secrets manager for Studio or Runtime."""
104
+ """
105
+ Retrieve a Dataflow secret value.
106
+
107
+ Args:
108
+ secret_name (str): Name of the secret to retrieve
109
+
110
+ Returns:
111
+ str or None: Secret value if found, None otherwise
112
+ """
91
113
  try:
92
114
  host_name = os.environ.get("HOSTNAME", "")
93
115
  user_name = host_name.replace("jupyter-", "") if host_name.startswith("jupyter-") else host_name
@@ -121,8 +143,17 @@ class Dataflow:
121
143
  print(f"[Dataflow.secret] Exception occurred: {e}")
122
144
  return None
123
145
 
124
- def connection(self, conn_id: str):
125
- """Get connection details from secrets manager."""
146
+ def connection(self, conn_id: str, mode="session"):
147
+ """
148
+ Connects with a Dataflow connection.
149
+
150
+ Args:
151
+ conn_id (str): Connection identifier
152
+ mode (str): Return type - "session" (default) or "engine" or "url"
153
+
154
+ Returns:
155
+ Session or Engine: SQLAlchemy session or engine based on mode
156
+ """
126
157
  try:
127
158
  host_name = os.environ["HOSTNAME"]
128
159
  user_name=host_name.replace("jupyter-","")
@@ -155,8 +186,14 @@ class Dataflow:
155
186
  # If 'extra' is not valid JSON, skip adding extra parameters
156
187
  pass
157
188
 
189
+ if mode == "url":
190
+ return connection_string
191
+
158
192
  connection_instance = DatabaseManager(connection_string)
159
- return next(connection_instance.get_session())
193
+ if mode == "engine":
194
+ return connection_instance.get_engine()
195
+ elif mode == "session":
196
+ return next(connection_instance.get_session())
160
197
 
161
198
  except Exception as e:
162
199
  return None
@@ -0,0 +1,51 @@
1
+ from .database_manager import DatabaseManager
2
+ from .configuration import ConfigurationManager
3
+ from sqlalchemy.orm import declarative_base
4
+ from sqlalchemy.exc import SQLAlchemyError
5
+ from .utils.logger import CustomLogger
6
+
7
+ logger = CustomLogger().get_logger(__name__)
8
+
9
+ dataflow_config = ConfigurationManager('/dataflow/app/config/dataflow.cfg')
10
+ db_url = dataflow_config.get_config_value('database', 'database_url')
11
+ local_db_url = dataflow_config.get_config_value('database', 'single_user_db_url')
12
+
13
+ db_manager = DatabaseManager(db_url)
14
+ local_db_manager = None
15
+
16
+ Base = declarative_base()
17
+ Local_Base = declarative_base()
18
+
19
+ def create_tables(local_db=False):
20
+ """
21
+ Create all tables in the database.
22
+ This is called at the start of the application.
23
+ """
24
+ try:
25
+ if local_db:
26
+ global local_db_manager
27
+ if local_db_manager is None:
28
+ local_db_manager = DatabaseManager(local_db_url)
29
+ Local_Base.metadata.create_all(bind=local_db_manager.get_engine())
30
+ else:
31
+ Base.metadata.create_all(bind=db_manager.get_engine())
32
+ logger.info("Database tables created successfully")
33
+ except SQLAlchemyError as e:
34
+ error_message = f"Failed to create tables: {str(e)}"
35
+ logger.error(error_message)
36
+ raise e
37
+
38
+ def get_local_db():
39
+ """
40
+ Get a local database session.
41
+
42
+ Yields:
43
+ Session: Local database session
44
+ """
45
+ global local_db_manager
46
+ if local_db_manager is None:
47
+ local_db_manager = DatabaseManager(local_db_url)
48
+ yield from local_db_manager.get_session()
49
+
50
+ def get_db():
51
+ yield from db_manager.get_session()
@@ -2,7 +2,7 @@ import os, shutil, subprocess, datetime
2
2
  from .models.environment import JobLogs, Environment
3
3
  import json, asyncio, pkg_resources
4
4
  from sqlalchemy.orm import Session
5
- from authenticator.package.configuration import ConfigurationManager
5
+ from .configuration import ConfigurationManager
6
6
 
7
7
  class EnvironmentManager:
8
8
  def __init__(self):
@@ -0,0 +1,22 @@
1
+ # init for loading models in the application
2
+
3
+ from .role import Role
4
+ from .user import User
5
+ from .team import Team
6
+ from .environment import Environment
7
+ from .project_details import ProjectDetails
8
+ from .recent_projects import RecentProjects
9
+ from .pinned_projects import PinnedProject
10
+ from .app_types import AppType
11
+ from .blacklist_library import BlacklistedLibrary
12
+ from .environment_status import EnvironmentStatus
13
+ from .session import Session
14
+ from .server_config import ServerConfig
15
+ from .runtime import RuntimeZone
16
+ from .environment_status import EnvironmentStatus
17
+ from .user_team import UserTeam
18
+ from .role_server import RoleServer
19
+ from .variables import Variable
20
+ from .recent_project_studio import RecentProjectStudio
21
+ from .connection import Connection
22
+ from .git_ssh import GitSSH
@@ -0,0 +1,10 @@
1
+ from sqlalchemy import Column, Integer, String, Boolean
2
+ from dataflow.db import Base
3
+
4
+ class AppType(Base):
5
+ __tablename__ = "RUNTIME_APP_TYPE"
6
+
7
+ id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
8
+ name = Column(String, unique=True, nullable=True)
9
+ display_name = Column(String, nullable=False)
10
+ code_based = Column(Boolean, nullable=False)
@@ -0,0 +1,26 @@
1
+ # models/blacklist_library.py
2
+ from sqlalchemy import Column, Integer, String, UniqueConstraint
3
+ from dataflow.db import Base
4
+
5
+ class BlacklistedLibrary(Base):
6
+ """
7
+ BlacklistedLibrary model represents a table for storing blacklisted libraries with their versions.
8
+
9
+ Attributes:
10
+ id (int): Primary key of the table, auto-incremented.
11
+ library_name (str): The name of the blacklisted library.
12
+ version (str): The version of the blacklisted library.
13
+
14
+ Unique constraint to ensure the combination of library_name and version is unique.
15
+ """
16
+
17
+ __tablename__ = "BLACKLISTED_LIBRARY"
18
+
19
+ id = Column(Integer, primary_key=True, index=True, doc="Primary key for the library.")
20
+ library_name = Column(String, index=True, doc="The name of the blacklisted library.")
21
+ version = Column(String, doc="The version of the blacklisted library.")
22
+
23
+ __table_args__ = (
24
+ UniqueConstraint('library_name', 'version', name='uq_library_version'),
25
+ )
26
+
@@ -0,0 +1,25 @@
1
+ from sqlalchemy import Column, String, Integer, Boolean, DateTime, UniqueConstraint
2
+ from sqlalchemy.sql import func
3
+ from dataflow.db import Base
4
+
5
+ class Connection(Base):
6
+ """
7
+ Database model for storing non-sensitive connection metadata
8
+ """
9
+ __tablename__ = "CONNECTION"
10
+
11
+ id = Column(Integer, primary_key=True, index=True)
12
+ conn_id = Column(String, index=True, nullable=False)
13
+ description = Column(String, nullable=True)
14
+ conn_type = Column(String, nullable=False)
15
+ runtime = Column(String, nullable=True)
16
+ slug = Column(String, nullable=True)
17
+ status = Column(Boolean, default=False)
18
+ created_by = Column(String, nullable=True)
19
+ created_at = Column(DateTime(timezone=True), server_default=func.now())
20
+ updated_at = Column(DateTime(timezone=True), onupdate=func.now())
21
+ is_active = Column(Boolean, default=True)
22
+
23
+ __table_args__ = (
24
+ UniqueConstraint('conn_id', 'runtime', 'slug', 'is_active', 'created_by', name='uq_active_conn_with_runtime_slug'),
25
+ )
@@ -1,9 +1,8 @@
1
1
  from sqlalchemy import Column, Integer, String, Boolean, Text, ForeignKey, DateTime
2
- from sqlalchemy.orm import relationship, declarative_base
2
+ from sqlalchemy.orm import relationship
3
3
  from sqlalchemy.sql import func
4
4
  from datetime import datetime
5
-
6
- Base = declarative_base()
5
+ from dataflow.db import Base
7
6
 
8
7
  class EnvironmentAttributes(Base):
9
8
  """
@@ -53,7 +52,7 @@ class ArchivedEnvironment(EnvironmentAttributes):
53
52
 
54
53
 
55
54
  class JobLogs(Base):
56
- __tablename__ = "JOB_LOGS"
55
+ __tablename__ = "JOB_LOG"
57
56
 
58
57
  id = Column(Integer, primary_key=True, index=True)
59
58
  created_at = Column(DateTime, default=datetime.now)
@@ -61,4 +60,5 @@ class JobLogs(Base):
61
60
  log_file_name = Column(String, unique=True, nullable=False)
62
61
  log_file_location = Column(String, nullable=False)
63
62
  status = Column(String)
64
- created_by = Column(String)
63
+ created_by = Column(String)
64
+
@@ -0,0 +1,17 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
3
+ from sqlalchemy.sql import func
4
+ from dataflow.db import Base
5
+
6
+ class EnvironmentStatus(Base):
7
+ """
8
+ Table ENVIRONMENT_STATUS
9
+ """
10
+
11
+ __tablename__='ENVIRONMENT_STATUS'
12
+
13
+ id = Column(Integer, ForeignKey('ENVIRONMENT.id'), primary_key=True, nullable=False)
14
+ status = Column(String, nullable=False)
15
+ comment = Column(String)
16
+ status_changed_date = Column(DateTime, server_default=func.now(), nullable=False)
17
+
@@ -0,0 +1,18 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, UniqueConstraint
3
+ from sqlalchemy.sql import func
4
+ from dataflow.db import Base
5
+
6
+ class GitSSH(Base):
7
+ __tablename__ = 'GIT_SSH'
8
+
9
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True)
10
+ user_name = Column(String, ForeignKey('USER.user_name', ondelete="CASCADE"), nullable=False)
11
+ description = Column(String)
12
+ key_name = Column(String, nullable=False)
13
+ created_date = Column(DateTime, server_default=func.now(), nullable=False)
14
+ last_used_date = Column(DateTime)
15
+
16
+ __table_args__ = (
17
+ UniqueConstraint(user_name, key_name, name='user_name_key_name_unique'),
18
+ )
@@ -0,0 +1,15 @@
1
+ from sqlalchemy import Column, Integer, ForeignKey, DateTime, UniqueConstraint
2
+ from dataflow.db import Base
3
+ from datetime import datetime
4
+
5
+ class PinnedProject(Base):
6
+ __tablename__ = "PINNED_PROJECT"
7
+
8
+ id = Column(Integer, primary_key=True)
9
+ user_id = Column(Integer, ForeignKey('USER.user_id'), index=True)
10
+ project_id = Column(Integer, ForeignKey('PROJECT_DETAIL.project_id'), index=True)
11
+ pinned_at = Column(DateTime, default=datetime.utcnow)
12
+
13
+ __table_args__ = (
14
+ UniqueConstraint("user_id", "project_id", name="uix_user_project"),
15
+ )
@@ -0,0 +1,23 @@
1
+ from sqlalchemy import Column, String, Enum, DateTime, Integer, func, ForeignKey
2
+ from sqlalchemy.orm import relationship
3
+ from dataflow.db import Base
4
+
5
+ class ProjectDetails(Base):
6
+ __tablename__ = "PROJECT_DETAIL"
7
+
8
+ project_id = Column(Integer, primary_key=True, autoincrement=True)
9
+ project_name = Column(String, nullable=False)
10
+ git_url = Column(String)
11
+ git_branch = Column(String, nullable=True)
12
+ git_folder = Column(String, nullable=True)
13
+ type = Column(String, ForeignKey('RUNTIME_APP_TYPE.name'), nullable=False)
14
+ slug = Column(String, nullable=False, unique=True)
15
+ runtime = Column(String, nullable=False)
16
+ py_env = Column(String, nullable=True)
17
+ launch_url = Column(String, nullable=True)
18
+ status = Column(Enum("pending", "created" ,"deployed", "stopped", "failed", name="deployment_status"), default="created")
19
+ last_deployed = Column(DateTime, nullable=True)
20
+ created_at = Column(DateTime, nullable=False, server_default=func.now())
21
+ created_by = Column(String, nullable=False)
22
+
23
+ app_type = relationship("AppType")
@@ -0,0 +1,19 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, DateTime, UniqueConstraint, Boolean
3
+ from sqlalchemy.sql import func
4
+ from dataflow.db import Local_Base as Base
5
+
6
+ class RecentProjectStudio(Base):
7
+ __tablename__ = 'RECENT_PROJECT_STUDIO'
8
+
9
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True)
10
+ user_name = Column(String, nullable=False, index=True)
11
+ app_name = Column(String, nullable=False, index=True)
12
+ project_name = Column(String, nullable=False)
13
+ project_path = Column(String, nullable=False)
14
+ last_opened_date = Column(DateTime, server_default=func.now(), nullable=False)
15
+ remember = Column(Boolean, default=False)
16
+
17
+ __table_args__ = (
18
+ UniqueConstraint(user_name, project_path, app_name, name='user_name_project_path_app_name_unique'),
19
+ )
@@ -0,0 +1,9 @@
1
+ from sqlalchemy import Column, Integer, ForeignKey
2
+ from dataflow.db import Base
3
+
4
+ class RecentProjects(Base):
5
+ __tablename__ = "RECENT_PROJECT"
6
+
7
+ id = Column(Integer, primary_key=True, autoincrement=True)
8
+ project_id = Column(Integer, ForeignKey('PROJECT_DETAIL.project_id'), nullable=False)
9
+
@@ -0,0 +1,19 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, Enum
3
+ from sqlalchemy.orm import relationship
4
+ from dataflow.db import Base
5
+
6
+ class Role(Base):
7
+ """
8
+ Table Role
9
+ """
10
+
11
+ __tablename__='ROLE'
12
+
13
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)
14
+ name = Column(String, unique=True, nullable=False)
15
+ description = Column(String, nullable=True)
16
+ base_role = Column(Enum('admin', 'user', name='base_role_field'), default='user', nullable=False)
17
+
18
+ users = relationship("User", back_populates="role_details", cascade="all, delete-orphan")
19
+ role_server_assocs = relationship("RoleServer", back_populates="role")
@@ -0,0 +1,14 @@
1
+ # models/user_team.py
2
+ from sqlalchemy import Column, Integer, ForeignKey, UniqueConstraint
3
+ from sqlalchemy.orm import relationship
4
+ from dataflow.db import Base
5
+
6
+ class RoleServer(Base):
7
+ __tablename__ = 'ROLE_SERVER'
8
+ __table_args__ = (UniqueConstraint('role_id', 'server_id', name='_role_server_uc'),)
9
+
10
+ role_id = Column(Integer, ForeignKey('ROLE.id', ondelete="CASCADE"), nullable=False, primary_key=True)
11
+ server_id = Column(Integer, ForeignKey('CUSTOM_SERVER.id', ondelete="CASCADE"), nullable=False, primary_key=True)
12
+
13
+ role = relationship("Role", back_populates="role_server_assocs")
14
+ server = relationship("CustomServerConfig", back_populates="role_server_assocs")
@@ -0,0 +1,11 @@
1
+ from sqlalchemy import Column, Integer, String, Boolean
2
+ from dataflow.db import Base
3
+
4
+ class RuntimeZone(Base):
5
+ __tablename__ = "RUNTIME_ZONE"
6
+
7
+ id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
8
+ name = Column(String, unique=True, nullable=False)
9
+ display_name = Column(String, nullable=False)
10
+ display_order = Column(Integer)
11
+ spark_enabled = Column(Boolean, default=False)
@@ -0,0 +1,33 @@
1
+ from sqlalchemy import Column, Integer, String, Boolean, Text, ForeignKey
2
+ from sqlalchemy.dialects.postgresql import JSONB
3
+ from sqlalchemy.sql import func
4
+ from sqlalchemy.orm import relationship
5
+ from dataflow.db import Base
6
+
7
+ class ServerConfig(Base):
8
+ __tablename__ = "SERVER_CONFIG"
9
+
10
+ id = Column(Integer, primary_key=True, autoincrement=True)
11
+ display_name = Column(String, nullable=False, unique=True)
12
+ slug = Column(String, unique=True, nullable=False)
13
+ price = Column(String, nullable=False)
14
+ ram = Column(String, nullable=False)
15
+ cpu = Column(String, nullable=False)
16
+ gpu = Column(String)
17
+ default = Column(Boolean, default=False)
18
+ tags = Column(JSONB, default=func.json([]))
19
+ description = Column(Text, nullable=True)
20
+ kubespawner_override = Column(JSONB, default=func.json({}))
21
+
22
+
23
+ class CustomServerConfig(Base):
24
+ __tablename__ = "CUSTOM_SERVER"
25
+
26
+ id = Column(Integer, primary_key=True, autoincrement=True)
27
+ base_server_id = Column(Integer, ForeignKey(ServerConfig.id), nullable=False)
28
+ display_name = Column(String, nullable=False, unique=True, index=True)
29
+ description = Column(Text, nullable=True)
30
+
31
+ # Relationship to the server_config table
32
+ server_config = relationship(ServerConfig)
33
+ role_server_assocs = relationship("RoleServer", back_populates="server", cascade="all, delete-orphan")
@@ -0,0 +1,17 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, ForeignKey
3
+ from dataflow.db import Base
4
+
5
+ class Session(Base):
6
+ """
7
+ Table SESSION
8
+ """
9
+
10
+ __tablename__='SESSION'
11
+
12
+ id = Column(Integer, primary_key=True, index=True, unique=True, nullable=False, autoincrement=True)
13
+ session_id = Column(String, unique=True, nullable=False)
14
+ user_id = Column(Integer, ForeignKey('USER.user_id', ondelete="CASCADE"), nullable=False)
15
+
16
+
17
+
@@ -0,0 +1,17 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String
3
+ from sqlalchemy.orm import relationship
4
+ from dataflow.db import Base
5
+
6
+ class Team(Base):
7
+ """
8
+ Table TEAM
9
+ """
10
+
11
+ __tablename__='TEAM'
12
+
13
+ team_id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)
14
+ team_name = Column(String, unique=True, nullable=False)
15
+ description = Column(String, nullable=True)
16
+
17
+ user_team_assocs = relationship("UserTeam", back_populates="team")
@@ -0,0 +1,29 @@
1
+ """models.py"""
2
+ from sqlalchemy import Column, Integer, String, Boolean, LargeBinary, Enum, ForeignKey
3
+ from sqlalchemy.orm import relationship
4
+ from dataflow.db import Base
5
+
6
+ class User(Base):
7
+ """
8
+ Table USER
9
+ """
10
+
11
+ __tablename__='USER'
12
+
13
+ user_id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)
14
+ user_name = Column(String, unique=True, nullable=False)
15
+ first_name = Column(String)
16
+ last_name = Column(String)
17
+ email = Column(String, unique=True)
18
+ role_id = Column(Integer, ForeignKey('ROLE.id'), nullable=False)
19
+ image = Column(LargeBinary)
20
+ image_url = Column(String, nullable=True)
21
+ active = Column(Enum('N', 'Y', name='active_field'), nullable=False, server_default=str("N"))
22
+ password = Column(String, nullable=False)
23
+ active_env = Column(String, ForeignKey('ENVIRONMENT.short_name'))
24
+ current_server = Column(String)
25
+ show_server_page = Column(Boolean, default = True)
26
+
27
+ role_details = relationship("Role")
28
+
29
+ user_team_assocs = relationship("UserTeam", back_populates="user")
@@ -0,0 +1,16 @@
1
+ from sqlalchemy import Column, Integer, String, DateTime
2
+ from sqlalchemy.sql.schema import ForeignKey
3
+ from sqlalchemy.sql.expression import func
4
+ from dataflow.db import Base
5
+
6
+ class UserEnvironment(Base):
7
+ """
8
+ Table USER_ENVIRONMENT
9
+ """
10
+
11
+ __tablename__ = 'USER_ENVIRONMENT'
12
+
13
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True)
14
+ user_id = Column(Integer, ForeignKey('USER.user_id', ondelete="CASCADE"), nullable=False)
15
+ env_name = Column(String)
16
+ timestamp = Column(DateTime, server_default=func.now(), onupdate=func.now())
@@ -0,0 +1,14 @@
1
+ # models/user_team.py
2
+ from sqlalchemy import Column, Integer, ForeignKey, UniqueConstraint
3
+ from sqlalchemy.orm import relationship
4
+ from dataflow.db import Base
5
+
6
+ class UserTeam(Base):
7
+ __tablename__ = 'USER_TEAM'
8
+ __table_args__ = (UniqueConstraint('user_id', 'team_id', name='_user_team_uc'),)
9
+
10
+ user_id = Column(Integer, ForeignKey('USER.user_id', ondelete="CASCADE"), nullable=False, primary_key=True)
11
+ team_id = Column(Integer, ForeignKey('TEAM.team_id', ondelete="CASCADE"), nullable=False, primary_key=True)
12
+
13
+ user = relationship("User", back_populates="user_team_assocs")
14
+ team = relationship("Team", back_populates="user_team_assocs")
@@ -0,0 +1,27 @@
1
+ from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, func, UniqueConstraint, CheckConstraint, Boolean
2
+ from dataflow.db import Base
3
+
4
+ class Variable(Base):
5
+ """
6
+ Unified VARIABLE table to support both Studio and Runtime environments.
7
+ """
8
+
9
+ __tablename__ = 'VARIABLE'
10
+
11
+ id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)
12
+ key = Column(String, nullable=False)
13
+ value = Column(Text, nullable=False)
14
+ type = Column(String, nullable=False)
15
+ description = Column(Text, nullable=True)
16
+ runtime = Column(String, nullable=True)
17
+ slug = Column(String, nullable=True)
18
+ created_at = Column(DateTime, server_default=func.now())
19
+ updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
20
+ created_by = Column(String, ForeignKey('USER.user_name'), nullable=True)
21
+ is_active = Column(Boolean, default=True, nullable=False)
22
+
23
+
24
+ __table_args__ = (
25
+ CheckConstraint(type.in_(['variable', 'secret']), name='check_variable_type'),
26
+ UniqueConstraint('key', 'runtime', 'slug', 'created_by', name='unique_key'),
27
+ )
@@ -0,0 +1,35 @@
1
+ from fastapi import HTTPException, status
2
+ from sqlalchemy.orm import Session
3
+ from dataflow.models import user as m_user
4
+ from dataflow.models import session as m_session
5
+
6
+ def get_user_from_session(session_id: str, db: Session):
7
+ """
8
+ Retrieve a user based on session ID.
9
+
10
+ Args:
11
+ session_id (str): The unique session identifier
12
+ db (Session): Database session
13
+
14
+ Returns:
15
+ User: User object if found
16
+
17
+ Raises:
18
+ HTTPException: If session is invalid or user not found
19
+ """
20
+ session_record = db.query(m_session.Session).filter(m_session.Session.session_id == session_id).first()
21
+ if not session_record:
22
+ raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid session")
23
+
24
+ user = db.query(m_user.User).filter(m_user.User.user_id == session_record.user_id).first()
25
+ if not user:
26
+ raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="User not found")
27
+
28
+ base_role = user.role_details.base_role
29
+ role_name = user.role_details.name
30
+ user.base_role = base_role
31
+ user.role = role_name
32
+
33
+ return user
34
+
35
+
@@ -0,0 +1,41 @@
1
+ import logging
2
+ import sys
3
+
4
+ class CustomLogger:
5
+ """
6
+ Custom logger class for configuring and using console-based logging functionality.
7
+ """
8
+ def __init__(self):
9
+ self._configure_handler()
10
+
11
+ def _configure_handler(self):
12
+ """
13
+ Configure the console handler once.
14
+ """
15
+ self.formatter = logging.Formatter(
16
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
17
+ )
18
+
19
+ self.console_handler = logging.StreamHandler(sys.stdout)
20
+ self.console_handler.setLevel(logging.INFO)
21
+ self.console_handler.setFormatter(self.formatter)
22
+
23
+ def get_logger(self, name=None):
24
+ """
25
+ Retrieve a configured logger instance with a dynamic name.
26
+
27
+ Args:
28
+ name (str): The name of the logger. Defaults to 'dataflow_logger'.
29
+
30
+ Returns:
31
+ logging.Logger: Configured logger instance.
32
+ """
33
+ logger_name = name or "dataflow_logger"
34
+ logger = logging.getLogger(logger_name)
35
+ logger.setLevel(logging.INFO)
36
+
37
+ # Prevent duplicate handlers if logger already configured
38
+ if not logger.handlers:
39
+ logger.addHandler(self.console_handler)
40
+
41
+ return logger
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataflow-core
3
- Version: 2.0.11
3
+ Version: 2.1.0
4
4
  Summary: Dataflow core package
5
5
  Author: Dataflow
6
6
  Author-email:
@@ -0,0 +1,46 @@
1
+ README.md
2
+ setup.py
3
+ authenticator/__init__.py
4
+ authenticator/dataflowairflowauthenticator.py
5
+ authenticator/dataflowhubauthenticator.py
6
+ authenticator/dataflowsupersetauthenticator.py
7
+ dataflow/__init__.py
8
+ dataflow/configuration.py
9
+ dataflow/database_manager.py
10
+ dataflow/dataflow.py
11
+ dataflow/db.py
12
+ dataflow/environment.py
13
+ dataflow/models/__init__.py
14
+ dataflow/models/app_types.py
15
+ dataflow/models/blacklist_library.py
16
+ dataflow/models/connection.py
17
+ dataflow/models/environment.py
18
+ dataflow/models/environment_status.py
19
+ dataflow/models/git_ssh.py
20
+ dataflow/models/pinned_projects.py
21
+ dataflow/models/project_details.py
22
+ dataflow/models/recent_project_studio.py
23
+ dataflow/models/recent_projects.py
24
+ dataflow/models/role.py
25
+ dataflow/models/role_server.py
26
+ dataflow/models/runtime.py
27
+ dataflow/models/server_config.py
28
+ dataflow/models/session.py
29
+ dataflow/models/team.py
30
+ dataflow/models/user.py
31
+ dataflow/models/user_environment.py
32
+ dataflow/models/user_team.py
33
+ dataflow/models/variables.py
34
+ dataflow/scripts/clone_environment.sh
35
+ dataflow/scripts/create_environment.sh
36
+ dataflow/utils/__init__.py
37
+ dataflow/utils/aws_secrets_manager.py
38
+ dataflow/utils/get_current_user.py
39
+ dataflow/utils/json_handler.py
40
+ dataflow/utils/logger.py
41
+ dataflow_core.egg-info/PKG-INFO
42
+ dataflow_core.egg-info/SOURCES.txt
43
+ dataflow_core.egg-info/dependency_links.txt
44
+ dataflow_core.egg-info/entry_points.txt
45
+ dataflow_core.egg-info/requires.txt
46
+ dataflow_core.egg-info/top_level.txt
@@ -14,7 +14,7 @@ class PostInstall(install):
14
14
 
15
15
  setup(
16
16
  name="dataflow-core",
17
- version="2.0.11",
17
+ version="2.1.0",
18
18
  packages=find_packages(include=["dataflow", "dataflow.*", "authenticator", "authenticator.*"]),
19
19
  include_package_data=True,
20
20
  package_data={
@@ -1,83 +0,0 @@
1
- from .package.models.database import DatabaseManager
2
- from dataflow.dataflow import Dataflow
3
-
4
- from typing import Any, Callable
5
- from airflow.www.security import FabAirflowSecurityManagerOverride
6
- from airflow.configuration import conf
7
-
8
- class DataflowAirflowAuthenticator(FabAirflowSecurityManagerOverride):
9
- def __init__(self, wsgi_app: Callable) -> None:
10
- self.wsgi_app = wsgi_app
11
- self.dataflow = Dataflow()
12
- self.airflow_database_url = conf.get("database", "sql_alchemy_conn")
13
-
14
- self.airflow_db_instance = DatabaseManager(self.airflow_database_url)
15
- self.airflow_db = next(self.airflow_db_instance.get_session())
16
-
17
- def __call__(self, environ: dict, start_response: Callable) -> Any:
18
-
19
- path = environ.get('PATH_INFO', '')
20
- if not path == '/login/':
21
- return self.wsgi_app(environ, start_response)
22
-
23
- try:
24
- # Extracting browser cookies
25
- cookies = environ.get('HTTP_COOKIE', '')
26
- user_session_id = None
27
- parts = cookies.split('; ')
28
- for part in parts:
29
- if part.startswith('dataflow_session='):
30
- user_session_id = part
31
- break
32
-
33
- if user_session_id is None:
34
- raise Exception("No session id found")
35
-
36
- user_session_id = user_session_id.split('=')[1]
37
-
38
- # Retrieving user details
39
- user_data = self.dataflow.auth(user_session_id)
40
-
41
- if user_data is None:
42
- raise Exception("No user found for the dataflow_session id")
43
-
44
- user = self.find_user(user_data["user_name"])
45
-
46
- if not 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
- )
55
-
56
- environ['REMOTE_USER'] = user.username
57
- return self.wsgi_app(environ, start_response)
58
-
59
- except Exception as e:
60
- return self.wsgi_app(environ, start_response)
61
-
62
- def find_user(self, username=None):
63
- """Find user by username or email."""
64
- return self.airflow_db.query(self.user_model).filter_by(username=username).one_or_none()
65
-
66
- def find_role(self, role):
67
- """Find a role in the database."""
68
- return self.airflow_db.query(self.role_model).filter_by(name=role).one_or_none()
69
-
70
- def add_user(self, username, first_name, last_name, email, role, password=""):
71
- """Create a user."""
72
- user = self.user_model()
73
- user.first_name = first_name
74
- user.last_name = last_name
75
- user.username = username
76
- user.email = email
77
- user.active = True
78
- user.roles = role if isinstance(role, list) else [role]
79
- user.password = password
80
- self.airflow_db.add(user)
81
- self.airflow_db.commit()
82
- return user
83
-
@@ -1,32 +0,0 @@
1
- """models/database.py"""
2
- from sqlalchemy.exc import SQLAlchemyError
3
- from sqlalchemy.ext.declarative import declarative_base
4
- from sqlalchemy import create_engine
5
- from sqlalchemy.orm import sessionmaker
6
-
7
- class DatabaseManager:
8
- def __init__(self, db_url):
9
- self.db_url = db_url
10
-
11
- def get_engine(self):
12
- try:
13
- engine = create_engine(self.db_url)
14
- return engine
15
- except SQLAlchemyError as e:
16
- raise e
17
-
18
- def get_session(self):
19
- try:
20
- engine = self.get_engine()
21
- session = sessionmaker(autocommit=False, autoflush=False, bind=engine or create_engine(self.db_url))
22
- db = session()
23
- try:
24
- yield db
25
- finally:
26
- db.close()
27
-
28
- except SQLAlchemyError as e:
29
- raise e
30
-
31
- def get_base(self):
32
- return declarative_base()
@@ -1,20 +0,0 @@
1
- """models.py"""
2
- from sqlalchemy import Column, Integer, String
3
- from sqlalchemy.ext.declarative import declarative_base
4
-
5
- #instance for create declarative base
6
- Base=declarative_base()
7
-
8
- class Session_table(Base):
9
- """
10
- Table SESSIONS
11
- """
12
-
13
- __tablename__='SESSION'
14
-
15
- id = Column(Integer, primary_key=True, index=True, unique=True, nullable=False, autoincrement=True)
16
- session_id = Column(String, unique=True, nullable=False)
17
- user_id = Column(String, nullable=False)
18
-
19
-
20
-
@@ -1,22 +0,0 @@
1
- """models.py"""
2
- from sqlalchemy import Column, Integer, String, LargeBinary, Enum, Boolean
3
- from sqlalchemy.ext.declarative import declarative_base
4
-
5
- #instance for create declarative base
6
- Base=declarative_base()
7
-
8
- class User(Base):
9
- """
10
- Table USER
11
- """
12
-
13
- __tablename__='USER'
14
-
15
- user_id = Column(Integer, primary_key=True, index=True, autoincrement=True, nullable=False)
16
- user_name = Column(String, unique=True, nullable=False)
17
- first_name = Column(String)
18
- last_name = Column(String)
19
- email = Column(String, unique=True)
20
- image = Column(LargeBinary)
21
- active = Column(Enum('N', 'Y', name='active_field'), nullable=False, server_default=str("N"))
22
- password = Column(String, nullable=False)
@@ -1,27 +0,0 @@
1
- """configuration.py"""
2
- import configparser
3
- from configparser import NoOptionError, NoSectionError
4
-
5
- class ConfigurationManager:
6
- """
7
- Configuration Manager
8
- """
9
-
10
- def __init__(self, config_file):
11
-
12
- self.config_file = config_file
13
- self.config = configparser.ConfigParser()
14
- try:
15
- self.config.read(self.config_file)
16
-
17
- except Exception as e:
18
- return None
19
-
20
- def get_config_value(self, section, option):
21
- """
22
- Get configuration value
23
- """
24
- try:
25
- return self.config.get(section, option)
26
- except (NoOptionError, NoSectionError):
27
- return None
File without changes
File without changes
@@ -1,30 +0,0 @@
1
- README.md
2
- setup.py
3
- authenticator/__init__.py
4
- authenticator/dataflowairflowauthenticator.py
5
- authenticator/dataflowhubauthenticator.py
6
- authenticator/dataflowsupersetauthenticator.py
7
- authenticator/package/__init__.py
8
- authenticator/package/configuration.py
9
- authenticator/package/models/__init__.py
10
- authenticator/package/models/database.py
11
- authenticator/package/models/session.py
12
- authenticator/package/models/user.py
13
- dataflow/__init__.py
14
- dataflow/configuration.py
15
- dataflow/dataflow.py
16
- dataflow/environment.py
17
- dataflow/models/__init__.py
18
- dataflow/models/database.py
19
- dataflow/models/environment.py
20
- dataflow/scripts/clone_environment.sh
21
- dataflow/scripts/create_environment.sh
22
- dataflow/utils/__init__.py
23
- dataflow/utils/aws_secrets_manager.py
24
- dataflow/utils/json_handler.py
25
- dataflow_core.egg-info/PKG-INFO
26
- dataflow_core.egg-info/SOURCES.txt
27
- dataflow_core.egg-info/dependency_links.txt
28
- dataflow_core.egg-info/entry_points.txt
29
- dataflow_core.egg-info/requires.txt
30
- dataflow_core.egg-info/top_level.txt
File without changes
File without changes