Skip to main content

'potato_util' is collection of simple useful utils package for python.

Project description

Python Utils (potato-util)

MIT License GitHub Workflow Status GitHub release (latest SemVer) PyPI PyPI - Python Version

'potato_util' is collection of simple useful utils package for python.

✨ Features

  • Python utilities
  • Datetime utilities
  • Generator utilities
  • Sanitation utilities
  • Security utilities
  • Validation utilities
  • HTTP utilities
  • File I/O utilities
  • And more...

🛠 Installation

1. 🚧 Prerequisites

[OPTIONAL] For DEVELOPMENT environment:

2. 📥 Download or clone the repository

[TIP] Skip this step, if you're going to install the package directly from PyPi or GitHub repository.

2.1. Prepare projects directory (if not exists):

# Create projects directory:
mkdir -pv ~/workspaces/projects

# Enter into projects directory:
cd ~/workspaces/projects

2.2. Follow one of the below options [A], [B] or [C]:

OPTION A. Clone the repository:

git clone https://github.com/bybatkhuu/module-python-utils.git && \
    cd module-python-utils

OPTION B. Clone the repository (for DEVELOPMENT: git + ssh key):

git clone git@github.com:bybatkhuu/module-python-utils.git && \
    cd module-python-utils

OPTION C. Download source code:

  1. Download archived zip file from releases.
  2. Extract it into the projects directory.

3. 📦 Install the package

[NOTE] Choose one of the following methods to install the package [A ~ F]:

OPTION A. [RECOMMENDED] Install from PyPi:

pip install -U potato-util

OPTION B. Install latest version directly from GitHub repository:

pip install git+https://github.com/bybatkhuu/module-python-utils.git

OPTION C. Install from the downloaded source code:

# Install directly from the source code:
pip install .

# Or install with editable mode:
pip install -e .

OPTION D. Install for DEVELOPMENT environment:

pip install -e .[dev]

# Install pre-commit hooks:
pre-commit install

OPTION E. Install from pre-built release files:

  1. Download .whl or .tar.gz file from releases
  2. Install with pip:
# Install from .whl file:
pip install ./potato_util-[VERSION]-py3-none-any.whl

# Or install from .tar.gz file:
pip install ./potato_util-[VERSION].tar.gz

OPTION F. Copy the module into the project directory (for testing):

# Install python dependencies:
pip install -r ./requirements.txt

# Copy the module source code into the project:
cp -r ./src/potato_util [PROJECT_DIR]
# For example:
cp -r ./src/potato_util /some/path/project/

🚸 Usage/Examples

Simple

examples/simple/main.py:

#!/usr/bin/env python

# Standard libraries
import os
import sys
import logging

# Third-party libraries
from pydantic import AnyHttpUrl

# Internal modules
import potato_util
import potato_util.dt as dt_utils
import potato_util.generator as gen_utils
import potato_util.sanitizer as sanitizer_utils
import potato_util.secure as secure_utils
import potato_util.validator as validator_utils
import potato_util.http as http_utils


logger = logging.getLogger(__name__)


