11# Potato Util (Python Utils)
22
33[ ![ MIT License] ( https://img.shields.io/badge/License-MIT-green.svg )] ( https://choosealicense.com/licenses/mit )
4- [ ![ GitHub Workflow Status] ( https://img.shields.io/github/actions/workflow/status/bybatkhuu/module. python-utils/2.build-publish.yml?logo=GitHub )] ( https://github.com/bybatkhuu/module. python-utils/actions/workflows/2.build-publish.yml )
5- [ ![ GitHub release (latest SemVer)] ( https://img.shields.io/github/v/release/bybatkhuu/module. python-utils?logo=GitHub&color=blue )] ( https://github.com/bybatkhuu/module. python-utils/releases )
4+ [ ![ GitHub Workflow Status] ( https://img.shields.io/github/actions/workflow/status/bybatkhuu/module- python-utils/2.build-publish.yml?logo=GitHub )] ( https://github.com/bybatkhuu/module- python-utils/actions/workflows/2.build-publish.yml )
5+ [ ![ GitHub release (latest SemVer)] ( https://img.shields.io/github/v/release/bybatkhuu/module- python-utils?logo=GitHub&color=blue )] ( https://github.com/bybatkhuu/module- python-utils/releases )
66
77'potato_util' is collection of simple useful utils package for python.
88
99## ✨ Features
1010
1111- Python utilities
1212- Datetime utilities
13- - File I/O utilities
14- - HTTP utilities
15- - Security utilities
13+ - Generator utilities
1614- Sanitation utilities
15+ - Security utilities
1716- Validation utilities
17+ - HTTP utilities
18+ - File I/O utilities
19+ - And more...
1820
1921---
2022
@@ -51,20 +53,20 @@ cd ~/workspaces/projects
5153** OPTION A.** Clone the repository:
5254
5355``` sh
54- git clone https://github.com/bybatkhuu/module. python-utils.git && \
55- cd module. python-utils
56+ git clone https://github.com/bybatkhuu/module- python-utils.git && \
57+ cd module- python-utils
5658```
5759
5860** OPTION B.** Clone the repository (for ** DEVELOPMENT** : git + ssh key):
5961
6062``` sh
61- git clone git@github.com:bybatkhuu/module. python-utils.git && \
62- cd module. python-utils
63+ git clone git@github.com:bybatkhuu/module- python-utils.git && \
64+ cd module- python-utils
6365```
6466
6567** OPTION C.** Download source code:
6668
67- 1 . Download archived ** zip** file from [ ** releases** ] ( https://github.com/bybatkhuu/module. python-utils/releases ) .
69+ 1 . Download archived ** zip** file from [ ** releases** ] ( https://github.com/bybatkhuu/module- python-utils/releases ) .
68702 . Extract it into the projects directory.
6971
7072### 3. 📦 Install the package
@@ -80,7 +82,7 @@ pip install -U potato-util
8082** OPTION B.** Install latest version directly from ** GitHub** repository:
8183
8284``` sh
83- pip install git+https://github.com/bybatkhuu/module. python-utils.git
85+ pip install git+https://github.com/bybatkhuu/module- python-utils.git
8486```
8587
8688** OPTION C.** Install from the downloaded ** source code** :
@@ -101,7 +103,7 @@ pip install -e .[dev]
101103
102104** OPTION E.** Install from ** pre-built release** files:
103105
104- 1 . Download ** ` .whl ` ** or ** ` .tar.gz ` ** file from [ ** releases** ] ( https://github.com/bybatkhuu/module. python-utils/releases )
106+ 1 . Download ** ` .whl ` ** or ** ` .tar.gz ` ** file from [ ** releases** ] ( https://github.com/bybatkhuu/module- python-utils/releases )
1051072 . Install with pip:
106108
107109``` sh
@@ -131,6 +133,177 @@ cp -r ./src/potato_util /some/path/project/
131133[ ** ` examples/simple/main.py ` ** ] ( ./examples/simple/main.py ) :
132134
133135``` python
136+ # !/usr/bin/env python
137+
138+ # Standard libraries
139+ import os
140+ import sys
141+ import logging
142+
143+ # Third-party libraries
144+ from pydantic import AnyHttpUrl
145+
146+ # Internal modules
147+ import potato_util
148+ import potato_util.dt as dt_utils
149+ import potato_util.generator as gen_utils
150+ import potato_util.sanitizer as sanitizer_utils
151+ import potato_util.secure as secure_utils
152+ import potato_util.validator as validator_utils
153+ import potato_util.http as http_utils
154+
155+
156+ logger = logging.getLogger(__name__ )
157+
158+
159+ def main () -> None :
160+ _log_level = logging.INFO
161+ if str (os.getenv(" DEBUG" , " 0" )).lower() in (" 1" , " true" , " t" , " yes" , " y" ):
162+ _log_level = logging.DEBUG
163+
164+ logging.basicConfig(
165+ stream = sys.stdout,
166+ level = _log_level,
167+ datefmt = " %Y-%m-%d %H:%M:%S %z" ,
168+ format = " [%(asctime)s | %(levelname)s | %(filename)s :%(lineno)d ]: %(message)s " ,
169+ )
170+
171+ # Base utils:
172+ logger.info(" [BASE UTILITIES]" )
173+ _dict1 = {" a" : 1 , " b" : {" c" : 2 , " d" : 3 }, " g" : [2 , 3 , 4 ]}
174+ _dict2 = {" b" : {" c" : 20 , " e" : 30 }, " f" : 40 , " g" : [5 , 6 , 7 ]}
175+ _merged_dict = potato_util.deep_merge(_dict1, _dict2)
176+ logger.info(f " Merged dict: { _merged_dict} " )
177+
178+ _camel_str = " CamelCaseString"
179+ _snake_str = potato_util.camel_to_snake(_camel_str)
180+ logger.info(f " Converted ' { _camel_str} ' to ' { _snake_str} ' " )
181+ logger.info(" -" * 80 )
182+
183+ # Datetime utils:
184+ logger.info(" [DATETIME UTILITIES]" )
185+ _now_local_dt = dt_utils.now_local_dt()
186+ logger.info(f " Current local datetime: { _now_local_dt} " )
187+
188+ _now_utc_dt = dt_utils.now_utc_dt()
189+ logger.info(f " Current UTC datetime: { _now_utc_dt} " )
190+
191+ _now_ny_dt = dt_utils.now_dt(tz = " America/New_York" )
192+ logger.info(f " Current New York datetime: { _now_ny_dt} " )
193+
194+ _now_ts = dt_utils.now_ts()
195+ logger.info(f " Current UTC timestamp (seconds): { _now_ts} " )
196+
197+ _now_ts_ms = dt_utils.now_ts(unit = " MILLISECONDS" )
198+ logger.info(f " Current UTC timestamp (ms): { _now_ts_ms} " )
199+
200+ _now_ts_micro = dt_utils.now_ts(unit = " MICROSECONDS" )
201+ logger.info(f " Current UTC timestamp (microseconds): { _now_ts_micro} " )
202+
203+ _now_ts_ns = dt_utils.now_ts(unit = " NANOSECONDS" )
204+ logger.info(f " Current UTC timestamp (nanoseconds): { _now_ts_ns} " )
205+
206+ _dt_ts = dt_utils.dt_to_ts(dt = _now_local_dt)
207+ logger.info(f " Converted local datetime to UTC timestamp (seconds): { _dt_ts} " )
208+
209+ _replaced_tz_dt = dt_utils.replace_tz(dt = _now_local_dt, tz = " Asia/Ulaanbaatar" )
210+ logger.info(f " Add or replace timezone with Asia/Ulaanbaatar: { _replaced_tz_dt} " )
211+
212+ _converted_dt = dt_utils.convert_tz(dt = _now_ny_dt, tz = " Asia/Seoul" )
213+ logger.info(
214+ f " Calculated and converted timezone from New York to Seoul: { _converted_dt} "
215+ )
216+
217+ _dt_iso = dt_utils.dt_to_iso(dt = _now_local_dt)
218+ logger.info(f " Parsing datetime to ISO 8601 format string: { _dt_iso} " )
219+
220+ _future_dt = dt_utils.calc_future_dt(delta = 3600 , dt = _now_local_dt, tz = " Asia/Tokyo" )
221+ logger.info(f " Calculated future datetime after 3600 seconds in Tokyo: { _future_dt} " )
222+ logger.info(" -" * 80 )
223+
224+ # Generator utils:
225+ logger.info(" [GENERATOR UTILITIES]" )
226+ _unique_id = gen_utils.gen_unique_id(prefix = " item_" )
227+ logger.info(f " Generated unique ID based on datetime and UUIDv4: { _unique_id} " )
228+
229+ _random_str = gen_utils.gen_random_string(length = 32 , is_alphanum = False )
230+ logger.info(f " Generated secure random string: { _random_str} " )
231+ logger.info(" -" * 80 )
232+
233+ # Sanitizer utils:
234+ logger.info(" [SANITIZER UTILITIES]" )
235+ _raw_html = ' <script>alert("XSS Attack!");</script> '
236+ _escaped_html = sanitizer_utils.escape_html(val = _raw_html)
237+ logger.info(f " Escaped HTML: { _escaped_html} " )
238+
239+ _raw_url = " https://www.example.com/search?q=potato util&body=<script>alert('Attack!')</script>&lang=한국어"
240+ _escaped_url = sanitizer_utils.escape_url(val = _raw_url)
241+ logger.info(f " Escaped URL: { _escaped_url} " )
242+
243+ _raw_str = " Hello@World! This is a test_string with special#chars$%&*()[]{} ;:'\" ,.<>?/\\ |`~"
244+ _sanitized_str = sanitizer_utils.sanitize_special_chars(val = _raw_str, mode = " STRICT" )
245+ logger.info(f " Sanitized string: { _sanitized_str} " )
246+ logger.info(" -" * 80 )
247+
248+ # Secure utils:
249+ logger.info(" [SECURE UTILITIES]" )
250+ _input_str = " SensitiveInformation123!"
251+ _hashed_str_sha256 = secure_utils.hash_str(val = _input_str, algorithm = " sha256" )
252+ logger.info(f " SHA-256 hashed string: { _hashed_str_sha256} " )
253+ logger.info(" -" * 80 )
254+
255+ # Validator utils:
256+ logger.info(" [VALIDATOR UTILITIES]" )
257+ _is_yes_truthy = validator_utils.is_truthy(val = " Yes" )
258+ logger.info(f " Is 'Yes' truthy: { _is_yes_truthy} " )
259+ _is_off_truthy = validator_utils.is_truthy(val = " OFF" )
260+ logger.info(f " Is 'OFF' truthy: { _is_off_truthy} " )
261+
262+ _is_no_falsy = validator_utils.is_falsy(val = " f" )
263+ logger.info(f " Is 'f' falsy: { _is_no_falsy} " )
264+ _is_1_falsy = validator_utils.is_falsy(val = " 1" )
265+ logger.info(f " Is '1' falsy: { _is_1_falsy} " )
266+
267+ _request_id = " f058ebd6-02f7-4d3f-942e-904344e8cde5"
268+ _is_valid_request_id = validator_utils.is_request_id(val = _request_id)
269+ logger.info(f " Is ' { _request_id} ' a valid request ID: { _is_valid_request_id} " )
270+
271+ _blacklist = [" hacker" , " guest" ]
272+ _input_username = " hacker"
273+ _is_blacklisted = validator_utils.is_blacklisted(
274+ val = _input_username, blacklist = _blacklist
275+ )
276+ logger.info(f " Is ' { _input_username} ' blacklisted: { _is_blacklisted} " )
277+
278+ _pattern = r " ^ [a-zA-Z0-9_ ]{3,16} $ " # Alphanumeric and underscores, 3-16 chars
279+ _test_username = " valid_user123"
280+ _is_valid_username = validator_utils.is_valid(val = _test_username, pattern = _pattern)
281+ logger.info(f " Is ' { _test_username} ' a valid username: { _is_valid_username} " )
282+
283+ _string_with_special_chars = " Hello@World!"
284+ _has_special_chars = validator_utils.has_special_chars(
285+ val = _string_with_special_chars, mode = " STRICT"
286+ )
287+ logger.info(
288+ f " Does ' { _string_with_special_chars} ' have special chars: { _has_special_chars} "
289+ )
290+ logger.info(" -" * 80 )
291+
292+ # HTTP utils:
293+ logger.info(" [HTTP UTILITIES]" )
294+ _http_status_tuple = http_utils.get_http_status(status_code = 403 )
295+ logger.info(f " HTTP status and known: { _http_status_tuple} " )
296+
297+ _url = AnyHttpUrl(" https://www.google.com" )
298+ _is_connectable = http_utils.is_connectable(url = _url, timeout = 3 , check_status = True )
299+ logger.info(f " Is ' { _url} ' connectable: { _is_connectable} " )
300+ logger.info(" -" * 80 )
301+
302+ return
303+
304+
305+ if __name__ == " __main__" :
306+ main()
134307```
135308
136309👍
0 commit comments