dtPyAppFramework 1.0__tar.gz → 1.2__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.
- {dtPyAppFramework-1.0/src/dtPyAppFramework.egg-info → dtpyappframework-1.2}/PKG-INFO +3 -2
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/README.md +1 -1
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/requirements.txt +1 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/__init__.py +4 -2
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/application.py +3 -2
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/misc/__init__.py +1 -1
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/process/__init__.py +5 -1
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/__init__.py +4 -1
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/aws_secret_store.py +22 -2
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/local_secret_store.py +1 -2
- dtpyappframework-1.2/src/dtPyAppFramework/version.dat +1 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2/src/dtPyAppFramework.egg-info}/PKG-INFO +3 -2
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework.egg-info/requires.txt +1 -0
- dtPyAppFramework-1.0/src/dtPyAppFramework/version.dat +0 -1
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/LICENCE.txt +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/MANIFEST.in +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/pyproject.toml +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/setup.cfg +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/setup.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/decorators/__init__.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/logging/__init__.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/logging/default_logging.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/paths/__init__.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/process/multiprocessing.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/resources/__init__.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/__init__.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/azure_secret_store.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/secret_store.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/settings_reader.py +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework.egg-info/SOURCES.txt +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework.egg-info/dependency_links.txt +0 -0
- {dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dtPyAppFramework
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2
|
|
4
4
|
Summary: A Python library for common features in application development.
|
|
5
5
|
Author-email: Digital-Thought <dev@digital-thought.org>
|
|
6
6
|
Maintainer-email: Digital-Thought <dev@digital-thought.org>
|
|
@@ -54,6 +54,7 @@ Requires-Dist: colorlog
|
|
|
54
54
|
Requires-Dist: psutil
|
|
55
55
|
Requires-Dist: pybase64
|
|
56
56
|
Requires-Dist: boto3
|
|
57
|
+
Requires-Dist: cryptography==39.0.2
|
|
57
58
|
Requires-Dist: azure-identity
|
|
58
59
|
Requires-Dist: azure-keyvault-secrets
|
|
59
60
|
Requires-Dist: pykeystore
|
|
@@ -88,7 +89,7 @@ The **`AbstractApp`** class serves as a base class for creating Python applicati
|
|
|
88
89
|
|
|
89
90
|
To create a simple Python application using dtPyAppFramework:
|
|
90
91
|
```python
|
|
91
|
-
from dtPyAppFramework.
|
|
92
|
+
from dtPyAppFramework.application import AbstractApp
|
|
92
93
|
from dtPyAppFramework import settings
|
|
93
94
|
|
|
94
95
|
import logging
|
|
@@ -25,7 +25,7 @@ The **`AbstractApp`** class serves as a base class for creating Python applicati
|
|
|
25
25
|
|
|
26
26
|
To create a simple Python application using dtPyAppFramework:
|
|
27
27
|
```python
|
|
28
|
-
from dtPyAppFramework.
|
|
28
|
+
from dtPyAppFramework.application import AbstractApp
|
|
29
29
|
from dtPyAppFramework import settings
|
|
30
30
|
|
|
31
31
|
import logging
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
dir_path = os.path.dirname(os.path.realpath(__file__))
|
|
2
4
|
|
|
3
5
|
# Define module-level variables with version-related information
|
|
4
|
-
with open('version.dat', 'r') as _version:
|
|
6
|
+
with open(os.path.join(dir_path, 'version.dat'), 'r') as _version:
|
|
5
7
|
__version__ = _version.read()
|
|
6
8
|
|
|
7
9
|
|
|
@@ -97,8 +97,9 @@ class AbstractApp(object):
|
|
|
97
97
|
arg_parser (ArgumentParser): The ArgumentParser object for defining command-line arguments.
|
|
98
98
|
"""
|
|
99
99
|
# Common arguments for various states
|
|
100
|
-
arg_parser.add_argument('--
|
|
101
|
-
|
|
100
|
+
arg_parser.add_argument('--init', action='store_true', required=False, help='Initialise environment')
|
|
101
|
+
arg_parser.add_argument('--add_secret', action='store_true', required=False, help='Add secret to store')
|
|
102
|
+
arg_parser.add_argument('--run', action='store_true', required=False, help='Run Processor')
|
|
102
103
|
|
|
103
104
|
# Check specific states and add corresponding arguments
|
|
104
105
|
opts, rem_args = arg_parser.parse_known_args()
|
|
@@ -6,7 +6,7 @@ from shlex import quote as shlex_quote
|
|
|
6
6
|
def run_cmd(cmd):
|
|
7
7
|
try:
|
|
8
8
|
# Execute the command, capturing the output and raising an exception if the command fails
|
|
9
|
-
result = subprocess.run(
|
|
9
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, check=True, encoding="utf-8")
|
|
10
10
|
|
|
11
11
|
# Return the stripped standard output
|
|
12
12
|
return result.stdout.strip()
|
|
@@ -84,6 +84,8 @@ class ProcessManager():
|
|
|
84
84
|
spawned_process=True,
|
|
85
85
|
job_id=job_id, worker_id=worker_id,
|
|
86
86
|
parent_log_path=parent_log_path)
|
|
87
|
+
self.application_settings.init_settings_readers()
|
|
88
|
+
self.application_settings.secret_manager.load_cloud_stores()
|
|
87
89
|
|
|
88
90
|
self.__initialise_stdout_capt__()
|
|
89
91
|
|
|
@@ -94,6 +96,7 @@ class ProcessManager():
|
|
|
94
96
|
|
|
95
97
|
self.load_config()
|
|
96
98
|
|
|
99
|
+
|
|
97
100
|
except Exception as ex:
|
|
98
101
|
logging.exception(ex)
|
|
99
102
|
if not self.console_app:
|
|
@@ -127,7 +130,7 @@ class ProcessManager():
|
|
|
127
130
|
self.application_settings = settings.Settings(application_paths=self.application_paths)
|
|
128
131
|
self.resource_manager = resources.ResourceManager(application_paths=self.application_paths)
|
|
129
132
|
self.log_path = app_logging.initialise_logging(redirect_console=not self.console_app)
|
|
130
|
-
|
|
133
|
+
self.application_settings.init_settings_readers()
|
|
131
134
|
self.application_settings.secret_manager.load_cloud_stores()
|
|
132
135
|
self.__initialise_stdout_capt__()
|
|
133
136
|
|
|
@@ -139,6 +142,7 @@ class ProcessManager():
|
|
|
139
142
|
print(f'Log Path: {self.log_path}')
|
|
140
143
|
self.multiprocessing_manager.set_log_path(self.log_path)
|
|
141
144
|
args = arg_parser.parse_args()
|
|
145
|
+
|
|
142
146
|
if args.add_secret:
|
|
143
147
|
self.__add_secret__(args)
|
|
144
148
|
else:
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/__init__.py
RENAMED
|
@@ -108,9 +108,12 @@ class SecretsManager(object):
|
|
|
108
108
|
if key.startswith("Secret#"):
|
|
109
109
|
elements = key.split("#")
|
|
110
110
|
store_name = elements[1]
|
|
111
|
+
else:
|
|
112
|
+
elements = key.split(".")
|
|
113
|
+
store_name = elements[0]
|
|
111
114
|
|
|
112
115
|
for store in self.stores:
|
|
113
|
-
if store_name and store_name == store.store_name
|
|
116
|
+
if store_name and store_name == store.store_name:
|
|
114
117
|
value = store.get_secret(key, None)
|
|
115
118
|
break
|
|
116
119
|
elif not store_name:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
1
3
|
from .secret_store import AbstractSecretStore, SecretsStoreException
|
|
2
4
|
from shutil import which
|
|
3
5
|
from ...misc import run_cmd
|
|
@@ -45,6 +47,8 @@ class AWSSecretsStore(AbstractSecretStore):
|
|
|
45
47
|
|
|
46
48
|
self.aws_session = None
|
|
47
49
|
|
|
50
|
+
self.secret_name = self.get_store_setting('secret_name')
|
|
51
|
+
|
|
48
52
|
# Initialize AWS session based on profile type
|
|
49
53
|
if self.aws_profile == 'key':
|
|
50
54
|
aws_access_key_id = self.get_store_setting('aws_access_key_id')
|
|
@@ -72,6 +76,8 @@ class AWSSecretsStore(AbstractSecretStore):
|
|
|
72
76
|
except Exception as ex:
|
|
73
77
|
raise SecretsStoreException(f'AWS Secrets Store, Not Available. Error: {str(ex)}')
|
|
74
78
|
|
|
79
|
+
logging.info(f'Initialised AWS Secrets Manager {store_name}')
|
|
80
|
+
|
|
75
81
|
def get_secret(self, key, default_value=None):
|
|
76
82
|
"""
|
|
77
83
|
Get a secret from the AWS Secrets Manager.
|
|
@@ -84,9 +90,23 @@ class AWSSecretsStore(AbstractSecretStore):
|
|
|
84
90
|
Secret value if found, else default_value.
|
|
85
91
|
"""
|
|
86
92
|
try:
|
|
87
|
-
|
|
93
|
+
if self.secret_name is not None:
|
|
94
|
+
entry = self.aws_secretsmanager.get_secret_value(SecretId=self.secret_name)['SecretString']
|
|
95
|
+
else:
|
|
96
|
+
entry = self.aws_secretsmanager.get_secret_value(SecretId=key)['SecretString']
|
|
97
|
+
if entry.startswith('{'):
|
|
98
|
+
entry = json.loads(entry)
|
|
99
|
+
|
|
100
|
+
if len(key.split('.')) == 0:
|
|
101
|
+
return entry
|
|
102
|
+
elif len(key.split('.')) == 2:
|
|
103
|
+
return entry[key.split('.')[1]]
|
|
104
|
+
elif len(key.split('.')) == 1 and key == self.store_name:
|
|
105
|
+
return entry
|
|
106
|
+
else:
|
|
107
|
+
raise SecretsStoreException(f'Unrecognised AWS Key of secret {key}')
|
|
88
108
|
except Exception as ex:
|
|
89
|
-
logging.error(str(ex))
|
|
109
|
+
logging.error(f'{str(ex)} KEY: {key}')
|
|
90
110
|
entry = None
|
|
91
111
|
|
|
92
112
|
if not entry:
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
-
import subprocess
|
|
4
3
|
import logging
|
|
5
4
|
import re
|
|
6
5
|
import pybase64
|
|
7
6
|
|
|
8
7
|
from .secret_store import AbstractSecretStore, SecretsStoreException
|
|
9
|
-
from pykeepass import PyKeePass
|
|
10
8
|
from itertools import cycle
|
|
11
9
|
from ...misc import run_cmd
|
|
12
10
|
import pykeystore
|
|
13
11
|
from base64 import urlsafe_b64encode
|
|
14
12
|
|
|
13
|
+
|
|
15
14
|
class LocalSecretStore(AbstractSecretStore):
|
|
16
15
|
"""
|
|
17
16
|
A class representing a local secret store for managing secrets.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dtPyAppFramework
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2
|
|
4
4
|
Summary: A Python library for common features in application development.
|
|
5
5
|
Author-email: Digital-Thought <dev@digital-thought.org>
|
|
6
6
|
Maintainer-email: Digital-Thought <dev@digital-thought.org>
|
|
@@ -54,6 +54,7 @@ Requires-Dist: colorlog
|
|
|
54
54
|
Requires-Dist: psutil
|
|
55
55
|
Requires-Dist: pybase64
|
|
56
56
|
Requires-Dist: boto3
|
|
57
|
+
Requires-Dist: cryptography==39.0.2
|
|
57
58
|
Requires-Dist: azure-identity
|
|
58
59
|
Requires-Dist: azure-keyvault-secrets
|
|
59
60
|
Requires-Dist: pykeystore
|
|
@@ -88,7 +89,7 @@ The **`AbstractApp`** class serves as a base class for creating Python applicati
|
|
|
88
89
|
|
|
89
90
|
To create a simple Python application using dtPyAppFramework:
|
|
90
91
|
```python
|
|
91
|
-
from dtPyAppFramework.
|
|
92
|
+
from dtPyAppFramework.application import AbstractApp
|
|
92
93
|
from dtPyAppFramework import settings
|
|
93
94
|
|
|
94
95
|
import logging
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/logging/default_logging.py
RENAMED
|
File without changes
|
|
File without changes
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/process/multiprocessing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/secrets/secret_store.py
RENAMED
|
File without changes
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework/settings/settings_reader.py
RENAMED
|
File without changes
|
|
File without changes
|
{dtPyAppFramework-1.0 → dtpyappframework-1.2}/src/dtPyAppFramework.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|