atomicshop 2.9.3__py3-none-any.whl → 2.9.5__py3-none-any.whl
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 atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/basics/classes.py +25 -0
- atomicshop/basics/numbers.py +28 -0
- atomicshop/system_resource_monitor.py +133 -133
- atomicshop/wrappers/psutilw/disks.py +36 -30
- {atomicshop-2.9.3.dist-info → atomicshop-2.9.5.dist-info}/METADATA +2 -1
- {atomicshop-2.9.3.dist-info → atomicshop-2.9.5.dist-info}/RECORD +10 -10
- {atomicshop-2.9.3.dist-info → atomicshop-2.9.5.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.9.3.dist-info → atomicshop-2.9.5.dist-info}/WHEEL +0 -0
- {atomicshop-2.9.3.dist-info → atomicshop-2.9.5.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/basics/classes.py
CHANGED
|
@@ -185,6 +185,31 @@ def import_first_class_name_from_file_path(script_directory: str, file_path: str
|
|
|
185
185
|
return imported_class
|
|
186
186
|
|
|
187
187
|
|
|
188
|
+
def import_file_as_module(script_directory: str, file_path: str):
|
|
189
|
+
"""
|
|
190
|
+
Function imports file as module and returns the module object.
|
|
191
|
+
|
|
192
|
+
:param script_directory: string, of file full path to working directory of the main script that will be subtracted
|
|
193
|
+
from the file path.
|
|
194
|
+
:param file_path: string, of full file path to python file module.
|
|
195
|
+
:return: module object.
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
# Get the module name string.
|
|
199
|
+
module_name: str = get_module_name_from_file_path(script_directory, file_path)
|
|
200
|
+
|
|
201
|
+
# Import the module.
|
|
202
|
+
try:
|
|
203
|
+
imported_module = import_module_by_string(module_name)
|
|
204
|
+
except ModuleNotFoundError:
|
|
205
|
+
# If the module is not found, we will try to add this path to the system path and try again.
|
|
206
|
+
sys.path.append(str(Path(file_path).parent))
|
|
207
|
+
|
|
208
|
+
imported_module = import_module_by_string(module_name)
|
|
209
|
+
|
|
210
|
+
return imported_module
|
|
211
|
+
|
|
212
|
+
|
|
188
213
|
def get_attributes(
|
|
189
214
|
obj,
|
|
190
215
|
include_private_1: bool = False,
|
atomicshop/basics/numbers.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
def is_divisible(n, k):
|
|
2
5
|
"""Return True if n is divisible by k, False otherwise."""
|
|
3
6
|
|
|
@@ -18,3 +21,28 @@ def find_highest_number(numbers: list[float, int, str]):
|
|
|
18
21
|
raise ValueError('The list of numbers is empty.')
|
|
19
22
|
|
|
20
23
|
return max(numbers)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def convert_bytes_to_readable(byte_size: Union[int, float]):
|
|
27
|
+
"""
|
|
28
|
+
Convert bytes to a more readable format (KB, MB, GB, etc.) with two numbers after the decimal point.
|
|
29
|
+
|
|
30
|
+
:param byte_size: Size in bytes
|
|
31
|
+
:type byte_size: int or float
|
|
32
|
+
:return: A string representing the size in a readable format
|
|
33
|
+
:rtype: str
|
|
34
|
+
"""
|
|
35
|
+
# Define the suffixes for each unit of measurement
|
|
36
|
+
suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
37
|
+
i = 0
|
|
38
|
+
# Convert byte_size to float for division
|
|
39
|
+
byte_size = float(byte_size)
|
|
40
|
+
|
|
41
|
+
# Calculate the unit of measurement to use
|
|
42
|
+
while byte_size >= 1024 and i < len(suffixes) - 1:
|
|
43
|
+
byte_size /= 1024.
|
|
44
|
+
i += 1
|
|
45
|
+
|
|
46
|
+
# Format the result to include two digits after the decimal point
|
|
47
|
+
readable_format = "{:.2f} {}".format(byte_size, suffixes[i])
|
|
48
|
+
return readable_format
|
|
@@ -1,45 +1,11 @@
|
|
|
1
1
|
from typing import Union
|
|
2
|
+
import threading
|
|
2
3
|
import multiprocessing
|
|
3
4
|
|
|
4
5
|
from .print_api import print_api
|
|
5
6
|
from . import system_resources
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
def run_check_system_resources(
|
|
9
|
-
interval, get_cpu, get_memory, get_disk_io_bytes, get_disk_files_count, get_disk_busy_time,
|
|
10
|
-
get_disk_used_percent, calculate_maximum_changed_disk_io, maximum_disk_io, shared_results, queue=None):
|
|
11
|
-
"""
|
|
12
|
-
Continuously update the system resources in the shared results dictionary.
|
|
13
|
-
This function runs in a separate process.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
while True:
|
|
17
|
-
# Get the results of the system resources check function and store them in temporary results dictionary.
|
|
18
|
-
results = system_resources.check_system_resources(
|
|
19
|
-
interval=interval, get_cpu=get_cpu, get_memory=get_memory,
|
|
20
|
-
get_disk_io_bytes=get_disk_io_bytes, get_disk_files_count=get_disk_files_count,
|
|
21
|
-
get_disk_busy_time=get_disk_busy_time, get_disk_used_percent=get_disk_used_percent)
|
|
22
|
-
|
|
23
|
-
if calculate_maximum_changed_disk_io:
|
|
24
|
-
if results['disk_io_read'] > maximum_disk_io['read_bytes_per_sec']:
|
|
25
|
-
maximum_disk_io['read_bytes_per_sec'] = results['disk_io_read']
|
|
26
|
-
if results['disk_io_write'] > maximum_disk_io['write_bytes_per_sec']:
|
|
27
|
-
maximum_disk_io['write_bytes_per_sec'] = results['disk_io_write']
|
|
28
|
-
if results['disk_files_count_read'] > maximum_disk_io['read_files_count_per_sec']:
|
|
29
|
-
maximum_disk_io['read_files_count_per_sec'] = results['disk_files_count_read']
|
|
30
|
-
if results['disk_files_count_write'] > maximum_disk_io['write_files_count_per_sec']:
|
|
31
|
-
maximum_disk_io['write_files_count_per_sec'] = results['disk_files_count_write']
|
|
32
|
-
results['maximum_disk_io'] = maximum_disk_io
|
|
33
|
-
|
|
34
|
-
# Update the shared results dictionary with the temporary results dictionary.
|
|
35
|
-
# This is done in separate steps to avoid overwriting the special 'multiprocessing.Manager.dict' object.
|
|
36
|
-
# So we update the shared results dictionary with the temporary results dictionary.
|
|
37
|
-
shared_results.update(results)
|
|
38
|
-
|
|
39
|
-
if queue is not None:
|
|
40
|
-
queue.put(results)
|
|
41
|
-
|
|
42
|
-
|
|
43
9
|
class SystemResourceMonitor:
|
|
44
10
|
"""
|
|
45
11
|
A class to monitor system resources in a separate process.
|
|
@@ -54,7 +20,8 @@ class SystemResourceMonitor:
|
|
|
54
20
|
get_disk_busy_time: bool = False,
|
|
55
21
|
get_disk_used_percent: bool = True,
|
|
56
22
|
calculate_maximum_changed_disk_io: bool = False,
|
|
57
|
-
|
|
23
|
+
queue_list: list = None,
|
|
24
|
+
manager_dict = None # multiprocessing.Manager().dict()
|
|
58
25
|
):
|
|
59
26
|
"""
|
|
60
27
|
Initialize the system resource monitor.
|
|
@@ -69,40 +36,55 @@ class SystemResourceMonitor:
|
|
|
69
36
|
:param get_disk_used_percent: bool, get the disk used percentage.
|
|
70
37
|
:param calculate_maximum_changed_disk_io: bool, calculate the maximum changed disk I/O. This includes the
|
|
71
38
|
maximum changed disk I/O read and write in bytes/s and the maximum changed disk files count.
|
|
72
|
-
:param
|
|
73
|
-
If you need
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Example:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
39
|
+
:param queue_list: list, list of queues to store results. The queue type depends on your application.
|
|
40
|
+
If you need to use the results of the System Resource Monitor in another process or several processes
|
|
41
|
+
you can pass several queues in the queue_list to store the results.
|
|
42
|
+
|
|
43
|
+
Usage Example with multiprocessing.Manager().dict():
|
|
44
|
+
# Create multiprocessing manager dict that will be shared for monitoring results between the processes.
|
|
45
|
+
manager = multiprocessing.Manager()
|
|
46
|
+
shared_dict = manager.dict()
|
|
47
|
+
|
|
48
|
+
# Start the system resource monitor.
|
|
49
|
+
multiprocessing.Process(
|
|
50
|
+
target=system_resource_monitor.start_monitoring, kwargs={'manager_dict': shared_dict}).start()
|
|
51
|
+
|
|
52
|
+
# If you need ot get the queue, you can access it through the 'queue' attribute:
|
|
53
|
+
# SystemResourceMonitor.queue
|
|
54
|
+
#
|
|
55
|
+
# Example:
|
|
56
|
+
# system_resource_monitor = SystemResourceMonitor()
|
|
57
|
+
# your_queue = system_resource_monitor.queue
|
|
58
|
+
#
|
|
59
|
+
# while True:
|
|
60
|
+
# if not your_queue.empty():
|
|
61
|
+
# results = your_queue.get()
|
|
62
|
+
# print(results)
|
|
63
|
+
#
|
|
64
|
+
# ================
|
|
65
|
+
#
|
|
66
|
+
# Usage Example with queue:
|
|
67
|
+
# system_resource_monitor = SystemResourceMonitor(use_queue=True)
|
|
68
|
+
# system_resource_monitor.start()
|
|
69
|
+
# queue = system_resource_monitor.queue
|
|
70
|
+
# while True:
|
|
71
|
+
# if not queue.empty():
|
|
72
|
+
# results = queue.get()
|
|
73
|
+
# print(results)
|
|
74
|
+
#
|
|
75
|
+
# ================
|
|
76
|
+
#
|
|
77
|
+
# Usage Example without queue:
|
|
78
|
+
# interval = 1
|
|
79
|
+
# system_resource_monitor = SystemResourceMonitor(interval=interval, use_queue=False)
|
|
80
|
+
# system_resource_monitor.start()
|
|
81
|
+
# while True:
|
|
82
|
+
# time.sleep(interval)
|
|
83
|
+
# results = system_resource_monitor.get_latest_results()
|
|
84
|
+
# print(results)
|
|
85
|
+
:param manager_dict: multiprocessing.Manager().dict(), a dictionary to store the results.
|
|
86
|
+
If you need to use the results of the System Resource Monitor in another process or several processes
|
|
87
|
+
you can pass the manager_dict to store the results.
|
|
106
88
|
"""
|
|
107
89
|
# Store parameters as instance attributes
|
|
108
90
|
self.interval: float = interval
|
|
@@ -113,10 +95,9 @@ class SystemResourceMonitor:
|
|
|
113
95
|
self.get_disk_busy_time: bool = get_disk_busy_time
|
|
114
96
|
self.get_disk_used_percent: bool = get_disk_used_percent
|
|
115
97
|
self.calculate_maximum_changed_disk_io: bool = calculate_maximum_changed_disk_io
|
|
98
|
+
self.queue_list: list = queue_list
|
|
99
|
+
self.manager_dict: multiprocessing.Manager().dict = manager_dict
|
|
116
100
|
|
|
117
|
-
self.manager = multiprocessing.Manager()
|
|
118
|
-
self.shared_results = self.manager.dict()
|
|
119
|
-
self.process = None
|
|
120
101
|
self.maximum_disk_io: dict = {
|
|
121
102
|
'read_bytes_per_sec': 0,
|
|
122
103
|
'write_bytes_per_sec': 0,
|
|
@@ -124,10 +105,12 @@ class SystemResourceMonitor:
|
|
|
124
105
|
'write_files_count_per_sec': 0
|
|
125
106
|
}
|
|
126
107
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
108
|
+
# Main thread that gets the monitoring results.
|
|
109
|
+
self.thread: Union[threading.Thread, None] = None
|
|
110
|
+
# Sets the running state of the monitoring process. Needed to stop the monitoring and queue threads.
|
|
111
|
+
self.running: bool = False
|
|
112
|
+
# The shared results dictionary.
|
|
113
|
+
self.results: dict = {}
|
|
131
114
|
|
|
132
115
|
def start(self, print_kwargs: dict = None):
|
|
133
116
|
"""
|
|
@@ -135,31 +118,72 @@ class SystemResourceMonitor:
|
|
|
135
118
|
:param print_kwargs:
|
|
136
119
|
:return:
|
|
137
120
|
"""
|
|
121
|
+
|
|
122
|
+
def run_check_system_resources(
|
|
123
|
+
interval, get_cpu, get_memory, get_disk_io_bytes, get_disk_files_count, get_disk_busy_time,
|
|
124
|
+
get_disk_used_percent, calculate_maximum_changed_disk_io, maximum_disk_io, queue_list, manager_dict):
|
|
125
|
+
"""
|
|
126
|
+
Continuously update the system resources in the shared results dictionary.
|
|
127
|
+
This function runs in a separate process.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
while self.running:
|
|
131
|
+
# Get the results of the system resources check function and store them in temporary results dictionary.
|
|
132
|
+
results = system_resources.check_system_resources(
|
|
133
|
+
interval=interval, get_cpu=get_cpu, get_memory=get_memory,
|
|
134
|
+
get_disk_io_bytes=get_disk_io_bytes, get_disk_files_count=get_disk_files_count,
|
|
135
|
+
get_disk_busy_time=get_disk_busy_time, get_disk_used_percent=get_disk_used_percent)
|
|
136
|
+
|
|
137
|
+
if calculate_maximum_changed_disk_io:
|
|
138
|
+
if results['disk_io_read'] > maximum_disk_io['read_bytes_per_sec']:
|
|
139
|
+
maximum_disk_io['read_bytes_per_sec'] = results['disk_io_read']
|
|
140
|
+
if results['disk_io_write'] > maximum_disk_io['write_bytes_per_sec']:
|
|
141
|
+
maximum_disk_io['write_bytes_per_sec'] = results['disk_io_write']
|
|
142
|
+
if results['disk_files_count_read'] > maximum_disk_io['read_files_count_per_sec']:
|
|
143
|
+
maximum_disk_io['read_files_count_per_sec'] = results['disk_files_count_read']
|
|
144
|
+
if results['disk_files_count_write'] > maximum_disk_io['write_files_count_per_sec']:
|
|
145
|
+
maximum_disk_io['write_files_count_per_sec'] = results['disk_files_count_write']
|
|
146
|
+
results['maximum_disk_io'] = maximum_disk_io
|
|
147
|
+
|
|
148
|
+
if queue_list is not None:
|
|
149
|
+
for queue in queue_list:
|
|
150
|
+
queue.put(results)
|
|
151
|
+
|
|
152
|
+
# Update the shared results dictionary with the temporary results dictionary.
|
|
153
|
+
# This is done in separate steps to avoid overwriting the special 'multiprocessing.Manager.dict' object.
|
|
154
|
+
# So we update the shared results dictionary with the temporary results dictionary.
|
|
155
|
+
if manager_dict is not None:
|
|
156
|
+
manager_dict.update(results)
|
|
157
|
+
|
|
158
|
+
self.results = results
|
|
159
|
+
|
|
138
160
|
if print_kwargs is None:
|
|
139
161
|
print_kwargs = {}
|
|
140
162
|
|
|
141
|
-
if self.
|
|
142
|
-
self.
|
|
163
|
+
if self.thread is None:
|
|
164
|
+
self.running = True
|
|
165
|
+
self.thread = threading.Thread(target=run_check_system_resources, args=(
|
|
143
166
|
self.interval, self.get_cpu, self.get_memory, self.get_disk_io_bytes, self.get_disk_files_count,
|
|
144
167
|
self.get_disk_busy_time, self.get_disk_used_percent, self.calculate_maximum_changed_disk_io,
|
|
145
|
-
self.maximum_disk_io, self.
|
|
146
|
-
self.
|
|
168
|
+
self.maximum_disk_io, self.queue_list, self.manager_dict))
|
|
169
|
+
self.thread.start()
|
|
147
170
|
else:
|
|
148
|
-
print_api("Monitoring
|
|
171
|
+
print_api("Monitoring is already running.", color='yellow', **print_kwargs)
|
|
149
172
|
|
|
150
|
-
def
|
|
173
|
+
def get_results(self) -> dict:
|
|
151
174
|
"""
|
|
152
|
-
Retrieve the latest results
|
|
175
|
+
Retrieve the latest results.
|
|
153
176
|
"""
|
|
154
|
-
|
|
177
|
+
|
|
178
|
+
return self.results
|
|
155
179
|
|
|
156
180
|
def stop(self):
|
|
157
181
|
"""
|
|
158
182
|
Stop the monitoring process.
|
|
159
183
|
"""
|
|
160
|
-
if self.
|
|
161
|
-
self.
|
|
162
|
-
self.
|
|
184
|
+
if self.thread is not None:
|
|
185
|
+
self.running = False
|
|
186
|
+
self.thread.join()
|
|
163
187
|
|
|
164
188
|
|
|
165
189
|
# === END OF SYSTEM RESOURCE MONITOR. ==================================================================================
|
|
@@ -177,7 +201,8 @@ def start_monitoring(
|
|
|
177
201
|
get_disk_busy_time: bool = False,
|
|
178
202
|
get_disk_used_percent: bool = True,
|
|
179
203
|
calculate_maximum_changed_disk_io: bool = False,
|
|
180
|
-
|
|
204
|
+
queue_list: list = None,
|
|
205
|
+
manager_dict=None, # multiprocessing.Manager().dict()
|
|
181
206
|
print_kwargs: dict = None
|
|
182
207
|
):
|
|
183
208
|
"""
|
|
@@ -192,14 +217,21 @@ def start_monitoring(
|
|
|
192
217
|
:param get_disk_used_percent: bool, get TOTAL disk used percentage.
|
|
193
218
|
:param calculate_maximum_changed_disk_io: bool, calculate the maximum changed disk I/O. This includes the
|
|
194
219
|
maximum changed disk I/O read and write in bytes/s and the maximum changed disk files count.
|
|
195
|
-
:param
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
220
|
+
:param queue_list: list, list of queues to store results. The queue type depends on your application.
|
|
221
|
+
If you need to use the results of the System Resource Monitor in another process or several processes
|
|
222
|
+
you can pass several queues in the queue_list to store the results.
|
|
223
|
+
:param manager_dict: multiprocessing.Manager().dict(), a dictionary to store the results.
|
|
224
|
+
If you need to use the results of the System Resource Monitor in another process or several processes
|
|
225
|
+
you can pass the manager_dict to store the results.
|
|
226
|
+
|
|
227
|
+
Usage Example with multiprocessing.Manager().dict():
|
|
228
|
+
# Create multiprocessing manager dict that will be shared for monitoring results between the processes.
|
|
229
|
+
manager = multiprocessing.Manager()
|
|
230
|
+
shared_dict = manager.dict()
|
|
231
|
+
|
|
232
|
+
# Start the system resource monitor.
|
|
233
|
+
multiprocessing.Process(
|
|
234
|
+
target=system_resource_monitor.start_monitoring, kwargs={'manager_dict': shared_dict}).start()
|
|
203
235
|
|
|
204
236
|
:param print_kwargs: dict, print kwargs.
|
|
205
237
|
:return:
|
|
@@ -220,7 +252,8 @@ def start_monitoring(
|
|
|
220
252
|
get_disk_busy_time=get_disk_busy_time,
|
|
221
253
|
get_disk_used_percent=get_disk_used_percent,
|
|
222
254
|
calculate_maximum_changed_disk_io=calculate_maximum_changed_disk_io,
|
|
223
|
-
|
|
255
|
+
queue_list=queue_list,
|
|
256
|
+
manager_dict=manager_dict
|
|
224
257
|
)
|
|
225
258
|
SYSTEM_RESOURCES_MONITOR.start()
|
|
226
259
|
else:
|
|
@@ -246,7 +279,7 @@ def get_monitoring_instance() -> SystemResourceMonitor:
|
|
|
246
279
|
return SYSTEM_RESOURCES_MONITOR
|
|
247
280
|
|
|
248
281
|
|
|
249
|
-
def
|
|
282
|
+
def get_results():
|
|
250
283
|
"""
|
|
251
284
|
Get system resources monitoring result.
|
|
252
285
|
|
|
@@ -268,39 +301,6 @@ def get_result():
|
|
|
268
301
|
"""
|
|
269
302
|
global SYSTEM_RESOURCES_MONITOR
|
|
270
303
|
if SYSTEM_RESOURCES_MONITOR is not None:
|
|
271
|
-
return SYSTEM_RESOURCES_MONITOR.
|
|
272
|
-
else:
|
|
273
|
-
raise RuntimeError("System resources monitoring is not running.")
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
def get_result_by_queue():
|
|
277
|
-
"""
|
|
278
|
-
Get system resources monitoring result by queue.
|
|
279
|
-
|
|
280
|
-
Usage Example:
|
|
281
|
-
system_resources.start_system_resources_monitoring()
|
|
282
|
-
|
|
283
|
-
while True:
|
|
284
|
-
result = system_resources.get_result_by_queue()
|
|
285
|
-
print(result)
|
|
286
|
-
|
|
287
|
-
:return: dict
|
|
288
|
-
"""
|
|
289
|
-
global SYSTEM_RESOURCES_MONITOR
|
|
290
|
-
if SYSTEM_RESOURCES_MONITOR is not None:
|
|
291
|
-
if not SYSTEM_RESOURCES_MONITOR.queue.empty():
|
|
292
|
-
return SYSTEM_RESOURCES_MONITOR.queue.get()
|
|
293
|
-
else:
|
|
294
|
-
raise RuntimeError("System resources monitoring is not running.")
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
def get_monitoring_queue() -> Union[multiprocessing.Queue, None]:
|
|
298
|
-
"""
|
|
299
|
-
Get the monitoring queue.
|
|
300
|
-
:return: multiprocessing.Queue
|
|
301
|
-
"""
|
|
302
|
-
global SYSTEM_RESOURCES_MONITOR
|
|
303
|
-
if SYSTEM_RESOURCES_MONITOR is not None:
|
|
304
|
-
return SYSTEM_RESOURCES_MONITOR.queue
|
|
304
|
+
return SYSTEM_RESOURCES_MONITOR.get_results()
|
|
305
305
|
else:
|
|
306
306
|
raise RuntimeError("System resources monitoring is not running.")
|
|
@@ -38,14 +38,16 @@ def get_disk_io(
|
|
|
38
38
|
}
|
|
39
39
|
:param io_busy_time: Boolean indicating whether to return I/O busy time.
|
|
40
40
|
!!! For some reason on Windows it gets the count of files read or written and not the time in ms.
|
|
41
|
+
!!! On Ubuntu it gets the time in ms, but for some reason it can return value higher than the interval.
|
|
42
|
+
Which is not possible, so it is not reliable.
|
|
41
43
|
Returned dictionary:
|
|
42
44
|
{
|
|
43
45
|
'read_time_ms': int,
|
|
44
46
|
'write_time_ms': int,
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
+
'read_time_in_sec': float,
|
|
48
|
+
'write_time_in_sec': float,
|
|
47
49
|
'busy_time': int,
|
|
48
|
-
'
|
|
50
|
+
'busy_time_in_sec': float,
|
|
49
51
|
'busy_time_percent': float
|
|
50
52
|
}
|
|
51
53
|
:return: Disk utilization data.
|
|
@@ -121,40 +123,44 @@ def get_disk_io(
|
|
|
121
123
|
io_change['aggregated'] = {}
|
|
122
124
|
|
|
123
125
|
if io_change_bytes:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
aggregated_read_change = io_end_aggregated.read_bytes - io_start_aggregated.read_bytes
|
|
127
|
+
aggregated_write_change = io_end_aggregated.write_bytes - io_start_aggregated.write_bytes
|
|
128
|
+
aggregated_read_change_per_sec = aggregated_read_change / interval
|
|
129
|
+
aggregated_write_change_per_sec = aggregated_write_change / interval
|
|
128
130
|
io_change['aggregated'] = {
|
|
129
|
-
'read_change_bytes':
|
|
130
|
-
'write_change_bytes':
|
|
131
|
-
'
|
|
132
|
-
'
|
|
131
|
+
'read_change_bytes': aggregated_read_change,
|
|
132
|
+
'write_change_bytes': aggregated_write_change,
|
|
133
|
+
'total_change_bytes': aggregated_read_change + aggregated_write_change,
|
|
134
|
+
'read_change_per_sec': aggregated_read_change_per_sec,
|
|
135
|
+
'write_change_per_sec': aggregated_write_change_per_sec,
|
|
136
|
+
'total_change_per_sec': aggregated_read_change_per_sec + aggregated_write_change_per_sec
|
|
133
137
|
}
|
|
134
138
|
if io_file_count:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
aggregated_read_count = io_end_aggregated.read_count - io_start_aggregated.read_count
|
|
140
|
+
aggregated_write_count = io_end_aggregated.write_count - io_start_aggregated.write_count
|
|
141
|
+
aggregated_read_count_per_sec = aggregated_read_count / interval
|
|
142
|
+
aggregated_write_count_per_sec = aggregated_write_count / interval
|
|
139
143
|
io_change['aggregated'].update({
|
|
140
|
-
'read_file_count':
|
|
141
|
-
'write_file_count':
|
|
142
|
-
'
|
|
143
|
-
'
|
|
144
|
+
'read_file_count': aggregated_read_count,
|
|
145
|
+
'write_file_count': aggregated_write_count,
|
|
146
|
+
'total_file_count': aggregated_read_count + aggregated_write_count,
|
|
147
|
+
'read_file_count_per_sec': aggregated_read_count_per_sec,
|
|
148
|
+
'write_file_count_per_sec': aggregated_write_count_per_sec,
|
|
149
|
+
'total_file_count_per_sec': aggregated_read_count_per_sec + aggregated_write_count_per_sec
|
|
144
150
|
})
|
|
145
151
|
if io_busy_time:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
aggregated_read_time = io_end_aggregated.read_time - io_start_aggregated.read_time
|
|
153
|
+
aggregated_write_time = io_end_aggregated.write_time - io_start_aggregated.write_time
|
|
154
|
+
aggregated_read_time_per_sec = aggregated_read_time / 1000 / interval
|
|
155
|
+
aggregated_write_time_per_sec = aggregated_write_time / 1000 / interval
|
|
150
156
|
io_change['aggregated'].update({
|
|
151
|
-
'read_time_ms':
|
|
152
|
-
'write_time_ms':
|
|
153
|
-
'
|
|
154
|
-
'
|
|
155
|
-
'busy_time_ms':
|
|
156
|
-
'
|
|
157
|
-
'busy_time_percent': (
|
|
157
|
+
'read_time_ms': aggregated_read_time,
|
|
158
|
+
'write_time_ms': aggregated_write_time,
|
|
159
|
+
'read_time_in_sec': aggregated_read_time_per_sec,
|
|
160
|
+
'write_time_in_sec': aggregated_write_time_per_sec,
|
|
161
|
+
'busy_time_ms': aggregated_read_time + aggregated_write_time,
|
|
162
|
+
'busy_time_in_sec': aggregated_read_time_per_sec + aggregated_write_time_per_sec,
|
|
163
|
+
'busy_time_percent': (aggregated_read_time + aggregated_write_time) / 1000 / interval
|
|
158
164
|
})
|
|
159
165
|
|
|
160
166
|
return io_change
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: atomicshop
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.5
|
|
4
4
|
Summary: Atomic functions and classes to make developer life easier
|
|
5
5
|
Author: Denis Kras
|
|
6
6
|
License: MIT License
|
|
@@ -52,6 +52,7 @@ Requires-Dist: pyopenssl
|
|
|
52
52
|
Requires-Dist: python-bidi
|
|
53
53
|
Requires-Dist: python-docx
|
|
54
54
|
Requires-Dist: python-magic
|
|
55
|
+
Requires-Dist: reportlab
|
|
55
56
|
Requires-Dist: SoundCard
|
|
56
57
|
Requires-Dist: soundfile
|
|
57
58
|
Requires-Dist: SpeechRecognition
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=QkIgch9FQImXtv5BITVxDWIEqyTcxufteFX_AG9NohM,122
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
|
|
4
4
|
atomicshop/appointment_management.py,sha256=N3wVGJgrqJfsj_lqiRfaL3FxMEe57by5Stzanh189mk,7263
|
|
@@ -36,7 +36,7 @@ atomicshop/sound.py,sha256=KSzWRF8dkpEVXmFidIv-Eftc3kET-hQzQOxZRE7rMto,24297
|
|
|
36
36
|
atomicshop/speech_recognize.py,sha256=55-dIjgkpF93mvJnJuxSFuft5H5eRvGNlUj9BeIOZxk,5903
|
|
37
37
|
atomicshop/ssh_remote.py,sha256=Sas3nrQv8ardxR51t59xZZsYm8nvUcA7tMSqEDViRLk,17155
|
|
38
38
|
atomicshop/sys_functions.py,sha256=MTBxRve5bh58SPvhX3gMiGqHlSBuI_rdNN1NnnBBWqI,906
|
|
39
|
-
atomicshop/system_resource_monitor.py,sha256=
|
|
39
|
+
atomicshop/system_resource_monitor.py,sha256=rQrY_iSNYisRXOXcCwykUxj937jCqeg-dDOF_ETO_0I,13626
|
|
40
40
|
atomicshop/system_resources.py,sha256=BndRa6qgHAe4vzhQYWKfhQIuw3WwnwgJ8Etda4i1914,8059
|
|
41
41
|
atomicshop/tempfiles.py,sha256=uq1ve2WlWehZ3NOTXJnpBBMt6HyCdBufqedF0HyzA6k,2517
|
|
42
42
|
atomicshop/timer.py,sha256=KxBBgVM8po6pUJDW8TgY1UXj0iiDmRmL5XDCq0VHAfU,1670
|
|
@@ -73,7 +73,7 @@ atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX
|
|
|
73
73
|
atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
|
|
74
74
|
atomicshop/basics/booleans.py,sha256=-4JnSQ1pSb6CNY_62wtHBW8NltjPJEKM-gYOxFujunA,1772
|
|
75
75
|
atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
|
|
76
|
-
atomicshop/basics/classes.py,sha256=
|
|
76
|
+
atomicshop/basics/classes.py,sha256=EijW_g4EhdNBnKPMG3nT3HjFspTchtM7to6zm9Ad_Mk,9771
|
|
77
77
|
atomicshop/basics/dicts.py,sha256=w9_ZolDNSf2ZyoZ53zIOrFq7VZWGWYAvAvwc4qHORAo,10973
|
|
78
78
|
atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
|
|
79
79
|
atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
|
|
@@ -86,7 +86,7 @@ atomicshop/basics/isinstancing.py,sha256=fQ35xfqbguQz2BUn-3a4KVGskhTcIn8JjRtxV2r
|
|
|
86
86
|
atomicshop/basics/list_of_dicts.py,sha256=fu0H6dUD9uUo2kl7FYIrWzOQMwCmg7qRxGnFM5S319E,5716
|
|
87
87
|
atomicshop/basics/lists.py,sha256=pLpYPSu0BjJIAe_Ar55XhLsH2YBhftn7b-tTAdkK1sw,3928
|
|
88
88
|
atomicshop/basics/multiprocesses.py,sha256=AczaI4TmYduNjE6_VEQhxvDQn4VLDdXYRxhPDpjH4T0,17974
|
|
89
|
-
atomicshop/basics/numbers.py,sha256=
|
|
89
|
+
atomicshop/basics/numbers.py,sha256=j0f4glCtyIypEdCKv145F1gkzEEoZ2GdsGO-OM4BN7o,1439
|
|
90
90
|
atomicshop/basics/randoms.py,sha256=DmYLtnIhDK29tAQrGP1Nt-A-v8WC7WIEB8Edi-nk3N4,282
|
|
91
91
|
atomicshop/basics/strings.py,sha256=aQ92AJPvb3U0O6n2FMqRUqEsPCiklwGX--jPmB9M0_s,15418
|
|
92
92
|
atomicshop/basics/threads.py,sha256=xvgdDJdmgN0wmmARoZ-H7Kvl1GOcEbvgaeGL4M3Hcx8,2819
|
|
@@ -205,7 +205,7 @@ atomicshop/wrappers/playwrightw/mouse.py,sha256=-2FZbQtjgH7tdXWld6ZPGqlKFUdf5in0
|
|
|
205
205
|
atomicshop/wrappers/playwrightw/scenarios.py,sha256=Wz7aVYfG7K4fuSe_TUAc1jhFXVq5jYvZKbDtvqUiONc,5236
|
|
206
206
|
atomicshop/wrappers/playwrightw/waits.py,sha256=308fdOu6YDqQ7K7xywj7R27sSmFanPBQqpZyBC-NFmo,7015
|
|
207
207
|
atomicshop/wrappers/psutilw/cpus.py,sha256=w6LPBMINqS-T_X8vzdYkLS2Wzuve28Ydp_GafTCngrc,236
|
|
208
|
-
atomicshop/wrappers/psutilw/disks.py,sha256=
|
|
208
|
+
atomicshop/wrappers/psutilw/disks.py,sha256=3ZSVoommKH1TWo37j_83frB-NqXF4Nf5q5mBCX8G4jE,9221
|
|
209
209
|
atomicshop/wrappers/psutilw/memories.py,sha256=wpdKEkQ9Wty_r7ZJKkfli7wIHMXdQOMlmDlzmc_0FWo,161
|
|
210
210
|
atomicshop/wrappers/psutilw/psutilw.py,sha256=W9PSEZmrm_Ct_-6oKqAcbgbyF21CwcIbbHOkVqgMiow,20866
|
|
211
211
|
atomicshop/wrappers/psycopgw/psycopgw.py,sha256=XJvVf0oAUjCHkrYfKeFuGCpfn0Oxj3u4SbKMKA1508E,7118
|
|
@@ -226,8 +226,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
226
226
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
227
227
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
228
228
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
229
|
-
atomicshop-2.9.
|
|
230
|
-
atomicshop-2.9.
|
|
231
|
-
atomicshop-2.9.
|
|
232
|
-
atomicshop-2.9.
|
|
233
|
-
atomicshop-2.9.
|
|
229
|
+
atomicshop-2.9.5.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
230
|
+
atomicshop-2.9.5.dist-info/METADATA,sha256=e5PpNLxmJbvsfWIKUZsmDxPJUk3LFk6RZtaW3E3infM,10395
|
|
231
|
+
atomicshop-2.9.5.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
232
|
+
atomicshop-2.9.5.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
233
|
+
atomicshop-2.9.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|