Skip to main content

Attribute-based data structures.

Project description

attrbox

Attribute-based data structures.

Build Status attrbox on PyPI Supported Python versions

Changelog - Issues - Documentation

Why?

I have common use cases where I want to improve python's dict and list:

  • AttrDict: attribute-based dict with better merge and deep value access
  • AttrList: list that broadcasts operations to its members
  • Environment: reading environment files
  • Configuration: loading command-line arguments and configuration files
  • JSend: sending JSON responses

Install

python -m pip install attrbox

AttrDict

AttrDict features:

  • Attribute Syntax for dict similar to accessing properties in JavaScript: thing.prop means thing["prop"] for get / set / delete.

  • No KeyError: if a key is missing, just return None (like dict.get()).

  • Deep Indexing: use a list of keys and int to get and set deeply nested values. This is similar to lodash.get except that only the array-like syntax is supported and you must use actual int to index across list objects.

  • Deep Merge: combine two dict objects by extending deeply-nested keys where possible. This is different than the new dict union operator (PEP 584).

from attrbox import AttrDict

items = AttrDict(a=1, b=[{"c": {"d": 5}}], e={"f": {"g": 7}})
items.a
# => 1
items.x is None
# => True
items.x = 10
items['x']
# => 10
items.get(["b", 0, "c", "d"])
# => 5
items <<= {"e": {"f": {"g": 20, "h": [30, 40]}}}
items.e.f.g
# => 20
items[['e', 'f', 'h', 1]]
# => 40

Read more about AttrDict

AttrList

AttrList provides member broadcast: performing operations on the list performs the operation on all the items in the list. I typically use this to achieve the Composite design pattern.

from attrbox import AttrDict, AttrList

numbers = AttrList([complex(1, 2), complex(3, 4), complex(5, 6)])
numbers.real
# => [1.0, 3.0, 5.0]

words = AttrList(["Apple", "Bat", "Cat"])
words.lower()
# => ['apple', 'bat', 'cat']

items = AttrList([AttrDict(a=1, b=2), AttrDict(a=5)])
items.a
# => [1, 5]
items.b
# => [2, None]

Read more about AttrList

Environment

attrbox.env is similar to python-dotenv, but uses the AttrDict ability to do deep indexing to allow for things like dotted variable names. Typically, you'll use it by calling attrbox.load_env() which will find the nearest .env file and load it into os.environ.

Read more about attrbox.env

Configuration

attrbox supports loading configuration files from .json, .toml, and .env files. By default, load_config() looks for a key imports and will recursively import those files (relative to the current file) before loading the rest of the current file (data is merged using AttrDict). This allows you to create templates or smaller configurations that build up to a larger configuration.

For CLI applications, attrbox.parse_docopt() let's you use the power of docopt with the flexibility of AttrDict. By default, --config and <config> arguments will load the file using the load_config()

"""Usage: prog.py [--help] [--version] [-c CONFIG] --file FILE

Options:
  --help                show this message and exit
  --version             show the version number and exit
  -c, --config CONFIG   load this configuration file (supported: .toml, .json, .env)
  --file FILE           the file to process
"""

def main():
    args = parse_docopt(__doc__, version=__version__)
    args.file # has the value of --file

if __name__ == "__main__":
    main()

Building on top of docopt we strip off leading dashes and convert them to underscores so that we can access the arguments as AttrDict attributes.

Read more about attrbox.config

JSend

JSend is an approximate implementation of the JSend specification that makes it easy to create standard JSON responses. The main difference is that I added an ok attribute to make it easy to tell if there was a problem (fail or error).

from attrbox import JSend

def some_function(arg1):
    result = JSend() # default is "success"

    if not is_good(arg1):
        # fail = controlled problem
        return result.fail(message="You gone messed up.")

    try:
        result.success(data=process(arg1))
    except Exception:
        # error = uncontrolled problem
        return result.error(message="We have a problem.")

    return result

Because the JSend object is an AttrDict, it acts like a dict in every other respect (e.g., it is JSON-serializable).

Read more about JSend

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

attrbox-0.1.5.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

attrbox-0.1.5-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

File details

Details for the file attrbox-0.1.5.tar.gz.

File metadata

  • Download URL: attrbox-0.1.5.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for attrbox-0.1.5.tar.gz
Algorithm Hash digest
SHA256 7c5a898e176ad43bc7369caa1d6c737b2542e6cddb15fef38c032f44794b3d91
MD5 8de1a5ec074ca059f489e72e4e50af59
BLAKE2b-256 87f6fe8d5f804a5fef520fa9e2f2e018827dcc0b267aa8449ca3322e4d27bbaa

See more details on using hashes here.

File details

Details for the file attrbox-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: attrbox-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 19.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for attrbox-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ffea00298ecc7b4d109fc0fe71d9490ecd89b698abff152dc643a820ed8c5755
MD5 1c688948b0247d11c5cde01063c6c543
BLAKE2b-256 c3334520765f25f1f4f9707a8b3244226b9cc63d2724054b22234f5f26aaf6bd

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