Skip to main content

SafeModel

PyPI version Downloads

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

Metadata

Release files for safemodel 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for safemodel 1.0.0
File Size Uploaded
safemodel-1.0.0.tar.gz 4.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for safemodel 1.0.0
File Interpreter ABI Platform
safemodel-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.8 kB

Release files / safemodel-1.0.0.tar.gz

Download URL safemodel-1.0.0.tar.gz
Size 4.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6484c365e1f3a4c2833de66b735959e291b5f7541d5de667c0383cf24d2072b5
BLAKE2b-256 checksum
How to use checksums
8439aeb3689c8606c014d10f9e47bd98de53665bc799fdba91ed38e063b87f3b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.0

Release files / safemodel-1.0.0-py3-none-any.whl

Download URL safemodel-1.0.0-py3-none-any.whl
Size 6.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4d467b2b2c4db65f34554b7314fa62e6accfa9ac78e1a728ed07b96a2b1f1821
BLAKE2b-256 checksum
How to use checksums
afbfec0fa1699bfd7d9735f7298880628b66e356c4ab437e53671b091184efd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.0

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page