Zoho Objects¶
The Python object which represents a Zoho object can also represent a list of Zoho objects, depending on the parameters passed during instantiation.
If you pass in the Zoho ID of the object, the Python object will map to that particular Zoho object. In all other cases, the Python object is a List-of those Zoho objects. Except if you pass NO parameters, then you get a “New” object. If you then iterate on it, it becomes a list. Strange but true.
Note
Updated in v0.10.0: Numeric field(s) in a Zoho object are mapped to a
decimal.Decimal to reduce or eliminate floating-point errors when doing math
on currency values. This should be largely transparent, but there may be cases
where you’ll need to write your calculative operations with decimal.Decimal
objects explicitly.
Common Methods¶
These are the methods available in EVERY Zoho object. Not every method makes sense in every context, and in those cases the method will generally No-op.
Many methods return self, so they can be chained.
As the header of this section suggests, there are also object-specific methods. These are documented in the Object Type Reference section.
Accessor/Constructor¶
To get an object of a particular type, you do something of the form:
>>> obj = api.ObjectType()
>>> print(obj)
New ObjectType
If you know the Zoho ID of the object you want, then:
>>> obj = api.ObjectType(id)
>>> print(obj)
ObjectType #9876543210987654321
Or you can specify API search criteria as key/value parameters:
>>> obj = api.ObjectType(search_criteria="9876543210987654321")
>>> print(obj)
List of ObjectType objects
Note
The above are (I hope clearly) just examples and are not directly usable. There’s no Zoho object called (as of this writing) “ObjectType”.
get()¶
Implements the get() semantics of a dictionary. Use this just like the native
function.
Create()¶
>>> item = inventory.Item()
>>> item.name = "Test Item"
>>> item.rate = 42.00
>>> item.Create()
Item #9876543210987654321
There is no checking to ensure all required fields are set, nor that any of the
values make sense. If the object was created in Zoho, self gets an ID and
is updated with all default fields Zoho provided.
Calling Create() on a not-New object raises an exception.
Delete()¶
>>> item = inventory.Item(id)
>>> item.ID
9876543210987654321
>>> item.Delete().IsDeleted
True
>>> item.ID
False
>>> item.item_id
None
After deleting the object from Zoho, all the field data is still available in
the Python object, so in theory you could re-create the object by calling
Create(), or modify it and then re-create. YMMV. Of course, you’ll get a
new ID in that case.
Calling Delete() on a List-of or New object raises an exception.
First()¶
First() returns the first object found by a search; if called on a new or
mapped object, it returns self, so it’s safe to use anywhere. Useful if you
know your search will only return one result.
>>> user = inventory.User(email="test@example.com").First()
>>> user.IsLoaded:
True
>>> user.email
'test@example.com'
Updated in v0.7.2: Keyword arguments provided to First() will be used as
a filter, in the manner of Iter(), to determine which object counts as
“first.” The filtered attributes MUST exist in the List-of object
attributes. For example:
>>> user = inventory.User().First(status="inactive")
>>> user.IsLoaded:
True
>>> user.email
'inactiveuser@example.com'
Iter() and __iter__()¶
We handle pagination of List-of objects transparently, so you can treat List-of objects as iterables:
>>> for invoice in inventory.Invoice(date="2021-01-01", status="paid"):
... invoice
Invoice #9876543210987654321
Invoice #9876543210987654322
Invoice #9876543210987654323
This has some potential drawbacks.
If your search criteria is too broad, the list could be much longer than you really need, and EVERY object which matches your criteria will be individually retrieved, costing you lots of API calls.
If you only need values from fields which are already in the search results,
and you don’t need to manipulate each individual object, use Iter()
with the raw flag:
>>> paid_today = inventory.Invoice(date="2021-01-01", status="paid")
>>> for invoice in paid_today.Iter(raw=True):
... print(invoice.invoice_id)
'9876543210987654321'
'9876543210987654322'
'9876543210987654323'
Note
In the above example, we used the Zoho field name invoice_id rather
than the object property ID because we didn’t retrieve an object. Here
invoice is a dictionary which supports using ‘.’ in addition to ‘[]’ semantics
for getting values.
You can also filter the list using Iter(). The caveat is that the field(s)
you’re filtering on must exist in the search results:
>>> paid_today = inventory.Invoice(date="2021-01-01", status="paid")
>>> for invoice in paid_today.Iter(currency_code="USD", due_date="2021-02-28"):
... invoice
Invoice #9876543210987654321
Invoice #9876543210987654323
If you need a more complex filter, pass a function as the first parameter:
>>> paid_today = inventory.Invoice(date="2021-01-01", status="paid")
>>> for invoice in paid_today.Iter(lambda inv: inv.total > 1000.00):
... invoice
Invoice #9876543210987654322
Invoice #9876543210987654323
Update()¶
Changes you make to the fields in an existing Zoho object are pushed into Zoho
by calling Update().
>>> salesorder.line_items.append({'item_id':"9876543210987654321", 'quantity': 2})
>>> salesorder.shipping_charges += 12.50
>>> salesorder.Update()
SalesOrder #9876543210987654321
Object Properties¶
ID¶
Each Zoho object type has a different “id” field, but they are mapped to the
ID property of the corresponding Python object. For example:
>>> customer = inventory.Contact(id)
>>> customer.ID == customer.contact_id
True
>>> item = inventory.Item(id)
>>> item.ID == item.item_id
True
Number¶
Some, but not all, Zoho object types have a “number” field. These are exposed
via the Number property. If the underlying object doesn’t have a “number”
field, using the Number property will raise a KeyError.
>>> invoice = inventory.Invoice(id)
>>> invoice.Number
INV-09472
>>> item = inventory.Item(id)
>>> item.Number
...(snip)...
KeyError: 'item_number'
IsDeleted¶
True if the object has been deleted from Zoho. The data contained within the
object is still available, except the object’s native *_id field, which will
be None. The ID property will be False. See Delete().
IsList¶
True if the object is a List-of Zoho objects.
>>> inventory.SalesOrder(customer_id="9876543210987654321").IsList
True
IsLoaded¶
True if we’ve loaded data from Zoho. This is helpful for testing if an object was available in Zoho.
>>> inventory.SalesOrder(id).IsLoaded
True
>>> inventory.SalesOrder(bad_id).IsLoaded
False
>>> inventory.SalesOrder(customer_id="9876543210987654321").IsLoaded
True
>>> inventory.SalesOrder().IsLoaded
False