Metadata-Version: 2.1
Name: magic-dot
Version: 0.2.0
Summary: Library that allows deep extraction of layered data structures (like JSON).
Home-page: https://github.com/bonafideduck/magic_dot
Author: Mark Eklund
Author-email: magic_dot@patnan.com
License: BSD license
Description: Magic Dot
        *********
        
        
        .. image:: https://img.shields.io/pypi/v/magic_dot.svg
                :target: https://pypi.python.org/pypi/magic_dot
        
        .. image:: https://img.shields.io/pypi/dm/magic_dot.svg
                :target: https://pypi.python.org/pypi/magic_dot
        
        .. image:: https://github.com/bonafideduck/magic_dot/workflows/Sanity/badge.svg
                :target: https://github.com/bonafideduck/magic_dot/actions?query=branch%3Amaster+workflow%3A%22Sanity%22
        
        .. image:: https://readthedocs.org/projects/magic-dot/badge/?version=latest
                :target: https://magic-dot.readthedocs.io/en/latest/?badge=latest
                :alt: Documentation Status
        
        
        
        
        Library that allows deep extraction of layered data structures (like JSON).
        
        
        * Free software: BSD license
        * Documentation: https://magic-dot.readthedocs.io.
        
        
        Introduction
        ============
        
        Magic Dot encapsulates data to allow the versatile extraction of its contents.
        It is easier to use than ``setdefault`` or ``try:`` ``except`` that typical
        extraction from a structured like JSON.  Consider the following simplified JSON 
        snipppet curl https://api.github.com/events: ::
        
          import json
          data = json.loads("""
            [
              {
                "type": "PushEvent",
                "payload": {
                  "commits": [
                    {
                      "author": {
                        "name": "Bubba"
            }}]}}]
          """)
        
        ``magic_dot`` can retrieve the first name of the first commit, with a default of "nobody" if any
        part of that chain is missing with the the following: ::
        
          from magic_dot import MagicDot, NOT_FOUND
          name = MagicDot(data)[0].payload.commits[0].author.name.get("nobody")
        
        Since the incoming JSON can't be trusted, without magic_dot, you have to verify that 
        each layer is there.  This can be done with a ``try:`` ``except``, nearly as
        efficiently, but it is more verbose. ::
        
          try:
            name = data[0]['payload']['commits'][0]['author']['name']
          except (IndexError, KeyError):
            name = "nobody"
        
        Other features, like pluck, selective exceptions,
        attribute support, and iteration can lead to cleaner code.
        
        Features
        ========
        
        Forgiving NOT_FOUND Handling
        ----------------------------
        
        Manipulations of the MagicDot structure will raise no exceptions
        when one of the attributes or keys are not found.  Instead it delays
        this until the ``get()`` call that extracts the data at the end.
        When the ``get()`` is called, there are three ways of handling
        missing data:
        
        **Default is to return magic_dot.NOT_FOUND** ::
        
          >>> md.nonexistent.get()
          magic_dot.NOT_FOUND
        
        **You can request a default value for magic_dot.NOT_FOUND** ::
        
          >>> md.nonexistent.get('bubba')
          'bubba'
        
        **Or you can enable exceptions when referencing the nonexistent data** ::
        
            >>> md.exception().nonexistent
            ---------------------------------------------------------------------------
            NotFound                                  Traceback (most recent call last)
        
        Exceptions are not enabled by default.  They can be enabled during creation
        I.E ``MagicDot(data, exception=True)`` and switched on and off with the 
        ``MagicDot::exception(exception=False)`` method.
        
        Dict and List Item Handling
        ---------------------------
        
        When a `md[item]` is encountered, data will be extracted as follows:
        
        1. If ``md.__data[item]`` exists, that is used.
        2. If ``md.__data.item`` attribute exists it is used.
        3. If ``.exception()`` is enabled, a NotFound exception is raised.
        4. Otherwise ``md.NOT_FOUND`` is assigned to the resulting encapsulated data.
        
        Attribute Handling
        ------------------
        
        When a ``md.key`` is supplied data will be extracted as follows:
        
        1. If ``md.__data.key`` attribute exists it is used.
        2. If ``md.__data[key]`` item exists, it is used.
        3. If ``.exception()`` is enabled, a NotFound exception is raised.
        4. Otherwise ``md.NOT_FOUND`` is assigned to the resulting ``md.__data``.
        
        
        Iteration Support
        -----------------
        
        If the currently encapsulated data is an iterable, MagicDot supports iterating
        over the contained data with the resulting iteration being a MagicDot wrapper
        around the iterated data.
        
          >>> from collections import namedtuple
          >>> data = [1, {'x': 2}, namedtuple('x', 'x')(3)]
          >>> for md in MagicDot(data):
          ...   print(md.get())
          1
          {'x': 2}
          x(x=3)
        
        By default, if an attempt is made to iterate over ``NOT_FOUND`` data, a ``TypeError``
        will be raised.  The iteration code can be changed to instead return an empty list. :::
        
          >> md = MagicDot(1, iter_nf_as_empty=True)
          >> for x in md.nonexistent:
          ..   print(md.get())
          (prints nothing)
        
        
        Other Operators
        ---------------
        
        Currently, there is one additional operator, ``MagicDot::pluck()``, which if
        the encapsulated data is a list, it will attempt to extract a named attribute
        or key from the entire list.  The returned value is a MagicDot with the new plucked list.
        
        
        Future Enhancement
        ==================
        
        Future enhancements will be to support many of the `Underscore js`_ array and collection capabilities
        like ``compact``, ``reject``, and ``count``.
        
        .. _`Underscore js`: https://underscorejs.org/#arrays
        
        
        Credits
        =======
        
        This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
        
        .. _Cookiecutter: https://github.com/audreyr/cookiecutter
        .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
        
        
        History
        *******
        
        0.2.0 (2020-04-30)
        ==================
        * This contains some modifications that are not backwards compatible.
        * Remove .lists() support.
        * Add .pluck() support.
        * Change exception() to be raised when NOT_FOUND is generated instead of at the .get()
        * Make documentation changes to reflect the above.
        
        0.1.1 (2020-03-19)
        ==================
        
        * No significant chagnes.  Testing github release automations.
        
        0.1.0 (2020-03-19)
        ==================
        
        * First release on PyPI.
        
Keywords: magic_dot
Platform: UNKNOWN
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Requires-Python: >=3.5
Description-Content-Type: text/x-rst
