osbot-utils 1.81.0__py3-none-any.whl → 1.83.0__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.
@@ -1,17 +1,5 @@
1
- import gzip
2
-
3
1
  import os
4
- import glob
5
- import pickle
6
- import re
7
- import shutil
8
- import tempfile
9
- from os.path import abspath, join
10
- from pathlib import Path, PosixPath
11
- from typing import Union
12
-
13
- from osbot_utils.utils.Misc import bytes_to_base64, base64_to_bytes, random_string
14
-
2
+ from typing import Union
15
3
 
16
4
  class Files:
17
5
  @staticmethod
@@ -21,6 +9,7 @@ class Files:
21
9
 
22
10
  @staticmethod
23
11
  def copy(source:str, destination:str) -> str:
12
+ import shutil
24
13
  if file_exists(source): # make sure source file exists
25
14
  destination_parent_folder = parent_folder(destination) # get target parent folder
26
15
  folder_create(destination_parent_folder) # ensure target folder exists # todo: check if this is still needed (we should be using a copy method that creates the required fodlers)
@@ -78,10 +67,14 @@ class Files:
78
67
 
79
68
  @staticmethod
80
69
  def find(path_pattern, recursive=True):
70
+ import glob
71
+
81
72
  return glob.glob(path_pattern, recursive=recursive)
82
73
 
83
74
  @staticmethod
84
75
  def files(path, pattern= '*', only_files=True):
76
+ from pathlib import Path
77
+
85
78
  result = []
86
79
  for file in Path(path).rglob(pattern):
87
80
  if only_files and is_not_file(file):
@@ -99,6 +92,8 @@ class Files:
99
92
 
100
93
  @staticmethod
101
94
  def file_create_all_parent_folders(file_path):
95
+ from pathlib import Path
96
+
102
97
  if file_path:
103
98
  parent_path = parent_folder(file_path)
104
99
  if parent_path:
@@ -136,10 +131,14 @@ class Files:
136
131
 
137
132
  @staticmethod
138
133
  def file_to_base64(path):
134
+ from osbot_utils.utils.Misc import bytes_to_base64
135
+
139
136
  return bytes_to_base64(file_bytes(path))
140
137
 
141
138
  @staticmethod
142
139
  def file_from_base64(bytes_base64, path=None, extension=None):
140
+ from osbot_utils.utils.Misc import base64_to_bytes
141
+
143
142
  bytes_ = base64_to_bytes(bytes_base64)
144
143
  return file_create_bytes(bytes=bytes_, path=path, extension=None)
145
144
 
@@ -181,6 +180,8 @@ class Files:
181
180
 
182
181
  @staticmethod
183
182
  def folder_copy(source, destination, ignore_pattern=None):
183
+ import shutil
184
+
184
185
  if ignore_pattern:
185
186
  if type(ignore_pattern) is str:
186
187
  ignore_pattern = [ignore_pattern]
@@ -214,6 +215,8 @@ class Files:
214
215
 
215
216
  @staticmethod
216
217
  def folder_delete_all(path): # this will remove recursively
218
+ import shutil
219
+
217
220
  if folder_exists(path):
218
221
  shutil.rmtree(path)
219
222
  return folder_exists(path) is False
@@ -267,6 +270,8 @@ class Files:
267
270
 
268
271
  @staticmethod
269
272
  def is_file(target):
273
+ from pathlib import Path
274
+
270
275
  if isinstance(target, Path):
271
276
  return target.is_file()
272
277
  if type(target) is str:
@@ -276,6 +281,8 @@ class Files:
276
281
 
277
282
  @staticmethod
278
283
  def is_folder(target):
284
+ from pathlib import Path
285
+
279
286
  if isinstance(target, Path):
280
287
  return target.is_dir()
281
288
  if type(target) is str:
@@ -290,6 +297,8 @@ class Files:
290
297
 
291
298
  @staticmethod
292
299
  def lines_gz(path):
300
+ import gzip
301
+
293
302
  with gzip.open(path, "rt") as file:
294
303
  for line in file:
295
304
  yield line
@@ -304,6 +313,8 @@ class Files:
304
313
 
305
314
  @staticmethod
306
315
  def open_gz(path, mode='r'):
316
+ import gzip
317
+
307
318
  return gzip.open(path, mode=mode)
308
319
 
309
320
  @staticmethod
@@ -320,6 +331,8 @@ class Files:
320
331
  # return abspath(join(parent_path,sub_path))
321
332
 
