Skip to main content

properties: an organizational aid and wrapper for validation and tab completion of class properties

Project description

Latest PyPI version MIT license ReadTheDocs Travis tests Code coverage

Overview Video

Python Properties

An overview of Properties, November 2016.

Why

Properties provides structure to aid development in an interactive programming environment while allowing for an easy transition to production code. It emphasizes usability and reproducibility for developers and users at every stage of the code life cycle.

Scope

The properties package enables the creation of strongly typed objects in a consistent, declarative way. This allows validation of developer expectations and hooks into notifications and other libraries. It provides documentation with no extra work, and serialization for portability and reproducibility.

Goals

  • Keep a clean namespace for easy interactive programming
  • Prioritize documentation
  • Provide built-in serialization/deserialization
  • Connect to other libraries for GUIs and visualizations

Documentation

API Documentation is available at ReadTheDocs.

Alternatives

  • traitlets (Jupyter project) and traits (Enthought) - These libraries are driven by GUI development (much of the Jupyter environment is built on traitlets; traits has automatic GUI generation) which leads to many similar features as properties such as strong typing, validation, and notifications. Also, some Properties features and aspects of the API take heavy inspiration from traitlets.

    However, There are a few key areas where properties differs:

    1. properties has a clean namespace - this (in addition to ? docstrings) allows for very easy discovery in an interactive programming environment.
    2. properties prioritizes documentation - this is not explicitly implemented yet in traits or traitlets, but works out-of-the-box in properties.
    3. properties prioritizes serialization - this is present in traits with pickling (but difficult to customize) and in traitlets with configuration files (which require extra work beyond standard class definition); in properties, serialization works out of the box but is also highly customizable.
    4. properties allows invalid object states - the GUI focus of traits/traitlets means an invalid object state at any time is never ok; without that constraint, properties allows interactive object building and experimentation. Validation then occurs when the user is ready and calls validate

    Significant advantages of traitlets and traits over properties are GUI interaction and larger suites of existing property types. Besides numerous types built-in to these libraries, some other examples are trait types that support unit conversion and NumPy/SciPy trait types (note: properties has a NumPy array property type).

  • param - This library also provides type-checking, validation, and notification. It has a few unique features and parameter types (possibly of note is the ability to provide dynamic values for parameters at any time, not just as the default). This was first introduced before built-in Python properties, and current development is very slow.

  • mypy and PEP0484 - This provides static typing for Python without coersion, notifications, etc. It has a very different scope and implementation than traits-like libraries.

  • built-in Python property - properties/traits-like behavior can be mostly recreated using @property. This requires significantly more work by the programmer, and results in not-declarative, difficult-to-read code.

Connections

  • casingSimulations - Research repository for electromagnetic simulations in the presence of well casing
  • OMF - Open Mining Format API and file serialization
  • SimPEG - Simulation and Parameter Estimation in Geophysics
  • Steno3D - Python client for building and uploading 3D models

Installation

To install the repository, ensure that you have pip installed and run:

pip install properties

For the development version:

git clone https://github.com/aranzgeo/properties.git
cd properties
pip install -e .

Examples

Lets start by making a class to organize your coffee habits.

import properties
class CoffeeProfile(properties.HasProperties):
    name = properties.String('What should I call you?')
    count = properties.Integer(
        'How many coffees have you had today?',
        default=0
    )
    had_enough_coffee = properties.Bool(
        'Have you had enough coffee today?',
        default=False
    )
    caffeine_choice = properties.StringChoice(
        'How do you take your caffeine?' ,
        choices=['coffee', 'tea', 'latte', 'cappuccino', 'something fancy'],
        required=False
    )

The CoffeeProfile class has 4 properties, all of which are documented! These can be set on class instantiation:

profile = CoffeeProfile(name='Bob')
print(profile.name)

Out [1]: Bob

Since a default value was provided for had_enough_coffee, the response is (naturally)

print(profile.had_enough_coffee)

Out [2]: False

We can set Bob’s caffeine_choice to one of the available choices; he likes coffee

profile.caffeine_choice = 'coffee'

Also, Bob is half way through his fourth cup of coffee today:

profile.count = 3.5

Out [3]: ValueError: The 'count' property of a CoffeeProfile instance must
         be an integer.

Ok, Bob, chug that coffee:

profile.count = 4

Now that Bob’s CoffeeProfile is established, properties can check that it is valid:

profile.validate()

Out [4]: True

Property Classes are auto-documented in Sphinx-style reStructuredText! When you ask for the doc string of CoffeeProfile, you get

**Required Properties:**

* **count** (:class:`Integer <properties.basic.Integer>`): How many coffees have you had today?, an integer, Default: 0
* **had_enough_coffee** (:class:`Bool <properties.basic.Bool>`): Have you had enough coffee today?, a boolean, Default: False
* **name** (:class:`String <properties.basic.String>`): What should I call you?, a unicode string

**Optional Properties:**

* **caffeine_choice** (:class:`StringChoice <properties.basic.StringChoice>`): How do you take your caffeine?, any of "coffee", "tea", "latte", "cappuccino", "something fancy"

Project details


Release history Release notifications

History Node

0.5.0b4

History Node

0.5.0b3

History Node

0.5.0b2

History Node

0.5.0b1

History Node

0.5.0b0

This version
History Node

0.4.0

History Node

0.4.0b1

History Node

0.3.6b1

History Node

0.3.6b0

History Node

0.3.5

History Node

0.3.4

History Node

0.3.3

History Node

0.3.2

History Node

0.3.1

History Node

0.3.1b2

History Node

0.3.1b1

History Node

0.3.1b0

History Node

0.3.0

History Node

0.3.0b1

History Node

0.3.0b0

History Node

0.2.3

History Node

0.2.2

History Node

0.2.1

History Node

0.2.0

History Node

0.1.5

History Node

0.1.4

History Node

0.1.3

History Node

0.1.1

History Node

0.0.1

Download files

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

Filename, size & hash SHA256 hash help File type Python version Upload date
properties-0.4.0.tar.gz (42.4 kB) Copy SHA256 hash SHA256 Source None Feb 22, 2018

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging CloudAMQP CloudAMQP RabbitMQ AWS AWS Cloud computing Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page