Skip to main content

No project description provided

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

safemodel-0.1.0.tar.gz (4.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

safemodel-0.1.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file safemodel-0.1.0.tar.gz.

File metadata

  • Download URL: safemodel-0.1.0.tar.gz
  • Upload date:
  • Size: 4.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for safemodel-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1d3a00cca86a88df917dfa8c0f6b004c6398caf1a682187951fac2c6df6dc239
MD5 ef5f873a19a805f88f3c995a14cf2b7c
BLAKE2b-256 71d0bdfc0de56b9f28cc08cc7e212e80e0c3f6fa8127fa119224f66adfbfcade

See more details on using hashes here.

File details

Details for the file safemodel-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: safemodel-0.1.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

Hashes for safemodel-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e0880dd0c13972c6142f912f114e516a12dba6045e1f175dc71594e059d1d39b
MD5 e2f0fffa198a0eafbdcc43c20c5b09cc
BLAKE2b-256 f594b8ccf00ed639ac536ee0541447c6362ff5f5741729d03b80d772cddbff0e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page