Quick Start

Installation

You’ll need at least Python 3.6 to install pyZohoAPI.

Via PyPI

$ python -m pip install pyzohoapi

From Source

We use Poetry for virtual environment and dependency management.

$ git clone https://github.com/tdesposito/pyZohoAPI.git
$ cd pyZohoAPI
$ poetry install
$ poetry build
$ pip install dist/*.whl

Basic Usage

>>> from pyzohoapi import ZohoInventory
>>> api = ZohoInventory("{your-orginization-id}", "{your-region}",
...   client_id="{your-client-id}",
...   client_secret="{your-client-secret}",
...   refresh_token="{your-refresh-token}"
... )
>>> contact = api.Contact(email="test@example.com").First()
>>> contact.IsLoaded
True
>>> contact.first_name
'test'
>>> contact.first_name = "Changed"
>>> contact.Update()

API Objects

All operations are, one way or another, performed via one of the several product-specific “API” objects, each named for the API they target. In the example above, we are using the “Inventory” API via the ZohoInventory object.

Each API object follows this pattern:

api = ZohoProduct(organization_id, region="us", **apiArgs)

where ZohoProduct is one of ZohoBooks, ZohoCheckout, ZohoExpense, ZohoInventory, ZohoInvoice, and ZohoSubscriptions.

Note

As of this release, we only include support for Inventory.

region should be either the Top-Level Domain name of the region you’re in, or the region’s “friendly” name (case insensitive), one of Australia, Europe, India, US.

Generally, provide client_id, client_secret, refresh_token and redirect_url as keyword arguments.

Note

You won’t need redirect_url for Self-Client or Non-Browser Client access.

Warning

Client ID and Secrets are just that: SECRET. Please don’t include them directly in any code you might share.

See also

Zoho uses OAuth procedures to provide your Access Tokens. Please see Zoho’s API Documentation on OAuth for details.

Zoho Objects

You access Zoho Objects via the API Object. Let’s assume you have an inventory object defined as:

inventory = ZohoInventory(...)

Now you can get various Zoho objects by using their type name, thus:

user = inventory.User(...)
item = inventory.Item(...)
composite = inventory.CompositeItem(...)

Object Properties

We surface a small number of properties, to wit:

Property

Purpose

ID

The Zoho id number of the underlying object.

IsDeleted

True if the object was deleted from Zoho.

IsList

True if the object is a list of Zoho objects

IsLoaded

True if we’ve fetched the corresponding object or list from Zoho

Number

The Zoho document number of the underlying object

Get an Existing Object

If you know the object ID:

customer = inventory.Contact(id)

If you know some other unique identifier, take the first (only) object from a search for that identifier.

customer = inventory.Contact(email="test@example.com").First()

Create a new Object

Instantiate a new object, set its fields, and Create() it. If it now has an ID, it was created.

invoice = inventory.Invoice()
invoice.customer_id = customer.ID
... # more fields should be set here.
invoice.Create()
if invoice.ID:
  print("Invoice created!")

Update an Existing Object

Given an object, change or add whichever fields you want, then Update() it.

customer.first_name = "Ford"
customer.last_name = "Prefect"
customer.Update()

Delete an Existing Object

Deleting an object in Zoho doesn’t zap the data in the Python object, so it’s available, if needed.

if invoice.Delete().IsDeleted:
  print(f"Deleted invoice {invoice.Number}")

Get a list of Objects

You can iterate over EVERY object of a particular type.

for user in inventory.User():
  print(user.name)

Warning

Use this with form with care. The above example, User, is likely not going to result in a huge list, but if you were to iterate over every, say, Invoice or Item in your organization, you could very well run yourself out of API calls.

You can search and filter lists of objects.

items = inventory.Item(category_id="9876543210987654321")
for item in items:
  print(item.name)
for item in items.Iter(lambda item: item.sku.startswith('S123'))
  print(item.name)

The first loop gathers all Item objects which match the criteria specified. The second loop walks the same list as the first, but only prints those which pass the filter function.

Warning

The following is a Bad Idea, because it will request EVERY Item in your inventory prior to filtering.

items = inventory.Item()
for item in items.Iter(lambda item: item.sku.startswith('S123'))
  print(item.name)