dtPyAppFramework 2.4__tar.gz → 3.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.
- {dtpyappframework-2.4/src/dtPyAppFramework.egg-info → dtpyappframework-3.0}/PKG-INFO +12 -10
- dtpyappframework-3.0/requirements.txt +14 -0
- dtpyappframework-3.0/src/dtPyAppFramework/_version.txt +1 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/application.py +16 -2
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/process/__init__.py +71 -14
- dtpyappframework-3.0/src/dtPyAppFramework/process/windows_service.py +61 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/local_secret_store.py +38 -1
- {dtpyappframework-2.4 → dtpyappframework-3.0/src/dtPyAppFramework.egg-info}/PKG-INFO +12 -10
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework.egg-info/SOURCES.txt +1 -0
- dtpyappframework-3.0/src/dtPyAppFramework.egg-info/requires.txt +16 -0
- dtpyappframework-2.4/requirements.txt +0 -12
- dtpyappframework-2.4/src/dtPyAppFramework/_version.txt +0 -1
- dtpyappframework-2.4/src/dtPyAppFramework.egg-info/requires.txt +0 -12
- {dtpyappframework-2.4 → dtpyappframework-3.0}/LICENCE.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/MANIFEST.in +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/README.md +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/pyproject.toml +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/setup.cfg +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/setup.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/_description.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/_licence.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/_metadata.yaml +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/_name.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/cloud/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/cloud/aws.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/cloud/azure.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/cloud/cloud_session.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/decorators/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/logging/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/logging/default_logging.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/misc/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/misc/packaging/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/misc/yaml/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/paths/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/process/multiprocessing.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/resources/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/__init__.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/aws_secret_store.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/azure_secret_store.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/keystore.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/local_secret_stores_manager.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/secret_store.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/settings_reader.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework.egg-info/dependency_links.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework.egg-info/top_level.txt +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/tests/test_keystore.py +0 -0
- {dtpyappframework-2.4 → dtpyappframework-3.0}/tests/test_settings_reader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: dtPyAppFramework
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0
|
|
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>
|
|
@@ -49,18 +49,20 @@ Classifier: Topic :: Utilities
|
|
|
49
49
|
Requires-Python: >=3.9
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
License-File: LICENCE.txt
|
|
52
|
-
Requires-Dist: PyYaml
|
|
53
|
-
Requires-Dist: colorlog
|
|
54
|
-
Requires-Dist: psutil
|
|
55
|
-
Requires-Dist: pybase64
|
|
56
|
-
Requires-Dist: boto3
|
|
57
|
-
Requires-Dist: cryptography
|
|
52
|
+
Requires-Dist: PyYaml~=6.0.2
|
|
53
|
+
Requires-Dist: colorlog~=6.9.0
|
|
54
|
+
Requires-Dist: psutil~=6.1.0
|
|
55
|
+
Requires-Dist: pybase64~=1.4.0
|
|
56
|
+
Requires-Dist: boto3~=1.35.54
|
|
57
|
+
Requires-Dist: cryptography~=44.0.0
|
|
58
58
|
Requires-Dist: azure-identity
|
|
59
59
|
Requires-Dist: azure-keyvault-secrets
|
|
60
60
|
Requires-Dist: pytest-mock
|
|
61
61
|
Requires-Dist: pytest-watch
|
|
62
|
-
Requires-Dist: pytest
|
|
63
|
-
Requires-Dist: watchdog
|
|
62
|
+
Requires-Dist: pytest~=8.3.3
|
|
63
|
+
Requires-Dist: watchdog~=6.0.0
|
|
64
|
+
Requires-Dist: azure-core~=1.32.0
|
|
65
|
+
Requires-Dist: pywin32; platform_system == "Windows"
|
|
64
66
|
|
|
65
67
|
# dtPyAppFramework
|
|
66
68
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
PyYaml~=6.0.2
|
|
2
|
+
colorlog~=6.9.0
|
|
3
|
+
psutil~=6.1.0
|
|
4
|
+
pybase64~=1.4.0
|
|
5
|
+
boto3~=1.35.54
|
|
6
|
+
cryptography~=44.0.0
|
|
7
|
+
azure-identity
|
|
8
|
+
azure-keyvault-secrets
|
|
9
|
+
pytest-mock
|
|
10
|
+
pytest-watch
|
|
11
|
+
pytest~=8.3.3
|
|
12
|
+
watchdog~=6.0.0
|
|
13
|
+
azure-core~=1.32.0
|
|
14
|
+
pywin32;platform_system == "Windows"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.0
|
|
@@ -103,21 +103,35 @@ class AbstractApp(object):
|
|
|
103
103
|
arg_parser.add_argument('--init', action='store_true', required=False, help='Initialise environment')
|
|
104
104
|
arg_parser.add_argument('--add_secret', action='store_true', required=False, help='Add secret to store')
|
|
105
105
|
arg_parser.add_argument('--run', action='store_true', required=False, help='Run Processor')
|
|
106
|
+
arg_parser.add_argument('--service', action='store_true', required=False, help='Run as Service')
|
|
106
107
|
arg_parser.add_argument('--single_folder', action='store_true', required=False, help='Keeps all Directories in a single folder')
|
|
108
|
+
arg_parser.add_argument('--working_dir', action='store', type=str, required=False, help="Sets the Working Directory")
|
|
109
|
+
|
|
107
110
|
self.define_args(arg_parser)
|
|
108
111
|
# Check specific states and add corresponding arguments
|
|
109
112
|
opts, rem_args = arg_parser.parse_known_args()
|
|
110
113
|
|
|
114
|
+
if opts.working_dir:
|
|
115
|
+
os.chdir(opts.working_dir)
|
|
116
|
+
|
|
111
117
|
if opts.single_folder:
|
|
112
118
|
os.environ['DEV_MODE'] = "True"
|
|
113
119
|
|
|
120
|
+
if opts.service:
|
|
121
|
+
arg_parser.add_argument('--install', action='store_true')
|
|
122
|
+
|
|
114
123
|
if opts.init:
|
|
115
124
|
arg_parser.add_argument('--password', action='store', type=str, required=False,
|
|
116
125
|
help="Secrets Store password")
|
|
117
|
-
|
|
118
126
|
elif opts.add_secret:
|
|
119
127
|
arg_parser.add_argument('--name', action='store', type=str, required=True, help="Secret Name")
|
|
120
|
-
|
|
128
|
+
|
|
129
|
+
group = arg_parser.add_mutually_exclusive_group(required=True)
|
|
130
|
+
group.add_argument('--value', action='store', type=str, help="Secret Value")
|
|
131
|
+
group.add_argument('--file', action='store', type=str, help="File to add to secret")
|
|
132
|
+
|
|
133
|
+
arg_parser.add_argument('--store_as', action='store', type=str, default='raw', choices=['raw', 'base64'],
|
|
134
|
+
help="Store file as either base64 or raw")
|
|
121
135
|
|
|
122
136
|
def exit(self):
|
|
123
137
|
self.exiting()
|
|
@@ -6,11 +6,21 @@ from .. import resources
|
|
|
6
6
|
from multiprocessing import current_process
|
|
7
7
|
from argparse import ArgumentParser
|
|
8
8
|
from .multiprocessing import MultiProcessingManager
|
|
9
|
-
|
|
9
|
+
import platform
|
|
10
10
|
import sys
|
|
11
11
|
import os
|
|
12
12
|
import logging
|
|
13
|
-
import
|
|
13
|
+
import base64
|
|
14
|
+
import threading
|
|
15
|
+
import signal
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
if platform.system() == "Windows":
|
|
19
|
+
try:
|
|
20
|
+
from dtPyAppFramework.process.windows_service import call_service
|
|
21
|
+
except ImportError as ex:
|
|
22
|
+
logging.error("pywin32 is not installed.")
|
|
23
|
+
raise ex
|
|
14
24
|
|
|
15
25
|
|
|
16
26
|
def is_multiprocess_spawned_instance():
|
|
@@ -63,6 +73,7 @@ class ProcessManager():
|
|
|
63
73
|
self.multiprocessing_manager = None
|
|
64
74
|
self.stdout_txt_file = None
|
|
65
75
|
self.stderr_txt_file = None
|
|
76
|
+
self.running = threading.Event()
|
|
66
77
|
|
|
67
78
|
def __initialise_spawned_application__(self, parent_log_path, job_id, worker_id, job_name, pipe_registry):
|
|
68
79
|
"""
|
|
@@ -112,10 +123,10 @@ class ProcessManager():
|
|
|
112
123
|
stdout_txt = '{}/stdout.txt'.format(self.log_path, self.application_paths.app_short_name)
|
|
113
124
|
stderr_txt = '{}/stderr.txt'.format(self.log_path, self.application_paths.app_short_name)
|
|
114
125
|
|
|
115
|
-
stdout_txt_file = open(stdout_txt, mode='w', buffering=1)
|
|
116
|
-
stderr_txt_file = open(stderr_txt, mode='w', buffering=1)
|
|
117
|
-
sys.stdout = stdout_txt_file
|
|
118
|
-
sys.stderr = stderr_txt_file
|
|
126
|
+
self.stdout_txt_file = open(stdout_txt, mode='w', buffering=1)
|
|
127
|
+
self.stderr_txt_file = open(stderr_txt, mode='w', buffering=1)
|
|
128
|
+
sys.stdout = self.stdout_txt_file
|
|
129
|
+
sys.stderr = self.stderr_txt_file
|
|
119
130
|
|
|
120
131
|
def initialise_application(self, arg_parser):
|
|
121
132
|
"""
|
|
@@ -147,16 +158,22 @@ class ProcessManager():
|
|
|
147
158
|
|
|
148
159
|
if args.add_secret:
|
|
149
160
|
self.__add_secret__(args)
|
|
161
|
+
elif args.service:
|
|
162
|
+
if platform.system() == "Windows":
|
|
163
|
+
sys.argv = [sys.argv[0]]
|
|
164
|
+
call_service(svc_name=self.short_name, svc_display_name=self.full_name,
|
|
165
|
+
svc_description=self.description, main_function=self.__main__,
|
|
166
|
+
exit_function=self.call_shutdown)
|
|
167
|
+
|
|
150
168
|
else:
|
|
169
|
+
signal.signal(signal.SIGINT, self.call_shutdown)
|
|
170
|
+
signal.signal(signal.SIGTERM, self.call_shutdown)
|
|
151
171
|
self.__main__(args)
|
|
152
172
|
|
|
153
173
|
except KeyboardInterrupt as kbi:
|
|
154
174
|
logging.warning('(KeyboardInterrupt) Exiting application.')
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if not self.console_app:
|
|
158
|
-
self.stdout_txt_file.close()
|
|
159
|
-
self.stderr_txt_file.close()
|
|
175
|
+
except Exception as ex:
|
|
176
|
+
logging.exception(str(ex))
|
|
160
177
|
|
|
161
178
|
def load_config(self):
|
|
162
179
|
"""
|
|
@@ -173,11 +190,46 @@ class ProcessManager():
|
|
|
173
190
|
args: Parsed command-line arguments.
|
|
174
191
|
"""
|
|
175
192
|
try:
|
|
176
|
-
|
|
193
|
+
name = args.name
|
|
194
|
+
value = None
|
|
195
|
+
if args.value:
|
|
196
|
+
value = args.value
|
|
197
|
+
if args.file:
|
|
198
|
+
file_path = args.file
|
|
199
|
+
if not os.path.exists(file_path):
|
|
200
|
+
raise FileNotFoundError(f'The file "{file_path}" could not be found.')
|
|
201
|
+
|
|
202
|
+
if args.store_as == 'raw':
|
|
203
|
+
with open(file_path, 'r') as file:
|
|
204
|
+
file_content = file.read()
|
|
205
|
+
value = file_content
|
|
206
|
+
elif args.store_as == 'base64':
|
|
207
|
+
with open(file_path, 'rb') as file:
|
|
208
|
+
file_content = file.read()
|
|
209
|
+
value = base64.b64encode(file_content).decode('utf-8')
|
|
210
|
+
else:
|
|
211
|
+
raise ValueError(f'Invalid store_as value: {args.store_as}')
|
|
212
|
+
|
|
213
|
+
if value is None:
|
|
214
|
+
raise ValueError(f'No "value" was specified for {name}')
|
|
215
|
+
|
|
216
|
+
settings.SecretsManager().set_secret(name, value)
|
|
217
|
+
logging.info(f'Added secret "{name}" to Secret Store.')
|
|
218
|
+
settings.Settings().close()
|
|
177
219
|
except Exception as ex:
|
|
178
220
|
logging.error(f'Error occurred while adding secret {args.name}. Error: {str(ex)}')
|
|
179
221
|
raise ex
|
|
180
222
|
|
|
223
|
+
def handle_shutdown(self):
|
|
224
|
+
if self.exit_procedure:
|
|
225
|
+
self.exit_procedure()
|
|
226
|
+
if not self.console_app:
|
|
227
|
+
self.stdout_txt_file.close()
|
|
228
|
+
self.stderr_txt_file.close()
|
|
229
|
+
|
|
230
|
+
def call_shutdown(self, signum=None, frame=None):
|
|
231
|
+
self.running.clear()
|
|
232
|
+
|
|
181
233
|
def __main__(self, args):
|
|
182
234
|
"""
|
|
183
235
|
Execute the main procedure of the application.
|
|
@@ -185,8 +237,13 @@ class ProcessManager():
|
|
|
185
237
|
Args:
|
|
186
238
|
args: Parsed command-line arguments.
|
|
187
239
|
"""
|
|
240
|
+
self.running.set()
|
|
188
241
|
self.load_config()
|
|
189
242
|
self.main_procedure(args)
|
|
190
243
|
|
|
191
|
-
|
|
192
|
-
|
|
244
|
+
while self.running.is_set():
|
|
245
|
+
time.sleep(0.5)
|
|
246
|
+
|
|
247
|
+
self.handle_shutdown()
|
|
248
|
+
|
|
249
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
if platform.system() == "Windows":
|
|
6
|
+
try:
|
|
7
|
+
import win32service
|
|
8
|
+
import socket
|
|
9
|
+
import win32serviceutil
|
|
10
|
+
import win32event
|
|
11
|
+
import servicemanager
|
|
12
|
+
except ImportError as ex:
|
|
13
|
+
logging.error("pywin32 is not installed.")
|
|
14
|
+
raise ex
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class WindowsService(win32serviceutil.ServiceFramework):
|
|
18
|
+
_svc_name_ = None
|
|
19
|
+
_svc_display_name_ = None
|
|
20
|
+
_svc_description_ = None
|
|
21
|
+
_running_function_ = None
|
|
22
|
+
_stop_function_ = None
|
|
23
|
+
|
|
24
|
+
def __init__(self, args):
|
|
25
|
+
win32serviceutil.ServiceFramework.__init__(self, args)
|
|
26
|
+
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
|
|
27
|
+
socket.setdefaulttimeout(60)
|
|
28
|
+
self.args = args
|
|
29
|
+
|
|
30
|
+
def SvcStop(self):
|
|
31
|
+
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
|
|
32
|
+
win32event.SetEvent(self.hWaitStop)
|
|
33
|
+
self._stop_function_()
|
|
34
|
+
|
|
35
|
+
def SvcDoRun(self):
|
|
36
|
+
try:
|
|
37
|
+
rc = None
|
|
38
|
+
logging.info(f"Service {self._svc_name_} is starting...")
|
|
39
|
+
servicemanager.LogInfoMsg(f"Service {self._svc_name_} is starting...")
|
|
40
|
+
self._running_function_(self.args)
|
|
41
|
+
while rc != win32event.WAIT_OBJECT_0:
|
|
42
|
+
rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)
|
|
43
|
+
except Exception as ex:
|
|
44
|
+
logging.exception(str(ex))
|
|
45
|
+
raise ex
|
|
46
|
+
logging.info(f"Service {self._svc_name_} is stopping...")
|
|
47
|
+
servicemanager.LogInfoMsg(f"Service {self._svc_name_} is stopping...")
|
|
48
|
+
|
|
49
|
+
def call_service(svc_name, svc_display_name, svc_description, main_function, exit_function):
|
|
50
|
+
WindowsService._svc_name_ = svc_name
|
|
51
|
+
WindowsService._svc_display_name_ = svc_display_name
|
|
52
|
+
WindowsService._svc_description_ = svc_description
|
|
53
|
+
WindowsService._running_function_ = main_function
|
|
54
|
+
WindowsService._stop_function_ = exit_function
|
|
55
|
+
|
|
56
|
+
if len(sys.argv) == 1:
|
|
57
|
+
servicemanager.Initialize()
|
|
58
|
+
servicemanager.PrepareToHostSingle(WindowsService)
|
|
59
|
+
servicemanager.StartServiceCtrlDispatcher()
|
|
60
|
+
else:
|
|
61
|
+
win32serviceutil.HandleCommandLine(WindowsService)
|
|
@@ -4,6 +4,8 @@ import sys
|
|
|
4
4
|
import logging
|
|
5
5
|
import re
|
|
6
6
|
import pybase64
|
|
7
|
+
import yaml
|
|
8
|
+
import base64
|
|
7
9
|
|
|
8
10
|
from .secret_store import AbstractSecretStore, SecretsStoreException
|
|
9
11
|
from itertools import cycle
|
|
@@ -64,9 +66,45 @@ class LocalSecretStore(AbstractSecretStore):
|
|
|
64
66
|
self.store_available = True
|
|
65
67
|
self.store_read_only = not self.__is_writeable()
|
|
66
68
|
logging.info(f'Successfully opened Secrets Store: {self.store_path}')
|
|
69
|
+
self.__check_auto_imports(root_store_path)
|
|
67
70
|
except Exception as ex:
|
|
68
71
|
raise SecretsStoreException(f'Failed to open Secrets Store: {self.store_path}. Error: {str(ex)}')
|
|
69
72
|
|
|
73
|
+
def __check_auto_imports(self, root_store_path):
|
|
74
|
+
auto_yaml = os.path.join(root_store_path, 'secrets.yaml')
|
|
75
|
+
if os.path.exists(auto_yaml):
|
|
76
|
+
print(f'Performing Auto-Import of Secrets from {auto_yaml}')
|
|
77
|
+
with open(auto_yaml, 'r', encoding='UTF-8') as auto_yaml_file:
|
|
78
|
+
secrets = yaml.safe_load(auto_yaml_file)
|
|
79
|
+
for entry in secrets['secrets']:
|
|
80
|
+
name = entry.get('name')
|
|
81
|
+
value = entry.get('value')
|
|
82
|
+
secret_file = entry.get('file')
|
|
83
|
+
store_as = entry.get('store_as')
|
|
84
|
+
|
|
85
|
+
if secret_file is not None:
|
|
86
|
+
if os.path.exists(secret_file):
|
|
87
|
+
if store_as == 'raw':
|
|
88
|
+
with open(secret_file, 'r') as file:
|
|
89
|
+
file_content = file.read()
|
|
90
|
+
value = file_content
|
|
91
|
+
elif store_as == 'base64':
|
|
92
|
+
with open(secret_file, 'rb') as file:
|
|
93
|
+
file_content = file.read()
|
|
94
|
+
value = base64.b64encode(file_content).decode('utf-8')
|
|
95
|
+
else:
|
|
96
|
+
print(f'Unsupported "store_as" value of {store_as} for {name}', file=sys.stderr)
|
|
97
|
+
else:
|
|
98
|
+
print(f'The file "{secret_file}" specified for {name} does not exist', file=sys.stderr)
|
|
99
|
+
|
|
100
|
+
if value is not None:
|
|
101
|
+
self.set_secret(name, value)
|
|
102
|
+
print(f'Imported Secret: {name}')
|
|
103
|
+
else:
|
|
104
|
+
print(f'Missing "value" for {name}. Not imported.', file=sys.stderr)
|
|
105
|
+
|
|
106
|
+
os.remove(auto_yaml)
|
|
107
|
+
|
|
70
108
|
def __guid(self):
|
|
71
109
|
"""
|
|
72
110
|
Generate a unique identifier based on the machine and store path.
|
|
@@ -155,7 +193,6 @@ class LocalSecretStore(AbstractSecretStore):
|
|
|
155
193
|
self.__set_index(index)
|
|
156
194
|
|
|
157
195
|
def __set_index(self, index: list):
|
|
158
|
-
logging.info(index)
|
|
159
196
|
self.store.set(key=f'{self.store_name}.INDEX', value=json.dumps(index))
|
|
160
197
|
|
|
161
198
|
def get_index(self) -> list:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: dtPyAppFramework
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0
|
|
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>
|
|
@@ -49,18 +49,20 @@ Classifier: Topic :: Utilities
|
|
|
49
49
|
Requires-Python: >=3.9
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
License-File: LICENCE.txt
|
|
52
|
-
Requires-Dist: PyYaml
|
|
53
|
-
Requires-Dist: colorlog
|
|
54
|
-
Requires-Dist: psutil
|
|
55
|
-
Requires-Dist: pybase64
|
|
56
|
-
Requires-Dist: boto3
|
|
57
|
-
Requires-Dist: cryptography
|
|
52
|
+
Requires-Dist: PyYaml~=6.0.2
|
|
53
|
+
Requires-Dist: colorlog~=6.9.0
|
|
54
|
+
Requires-Dist: psutil~=6.1.0
|
|
55
|
+
Requires-Dist: pybase64~=1.4.0
|
|
56
|
+
Requires-Dist: boto3~=1.35.54
|
|
57
|
+
Requires-Dist: cryptography~=44.0.0
|
|
58
58
|
Requires-Dist: azure-identity
|
|
59
59
|
Requires-Dist: azure-keyvault-secrets
|
|
60
60
|
Requires-Dist: pytest-mock
|
|
61
61
|
Requires-Dist: pytest-watch
|
|
62
|
-
Requires-Dist: pytest
|
|
63
|
-
Requires-Dist: watchdog
|
|
62
|
+
Requires-Dist: pytest~=8.3.3
|
|
63
|
+
Requires-Dist: watchdog~=6.0.0
|
|
64
|
+
Requires-Dist: azure-core~=1.32.0
|
|
65
|
+
Requires-Dist: pywin32; platform_system == "Windows"
|
|
64
66
|
|
|
65
67
|
# dtPyAppFramework
|
|
66
68
|
|
|
@@ -29,6 +29,7 @@ src/dtPyAppFramework/misc/yaml/__init__.py
|
|
|
29
29
|
src/dtPyAppFramework/paths/__init__.py
|
|
30
30
|
src/dtPyAppFramework/process/__init__.py
|
|
31
31
|
src/dtPyAppFramework/process/multiprocessing.py
|
|
32
|
+
src/dtPyAppFramework/process/windows_service.py
|
|
32
33
|
src/dtPyAppFramework/resources/__init__.py
|
|
33
34
|
src/dtPyAppFramework/settings/__init__.py
|
|
34
35
|
src/dtPyAppFramework/settings/settings_reader.py
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
PyYaml~=6.0.2
|
|
2
|
+
colorlog~=6.9.0
|
|
3
|
+
psutil~=6.1.0
|
|
4
|
+
pybase64~=1.4.0
|
|
5
|
+
boto3~=1.35.54
|
|
6
|
+
cryptography~=44.0.0
|
|
7
|
+
azure-identity
|
|
8
|
+
azure-keyvault-secrets
|
|
9
|
+
pytest-mock
|
|
10
|
+
pytest-watch
|
|
11
|
+
pytest~=8.3.3
|
|
12
|
+
watchdog~=6.0.0
|
|
13
|
+
azure-core~=1.32.0
|
|
14
|
+
|
|
15
|
+
[:platform_system == "Windows"]
|
|
16
|
+
pywin32
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.4
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/logging/default_logging.py
RENAMED
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/misc/packaging/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/process/multiprocessing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/keystore.py
RENAMED
|
File without changes
|
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/secrets/secret_store.py
RENAMED
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework/settings/settings_reader.py
RENAMED
|
File without changes
|
{dtpyappframework-2.4 → dtpyappframework-3.0}/src/dtPyAppFramework.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|