322
333
  def path_combine(path1: Union[str, os.PathLike], path2: Union[str, os.PathLike]) -> str:
334
+ from os.path import abspath, join
335
+
323
336
  if path1 is None or path2 is None:
324
337
  raise ValueError("Both paths must be provided")
325
338
 
@@ -345,6 +358,8 @@ class Files:
345
358
 
346
359
  @staticmethod
347
360
  def pickle_save_to_file(object_to_save, path=None):
361
+ import pickle
362
+
348
363
  path = path or temp_file(extension=".pickle")
349
364
  file_to_store = open(path, "wb")
350
365
  pickle.dump(object_to_save, file_to_store)
@@ -353,6 +368,8 @@ class Files:
353
368
 
354
369
  @staticmethod
355
370
  def pickle_load_from_file(path=None):
371
+ import pickle
372
+
356
373
  file_to_read = open(path, "rb")
357
374
  loaded_object = pickle.load(file_to_read)
358
375
  file_to_read.close()
@@ -360,6 +377,8 @@ class Files:
360
377
 
361
378
  @staticmethod
362
379
  def safe_file_name(file_name):
380
+ import re
381
+
363
382
  if type(file_name) is not str:
364
383
  file_name = f"{file_name}"
365
384
  return re.sub(r'[^a-zA-Z0-9_.-]', '_',file_name or '')
@@ -388,6 +407,8 @@ class Files:
388
407
 
389
408
  @staticmethod
390
409
  def temp_file(extension = '.tmp', contents=None, target_folder=None):
410
+ import tempfile
411
+
391
412
  extension = file_extension_fix(extension)
392
413
  if target_folder is None:
393
414
  (fd, tmp_file) = tempfile.mkstemp(extension)
@@ -401,6 +422,8 @@ class Files:
401
422
 
402
423
  @staticmethod
403
424
  def temp_file_in_folder(target_folder, prefix="temp_file_", postfix='.txt'):
425
+ from osbot_utils.utils.Misc import random_string
426
+
404
427
  if is_folder(target_folder):
405
428
  path_to_file = path_combine(target_folder, random_string(prefix=prefix, postfix=postfix))
406
429
  file_create(path_to_file, random_string())
@@ -414,10 +437,14 @@ class Files:
414
437
 
415
438
  @staticmethod
416
439
  def temp_folder(prefix=None, suffix=None,target_folder=None):
440
+ import tempfile
441
+
417
442
  return tempfile.mkdtemp(suffix, prefix, target_folder)
418
443
 
419
444
  @staticmethod
420
445
  def temp_folder_current():
446
+ import tempfile
447
+
421
448
  return tempfile.gettempdir()
422
449
 
423
450
  @staticmethod
@@ -440,6 +467,8 @@ class Files:
440
467
 
441
468
  @staticmethod
442
469
  def write_gz(path=None, contents=None):
470
+ import gzip
471
+
443
472
  path = path or temp_file(extension='.gz')
444
473
  contents = contents or ''
445
474
  if type(contents) is str:
@@ -450,6 +479,8 @@ class Files:
450
479
 
451
480
  # todo: refactor the methods above into static methods (as bellow)
452
481
  def absolute_path(path):
482
+ from os.path import abspath
483
+
453
484
  return abspath(path)
454
485
 
455
486
  def all_parent_folders(path=None, include_path=False):
@@ -499,6 +530,8 @@ def files_names_in_folder(target, with_extension=False):
499
530
  return files_names_without_extension(files_in_folder(target))
500
531
 
501
532
  def files_in_folder(path,pattern='*', only_files=True):
533
+ from pathlib import Path
534
+
502
535
  result = []
503
536
  for file in Path(path).glob(pattern):
504
537
  if only_files and is_not_file(file):
osbot_utils/utils/Json.py CHANGED
@@ -1,14 +1,11 @@
1
- import json
2
- import os
3
-
4
- from osbot_utils.utils.Misc import str_lines, str_md5, str_sha256
5
- from osbot_utils.utils.Files import file_create_gz, file_create, load_file_gz, file_contents, file_lines, file_lines_gz
6
- from osbot_utils.utils.Zip import str_to_gz, gz_to_str
7
1
 
8
2
  def bytes_to_json_loads(data):
3
+ import json
9
4
  return json.loads(data.decode())
10
5
 
11
6
  def json_dumps(python_object, indent=4, pretty=True, sort_keys=False, default=str, raise_exception=False):
7
+ import json
8
+
12
9
  if python_object:
13
10
  try:
14
11
  if pretty:
