A safe container, a wrapper around a structure whose schema is unknown or may dynamically change.
Project description
SafeModel
A safe container, a wrapper around a structure whose schema is unknown or may dynamically change.
The idea is to put an object (e.g. a structure that is retrieved from an external source)
in a container that will support the __getattr__ and __getitem__ methods,
but will not throw errors if non-existent data is accessed.
How to install
Using uv
uv add safemodel
Using pip
pip install safemodel
How to Use
General
SafeModel is a potentially iterable object. If we try to iterate it, we get: 1. If iterable is wrapped: (SafeModel(x) for x in iterable) 2. If non-iterable is wrapped: empty iterator
When unpacking a wraparound value via __call__, it is passed to each processor sequentially.
If any processor raises ProcessingError, the value will be replaced with Placeholder.
If there is no wraparound data, Placeholder will be returned.
Processors
Functions that take 1 positional argument and return a value (usually the one passed in unchanged, but it can be changed) or throw a ProcessingError exception. The result of a processor is used by the next one in the chain.
NO_DATA
A special value denoting the absence of data.
None is not suitable because it may be the expected value in some cases.
The object denoting the absence of data must be fundamentally unobtainable from the source structure.
Examples
from safemodel import SafeModel, default_placeholder_context
unsafe_struct = {
"hello": "world",
"list_of_optional_dict_with_value": [
{"value": 1},
None,
{"value": 2},
3,
4,
],
"age_str": "24",
"strange_struct": {
"foo": "bar",
"members": [
{
"fio": {
"name": "Ivan",
}
},
],
},
"camelCaseField": "ok",
}
safe_struct = SafeModel(unsafe_struct)
assert safe_struct.hello() == "world"
expected_values = [1, "-", 2, "-", "-"]
actual_values_1 = [value_container.value("-") for value_container in safe_struct.list_of_optional_dict_with_value]
with default_placeholder_context(safe_struct, "-"):
actual_values_2 = [value_container.value() for value_container in safe_struct.list_of_optional_dict_with_value]
assert actual_values_1 == actual_values_2 == expected_values
assert safe_struct.age_str | int == 24
assert safe_struct.camel_case_field() == "ok"
assert safe_struct.strange_struct.members[0].fio.name() == "Ivan"
assert safe_struct.some.field.that.does.not_.exist("Nothing!!!") == "Nothing!!!"
assert not safe_struct.some.field.that.does.not_.exist.should.be.false
assert safe_struct.age_str | [float, str] == safe_struct.age_str(extend_processors=[float, str]) == "24.0"
How To Develop
Prepare your environment (once)
Install uv
Using scoop
scoop install uv
Without scoop
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Run Linter
Using Make
make lintfix
If Make is not installed
uv run ruff format
uv run ruff check --fix
Run Tests
With Make
make
or
make test
Without Make
uv pip install -e .
uv run pytest -v
Build
uv build
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file safemodel-1.0.0.tar.gz.
File metadata
- Download URL: safemodel-1.0.0.tar.gz
- Upload date:
- Size: 4.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6484c365e1f3a4c2833de66b735959e291b5f7541d5de667c0383cf24d2072b5
|
|
| MD5 |
72b849b825d520f59a3af688dd244b76
|
|
| BLAKE2b-256 |
8439aeb3689c8606c014d10f9e47bd98de53665bc799fdba91ed38e063b87f3b
|
File details
Details for the file safemodel-1.0.0-py3-none-any.whl.
File metadata
- Download URL: safemodel-1.0.0-py3-none-any.whl
- Upload date:
- Size: 6.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d467b2b2c4db65f34554b7314fa62e6accfa9ac78e1a728ed07b96a2b1f1821
|
|
| MD5 |
944c4bd6e62d8b3c3ced56cfa686a3e7
|
|
| BLAKE2b-256 |
afbfec0fa1699bfd7d9735f7298880628b66e356c4ab437e53671b091184efd4
|