Skip to content

Commit 0feeb7e

Browse files
committed
Configuration File Initialization
✨ Configuration now handled thru config file - not environment variables Working on debugging setup overwrite still. Also realized that not all users will be able to set up environment variables. Switched over to a configuration file instead.
1 parent 20e82d3 commit 0feeb7e

File tree

8 files changed

+112
-46
lines changed

8 files changed

+112
-46
lines changed

process_tracker/cli.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
# A set of tools to set up ProcessTracker and maintain lookup topics
33

44
import click
5-
import os
65
import logging
76

87
from process_tracker.data_store import DataStore
9-
from process_tracker.logging import console
8+
from process_tracker.utilities.logging import console
109

1110
data_store = DataStore()
1211
logger = logging.getLogger('Process Tracker')
@@ -22,16 +21,16 @@ def main():
2221

2322

2423
@main.command()
25-
# @click.option('-o', '--overwrite', default=False, help='Wipe out the current data store and rebuild'
26-
# ', starting from fresh.')
27-
def setup():
24+
@click.option('-o', '--overwrite', default=False, help='Wipe out the current data store and rebuild'
25+
', starting from fresh.')
26+
def setup(overwrite):
2827
"""
2928
Initialize ProcessTracker's data store with user provided input. If already in place, do nothing unless overwrite
3029
set to True.
3130
:return:
3231
"""
3332
click.echo('Attempting to initialize data store...')
34-
data_store.initialize_data_store()
33+
data_store.initialize_data_store(overwrite=overwrite)
3534

3635

3736
# @main.command()

process_tracker/data_store.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from sqlalchemy.orm import sessionmaker
88
from sqlalchemy_utils import database_exists
99

10-
from process_tracker.logging import console
10+
from process_tracker.utilities.logging import console
11+
from process_tracker.utilities.settings import SettingsManager
1112

1213
from process_tracker.models.actor import Actor
1314
from process_tracker.models.extract import ExtractStatus
@@ -25,12 +26,16 @@
2526

2627
class DataStore:
2728

28-
def __init__(self):
29+
def __init__(self, config_location=None):
2930
"""
3031
Need to initialize the data store connection when starting to access the data store.
32+
:param config_location: Location where Process Tracker configuration file is.
33+
:type config_location: file path
3134
"""
3235
self.logger = logging.getLogger(__name__)
3336

37+
self.config_location=config_location
38+
3439
data_store = self.verify_and_connect_to_data_store()
3540
self.engine = data_store['engine']
3641
self.session = data_store['session']
@@ -83,8 +88,7 @@ def initialize_data_store(self, overwrite=False):
8388
if overwrite:
8489
self.logger.warn('ALERT - DATA STORE TO BE OVERWRITTEN - ALL DATA WILL BE LOST')
8590
self.meta.reflect()
86-
self.meta.drop_all(bind=self.engine)
87-
self.session.commit()
91+
self.meta.drop_all()
8892

8993
version = None
9094
else:
@@ -103,30 +107,27 @@ def initialize_data_store(self, overwrite=False):
103107
for error_type in preload_error_types:
104108
self.logger.info('Adding %s' % error_type)
105109
self.session.add(ErrorType(error_type_name=error_type))
106-
self.session.commit()
107110

108111
self.logger.info('Adding extract status types...')
109112
for extract_status_type in preload_extract_status_types:
110113
self.logger.info('Adding %s' % extract_status_type)
111114
self.session.add(ExtractStatus(extract_status_name=extract_status_type))
112-
self.session.commit()
113115

114116
self.logger.info('Adding process status types...')
115117
for process_status_type in preload_process_status_types:
116118
self.logger.info('Adding %s' % process_status_type)
117119
self.session.add(ProcessStatus(process_status_name=process_status_type))
118-
self.session.commit()
119120

120121
self.logger.info('Adding process types...')
121122
for process_type in preload_process_types:
122123
self.logger.info('Adding %s' % process_type)
123124
self.session.add(ProcessType(process_type_name=process_type))
124-
self.session.commit()
125125

