aimbat.utils
Miscellaneous helpers for AIMBAT.
Covers five areas:
- Maths — mean/SEM over numeric and
pd.Timedeltavalues (mean_and_sem,mean_and_sem_timedelta). - Errors — exception message plus attached notes, for display
(
exception_message). - Pydantic — validation-error formatting, title-map lookup, and the
serialisation shared by the
core.dump_*_tablefunctions (format_validation_error,get_title_map,dump_models). - Sample data — download and delete the bundled sample dataset
(
download_sampledata,delete_sampledata). - UUIDs / formatting — short-UUID lookup,
rel()for typed relationships, and thefmt_*display formatters (utils.formatters).
Modules:
| Name | Description |
|---|---|
formatters |
Formatters for displaying values in tables and panels. |
Functions:
| Name | Description |
|---|---|
check_field_name_flags |
Check the field-naming flags the |
delete_sampledata |
Delete the sample data directory ( |
download_sampledata |
Download and extract the AIMBAT sample dataset. |
dump_models |
Serialise records to a JSON-compatible list of dicts. |
exception_message |
Return an exception's message together with any notes attached to it. |
format_validation_error |
Format a |
get_title_map |
Build a mapping from field names to their display titles. |
mean_and_sem |
Return the mean and standard error of the mean (SEM) for a list of numeric values, ignoring None values. |
mean_and_sem_timedelta |
Return (mean, sem) for a list of pd.Timedelta values. |
rel |
Cast a SQLModel relationship attribute to |
string_to_uuid |
Determine a UUID from a string containing the first few characters. |
uuid_shortener |
Return the shortest unique prefix for a UUID, formatted with dashes. |
check_field_name_flags
check_field_name_flags(
by_alias: bool,
by_title: bool,
from_read_model: bool | None = None,
) -> None
Check the field-naming flags the dump_*_table functions take.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
by_alias
|
bool
|
Whether serialisation aliases are to be used for the field names. |
required |
by_title
|
bool
|
Whether field title metadata is to be used for the field names. |
required |
from_read_model
|
bool | None
|
Whether the caller is dumping from its read model, for
the functions that offer the choice. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
ValueError
|
If |
Source code in src/aimbat/utils/_pydantic.py
delete_sampledata
Delete the sample data directory (Settings.sampledata_dir) and its contents.
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/aimbat/utils/_sampledata.py
download_sampledata
download_sampledata(force: bool = False) -> None
Download and extract the AIMBAT sample dataset.
Downloads the sample data archive and extracts it into
Settings.sampledata_dir.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
force
|
bool
|
Delete and replace an existing non-empty sample data directory instead of raising an error. |
False
|
Raises:
| Type | Description |
|---|---|
FileExistsError
|
If the sample data directory already exists and is
non-empty, and |
Source code in src/aimbat/utils/_sampledata.py
dump_models
dump_models(
records: Sequence[T],
model_class: type[T],
*,
by_alias: bool = False,
by_title: bool = False,
exclude: set[str] | None = None,
) -> list[dict[str, Any]]
Serialise records to a JSON-compatible list of dicts.
The shared tail of the core.dump_*_table functions: each builds its own
query, and its read models where it has them, then hands the result here
so field naming and exclusions are applied the same way everywhere.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
records
|
Sequence[T]
|
Records to serialise, all instances of |
required |
model_class
|
type[T]
|
Class of the records, used for both the type adapter and the title map. |
required |
by_alias
|
bool
|
Whether to use serialisation aliases for the field names. |
False
|
by_title
|
bool
|
Whether to use the field title metadata for the field names.
Mutually exclusive with |
False
|
exclude
|
set[str] | None
|
Field names to exclude from every record. |
None
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
One dict per record. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
Source code in src/aimbat/utils/_pydantic.py
exception_message
exception_message(exc: BaseException) -> str
Return an exception's message together with any notes attached to it.
Code that knows context the raising site does not - which data source was
being read, say - attaches it with BaseException.add_note instead of
re-raising a different exception type. Notes only show up in a traceback,
so anything that reports an exception without one has to add them back.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc
|
BaseException
|
The exception to describe. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The exception's message, followed by one line per note. |
Source code in src/aimbat/utils/_errors.py
format_validation_error
format_validation_error(exc: ValidationError) -> str
Format a ValidationError as a short, semicolon-joined message.
Strips the redundant "Value error, " prefix Pydantic adds to custom
validator messages, so the result is fit for display without leaking
implementation detail.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exc
|
ValidationError
|
The validation error to format. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A single-line, semicolon-joined summary of all validation errors. |
Source code in src/aimbat/utils/_pydantic.py
get_title_map
cached
Build a mapping from field names to their display titles.
Includes both regular and computed fields. A field without a title set
falls back to its name with underscores replaced by spaces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_class
|
type[BaseModel]
|
Pydantic model class to inspect. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Mapping of field name to display title. |
Source code in src/aimbat/utils/_pydantic.py
mean_and_sem
Return the mean and standard error of the mean (SEM) for a list of numeric values, ignoring None values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Sequence[float | None]
|
List of numeric values (float or int) or None. |
required |
Returns:
| Type | Description |
|---|---|
tuple[float | None, float | None]
|
A tuple containing the mean and SEM of the input data, both as floats or None if not computable. |
Source code in src/aimbat/utils/_maths.py
mean_and_sem_timedelta
Return (mean, sem) for a list of pd.Timedelta values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
Sequence[Timedelta]
|
List of pd.Timedelta values. |
required |
Returns:
| Type | Description |
|---|---|
tuple[Timedelta | None, Timedelta | None]
|
|
Source code in src/aimbat/utils/_maths.py
rel
rel(attr: Any) -> QueryableAttribute[Any]
Cast a SQLModel relationship attribute to QueryableAttribute for use with selectinload.
SQLModel types relationship fields as their Python collection type (e.g. list[Foo]),
but SQLAlchemy's selectinload expects a QueryableAttribute. This helper performs
the cast to satisfy mypy without requiring per-call # type: ignore comments.
Source code in src/aimbat/utils/_sqlalchemy.py
string_to_uuid
string_to_uuid(
session: Session,
id: str,
aimbat_class: type[AimbatTypes],
custom_error: str | None = None,
) -> UUID
Determine a UUID from a string containing the first few characters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
Database session. |
required |
id
|
str
|
Input string to find UUID for. |
required |
aimbat_class
|
type[AimbatTypes]
|
Aimbat class to use to find UUID. |
required |
custom_error
|
str | None
|
Overrides the default error message. |
None
|
Returns:
| Type | Description |
|---|---|
UUID
|
The full UUID. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no record matches |
Source code in src/aimbat/utils/_uuid.py
uuid_shortener
uuid_shortener(
session: Session,
aimbat_obj: T | type[T],
min_length: int | None = None,
str_uuid: str | None = None,
) -> str
Return the shortest unique prefix for a UUID, formatted with dashes.
The table's ids are fetched once per session and cached there, so calling
this once per row (or once per cell) stays a single query - see
_id_pool for what that caching does and does not guarantee.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
An active SQLModel/SQLAlchemy session. |
required |
aimbat_obj
|
T | type[T]
|
Either an instance of a SQLModel or the SQLModel class itself. |
required |
min_length
|
int | None
|
The starting character length for the shortened ID.
Defaults to |
None
|
str_uuid
|
str | None
|
The full UUID string. Required only if |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The shortest unique prefix string, including hyphens where applicable. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/aimbat/utils/_uuid.py
formatters
Formatters for displaying values in tables and panels.
Functions:
| Name | Description |
|---|---|
fmt_bool |
Format a boolean as |
fmt_depth_km |
Format a depth value in metres as kilometres with one decimal place. |
fmt_flip |
Format a boolean flip flag as |
fmt_float |
Format a float to 3 decimal places, or |
fmt_float_sem |
Format a float with an optional SEM as |
fmt_timedelta |
Format a |
fmt_timedelta_sem |
Format a |
fmt_timestamp |
Format a timestamp as |
fmt_bool
fmt_depth_km
Format a depth value in metres as kilometres with one decimal place.
fmt_flip
Format a boolean flip flag as ↕ (True) or empty string (False).
fmt_float
Format a float to 3 decimal places, or — for a null value (None/NaN/NaT/NA).
Source code in src/aimbat/utils/formatters.py
fmt_float_sem
Format a float with an optional SEM as value ± sem, or — if v is None.
Source code in src/aimbat/utils/formatters.py
fmt_timedelta
Format a Timedelta as seconds, or — if None.
fmt_timedelta_sem
Format a Timedelta mean with an optional SEM as mean ± sem (in seconds).
Returns — if mean is null (None/NaT/NA).
Source code in src/aimbat/utils/formatters.py
fmt_timestamp
Format a timestamp as YYYY-MM-DD HH:MM:SS, or — for missing values.