Skip to main content

(Un)marshaling framework.

Project description

Marsh

(Un)marshaling library for objects in Python 3.8+.

Tested on Ubuntu, Windows and Mac OSX for Python 3.8, 3.9 and 3.10.

Relies heavily on type-hint reflection. All (un)marshaling is performed recursively which allows for support of nested types.

Influenced by the work of Omry Yadan on hydra.

The documentation is hosted on ReadTheDocs.

Getting Started

Install

marsh is available through pip

pip install marsh

Entry point

Using the unmarshaling capabilities of marsh we can create entry points for python code.

These entry points allow for arguments to be given on the command line and/or through config files which are then validated, converted to the correct types and passed to the entry point function.

Most python types are supported (primitives, type aliases, dataclasses, namedtuple e.t.c.)

Create

Creating an entry point is as simple as decorating a function and calling it without arguments.

# app.py
import marsh
from typing import Sequence, Union


@marsh.main
def run(
    a: int,
    b: Union[float, Sequence[int]],
    c: dict[str, bool],
) -> None:
    """Example of an entry point.

    Arguments:
        a: An integer argument.
        b: A floating point value or a sequence of ints.
        c: A dictionary with string keys and
            bool values. If this was python 3.8
            we would instead use typing.Dict[str, bool] as
            type hint as the builtin dict did not support
            type annotations.
    """
    print(a, type(a))
    print(b, type(b))
    print(c, type(c))


if __name__ == '__main__':
    run()

Run

When running the application we can use the positional arguments on the command line to pass values to our function.

$ python app.py a=1 b=5e-1 c.key1=true c.key2=false
1 <class 'int'>
0.5 <class 'float'>
{'key1': True, 'key2': False} <class 'dict'>

Argument validation

When giving invalid values or when required arguments are missing an error message is printed and the application exits.

$ python app.py a=1.5 b=0 c.some_key=true
failed to unmarshal config: int: could not convert: 1.5
	path: a
$ python app.py b=0 c.some_key=true
failed to unmarshal config: MissingValueError
	path: a

Help

Using --help we can also get a help message for the arguments. Here the output was piped to tail to truncate the output into displaying only the arguments of our entry point.

$ python app.py --help | tail -n 11
fields:
  a: <int>              An integer argument.

  b: <float> | [<int>, ...]
                        A floating point value or a sequence of ints.

  c: {<str>: <bool>, ...}
                        A dictionary with string keys and bool values. If this
                        was python 3.8 we would instead use typing.Dict[str,
                        bool] as type hint as the builtin dict did not support
                        type annotations.

Marshal

Marshaling values simply means taking a python object and turning it into JSON-like data.

# marshal.py
import dataclasses
import marsh


@dataclasses.dataclass
class Config:
    a: int
    b: float


config = Config(1, 5e-1)
print(marsh.marshal(config))
$ python marshal.py
{'a': 1, 'b': 0.5}

Unmarshal

Unmarshaling is the opposite of marshaling. A type is instantiated using JSON-like data.

# unmarshal.py
import dataclasses
import typing
import marsh


class Range(typing.NamedTuple):
    start: typing.Optional[int]
    stop: int


@dataclasses.dataclass
class Config:
    a: int
    b: float
    c: Range


config = marsh.unmarshal(
    Config,
    {
        'a': 1,
        'b': 1.5,
        'c': {
            'start': None,
            'stop': 5,
        },
    }
)
print(config)
$ python umarshal.py
Config(a=1, b=1.5, c=Range(start=None, stop=5))

License

MIT License.

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

marsh-0.1.1.tar.gz (63.2 kB view details)

Uploaded Source

Built Distribution

marsh-0.1.1-py3-none-any.whl (85.7 kB view details)

Uploaded Python 3

File details

Details for the file marsh-0.1.1.tar.gz.

File metadata

  • Download URL: marsh-0.1.1.tar.gz
  • Upload date:
  • Size: 63.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.13

File hashes

Hashes for marsh-0.1.1.tar.gz
Algorithm Hash digest
SHA256 692b7efe852e2c55f5e608bedee84325767fbfac7c025e0cbeb1b19199e397fc
MD5 4b13e75cd5d0c8859011369b62ca3fec
BLAKE2b-256 e64cc941be62237aa1d821d4296e72174f3619a1a7bfeb81da5cfde82d45c60f

See more details on using hashes here.

File details

Details for the file marsh-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: marsh-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 85.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.13

File hashes

Hashes for marsh-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f75d542f3a5e55b3574c509c7ac5d52c2b9bba03168225346d79f91e90f3b613
MD5 413c7e6f4a738bd8846c8503fdafb9e9
BLAKE2b-256 e48777bc36620e7eb1ce116f9bc4fbadafec71f4ae7a7a53fd8858ece3c5e30d

See more details on using hashes here.

Supported by

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