126126
self.logger.info('Adding system keys...')
127127
for system_key, value in preload_system_keys:
128128
self.logger.info('Adding %s' % system_key)
129129
self.session.add(System(system_key=system_key, system_value=value))
130+
130131
self.session.commit()
131132
else:
132133
self.logger.error('It appears the system has already been setup.')
@@ -322,31 +323,33 @@ def verify_and_connect_to_data_store(self):
322323
:return:
323324
"""
324325

325-
data_store_type = os.environ.get('process_tracking_data_store_type')
326-
data_store_username = os.environ.get('process_tracking_data_store_username')
327-
data_store_password = os.environ.get('process_tracking_data_store_password')
328-
data_store_host = os.environ.get('process_tracking_data_store_host')
329-
data_store_port = os.environ.get('process_tracking_data_store_port')
330-
data_store_name = os.environ.get('process_tracking_data_store_name')
326+
config = SettingsManager(config_location=self.config_location).config
327+
328+
data_store_type = config['DEFAULT']['data_store_type']
329+
data_store_username = config['DEFAULT']['data_store_username']
330+
data_store_password = config['DEFAULT']['data_store_password']
331+
data_store_host = config['DEFAULT']['data_store_host']
332+
data_store_port = config['DEFAULT']['data_store_port']
333+
data_store_name = config['DEFAULT']['data_store_name']
331334

332335
errors = []
333336

334-
if data_store_type is None:
337+
if data_store_type is None or data_store_type == 'None':
335338
errors.append(Exception('Data store type is not set.'))
336339

337-
if data_store_username is None:
340+
if data_store_username is None or data_store_username == 'None':
338341
errors.append(Exception('Data store username is not set.'))
339342

340-
if data_store_password is None:
343+
if data_store_password is None or data_store_password == 'None':
341344
errors.append(Exception('Data store password is not set'))
342345

343-
if data_store_host is None:
346+
if data_store_host is None or data_store_host == 'None':
344347
errors.append(Exception('Data store host is not set'))
345348

346-
if data_store_port is None:
349+
if data_store_port is None or data_store_port == 'None':
347350
errors.append(Exception('Data store port is not set'))
348351

349-
if data_store_name is None:
352+
if data_store_name is None or data_store_name == 'None':
350353
errors.append(Exception('Data store name is not set'))
351354

352355
if errors:
@@ -374,9 +377,9 @@ def verify_and_connect_to_data_store(self):
374377
if database_exists(engine.url):
375378
self.logger.info("Data store exists. Continuing to work.")
376379

377-
Session = sessionmaker(bind=engine)
380+
session = sessionmaker(bind=engine)
378381

379-
session = Session(expire_on_commit=False)
382+
session = session(expire_on_commit=False)
380383
session.execute("SET search_path TO %s" % data_store_name)
381384

382385
meta = MetaData(engine)

process_tracker/location_tracker.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
# Location
22
# For processes dealing with Extract Locations.
33
import logging
4-
import os
54
from os.path import basename, normpath
65

76
from process_tracker.data_store import DataStore
8-
from process_tracker.logging import console
7+
from process_tracker.utilities.logging import console
98

109
from process_tracker.models.extract import Location, LocationType
1110

process_tracker/process_tracker.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
import os
77
from os.path import join
88

9-
import boto3
109
from sqlalchemy.orm import aliased
1110

1211
from process_tracker.data_store import DataStore
1312
from process_tracker.extract_tracker import ExtractTracker
1413
from process_tracker.location_tracker import LocationTracker
15-
from process_tracker.logging import console
14+
from process_tracker.utilities.logging import console
1615

1716
from process_tracker.models.actor import Actor
1817
from process_tracker.models.extract import Extract, ExtractProcess, ExtractStatus, Location
@@ -23,20 +22,24 @@
2322

2423
class ProcessTracker:
2524

26-
def __init__(self, process_name, process_type, actor_name, tool_name, sources, targets):
25+
def __init__(self, process_name, process_type, actor_name, tool_name, sources, targets, config_location=None):
2726
"""
2827
ProcessTracker is the primary engine for tracking data integration processes.
2928
:param process_name: Name of the process being tracked.
3029
:param actor_name: Name of the person or environment runnning the process.
3130
:param tool_name: Name of the tool used to run the process.
3231
:param sources: A single source name or list of source names for the given process.
3332
:type sources: list
33+
:param targets: A single target name or list of target names for the given process.
34+
:type targets: list
35+
:param config_location: Location where Process Tracker configuration file is.
36+
:type config_location: file path
3437
"""
3538

3639
self.logger = logging.getLogger(__name__)
3740
self.logger.addHandler(console)
3841

39-
self.data_store = DataStore()
42+
self.data_store = DataStore(config_location=config_location)
4043
self.session = self.data_store.session
4144

4245
self.actor = self.data_store.get_or_create_item(model=Actor, actor_name=actor_name)

process_tracker/utilities/__init__.py

Whitespace-only changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Settings manager and configuration, both for initialization and reading.
2+
3+
import configparser
4+
import os
5+
from pathlib import Path
6+
7+
8+
class SettingsManager:
9+
10+
def __init__(self, config_location=None):
11+
"""
12+
Determine if config file exists, and if not create a basic file under the application directory.
13+
:param config_location: Location where configuration file can be found.
14+
:type config_location: str
15+
"""
16+
17+
self.config = configparser.ConfigParser(allow_no_value=True)
18+
19+
if config_location is None:
20+
home = str(Path.home())
21+
self.config_path = os.path.join(home, '.process_tracker/')
22+
self.config_file = os.path.join(self.config_path, 'process_tracker_config.ini')
23+
24+
else:
25+
self.config_path = os.path.join(config_location, 'process_tracker_config.ini')
26+
27+
exists = os.path.isfile(self.config_file)
28+
29+
if exists:
30+
self.read_config_file()
31+
else:
32+
self.create_config_file()
33+
34+
def create_config_file(self):
35+
"""
36+
When config file does not exist, setup a stock config file.
37+
:return:
38+
"""
39+
40+
self.config['DEFAULT'] = {
41+
'log_level': 'ERROR'
42+
}
43+
44+
self.config['DEFAULT']['data_store_type'] = 'None'
45+
self.config['DEFAULT']['data_store_username'] = 'None'
46+
self.config['DEFAULT']['data_store_password'] = 'None'
47+
self.config['DEFAULT']['data_store_host'] = 'None'
48+
self.config['DEFAULT']['data_store_port'] = 'None'
49+
self.config['DEFAULT']['data_store_name'] = 'None'
50+
51+
if not os.path.exists(self.config_path):
52+
os.makedirs(self.config_path)
53+
54+
with open(self.config_file, 'w') as configfile:
55+
self.config.write(configfile)
56+
57+
def read_config_file(self):
58+
"""
59+
Read and parse the config file for use.
60+
:return:
61+
"""
62+
63+
return self.config.read(self.config_file)

tests/test_cli.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import logging
2-
import os
32
import unittest
43

54
from click.testing import CliRunner
65

76
from process_tracker.cli import main
87
from process_tracker.data_store import DataStore
9-
from process_tracker.logging import console
8+
from process_tracker.utilities.logging import console
109

1110
from process_tracker.models.actor import Actor
1211
from process_tracker.models.extract import ExtractStatus
@@ -27,16 +26,16 @@ def setUp(self):
2726
self.session = self.data_store.session
2827
self.runner = CliRunner()
2928

30-
# def test_setup_overwrite(self):
31-
# """
32-
# Testing that if data store is already set up and overwrite is set to True, wipe and recreate the data store.
33-
# :return:
34-
# """
35-
# self.runner.invoke(main, 'setup -o True')
36-
#
37-
# instance = self.session.query(Actor).count()
38-
#
39-
# self.assertEqual(0, instance)
29+
def test_setup_overwrite(self):
30+
"""
31+
Testing that if data store is already set up and overwrite is set to True, wipe and recreate the data store.
32+
:return:
33+
"""
34+
self.runner.invoke(main, 'setup -o True')
35+
36+
instance = self.session.query(Actor).count()
37+
38+
self.assertEqual(0, instance)
4039

4140
def test_setup_already_exists(self):
4241
"""

0 commit comments

Comments
 (0)