Core Utilities
The core utilities provide fundamental functionality for the Siege Utilities package, including logging, string manipulation, and package initialization.
Package Discovery
Core package — lazy-loaded.
Contains logging, string utilities, SQL safety, and other core functions. All submodules load on first attribute access via PEP 562 __getattr__.
- siege_utilities.core.init_logger(name, log_to_file=False, log_dir='logs', level='INFO', max_bytes=5000000, backup_count=5, shared_log_file=None)[source]
Initialize a logger with specific configuration.
Deprecated since version The: name suggests this function does first-time setup distinct from
get_logger(), but both are get-or-create with shared config. Preferconfigure_shared_logging()to set the shared config andget_logger()to retrieve loggers; theinit_loggershape will be removed in a future release.- Parameters:
- Returns:
Configured logger instance
- Return type:
Configure shared logging for all loggers.
- siege_utilities.core.remove_wrapping_quotes_and_trim(target_string)[source]
Removes wrapping quotes (single or double) from a string and trims whitespace
- siege_utilities.core.clean_string(target_string)[source]
Clean a string by removing quotes, trimming whitespace, and normalizing.
- siege_utilities.core.normalize_whitespace(target_string)[source]
Normalize whitespace in a string by replacing multiple spaces with single space.
- Parameters:
target_string (str | None) – String to normalize
- Returns:
String with normalized whitespace
- Return type:
Examples
>>> normalize_whitespace("hello world") 'hello world' >>> normalize_whitespace("test\n\n\nvalue") 'test value'
- siege_utilities.core.snake_case(text)[source]
Convert text to snake_case.
Examples
>>> snake_case("HelloWorld") 'hello_world' >>> snake_case("hello-world") 'hello_world' >>> snake_case("Hello World") 'hello_world'
- siege_utilities.core.remove_non_alphanumeric(text, keep_chars='_-')[source]
Remove non-alphanumeric characters from text, optionally keeping specified chars.
- Parameters:
- Returns:
Cleaned text
- Return type:
Examples
>>> remove_non_alphanumeric("hello@world!") 'helloworld' >>> remove_non_alphanumeric("test_value-123", keep_chars="_-") 'test_value-123'
- siege_utilities.core.validate_sql_identifier(name, label='identifier', *, allow_dotted=False)[source]
Validate that name is a safe SQL identifier.
Checks that the identifier contains only alphanumeric characters and underscores, starts with a letter or underscore, and is non-empty. This prevents SQL injection when identifiers must be interpolated into SQL strings (e.g.,
CREATE DATABASE {name}).- Parameters:
name (str) – The identifier to validate (database name, table name, etc.).
label (str) – Human-readable label for error messages (e.g., “database”, “table”).
allow_dotted (bool) – If True, accept
schema.tableorcatalog.schema.table– every dot-separated component must itself be a safe identifier. Defaults to False to preserve backwards-compatible single-component behaviour.
- Returns:
The validated identifier (unchanged).
- Raises:
ValueError – If name is empty, structurally invalid, or (when
allow_dotted=False) contains a dot.- Return type:
Examples
>>> validate_sql_identifier("electronic_silver", "database") 'electronic_silver' >>> validate_sql_identifier("silver; DROP TABLE --", "database") Traceback (most recent call last): ... ValueError: Invalid SQL database: ... >>> validate_sql_identifier("public.users", "table", allow_dotted=True) 'public.users'
- siege_utilities.core.validate_sql_identifier_in(name, allowed, label='identifier')[source]
Validate that name is both structurally safe AND in allowed.
Use this when the caller has a known set of legal values – the typical case is a column name that must exist on a DataFrame:
validate_sql_identifier_in(geometry_col, df.columns, "column")
- siege_utilities.core.escape_sql_string_literal(value, *, dialect='standard')[source]
SQL-escape a string for use inside single-quoted SQL literals.
Use sparingly – parameter binding is always preferred. The cases that legitimately need this are:
Sedona / Spark-SQL spatial UDFs (
ST_GeomFromText) where Spark parameter substitution doesn’t apply uniformly across versions.Hand-written SQL files generated for human inspection / batch re-import – defensive escaping in case the row data is later hand-edited.
The escape rule is the SQL standard: replace
'with''. For MySQL (dialect="mysql"), backslashes are also doubled because MySQL treats\as an escape character by default (NO_BACKSLASH_ESCAPESoff).NUL bytes are rejected – most drivers refuse to send them anyway and they can split a query in C-string-aware backends.
- Parameters:
- Raises:
TypeError – value is not a string.
ValueError – value contains a NUL byte or dialect is unknown.
- Return type:
- siege_utilities.core.validate_sql_fragment(fragment, label='SQL fragment')[source]
Reject SQL fragments containing dangerous structural keywords.
This is defense-in-depth for cases where a free-form SQL expression (e.g. a WHERE clause) must be interpolated into a query string. Parameter binding is always preferred; use this only when binding is not possible.
The blocklist catches statement-level injection (semicolons, DDL/DML keywords, comments). It does NOT make arbitrary input safe — callers should still avoid passing untrusted user input.
- Parameters:
- Returns:
The validated fragment (unchanged).
- Raises:
TypeError – fragment is not a string.
ValueError – fragment contains a blocked pattern.
- Return type:
Examples
>>> validate_sql_fragment("state_fips = '06'") "state_fips = '06'" >>> validate_sql_fragment("1=1; DROP TABLE users--") Traceback (most recent call last): ... ValueError: Dangerous pattern in SQL fragment: ...
Note
All functions in this module are automatically discovered and available at the package level. No explicit imports are required.
Functions
- siege_utilities.core.__init__(*args, **kwargs)
Initialize self. See help(type(self)) for accurate signature.
Usage Examples
Basic package usage:
import siege_utilities
# All functions are automatically available
print(dir(siege_utilities))
Unit Tests
The core module has comprehensive test coverage:
✅ test_package_discovery.py - Package discovery and import tests
✅ test_core_logging.py - Logging functionality tests
✅ test_string_utils.py - String utility tests
Test Results: All core utilities tests pass successfully.