def main() -> None:
    _log_level = logging.INFO
    if str(os.getenv("DEBUG", "0")).lower() in ("1", "true", "t", "yes", "y"):
        _log_level = logging.DEBUG

    logging.basicConfig(
        stream=sys.stdout,
        level=_log_level,
        datefmt="%Y-%m-%d %H:%M:%S %z",
        format="[%(asctime)s | %(levelname)s | %(filename)s:%(lineno)d]: %(message)s",
    )

    # Base utils:
    logger.info("[BASE UTILITIES]")
    _dict1 = {"a": 1, "b": {"c": 2, "d": 3}, "g": [2, 3, 4]}
    _dict2 = {"b": {"c": 20, "e": 30}, "f": 40, "g": [5, 6, 7]}
    _merged_dict = potato_util.deep_merge(_dict1, _dict2)
    logger.info(f"Merged dict: {_merged_dict}")

    _camel_str = "CamelCaseString"
    _snake_str = potato_util.camel_to_snake(_camel_str)
    logger.info(f"Converted '{_camel_str}' to '{_snake_str}'")
    logger.info("-" * 80)

    # Datetime utils:
    logger.info("[DATETIME UTILITIES]")
    _now_local_dt = dt_utils.now_local_dt()
    logger.info(f"Current local datetime: {_now_local_dt}")

    _now_utc_dt = dt_utils.now_utc_dt()
    logger.info(f"Current UTC datetime: {_now_utc_dt}")

    _now_ny_dt = dt_utils.now_dt(tz="America/New_York")
    logger.info(f"Current New York datetime: {_now_ny_dt}")

    _now_ts = dt_utils.now_ts()
    logger.info(f"Current UTC timestamp (seconds): {_now_ts}")

    _now_ts_ms = dt_utils.now_ts(unit="MILLISECONDS")
    logger.info(f"Current UTC timestamp (ms): {_now_ts_ms}")

    _now_ts_micro = dt_utils.now_ts(unit="MICROSECONDS")
    logger.info(f"Current UTC timestamp (microseconds): {_now_ts_micro}")

    _now_ts_ns = dt_utils.now_ts(unit="NANOSECONDS")
    logger.info(f"Current UTC timestamp (nanoseconds): {_now_ts_ns}")

    _dt_ts = dt_utils.dt_to_ts(dt=_now_local_dt)
    logger.info(f"Converted local datetime to UTC timestamp (seconds): {_dt_ts}")

    _replaced_tz_dt = dt_utils.replace_tz(dt=_now_local_dt, tz="Asia/Ulaanbaatar")
    logger.info(f"Add or replace timezone with Asia/Ulaanbaatar: {_replaced_tz_dt}")

    _converted_dt = dt_utils.convert_tz(dt=_now_ny_dt, tz="Asia/Seoul")
    logger.info(
        f"Calculated and converted timezone from New York to Seoul: {_converted_dt}"
    )

    _dt_iso = dt_utils.dt_to_iso(dt=_now_local_dt)
    logger.info(f"Parsing datetime to ISO 8601 format string: {_dt_iso}")

    _future_dt = dt_utils.calc_future_dt(delta=3600, dt=_now_local_dt, tz="Asia/Tokyo")
    logger.info(f"Calculated future datetime after 3600 seconds in Tokyo: {_future_dt}")
    logger.info("-" * 80)

    # Generator utils:
    logger.info("[GENERATOR UTILITIES]")
    _unique_id = gen_utils.gen_unique_id(prefix="item_")
    logger.info(f"Generated unique ID based on datetime and UUIDv4: {_unique_id}")

    _random_str = gen_utils.gen_random_string(length=32, is_alphanum=False)
    logger.info(f"Generated secure random string: {_random_str}")
    logger.info("-" * 80)

    # Sanitizer utils:
    logger.info("[SANITIZER UTILITIES]")
    _raw_html = '  <script>alert("XSS Attack!");</script>  '
    _escaped_html = sanitizer_utils.escape_html(val=_raw_html)
    logger.info(f"Escaped HTML: {_escaped_html}")

    _raw_url = "https://www.example.com/search?q=potato util&body=<script>alert('Attack!')</script>&lang=한국어"
    _escaped_url = sanitizer_utils.escape_url(val=_raw_url)
    logger.info(f"Escaped URL: {_escaped_url}")

    _raw_str = "Hello@World! This is a test_string with special#chars$%&*()[]{};:'\",.<>?/\\|`~"
    _sanitized_str = sanitizer_utils.sanitize_special_chars(val=_raw_str, mode="STRICT")
    logger.info(f"Sanitized string: {_sanitized_str}")
    logger.info("-" * 80)

    # Secure utils:
    logger.info("[SECURE UTILITIES]")
    _input_str = "SensitiveInformation123!"
    _hashed_str_sha256 = secure_utils.hash_str(val=_input_str, algorithm="sha256")
    logger.info(f"SHA-256 hashed string: {_hashed_str_sha256}")
    logger.info("-" * 80)

    # Validator utils:
    logger.info("[VALIDATOR UTILITIES]")
    _is_yes_truthy = validator_utils.is_truthy(val="Yes")
    logger.info(f"Is 'Yes' truthy: {_is_yes_truthy}")
    _is_off_truthy = validator_utils.is_truthy(val="OFF")
    logger.info(f"Is 'OFF' truthy: {_is_off_truthy}")

    _is_no_falsy = validator_utils.is_falsy(val="f")
    logger.info(f"Is 'f' falsy: {_is_no_falsy}")
    _is_1_falsy = validator_utils.is_falsy(val="1")
    logger.info(f"Is '1' falsy: {_is_1_falsy}")

    _request_id = "f058ebd6-02f7-4d3f-942e-904344e8cde5"
    _is_valid_request_id = validator_utils.is_request_id(val=_request_id)
    logger.info(f"Is '{_request_id}' a valid request ID: {_is_valid_request_id}")

    _blacklist = ["hacker", "guest"]
    _input_username = "hacker"
    _is_blacklisted = validator_utils.is_blacklisted(
        val=_input_username, blacklist=_blacklist
    )
    logger.info(f"Is '{_input_username}' blacklisted: {_is_blacklisted}")

    _pattern = r"^[a-zA-Z0-9_]{3,16}$"  # Alphanumeric and underscores, 3-16 chars
    _test_username = "valid_user123"
    _is_valid_username = validator_utils.is_valid(val=_test_username, pattern=_pattern)
    logger.info(f"Is '{_test_username}' a valid username: {_is_valid_username}")

    _string_with_special_chars = "Hello@World!"
    _has_special_chars = validator_utils.has_special_chars(
        val=_string_with_special_chars, mode="STRICT"
    )
    logger.info(
        f"Does '{_string_with_special_chars}' have special chars: {_has_special_chars}"
    )
    logger.info("-" * 80)

    # HTTP utils:
    logger.info("[HTTP UTILITIES]")
    _http_status_tuple = http_utils.get_http_status(status_code=403)
    logger.info(f"HTTP status and known: {_http_status_tuple}")

    _url = AnyHttpUrl("https://www.google.com")
    _is_connectable = http_utils.is_connectable(url=_url, timeout=3, check_status=True)
    logger.info(f"Is '{_url}' connectable: {_is_connectable}")
    logger.info("-" * 80)

    return