@@ -25,6 +22,8 @@ def json_dumps_to_bytes(*args, **kwargs):
25
22
  return json_dumps(*args, **kwargs).encode()
26
23
 
27
24
  def json_lines_file_load(target_path):
25
+ from osbot_utils.utils.Files import file_lines
26
+
28
27
  raw_json = '[' # start the json array
29
28
  lines = file_lines(target_path) # get all lines from the file provided in target_path
30
29
  raw_json += ','.join(lines) # add lines to raw_json split by json array separator
@@ -32,6 +31,8 @@ def json_lines_file_load(target_path):
32
31
  return json_parse(raw_json) # convert json data into a python object
33
32
 
34
33
  def json_lines_file_load_gz(target_path):
34
+ from osbot_utils.utils.Files import file_lines_gz
35
+
35
36
  raw_json = '[' # start the json array
36
37
  lines = file_lines_gz(target_path) # get all lines from the file provided in target_path
37
38
  raw_json += ','.join(lines) # add lines to raw_json split by json array separator
@@ -40,14 +41,19 @@ def json_lines_file_load_gz(target_path):
40
41
 
41
42
 
42
43
  def json_sha_256(target):
44
+ from osbot_utils.utils.Misc import str_sha256
43
45
  return str_sha256(json_dumps(target))
44
46
 
45
47
 
46
48
  def json_to_gz(data):
49
+ from osbot_utils.utils.Zip import str_to_gz
47
50
  value = json_dumps(data, pretty=False)
48
51
  return str_to_gz(value)
49
52
 
50
53
  def gz_to_json(gz_data):
54
+ import json
55
+ from osbot_utils.utils.Zip import gz_to_str
56
+
51
57
  data = gz_to_str(gz_data)
52
58
  return json.loads(data)
53
59
 
@@ -62,11 +68,15 @@ class Json:
62
68
  Note: will not throw errors and will return {} as default
63
69
  errors are logged to Json.log
64
70
  """
71
+ from osbot_utils.utils.Files import file_contents
72
+
65
73
  json_data = file_contents(path)
66
74
  return json_loads(json_data)
67
75
 
68
76
  @staticmethod
69
77
  def load_file_and_delete(path):
78
+ import os
79
+
70
80
  data = json_load_file(path)
71
81
  if data:
72
82
  os.remove(path)
@@ -74,11 +84,14 @@ class Json:
74
84
 
75
85
  @staticmethod
76
86
  def load_file_gz(path):
87
+ from osbot_utils.utils.Files import load_file_gz
77
88
  data = load_file_gz(path)
78
89
  return json_loads(data)
79
90
 
80
91
  @staticmethod
81
92
  def load_file_gz_and_delete(path):
93
+ import os
94
+
82
95
  data = json_load_file_gz(path)
83
96
  if data:
84
97
  os.remove(path)
@@ -91,6 +104,8 @@ class Json:
91
104
  Note: will not throw errors and will return {} as default
92
105
  errors are logged to Json.log
93
106
  """
107
+ import json
108
+
94
109
  if json_data:
95
110
  try:
96
111
  return json.loads(json_data)
@@ -103,11 +118,15 @@ class Json:
103
118
 
104
119
  @staticmethod
105
120
  def loads_json_lines(json_lines):
121
+ from osbot_utils.utils.Misc import str_lines
122
+
106
123
  json_data = '[' + ','.join(str_lines(json_lines.strip())) + ']'
107
124
  return json_loads(json_data)
108
125
 
109
126
  @staticmethod
110
127
  def md5(data):
128
+ from osbot_utils.utils.Misc import str_md5
129
+
111
130
  return str_md5(json_dump(data))
112
131
 
113
132
  @staticmethod
@@ -116,6 +135,8 @@ class Json:
116
135
 
117
136
  @staticmethod
118
137
  def save_file(python_object, path=None, pretty=False, sort_keys=False):
138
+ from osbot_utils.utils.Files import file_create
139
+
119
140
  json_data = json_dumps(python_object=python_object, indent=2, pretty=pretty, sort_keys=sort_keys)
120
141
  return file_create(path=path, contents=json_data)
121
142
 
@@ -125,6 +146,7 @@ class Json:
125
146
 
126
147
  @staticmethod
127
148
  def save_file_gz(python_object, path=None, pretty=False):
149
+ from osbot_utils.utils.Files import file_create_gz
128
150
  json_data = json_dumps(python_object,indent=2, pretty=pretty)
129
151
  return file_create_gz(path=path, contents=json_data)
