potato-util 0.0.2__py3-none-any.whl → 0.0.3__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.
potato_util/__init__.py CHANGED
@@ -1,6 +1,4 @@
1
- from .__version__ import __version__
2
-
1
+ # flake8: noqa
3
2
 
4
- __all__ = [
5
- "__version__",
6
- ]
3
+ from .__version__ import __version__
4
+ from ._base import *
@@ -1 +1 @@
1
- __version__ = "0.0.2"
1
+ __version__ = "0.0.3"
potato_util/_base.py CHANGED
@@ -51,67 +51,7 @@ def camel_to_snake(val: str) -> str:
51
51
  return val
52
52
 
53
53
 
54
- @validate_call
55
- def clean_obj_dict(obj_dict: dict, cls_name: str) -> dict:
56
- """Clean class name from object.__dict__ for str(object).
57
-
58
- Args:
59
- obj_dict (dict, required): Object dictionary by object.__dict__.
60
- cls_name (str , required): Class name by cls.__name__.
61
-
62
- Returns:
63
- dict: Clean object dictionary.
64
- """
65
-
66
- try:
67
- if not obj_dict:
68
- raise ValueError("'obj_dict' argument value is empty!")
69
-
70
- if not cls_name:
71
- raise ValueError("'cls_name' argument value is empty!")
72
- except ValueError as err:
73
- logger.error(err)
74
- raise
75
-
76
- _self_dict = obj_dict.copy()
77
- for _key in _self_dict.copy():
78
- _class_prefix = f"_{cls_name}__"
79
- if _key.startswith(_class_prefix):
80
- _new_key = _key.replace(_class_prefix, "")
81
- _self_dict[_new_key] = _self_dict.pop(_key)
82
- return _self_dict
83
-
84
-
85
- @validate_call(config={"arbitrary_types_allowed": True})
86
- def obj_to_repr(obj: object) -> str:
87
- """Modifying object default repr() to custom info.
88
-
89
- Args:
90
- obj (object, required): Any python object.
91
-
92
- Returns:
93
- str: String for repr() method.
94
- """
95
-
96
- try:
97
- if not obj:
98
- raise ValueError("'obj' argument value is empty!")
99
- except ValueError as err:
100
- logger.error(err)
101
- raise
102
-
103
- _self_repr = (
104
- f"<{obj.__class__.__module__}.{obj.__class__.__name__} object at {hex(id(obj))}: "
105
- + "{"
106
- + f"{str(dir(obj)).replace('[', '').replace(']', '')}"
107
- + "}>"
108
- )
109
- return _self_repr
110
-
111
-
112
54
  __all__ = [
113
55
  "deep_merge",
114
56
  "camel_to_snake",
115
- "clean_obj_dict",
116
- "obj_to_repr",
117
57
  ]
potato_util/dt.py CHANGED
@@ -11,13 +11,55 @@ from .constants import WarnEnum, TSUnitEnum
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
+ def now_local_dt() -> datetime:
15
+ """Get current datetime in local timezone with tzinfo.
16
+
17
+ Returns:
18
+ datetime: Current datetime in local timezone with tzinfo.
19
+ """
20
+
21
+ _local_dt = datetime.now().astimezone()
22
+ return _local_dt
23
+
24
+
25
+ def now_utc_dt() -> datetime:
26
+ """Get current datetime in UTC timezone with tzinfo.
27
+
28
+ Returns:
29
+ datetime: Current datetime in UTC timezone with tzinfo.
30
+ """
31
+
32
+ _utc_dt = datetime.now(tz=timezone.utc)
33
+ return _utc_dt
34
+
35
+
36
+ @validate_call(config={"arbitrary_types_allowed": True})
37
+ def now_dt(tz: ZoneInfo | tzinfo | str | None = None) -> datetime:
38
+ """Get current datetime in specified timezone with tzinfo.
39
+
40
+ Args:
41
+ tz (ZoneInfo | tzinfo | str | None, optional): Timezone info. Defaults to None (UTC timezone).
42
+
43
+ Returns:
44
+ datetime: Current datetime in specified timezone with tzinfo.
45
+ """
46
+
47
+ _dt = now_utc_dt()
48
+ if tz:
49
+ _dt = convert_tz(dt=_dt, tz=tz)
50
+ return _dt
51
+
52
+
14
53
  @validate_call(config={"arbitrary_types_allowed": True})
