Skip to main content

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.

Metadata

Release files for marsh 0.2.6

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

Source distribution (sdist)

Source distribution for marsh 0.2.6
File Size Uploaded
marsh-0.2.6.tar.gz 64.2 kB Details

Built distribution (wheel)

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

Total release size: 150.6 kB

Release files / marsh-0.2.6.tar.gz

Download URL marsh-0.2.6.tar.gz
Size 64.2 kB
Tags Source
SHA-256 checksum
How to use checksums
14c359d12b2a5e5d66cba2ebad460adf84215f22db016354867ccf682bf65e54
BLAKE2b-256 checksum
How to use checksums
6b53cd3ff0229f34f5e485b9c9378aaa1df599cb72a4f6c3e669fb0c3fa05bf4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.11.1

Release files / marsh-0.2.6-py3-none-any.whl

Download URL marsh-0.2.6-py3-none-any.whl
Size 86.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b7999d78be426a2b617ce9a87fe04ddf22017db4c07c03666c57b222095abf5
BLAKE2b-256 checksum
How to use checksums
68d18f9dc2a4df06590f481642420df5da6aecd82770f2623da63c8b48412e94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.11.1

Release history Release notifications | RSS feed

This release

0.2.6 This release

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2

2 release files

0.1.1

2 release files

0.1

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