130
152
 
osbot_utils/utils/Misc.py CHANGED
@@ -1,22 +1,4 @@
1
- import base64
2
- import hashlib
3
- import importlib
4
- import logging
5
- import os
6
- import random
7
- import string
8
1
  import sys
9
- import textwrap
10
- import re
11
- import threading
12
- import uuid
13
- import warnings
14
- from datetime import datetime, timedelta
15
- from secrets import token_bytes
16
- from time import sleep
17
- from typing import Iterable
18
- from urllib.parse import quote_plus, unquote_plus
19
-
20
2
 
21
3
  if sys.version_info >= (3, 11):
22
4
  from datetime import UTC
@@ -28,21 +10,26 @@ def append_random_string(target, length=6, prefix='-'):
28
10
  return f'{target}{random_string(length, prefix)}'
29
11
 
30
12
  def attr_value_from_module_name(module_name, attr_name, default_value=None):
13
+ import importlib
31
14
  module = importlib.import_module(module_name)
32
15
  if hasattr(module, attr_name):
33
16
  return getattr(module, attr_name)
34
17
  return default_value
35
18
 
36
19
  def bytes_md5(target : bytes):
20
+ import hashlib
37
21
  return hashlib.md5(target).hexdigest()
38
22
 
39
23
  def bytes_sha256(target : bytes):
24
+ import hashlib
40
25
  return hashlib.sha256(target).hexdigest()
41
26
 
42
27
  def bytes_sha384(target : bytes):
28
+ import hashlib
43
29
  return hashlib.sha384(target).hexdigest()
44
30
 
45
31
  def base64_to_bytes(bytes_base64):
32
+ import base64
46
33
  if type(bytes_base64) is str:
47
34
  bytes_base64 = bytes_base64.encode()
48
35
  return base64.decodebytes(bytes_base64)
@@ -51,12 +38,14 @@ def base64_to_str(target, encoding='ascii'):
51
38
  return bytes_to_str(base64_to_bytes(target), encoding=encoding)
52
39
 
53
40
  def bytes_to_base64(target):
41
+ import base64
54
42
  return base64.b64encode(target).decode()
55
43
 
56
44
  def bytes_to_str(target, encoding='ascii'):
57
45
  return target.decode(encoding=encoding)
58
46
 
59
47
  def convert_to_number(value):
48
+ import re
60
49
  if value:
61
50
  try:
62
51
  if value[0] in ['£','$','€']:
@@ -69,10 +58,12 @@ def convert_to_number(value):
69
58
  return 0
70
59
 
71
60
  def current_thread_id():
61
+ import threading
72
62
  return threading.current_thread().native_id
73
63
 
74
64
 
75
65
  def date_time_from_to_str(date_time_str, format_from, format_to, print_conversion_error=False):
66
+ from datetime import datetime
76
67
  try:
77
68
  date_time = datetime.strptime(date_time_str, format_from)
78
69
  return date_time.strftime(format_to)
@@ -96,10 +87,9 @@ def date_now(use_utc=True, return_str=True):
96
87
  return value
97
88
 
98
89
  def date_time_now(use_utc=True, return_str=True, milliseconds_numbers=0, date_time_format='%Y-%m-%d %H:%M:%S.%f'):
90
+ from datetime import datetime
99
91
  if use_utc:
100
92
  value = datetime.now(UTC)
101
- #value = datetime.utcnow() # todo: this has been marked for depreciation in python 11
102
- # value = datetime.now(UTC) # but this doesn't seem to work in python 10.x : E ImportError: cannot import name 'UTC' from 'datetime' (/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/datetime.py)
103
93
 
104
94
  else:
105
95
  value = datetime.now()