if __name__ == "__main__":
    main()

👍


🌎 Environment Variables

.env.example:

# ENV=LOCAL
# DEBUG=false
# TZ=UTC

🧪 Running Tests

To run tests, run the following command:

# Install python test dependencies:
pip install .[test]

# Run tests:
python -m pytest -sv -o log_cli=true
# Or use the test script:
./scripts/test.sh -l -v -c

🏗️ Build Package

To build the python package, run the following command:

# Install python build dependencies:
pip install -r ./requirements/requirements.build.txt

# Build python package:
python -m build
# Or use the build script:
./scripts/build.sh

📝 Generate Docs

To build the documentation, run the following command:

# Install python documentation dependencies:
pip install -r ./requirements/requirements.docs.txt

# Serve documentation locally (for development):
mkdocs serve -a 0.0.0.0:8000
# Or use the docs script:
./scripts/docs.sh

# Or build documentation:
mkdocs build
# Or use the docs script:
./scripts/docs.sh -b

📚 Documentation


📑 References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

potato_util-0.1.0.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

potato_util-0.1.0-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file potato_util-0.1.0.tar.gz.

File metadata

  • Download URL: potato_util-0.1.0.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for potato_util-0.1.0.tar.gz
Algorithm Hash digest
SHA256 629247d0d119e307501a46d8bac51a5dc2cdba3eda56f43f3d8c6e180a70db77
MD5 1c1511cda59715a0a4f10b7045e67fed
BLAKE2b-256 58e85b403e945a0bbdf9d83979f4a066ee077f66e3b21b2c003f422f1c8d1571

See more details on using hashes here.

File details

Details for the file potato_util-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: potato_util-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for potato_util-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ec84a0a36c1a4e5d4b3491af310c0bfdff1e12176fac6f4f858dc1c522e448e9
MD5 bfb196bef320d1ef143df934649dce38
BLAKE2b-256 7e6429b5e65f8ad6aca8a1fb525b7e094d4841de1503ac73aff04d3930480954

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page