API Client Class#

Warning

These features and documentation are a work in progress!

In addition to the standard API wrapper functions, pyinaturalist provides iNatClient, a higher-level, object-oriented interface. It adds the following features:

  • Returns fully typed model objects instead of JSON

  • Easier to configure

  • Easier to paginate large responses

  • Basic async support

Basic usage#

All API calls are available as methods on iNatClient, grouped by resource type. For example:

  • Taxon requests: iNatClient.taxa

  • Observation requests: iNatClient.observations

  • These resource groups are referred to elsewhere in the docs as controllers. See :ref:Controller classes <controllers> for more info.

The main observation search is available in client.observations.search(). Here is an example of searching for observations by taxon name:

 >>> from pyinaturalist import iNatClient
 >>> client = iNatClient()
 >>> observations = client.observations.search(user_id='my_username', taxon_name='Danaus plexippus').all()

Pagination#

Most client methods return a Paginator object. This is done so we can both:

  • Make it easy to fetch multiple (or all) pages of a large request, and

  • Avoid fetching more data than needed.

Paginators can be iterated over like a normal collection, and new pages will be fetched as they are needed:

for obs in client.observations.search(user_id='my_username', taxon_name='Danaus plexippus'):
    print(obs)

You can get all results at once with .all():

query = client.observations.search(user_id='my_username', taxon_name='Danaus plexippus')
observations = query.all()

Or get only up to a certain number of results with .limit():

observations = query.limit(500)

You can get only the first result with .one():

observation = query.one()

Or only the total number of results (without fetching any of them) with .count():

print(query.count())

Single-ID requests#

For most controllers, there is a shortcut to get a single object by ID, by calling the controller as a method with a single argument. For example, to get an observation by ID:

observation = client.observations(12345)

Authentication#

Add credentials needed for authenticated requests: Note: Passing credentials via environment variables or keyring is preferred

>>> creds = {
...     'username': 'my_inaturalist_username',
...     'password': 'my_inaturalist_password',
...     'app_id': '33f27dc63bdf27f4ca6cd95dd9dcd5df',
...     'app_secret': 'bbce628be722bfe2abd5fc566ba83de4',
... }
>>> client = iNatClient(creds=creds)

Default request parameters#

There are some parameters that several different API endpoints have in common, and in some cases you may want to always use the same value. As a shortcut for this, you can pass these common parameters and their values via default_params.

For example, a common use case for this is to add locale and preferred_place_id:

>>> default_params={'locale': 'en', 'preferred_place_id': 1}
>>> client = iNatClient(default_params=default_params)

These parameters will then be automatically used for any endpoints that accept them.

Caching, Rate-limiting, and Retries#

See :py:class:.ClientSession and :ref:advanced for details on these settings.

iNatClient will accept any arguments for ClientSession, for example:

>>> client = iNatClient(per_second=50, expire_after=3600, retries=3)

Or you can provide your own session object:

>>> session = MyCustomSession(encabulation_factor=47.2)
>>> client = iNatClient(session=session)

Updating settings#

All settings can also be modified after creating the client:

>>> client.session = ClientSession()
>>> client.creds['username'] = 'my_inaturalist_username'
>>> client.default_params['locale'] = 'es'
>>> client.dry_run = True

Async usage#

Most client methods can be used in an async application without blocking the event loop. Paginator objects can be used as an async iterator:

async for obs in client.observations.search(user_id='my_username'):
    print(obs)

Or to get all results at once, use Paginator.async_all():

query = client.observations.search(user_id='my_username')
observations = await query.async_all()

Controller methods#

This section lists all the methods available on each controller.