15
- def add_tzinfo(dt: datetime, tz: ZoneInfo | tzinfo | str) -> datetime:
54
+ def replace_tz(dt: datetime, tz: ZoneInfo | tzinfo | str) -> datetime:
16
55
  """Add or replace timezone info to datetime object.
17
56
 
18
57
  Args:
19
- dt (datetime , required): Datetime object.
20
- tz (Union[ZoneInfo, tzinfo, str], required): Timezone info.
58
+ dt (datetime , required): Datetime object.
59
+ tz (ZoneInfo | tzinfo | str, required): Timezone info.
60
+
61
+ Raises:
62
+ ZoneInfoNotFoundError: If `tz` argument value is invalid.
21
63
 
22
64
  Returns:
23
65
  datetime: Datetime object with timezone info.
@@ -30,30 +72,29 @@ def add_tzinfo(dt: datetime, tz: ZoneInfo | tzinfo | str) -> datetime:
30
72
  return dt
31
73
 
32
74
 
33
- @validate_call
34
- def datetime_to_iso(
35
- dt: datetime, sep: str = "T", warn_mode: WarnEnum = WarnEnum.IGNORE
36
- ) -> str:
37
- """Convert datetime object to ISO 8601 format.
75
+ @validate_call(config={"arbitrary_types_allowed": True})
76
+ def convert_tz(
77
+ dt: datetime,
78
+ tz: ZoneInfo | tzinfo | str,
79
+ warn_mode: WarnEnum | str = WarnEnum.ALWAYS,
80
+ ) -> datetime:
81
+ """Convert datetime object to another timezone.
38
82
 
39
83
  Args:
40
- dt (datetime, required): Datetime object.
41
- sep (str , optional): Separator between date and time. Defaults to "T".
42
- warn_mode (WarnEnum, optional): Warning mode. Defaults to WarnEnum.IGNORE.
84
+ dt (datetime , required): Datetime object to convert.
85
+ tz (ZoneInfo | tzinfo | str, required): Timezone info to convert.
86
+ warn_mode (WarnEnum | str , optional): Warning mode. Defaults to WarnEnum.ALWAYS.
43
87
 
44
88
  Raises:
45
- ValueError: If `sep` argument length is greater than 8.
46
89
  ValueError: If `dt` argument doesn't have any timezone info and `warn_mode` is set to WarnEnum.ERROR.
90
+ ValueError: If `warn_mode` argument value is invalid.
47
91
 
48
92
  Returns:
49
- str: Datetime string in ISO 8601 format.
93
+ datetime: Datetime object which has been converted to another timezone.
50
94
  """
51
95
 
52
- sep = sep.strip()
53
- if 8 < len(sep):
54
- raise ValueError(
55
- f"`sep` argument length '{len(sep)}' is too long, must be less than or equal to 8!"
56
- )
96
+ if isinstance(warn_mode, str):
97
+ warn_mode = WarnEnum(warn_mode.strip().upper())
57
98
 
58
99
  if not dt.tzinfo:
59
100
  _message = "Not found any timezone info in `dt` argument, assuming it's UTC timezone..."