@@ -107,18 +97,18 @@ def date_time_now(use_utc=True, return_str=True, milliseconds_numbers=0, date_ti
107
97
  return date_time_to_str(value, milliseconds_numbers=milliseconds_numbers, date_time_format=date_time_format)
108
98
  return value
109
99
 
110
- # def date_time_parse(value):
111
- # if type(value) is datetime:
112
- # return value
113
- # return parser.parse(value)
114
100
 
115
101
  def date_time_less_time_delta(date_time, days=0, hours=0, minutes=0, seconds=0, date_time_format='%Y-%m-%d %H:%M:%S' , return_str=True):
102
+ from datetime import timedelta
103
+
116
104
  new_date_time = date_time - timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
117
105
  if return_str:
118
106
  return date_time_to_str(new_date_time, date_time_format=date_time_format)
119
107
  return new_date_time
120
108
 
121
109
  def date_time_now_less_time_delta(days=0,hours=0, minutes=0, seconds=0, date_time_format='%Y-%m-%d %H:%M:%S', return_str=True):
110
+ from datetime import datetime
111
+
122
112
  return date_time_less_time_delta(datetime.now(UTC),days=days, hours=hours, minutes=minutes, seconds=seconds,date_time_format=date_time_format, return_str=return_str)
123
113
 
124
114
  def date_to_str(date, date_format='%Y-%m-%d'):
@@ -181,6 +171,7 @@ def is_float(value):
181
171
  return False
182
172
 
183
173
  def is_guid(value):
174
+ import uuid
184
175
  try:
185
176
  uuid_obj = uuid.UUID(value)
186
177
  return str(uuid_obj) == value.lower()
@@ -189,6 +180,7 @@ def is_guid(value):
189
180
 
190
181
 
191
182
  def ignore_warning__unclosed_ssl():
183
+ import warnings
192
184
  warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*<ssl.SSLSocket.*>")
193
185
 
194
186
 
@@ -213,15 +205,18 @@ def log_to_file(level="INFO"):
213
205
  return logger_add_handler__file()
214
206
 
215
207
  def logger():
208
+ import logging
216
209
  return logging.getLogger()
217
210
 
218
211
  def logger_add_handler(handler):
219
212
  logger().addHandler(handler)
220
213
 
221
214
  def logger_add_handler__console():
215
+ import logging
222
216
  logger_add_handler(logging.StreamHandler())
223
217
 
224
218
  def logger_add_handler__file(log_file=None):
219
+ import logging
225
220
  from osbot_utils.utils.Files import temp_file
226
221
  log_file = log_file or temp_file(extension=".log")
227
222
  logger_add_handler(logging.FileHandler(filename=log_file))
@@ -275,6 +270,8 @@ def str_sha384(text:str):
275
270
  return
276
271
 
277
272
  def str_sha384_as_base64(text:str, include_prefix=True):
273
+ import hashlib
274
+ import base64
278
275
  if type(text) is str:
279
276
  hash_object = hashlib.sha384(text.encode())
280
277
  digest = hash_object.digest() # Getting the digest of the hash
@@ -306,6 +303,8 @@ def time_delta_in_days_hours_or_minutes(time_delta):
306
303
 
307
304
 
308
305
  def time_now(use_utc=True, milliseconds_numbers=1):
306
+ from datetime import datetime
307
+
309
308
  if use_utc:
310
309
  datetime_now = datetime.now(UTC)
311
310
  else:
@@ -317,6 +316,8 @@ def time_to_str(datetime_value, time_format='%H:%M:%S.%f', milliseconds_numbers=
317
316
  return time_str_milliseconds(datetime_str=time_str, datetime_format=time_format, milliseconds_numbers=milliseconds_numbers)
318
317
 
319
318
  def timestamp_utc_now():
319
+ from datetime import datetime
320
+
320
321
  return int(datetime.now(UTC).timestamp() * 1000)
321
322
 
322
323
  def timestamp_utc_now_less_delta(days=0,hours=0, minutes=0, seconds=0):
@@ -327,6 +328,8 @@ def datetime_to_timestamp(datetime):
327
328
  return int(datetime.timestamp() * 1000)
328
329
 
329
330
  def timestamp_to_datetime(timestamp):
331
+ from datetime import datetime
332
+
330
333
  timestamp = float(timestamp) # handle cases when timestamp is a Decimal
331
334
  return datetime.fromtimestamp(timestamp/1000)
332
335
 
@@ -346,9 +349,13 @@ def to_string(target):
346
349
  return ''
347
350
 
348
351
  def random_bytes(length=24):
352
+ from secrets import token_bytes
349
353
  return token_bytes(length)
350
354
 
351
355
  def random_filename(extension='.tmp', length=10):
356
+ import random
357
+ import string
358
+
352
359
  from osbot_utils.utils.Files import file_extension_fix
353
360
  extension = file_extension_fix(extension)
354
361
  return '{0}{1}'.format(''.join(random.choices(string.ascii_lowercase + string.digits, k=length)) , extension)
@@ -357,9 +364,12 @@ def random_port(min=20000,max=65000):
357
364
  return random_number(min, max)
358
365
 
359
366
  def random_number(min=1,max=65000):
367
+ import random
360
368
  return random.randint(min, max)
361
369
 
362
370
  def random_password(length=24, prefix=''):
371
+ import random
372
+ import string
363
373
  password = prefix + ''.join(random.choices(string.ascii_lowercase +
364
374
  string.ascii_uppercase +
365
375
  string.punctuation +
@@ -372,6 +382,10 @@ def random_password(length=24, prefix=''):
372
382
  return password
373
383
 
374
384
  def random_string(length:int=8, prefix:str='', postfix:str=''):
385
+ import string
386
+
387
+ import random
388
+
375
389
  if is_int(length):
376
390
  length -= 1 # so that we get the exact length when the value is provided
377
391
  else:
@@ -383,6 +397,9 @@ def random_string_short(prefix:str = None):
383
397
  return random_id(prefix=prefix, length=6).lower()
384
398
 
385
399
  def random_string_and_numbers(length:int=6,prefix:str=''):
400
+ import random
401
+ import string
402
+
386
403
  return prefix + ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
387
404
 
388
405
  def random_text(prefix:str=None,length:int=12, lowercase=False):
@@ -395,21 +412,27 @@ def random_text(prefix:str=None,length:int=12, lowercase=False):
395
412
  return value
396
413
 
397
414
  def random_uuid():
415
+ import uuid
398
416
  return str(uuid.uuid4())
399
417
 
400
418
  def random_uuid_short():
419
+ import uuid
401
420
  return str(uuid.uuid4())[0:6]
402
421
 
403
422
  def remove(target_string, string_to_remove): # todo: refactor to str_*
404
423
  return replace(target_string, string_to_remove, '')
405
424
 
406
425
  def remove_multiple_spaces(target): # todo: refactor to str_*
426
+ import re
427
+
407
428
  return re.sub(' +', ' ', target)
408
429
 
409
430
  def replace(target_string, string_to_find, string_to_replace): # todo: refactor to str_*
410
431
  return target_string.replace(string_to_find, string_to_replace)
411
432
 
412
433
  def remove_html_tags(html):
434
+ import re
435
+
413
436
  if html:
414
437
  TAG_RE = re.compile(r'<[^>]+>')
415
438
  return TAG_RE.sub('', html).replace('&nbsp;', ' ')
@@ -420,8 +443,9 @@ def split_lines(text):
420
443
  def split_spaces(target):
421
444
  return remove_multiple_spaces(target).split(' ')
422
445
 
423
- def sorted_set(target : Iterable):
424
- if target:
446
+ def sorted_set(target):
447
+ from typing import Iterable
448
+ if isinstance(target, Iterable) and target:
425
449
  return sorted(set(target))
426
450
  return []
427
451
 
@@ -437,9 +461,13 @@ def str_to_bool(value):
437
461
  return False
438
462
 
439
463
  def str_to_date(str_date, format='%Y-%m-%d %H:%M:%S.%f'):
464
+ from datetime import datetime
465
+
440
466
  return datetime.strptime(str_date,format)
441
467
 
442
468
  def str_to_date_time(str_date, format='%Y-%m-%d %H:%M:%S'):
469
+ from datetime import datetime
470
+
443
471
  return datetime.strptime(str_date,format)
444
472
 
445
473
  def str_to_int(str_data):
@@ -457,14 +485,18 @@ def under_debugger():
457
485
 
458
486
 
459
487
  def url_encode(data):
488
+ from urllib.parse import quote_plus
460
489
  if type(data) is str:
461
490
  return quote_plus(data)
462
491
 
463
492
  def url_decode(data):
493
+ from urllib.parse import unquote_plus
464
494
  if type(data) is str:
465
495
  return unquote_plus(data)
466
496
 
467
497
  def utc_now():
498
+ from datetime import datetime
499
+
468
500
  return datetime.now(UTC)
469
501
 
470
502
  def upper(target : str):
@@ -473,10 +505,13 @@ def upper(target : str):
473
505
  return ""
474
506
 
475
507
  def wait(seconds):
508
+ from time import sleep
509
+
476
510
  if seconds and seconds > 0:
477
511
  sleep(seconds)
478
512
 
479
513
  def word_wrap(text,length = 40):
514
+ import textwrap
480
515
  if text:
481
516
  wrapped_text = ""
482
517
  for line in text.splitlines(): # handle case when there are newlines inside the text value
@@ -486,6 +521,7 @@ def word_wrap(text,length = 40):
486
521
  return ''
487
522
 
488
523
  def word_wrap_escaped(text,length = 40):
524
+ import textwrap
489
525
  if text:
490
526
  return '\\n'.join(textwrap.wrap(text, length))
491
527