Developer Documentation for Climesync

Setting up the Development Environment

Climesync is developed using the `virtualenvwrapper`_ utility to manage versions and dependencies. To install virtualenvwrapper, run

$ pip install virtualenvwrapper

To create a new virtualenv and install all of Climesync's dependencies, do

$ mkvirtualenv venv
...
(venv) $ pip install -r requirements.txt

Testing Climesync

To lint climesync for non-PEP8 compliance, run

(venv) $ flake8 climesync.py commands.py util.py testing

To run unit tests, use this command:

(venv) $ nosetests

To enable Pymesync test mode when writing unit tests, call

connect(test=True)

instead of

connect()

Docopt

docopt is a module that creates command line parsers from docstrings. In interactive mode, docopt is used once to parse command line arguments such as username and password, but in scripting mode it's called twice. The first time it's called, it uses the main docstring to parse any global options, and if it sees that a command has been provided then the arguments after the command name are given to the command, which uses its own docstring to parse arguments and options.

The @climesync_command Decorator

If you don't know what a decorator is in Python, this article is a good starting point to understanding what they are and how they are used. In essence, decorators are Python's form of metaprogramming that are somewhat analagous to C/C++ #define macros.

Every Climesync command that is accessible from both interactive mode and scripting mode uses a decorator as a wrapper to handle both use cases. If the command is called in scripting mode, it handles calling docopt() to parse command line arguments as well as util.fix_args() to fix the names of the parsed arguments. If the program is in interactive mode, the decorator simply calls the command.

The decorator takes two arguments: select_arg and optional_args. optional_args is the simpler of the two arguments. It simply indicates whether options that are left blank should be included as non-truthy values (such as None) or simply left out of the dictionary that is given to Pymesync.

select_arg is slightly more complicated. Certain Pymesync methods don't just take a dictionary of values and also require that another keyword argument be given to select a specific object (The most notable examples being the update_*() methods). Since there's no good way in docopt to distinguish these select arguments from other arguments that do get put in the values dictionary, these arguments must be specified to the decorator so it handles them correctly.

Because some commands can't be called in scripting mode (Such as connect() and sign_in(), they don't have the decorator. In the command_lookup table, this is shown by putting None for the scripting mode name

Function Documentation

For the most part, Climesync functions match 1 to 1 with menu options. However, there are several utility functions (Such as print_json and get_fields) that help eliminate cluttered and unnecessary repeated code.

Detailed information on how to use these functions is included in the docstrings inside the Climesync source code.