@@ -66,30 +107,44 @@ def datetime_to_iso(
66
107
  logger.error(_message)
67
108
  raise ValueError(_message)
68
109
 
69
- dt = add_tzinfo(dt=dt, tz="UTC")
110
+ dt = replace_tz(dt=dt, tz="UTC")
70
111
 
71
- _dt_str = dt.isoformat(sep=sep, timespec="milliseconds")
72
- return _dt_str
112
+ if isinstance(tz, str):
113
+ tz = ZoneInfo(tz)
73
114
 
115
+ dt = dt.astimezone(tz=tz)
116
+ return dt
74
117
 
75
- @validate_call(config={"arbitrary_types_allowed": True})
76
- def convert_tz(
77
- dt: datetime, tz: ZoneInfo | tzinfo | str, warn_mode: WarnEnum = WarnEnum.ALWAYS
78
- ) -> datetime:
79
- """Convert datetime object to another timezone.
118
+
119
+ @validate_call
120
+ def dt_to_iso(
121
+ dt: datetime, sep: str = "T", warn_mode: WarnEnum | str = WarnEnum.IGNORE
122
+ ) -> str:
123
+ """Convert datetime object to ISO 8601 format.
80
124
 
81
125
  Args:
82
- dt (datetime , required): Datetime object to convert.
83
- tz (Union[ZoneInfo, tzinfo, str], required): Timezone info to convert.
84
- warn_mode (WarnEnum , optional): Warning mode. Defaults to WarnEnum.ALWAYS.
126
+ dt (datetime , required): Datetime object.
127
+ sep (str , optional): Separator between date and time. Defaults to "T".
128
+ warn_mode (WarnEnum | str, optional): Warning mode. Defaults to WarnEnum.IGNORE.
85
129
 
86
130
  Raises:
87
131
  ValueError: If `dt` argument doesn't have any timezone info and `warn_mode` is set to WarnEnum.ERROR.
132
+ ValueError: If `sep` argument length is greater than 8.
133
+ ValueError: If `warn_mode` argument value is invalid.
88
134
 
89
135
  Returns:
90
- datetime: Datetime object which has been converted to another timezone.
136
+ str: Datetime string in ISO 8601 format.
91
137
  """
92
138
 
139
+ sep = sep.strip()
140
+ if 8 < len(sep):
141
+ raise ValueError(
142
+ f"`sep` argument length '{len(sep)}' is too long, must be less than or equal to 8!"
143
+ )
144
+
145
+ if isinstance(warn_mode, str):
146
+ warn_mode = WarnEnum(warn_mode.strip().upper())
147
+
93
148
  if not dt.tzinfo:
94
149
  _message = "Not found any timezone info in `dt` argument, assuming it's UTC timezone..."
95
150
  if warn_mode == WarnEnum.ALWAYS:
@@ -101,59 +156,51 @@ def convert_tz(
101
156
  logger.error(_message)
102
157
  raise ValueError(_message)
103
158
 
104
- dt = add_tzinfo(dt=dt, tz="UTC")
159
+ dt = replace_tz(dt=dt, tz="UTC")
105
160
 
106
- if isinstance(tz, str):
107
- tz = ZoneInfo(tz)
108
-
109
- dt = dt.astimezone(tz=tz)
110
- return dt
111
-
112
-
113
- def now_utc_dt() -> datetime:
114
- """Get current datetime in UTC timezone with tzinfo.
115
-
116
- Returns:
117
- datetime: Current datetime in UTC timezone with tzinfo.
118
- """
161
+ _dt_str = dt.isoformat(sep=sep, timespec="milliseconds")
162
+ return _dt_str
119
163
 
120
- _utc_dt = datetime.now(tz=timezone.utc)
121
- return _utc_dt
122
164
 
165
+ @validate_call(config={"arbitrary_types_allowed": True})
166
+ def calc_future_dt(
167
+ delta: timedelta | int,
168
+ dt: datetime | None = None,
169
+ tz: ZoneInfo | tzinfo | str | None = None,
170
+ ) -> datetime:
171
+ """Calculate future datetime by adding delta time to current or specified datetime.
123
172
 
124
- def now_local_dt() -> datetime:
125
- """Get current datetime in local timezone with tzinfo.
173
+ Args:
174
+ delta (timedelta | int , required): Delta time to add to current or specified datetime.
175
+ dt (datetime | None , optional): Datetime before adding delta time. Defaults to None.
176
+ tz (ZoneInfo | tzinfo, str, None, optional): Timezone info. Defaults to None.
126
177
 
127
178
  Returns:
128
- datetime: Current datetime in local timezone with tzinfo.
179
+ datetime: Calculated future datetime.
129
180
  """
130
181
 
131
- _local_dt = datetime.now().astimezone()
132
- return _local_dt
133
-
134
-
135
- @validate_call(config={"arbitrary_types_allowed": True})
136
- def now_dt(tz: ZoneInfo | tzinfo | str) -> datetime:
137
- """Get current datetime in specified timezone with tzinfo.
182
+ if not dt:
183
+ dt = now_utc_dt()
138
184
 
139
- Args:
140
- tz (Union[ZoneInfo, tzinfo, str], required): Timezone info.
185
+ if tz:
186
+ dt = convert_tz(dt=dt, tz=tz)
141
187
 
142
- Returns:
143
- datetime: Current datetime in specified timezone with tzinfo.
144
- """
188
+ if isinstance(delta, int):
189
+ delta = timedelta(seconds=delta)
145
190
 
146
- _dt = now_utc_dt()
147
- _dt = convert_tz(dt=_dt, tz=tz)
148
- return _dt
191
+ _future_dt = dt + delta
192
+ return _future_dt
149
193
 
150
194
 
151
195
  @validate_call
152
- def now_ts(unit: TSUnitEnum = TSUnitEnum.SECONDS) -> int:
196
+ def now_ts(unit: TSUnitEnum | str = TSUnitEnum.SECONDS) -> int:
153
197
  """Get current timestamp in UTC timezone.
154
198
 
155
199
  Args:
156
- unit (TSUnitEnum, optional): Type of timestamp unit. Defaults to `TSUnitEnum.SECONDS`.
200
+ unit (TSUnitEnum | str, optional): Type of timestamp unit. Defaults to TSUnitEnum.SECONDS.
201
+
202
+ Raises:
203
+ ValueError: If `unit` argument value is invalid.
157
204
 
158
205
  Returns:
159
206
  int: Current timestamp.
@@ -168,17 +215,22 @@ def now_ts(unit: TSUnitEnum = TSUnitEnum.SECONDS) -> int:
168
215
  _now_ts = int(time.time_ns() / 1000)
169
216
  elif unit == TSUnitEnum.NANOSECONDS:
170
217
  _now_ts = int(time.time_ns())
218
+ else:
219
+ raise ValueError(f"`unit` argument value '{unit}' is invalid!")
171
220
 
172
221
  return _now_ts
173
222
 
174
223
 
175
224
  @validate_call
176
- def convert_ts(dt: datetime, unit: TSUnitEnum = TSUnitEnum.SECONDS) -> int:
225
+ def dt_to_ts(dt: datetime, unit: TSUnitEnum | str = TSUnitEnum.SECONDS) -> int:
177
226
  """Convert datetime to timestamp.
178
227
 
179
228
  Args:
180
- dt (datetime , required): Datetime object to convert.
181
- unit (TSUnitEnum, optional): Type of timestamp unit. Defaults to `TSUnitEnum.SECONDS`.
229
+ dt (datetime , required): Datetime object to convert.
230
+ unit (TSUnitEnum | str, optional): Type of timestamp unit. Defaults to `TSUnitEnum.SECONDS`.
231
+
232
+ Raises:
233
+ ValueError: If `unit` argument value is invalid.
182
234
 
183
235
  Returns:
184
236
  int: Converted timestamp.
@@ -193,48 +245,20 @@ def convert_ts(dt: datetime, unit: TSUnitEnum = TSUnitEnum.SECONDS) -> int:
193
245
  _ts = int(dt.timestamp() * 1000000)
194
246
  elif unit == TSUnitEnum.NANOSECONDS:
195
247
  _ts = int(dt.timestamp() * 1000000000)
248
+ else:
249
+ raise ValueError(f"`unit` argument value '{unit}' is invalid!")
196
250
 
197
251
  return _ts
198
252
 
199
253
 
200
- @validate_call(config={"arbitrary_types_allowed": True})
201
- def calc_future_dt(
202
- delta: timedelta | int,
203
- dt: datetime | None = None,
204
- tz: ZoneInfo | tzinfo | str | None = None,
205
- ) -> datetime:
206
- """Calculate future datetime by adding delta time to current or specified datetime.
207
-
208
- Args:
209
- delta (Union[timedelta, int] , required): Delta time to add to current or specified datetime.
210
- dt (Optional[datetime] , optional): Datetime before adding delta time. Defaults to None.
211
- tz (Union[ZoneInfo, tzinfo, str, None], optional): Timezone info. Defaults to None.
212
-
213
- Returns:
214
- datetime: Calculated future datetime.
215
- """
216
-
217
- if not dt:
218
- dt = now_utc_dt()
219
-
220
- if tz:
221
- dt = convert_tz(dt=dt, tz=tz)
222
-
223
- if isinstance(delta, int):
224
- delta = timedelta(seconds=delta)
225
-
226
- _future_dt = dt + delta
227
- return _future_dt
228
-
229
-
230
254
  __all__ = [
231
- "add_tzinfo",
232
- "datetime_to_iso",
233
- "convert_tz",
234
255
  "now_utc_dt",
235
256
  "now_local_dt",
236
257
  "now_dt",
237
- "now_ts",
238
- "convert_ts",
258
+ "replace_tz",
259
+ "convert_tz",
260
+ "dt_to_iso",
239
261
  "calc_future_dt",
262
+ "now_ts",
263
+ "dt_to_ts",
240
264
  ]
@@ -0,0 +1,65 @@
1
+ import uuid
2
+ import string
3
+ import secrets
4
+
5
+ from pydantic import validate_call
6
+
7
+ from .dt import now_ts
8
+
9
+
10
+ @validate_call
11
+ def gen_unique_id(prefix: str = "") -> str:
12
+ """Generate unique ID. Format: '{prefix}{datetime}_{uuid4}'.
13
+
14
+ Args:
15
+ prefix (str, optional): Prefix of ID. Defaults to ''.
16
+
17
+ Raises:
18
+ ValueError: If `prefix` length is greater than 32.
19
+
20
+ Returns:
21
+ str: Unique ID.
22
+ """
23
+
24
+ prefix = prefix.strip()
25
+ if 32 < len(prefix):
26
+ raise ValueError(
27
+ f"`prefix` argument length {len(prefix)} is too long, must be less than or equal to 32!",
28
+ )
29
+
30
+ _id = str(f"{prefix}{now_ts()}_{uuid.uuid4().hex}").lower()
31
+ return _id
32
+
33
+
34
+ @validate_call
35
+ def gen_random_string(length: int = 16, is_alphanum: bool = True) -> str:
36
+ """Generate secure random string.
37
+
38
+ Args:
39
+ length (int , optional): Length of random string. Defaults to 16.
40
+ is_alphanum (bool, optional): If True, generate only alphanumeric string. Defaults to True.
41
+
42
+ Raises:
43
+ ValueError: If `length` is less than 1.
44
+
45
+ Returns:
46
+ str: Generated random string.
47
+ """
48
+
49
+ if length < 1:
50
+ raise ValueError(
51
+ f"`length` argument value {length} is too small, must be greater than or equal to 1!",
52
+ )
53
+
54
+ _base_chars = string.ascii_letters + string.digits
55
+ if not is_alphanum:
56
+ _base_chars += string.punctuation
57
+
58
+ _random_str = "".join(secrets.choice(_base_chars) for _i in range(length))
59
+ return _random_str
60
+
61
+
62
+ __all__ = [
63
+ "gen_unique_id",
64
+ "gen_random_string",
65
+ ]
potato_util/http/_base.py CHANGED
@@ -34,7 +34,9 @@ def get_http_status(status_code: int) -> tuple[HTTPStatus, bool]:
34
34
  elif (500 <= status_code) and (status_code < 600):
35
35
  status_code = 500
36
36
  else:
37
- raise ValueError(f"Invalid HTTP status code: '{status_code}'!")
37
+ raise ValueError(
38
+ f"`status_code` argument value '{status_code}' is invalid, must be in range 100-599!",
39
+ )
38
40
 
39
41
  _http_status = HTTPStatus(status_code)
40
42
 
@@ -8,7 +8,7 @@ def get_relative_url(val: Request | URL) -> str:
8
8
  """Get relative url only path with query params from request object or URL object.
9
9
 
10
10
  Args:
11
- val (Union[Request, URL]): Request object or URL object to extract relative url.
11
+ val (Request | URL, required): Request object or URL object to extract relative url.
12
12
 
13
13
  Returns:
14
14
  str: Relative url only path with query params.
potato_util/io/_async.py CHANGED
@@ -14,14 +14,14 @@ logger = logging.getLogger(__name__)
14
14
 
15
15
  @validate_call
16
16
  async def async_create_dir(
17
- create_dir: str, warn_mode: WarnEnum = WarnEnum.DEBUG
17
+ create_dir: str, warn_mode: WarnEnum | str = WarnEnum.DEBUG
18
18
  ) -> None:
19
19
  """Asynchronous create directory if `create_dir` doesn't exist.
20
20
 
21
21
  Args:
22
- create_dir (str, required): Create directory path.
23
- warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
24
- Defaults to 'DEBUG'.
22
+ create_dir (str , required): Create directory path.
23
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
24
+ Defaults to 'DEBUG'.
25
25
 
26
26
  Raises:
27
27
  ValueError: If `create_dir` argument length is out of range.
@@ -36,6 +36,9 @@ async def async_create_dir(
36
36
  f"must be between 1 and {MAX_PATH_LENGTH} characters!"
37
37
  )
38
38
 
39
+ if isinstance(warn_mode, str):
40
+ warn_mode = WarnEnum(warn_mode.strip().upper())
41
+
39
42
  if not await aiofiles.os.path.isdir(create_dir):
40
43
  try:
41
44
  _message = f"Creating '{create_dir}' directory..."
@@ -66,14 +69,14 @@ async def async_create_dir(
66
69
 
67
70
  @validate_call
68
71
  async def async_remove_dir(
69
- remove_dir: str, warn_mode: WarnEnum = WarnEnum.DEBUG
72
+ remove_dir: str, warn_mode: WarnEnum | str = WarnEnum.DEBUG
70
73
  ) -> None:
71
74
  """Asynchronous remove directory if `remove_dir` exists.
72
75
 
73
76
  Args:
74
- remove_dir (str, required): Remove directory path.
75
- warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
76
- Defaults to 'DEBUG'.
77
+ remove_dir (str , required): Remove directory path.
78
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
79
+ Defaults to 'DEBUG'.
77
80
 
78
81
  Raises:
79
82
  ValueError: If `remove_dir` argument length is out of range.
@@ -88,6 +91,9 @@ async def async_remove_dir(
88
91
  f"must be between 1 and {MAX_PATH_LENGTH} characters!"
89
92
  )
90
93
 
94
+ if isinstance(warn_mode, str):
95
+ warn_mode = WarnEnum(warn_mode.strip().upper())
96
+
91
97
  if await aiofiles.os.path.isdir(remove_dir):
92
98
  try:
93
99
  _message = f"Removing '{remove_dir}' directory..."
@@ -118,14 +124,14 @@ async def async_remove_dir(
118
124
 
119
125
  @validate_call
120
126
  async def async_remove_dirs(
121
- remove_dirs: list[str], warn_mode: WarnEnum = WarnEnum.DEBUG
127
+ remove_dirs: list[str], warn_mode: WarnEnum | str = WarnEnum.DEBUG
122
128
  ) -> None:
123
129
  """Asynchronous remove directories if `remove_dirs` exists.
124
130
 
125
131
  Args:
126
- remove_dirs (List[str], required): Remove directories paths as list.
127
- warn_mode (str , optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
128
- Defaults to 'DEBUG'.
132
+ remove_dirs (list[str] , required): Remove directories paths as list.
133
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
134
+ Defaults to 'DEBUG'.
129
135
  """
130
136
 
131
137
  for _remove_dir in remove_dirs:
@@ -136,14 +142,14 @@ async def async_remove_dirs(
136
142
 
137
143
  @validate_call
138
144
  async def async_remove_file(
139
- file_path: str, warn_mode: WarnEnum = WarnEnum.DEBUG
145
+ file_path: str, warn_mode: WarnEnum | str = WarnEnum.DEBUG
140
146
  ) -> None:
141
147
  """Asynchronous remove file if `file_path` exists.
142
148
 
143
149
  Args:
144
- file_path (str, required): Remove file path.
145
- warn_mode (str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
146
- Defaults to 'DEBUG'.
150
+ file_path (str , required): Remove file path.
151
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
152
+ Defaults to 'DEBUG'.
147
153
 
148
154
  Raises:
149
155
  ValueError: If `file_path` argument length is out of range.
@@ -158,6 +164,9 @@ async def async_remove_file(
158
164
  f"must be between 1 and {MAX_PATH_LENGTH} characters!"
159
165
  )
160
166
 
167
+ if isinstance(warn_mode, str):
168
+ warn_mode = WarnEnum(warn_mode.strip().upper())
169
+
161
170
  if await aiofiles.os.path.isfile(file_path):
162
171
  try:
163
172
  _message = f"Removing '{file_path}' file..."
@@ -188,13 +197,13 @@ async def async_remove_file(
188
197
 
189
198
  @validate_call
190
199
  async def async_remove_files(
191
- file_paths: list[str], warn_mode: WarnEnum = WarnEnum.DEBUG
200
+ file_paths: list[str], warn_mode: WarnEnum | str = WarnEnum.DEBUG
192
201
  ) -> None:
193
202
  """Asynchronous remove files if `file_paths` exists.
194
203
 
195
204
  Args:
196
- file_paths (List[str], required): Remove file paths as list.
197
- warn_mode (str , optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
205
+ file_paths (list[str] , required): Remove file paths as list.
206
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
198
207
  Defaults to 'DEBUG'.
199
208
  """
200
209
 
@@ -209,15 +218,15 @@ async def async_get_file_checksum(
209
218
  file_path: str,
210
219
  hash_method: HashAlgoEnum = HashAlgoEnum.md5,
211
220
  chunk_size: int = 4096,
212
- warn_mode: WarnEnum = WarnEnum.DEBUG,
221
+ warn_mode: WarnEnum | str = WarnEnum.DEBUG,
213
222
  ) -> str | None:
214
223
  """Asynchronous get file checksum.
215
224
 
216
225
  Args:
217
- file_path (str , required): Target file path.
218
- hash_method (HashAlgoEnum, optional): Hash method. Defaults to `HashAlgoEnum.md5`.
219
- chunk_size (int , optional): Chunk size. Defaults to 4096.
220
- warn_mode (str , optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
226
+ file_path (str , required): Target file path.
227
+ hash_method (HashAlgoEnum , optional): Hash method. Defaults to `HashAlgoEnum.md5`.
228
+ chunk_size (int , optional): Chunk size. Defaults to 4096.
229
+ warn_mode (WarnEnum | str, optional): Warning message mode, for example: 'ERROR', 'ALWAYS', 'DEBUG', 'IGNORE'.
221
230
  Defaults to 'DEBUG'.
222
231
 
223
232
  Raises:
@@ -241,6 +250,9 @@ async def async_get_file_checksum(
241
250
  f"`chunk_size` argument value {chunk_size} is invalid, must be greater than 10!"
242
251
  )
243
252
 
253
+ if isinstance(warn_mode, str):
254
+ warn_mode = WarnEnum(warn_mode.strip().upper())
255
+
244
256
  _file_checksum: str | None = None
245
257
  if await aiofiles.os.path.isfile(file_path):
246
258
  _file_hash = hashlib.new(hash_method.value)