Misc Utilities

Smarter.common.utils.utils

Utility functions for the Smarter framework.

This module provides a collection of helper functions and classes that are shared across multiple Smarter base classes to keep the code DRY (Don’t Repeat Yourself). It is intended for internal use within the Smarter framework and is designed to be compatible with Python 3, Django, Django REST Framework (DRF), and Pydantic.

Functions in this module include helpers for asynchronous context detection, random hash generation, environment variable parsing, encryption key generation, and string masking.

Example usage:

from smarter.common.utils import hash_factory, bool_environment_variable

token = hash_factory(length=16)
debug_mode = bool_environment_variable('DEBUG', default=False)
smarter.common.utils.utils.bool_environment_variable(var_name, default)[source]

Retrieve a boolean value from an environment variable.

This function checks for the presence of an environment variable with the given name, or with the prefix SMARTER_ added to the name. If the variable is not set, the provided default value is returned. The value is interpreted as True if it matches any of the following (case-insensitive): “true”, “1”, “t”, “y”, or “yes”.

Parameters:
  • var_name (str) – The name of the environment variable to check.

  • default (bool) – The default boolean value to return if the environment variable is not set.

Returns:

The boolean value of the environment variable, or the default if not set.

Return type:

bool

Example usage:

from smarter.common.utils import bool_environment_variable

# Returns True if the environment variable 'DEBUG' is set to a truthy value
debug_mode = bool_environment_variable('DEBUG', default=False)
smarter.common.utils.utils.generate_fernet_encryption_key()[source]

Generates a new Fernet encryption key.

Returns:

A URL-safe base64-encoded 32-byte key suitable for use with the Fernet symmetric encryption system.

Return type:

str

Note

  • This function uses the cryptography library to generate a secure random key. The key is encoded as a UTF-8 string for easy storage and transmission.

  • The generated key is random and should be securely stored. It is essential for encrypting and decrypting data using the Fernet protocol.

Example usage:

from smarter.common.utils import generate_fernet_encryption_key

key = generate_fernet_encryption_key()
print(key)  # e.g., 'gAAAAABh...'
smarter.common.utils.utils.hash_factory(length=16)[source]

Generates a random hexadecimal hash string of the specified length.

Parameters:

length (int) – The desired length of the hash string. Must be a positive integer. If the value exceeds the length of a SHA-256 hash (64), the result will be truncated to the maximum available length.

Returns:

A random hexadecimal string of the specified length.

Return type:

str

Note

The hash is generated using a random 256-bit integer, encoded with SHA-256, and truncated to the requested length. The output is suitable for use as a unique identifier, token, or nonce in most application contexts.

Warning

This function does not guarantee cryptographic security for all use cases. For security-critical applications (such as password hashing or cryptographic keys), use dedicated libraries and algorithms.

Example usage:

from smarter.common.utils import hash_factory

# Generate a 16-character random hash
token = hash_factory()
print(token)  # e.g., 'a3f9c1e2b4d5f6a7'

# Generate a 32-character random hash
long_token = hash_factory(length=32)
print(long_token)  # e.g., 'a3f9c1e2b4d5f6a7c8e9d0b1a2c3d4e5'
smarter.common.utils.utils.is_async_context()[source]

Checks if the current context is asynchronous.

Returns:

True if running in an asynchronous context, False otherwise.

Return type:

bool

smarter.common.utils.utils.mask_string(string, mask_char='*', mask_length=4, string_length=12)[source]

Masks a string by replacing all but the last mask_length characters with mask_char.

Deprecated since version 0.10.0: This function is deprecated and will be removed in a future release. Use Pydantic’s SecretStr or other secure alternatives for string masking.

Parameters:
  • string (Union[str, bytes]) – The string to mask. If a bytes object is provided, it will be decoded to UTF-8.

  • mask_char (str) – The character to use for masking. Default is '*'.

  • mask_length (int) – The number of characters at the end of the string to leave unmasked. Must be non-negative and less than or equal to the length of the string.

  • string_length (int) – The total length of the returned masked string. If the original string is shorter, the result will be truncated or padded accordingly.

Returns:

The masked string, with all but the last mask_length characters replaced by mask_char. The result is truncated to string_length if necessary.

Return type:

str

Raises:
  • TypeError – If string is not a string or bytes.

  • ValueError – If mask_length or string_length are negative, or if mask_length exceeds the length of the string.

Note

  • If the input string is shorter than mask_length, the original string is returned.

  • If mask_length is greater than string_length, it is reduced to string_length.

Example usage:

from smarter.common.utils import mask_string

# Mask all but the last 4 characters
masked = mask_string("supersecretpassword", mask_char="*", mask_length=4)
print(masked)  # Output: *************word

# Mask and truncate to 8 characters
masked = mask_string("supersecretpassword", mask_char="#", mask_length=3, string_length=8)
print(masked)  # Output: #####ord

# Mask a short string
masked = mask_string("abc", mask_length=4)
print(masked)  # Output: abc