Project Setup

Set up the Tooling

First, of course, fork and clone the repo on GitHub.

We use Poetry to manage our development virtual environment. This must be installed before starting development on pyZohoAPI.

Once installed, you can set up the virtual environment:

$ git clone https://github.com/{your-name}/pyZohoAPI.git
...snip...
$ cd pyZohoAPI
$ poetry install
...snip...

Poetry will install all the packages needed, but they’re also mentioned below for completeness.

See the Poetry docs for more.

Tooling for Testing

We use pytest for testing.

Tests rely on a python module NOT INCLUDED IN THIS REPOSITORY called private which exports a dictionary called testdata, something like:

from pyzohoapi.core.collection import DottedDict
testdata = DottedDict({
    'orgid': "your-org-id",
    'region': "your-region",
    'api': {
    	"access_token": None,
    	"refresh_token": "your-refresh-token",
    	"expires_in": 0,
    	"client_id": "your-client-id",
    	"client_secret": "your-client-secret",
    	"redirect_url": None,
    },
    'books': { ... },
    'inventory': { ... },
    ...
})

Danger

The tests rely on actual secrets data to interact with the live Zoho APIs, and it’s a REALLY BAD IDEA to publish those, so our .gitignore specifically ignores the private/ directory, and that’s where we look for these secrets.

In order to run the tests, you must create private/__init__.py with at least the data indicated above, and add those key/value pairs the tests themselves require. See the tests codes themselves for the details.

To run the tests:

$ poetry run pytest

Or, a particular test, such as one you added:

$ poetry run pytest -k my_test_name

All the tests are under the tests directory, naturally. Contained therein are:

  • __init__.py - lets Python consider the tests part of a module.

  • test_00_pyzohoapi.py - tests for the primitives in the ZohoAPI base class.

  • test_inventory{_.*}.py - tests specifically for ZohoInventory.

Tests you add should follow the same pattern; Additional tests for the already-present APIs should either be added into the existing test_... file, or a new one of the form test_{api}_{seq}.py

Tooling for Documentation

All documentation is written in Markdown.

We use:

To use sphinx-autobuild:

$  poetry run sphinx-autobuild docs docs/build/html --open-browser --watch .

Commits, Versioning and ChangeLog

We adhere to Semantic Versioning and Conventional Commits* and apply the principles espoused on Keep A Changelog.

We use BumpyTrack for versioning, thus:

$ bumpytrack {aspect} --config-path bumpytrack.toml

Of course, {aspect} should be major, minor or patch depending on the actual aspect we are bumping.

We use Git-Changelog to generate our CHANGELOG.md, thus:

$ git-changelog . -o CHANGELOG.md

Naturally, pull-requests will be bumped/changelogged by the maintainer(s), but if you’re going to issue a pull request, please ensure your commit messages will be parsed properly.

*Going forward. Previous commits may not.

Helpful Dev and Debug Tools

There are two tools in the tools directory to make development and testing (hopefully) easier.

Note

Both of these tools rely on the private module mentioned above.

Interactive Test Server

The Interactive Test Server spins up a simple web server on http://localhost:8080. This allows you to send queries to the Zoho APIs and see the JSON response data.

$ poetry run python tools/interactive-test-server.py

You can add --port and a port number to the above to override the default port (8080).

If you want to see the log entries the library is making, add --log to the above.

Interactive Shell

The Interactive Shell launches a Python REPL with pyzohoapi pre-loaded and confgured (see the section on private, above).

$ poetry run python -i tools/test-shell.py

Note

Don’t forget the -i in the command above to get your interactive shell.

testshell()
    Test shell loaded. Here's what you have:

    Modules:
        decimal.Decimal (as Decimal);
        json (simplejson, aliased to json);

    Functions:
        pprint();
        show(object, key=None) -> shows a Zoho Object (or optional attribute);

    Objects:
        private.testdata -> dict, aliased to td;
        books -> ZohoBooks object : configured via testdata;
        inv -> ZohoInventory object : configured via testdata;

    Type: help(testshell) to get this help again.

    Enjoy your testing!

>>> inv.Item('9876543210987654321')
Item #9876543210987654321
>>>