Current version: 0.5

Welcome to civicrmapi documentation#

About#

This package provides a convenient way to access CiviCRM’s REST API from python applications. It supports both API verions v3 and v4 via http requests and the cv command.

Getting Started#

There are four ready to use api classes:

  • HttpApiV3 - HTTP API bindings for CiviCRM’s APIv3

  • HttpApiV4 - HTTP API bindings for CiviCRM’s APIv4

  • CvApiV3 - cv API bindings for CiviCRM’s APIv3

  • CvApiV4 - cv API bindings for CiviCRM’s APIv4

All you need to do is to initialize the api of your choice and use it:

>>> api = CvApiV4(cv=cv, context=context)
>>> params = {
...     "contact_type": "Organization",
...     "organization_name": "pretty org",
...     }
>>> result = api.Contact.create(params)
>>> result[0]['organization_name']
'pretty org'

Concept#

There are three main base classes an api binding is built of:

  • BaseApi - Base class for all API implementations

  • BaseEntity - Base class for CiviCRM entities

  • BaseAction - Base class for CiviCRM actions

Initializing an api class will automatically equip it with entities, which themselves are equipped with actions - each as instance attributes. And on each level of this hierarchy an api call can be performed. The api, its entities and their actions are all callable.

The following ways of performing an api call are equivalent:

>>> api = HttpApiV4(url=url, api_key=api_key)
>>> params = {"contact_type": "Organization"}

>>> # Calling the action instance.
>>> result_one = api.Contact.get(params)

>>> # Calling the entity instance passing the action as parameter.
>>> result_two = api.Contact('get', params)

>>> # Calling the api instance  passing the entity and action as parameters.
>>> result_three = api('Contact', 'get', params)

>>> result_one == result_two == result_three
True

The standard entities and actions for each api version are defined within the the corresponding modules v3 and v4. You can also implement special behavior like custom validation, result parsing or error handling by writing your own api, entity or action subclasses.

API Parameters#

The API v3 and API v4 have different formats for api parameters. While the API v3 uses a flat dictonary with entity field parameters as well as meta informations like limit on the same level, the API v4 has a more structured and “sql-like” way to format the parameters - using keywords like select, values, where and join.

You can always use the version’s specific way of structuring the parameters for your api call. Just use the api explorer or read the api documentation to check out what’s possible and how to achieve it.

For simple api calls using only entity field parameters to get, create, delete or update objects, civicrmapi helps you building the v4 parameters out of a plain field-value dictonary.

So those Contact.get api calls are equivalent:

>>> api = CvApiV4(cv=cv, context=context)

>>> # Api call with original v4 parameter format.:
>>> params = {
...     'where': [
...         ['contact_type', '=', 'Individual'],
...         ['preferred_language', '=', 'de_DE'],
...     ]
... }
>>> result_one = api.Contact.get(params)

>>> # Api call using a simple field value dictonary:
>>> params = {
...     'contact_type': 'Individual',
...     'preferred_language': 'de_DE',
... }
>>> result_two = api.Contact.get(params)

>>> result_one == result_two
True

The same works for a create api call:

>>> api = CvApiV4(cv=cv, context=context)

>>> # Original v4 parameters are:
>>> params = {
...     'values': {
...         'contact_type': 'Organization',
...         'organization_name': 'Super Org',
...     }
... }
>>> result = api.Contact.create(params)
>>> result[0]['organization_name']
'Super Org'

>>> # Those could be also passed in as:
>>> params = {
...     'contact_type': 'Organization',
...     'organization_name': 'Another Super Org',
... }
>>> result = api.Contact.create(params)
>>> result[0]['organization_name']
'Another Super Org'

And even for an update api call if you use the id field to select your entity:

>>> api = CvApiV4(cv=cv, context=context)

>>> # Original v4 parameters are:
>>> params = {
...     'where': [
...         ['id', '=', 1],
...     ],
...     'values': {
...         'organization_name': 'Super Org',
...     }
... }
>>> result = api.Contact.update(params)
>>> result[0]['organization_name']
'Super Org'

>>> # Those could be also passed in as:
>>> params = {
...     'id': 1,
...     'organization_name': 'Mega Org',
... }
>>> result = api.Contact.update(params)
>>> result[0]['organization_name']
'Mega Org'

Results#

In most cases the CiviCRM’s API returns a dictonary holding some meta data and a values key with the actual result data. But APIv4 calls done via the cv command returns the results as a plain list - skipping all the meta data.

Since the result’s meta data is irrelevant in the very most usage cases, and to be consistent throughout all api classes, civicrmapi always returns results as a plain list. So with all API classes you get something like:

[{'id': 1, ...}, {'id': 2, ...}, ...]

Build your own API class#

civicrmapi is not only ment as ready-to-use API bindings but also as a build kit for complex api tasks. New functionality can be implemented on api, entity and action level. As an example let’s build an get-or-create action for the Contact entity:

>>> class Contact(BaseEntity):
...     NAME = 'Contact'
...     def get_or_create(self, params):
...         result = self.get(params)
...         if not result:
...             result = self.create(params)
...         return result

>>> api = CvApiV4(cv=cv, context=context)
>>> params = {
...     'contact_type': 'Organization',
...     'organization_name': 'Super Org',
... }

>>> contact_entity = Contact(api)
>>> contact = contact_entity.get_or_create(params)
>>> same_contact = contact_entity.get_or_create(params)
>>> contact[0]['id'] == same_contact[0]['id']
True

What if we want a get-or-create action for all entities of an api instance? Let’s try another approach using a mixin for our entities:

>>> class MyMixin:
...     def get_or_create(self, params):
...         result = self.get(params)
...         if not result:
...             result = self.create(params)
...         return result

>>> class MyApi(CvApiV4):
...     def _add_entities(self):
...         for entity in self.VERSION.ENTITIES:
...             entity = type(entity, (MyMixin, BaseEntity), dict(NAME=entity))
...             setattr(self, entity.NAME, entity(self))

>>> api = MyApi(cv=cv, context=context)
>>> params = {
...     'contact_id': 2,
...     'email': 'foo@bar.de',
... }

>>> email = api.Email.get_or_create(params)
>>> same_email = api.Email.get_or_create(params)
>>> email[0]['id'] == same_email[0]['id']
True

There are surely other options like writing a custom api action and using them with different entities or writing custom code on an api level to collect statistics on api usage ect. Use what ever approach fits to your needs.


Reference#

Base API classes#

class civicrmapi.base.BaseApi#

Base CiviCRM API class. Instances are callables performing api calls.

This class will be initialized with the standard entities for the specific api version as instance attributes. (See civicrmapi.v3.ENTITIES and civicrmapi.v4.ENTITIES.)

Raises
  • NotImplemented – when VERSION is not defined

  • NotImplemented – when _perform_api_call() is not implemented

VERSION = None#

The CiviCRM API version. Use either v3 or v4 in your subclass.

__call__(entity, action, params=None)#

Perform an api call.

Parameters
  • entity (str) – CiviCRM-entitiy

  • action (str) – api call action

  • params (dict) – api call parameters (optional)

Return list

result data as list of dictonaries

class civicrmapi.base.BaseEntity(api)#

Base class for CiviCRM entities. Instances are callables performing api calls with the api instance the class was initialized with.

The api version’s default actions are added automatically on initialization.

(See civicrmapi.v3.ACTIONS and civicrmapi.v4.ACTIONS.)

Parameters

api (BaseApi) – CiviCRM API instance

Raises

NotImplemented – when NAME is not defined

NAME = None#

Must be set by a subclass.

__call__(action, params=None)#

Perform an api call on this entity using its api.

Parameters
  • action (str) – api call action

  • params (dict) – api call parameters (optional)

Return list

result data as list of dictonaries

class civicrmapi.base.BaseAction(entity)#

Base class for CiviCRM API actions. Instances are callables performing api calls on the entity instance the class was initialized with.

Parameters

entity (BaseEntity) – entity instance

Raises

NotImplemented – when NAME is not defined

NAME = None#

Must be set by a subclass.

__call__(params=None)#

Perform an api call with this action using its entity.

Parameters

params (dict) – api call parameters (optional)

Return list

result data as list of dictonaries

REST API for v3 and v4#

class civicrmapi.http.HttpApiV3(url, api_key, site_key, htaccess=None, verify_ssl=True, timeout=None)#

HTTP API bindings for CiviCRM’s API v3.

Parameters
  • url (str) – CiviCRM’s base-url

  • api_key (str) – CiviCRM’s api-key

  • site_key (str) – CiviCRM’s api-site_key

  • htaccess (dict) – htaccess credentials with ‘user’ and ‘pass’ keys. (optional)

  • verify_ssl (bool) – Verify SSL-certificate or not. Default is True. (optional)

  • timeout (int) – Timeout in seconds. (optional)

class civicrmapi.http.HttpApiV4(url, api_key, htaccess=None, verify_ssl=True, timeout=None)#

HTTP API bindings for CiviCRM’s API v4.

Parameters
  • url (str) – CiviCRM’s base-url

  • api_key (str) – CiviCRM’s api-key

  • htaccess (dict) – htaccess credentials with ‘user’ and ‘pass’ keys. (optional)

  • verify_ssl (bool) – Verify SSL-certificate or not. Default is True. (optional)

  • timeout (int) – Timeout in seconds. (optional)

API v3 and v4 for cv#

class civicrmapi.cv.CvApiV3(cv='cv', cwd=None, context=None)#

Cv API bindings for CiviCRM APIv3.

Parameters
  • cv (str) – cv command

  • cwd (str) – working directory for cv

  • context (str) – If a context is given the original command will be tokenized and given to the context as positional argument. The simplest context migth be a ‘sh -c’. But it could also be a docker-exec- or ssh-command to run the api call within a docker container or on a remote machine.

class civicrmapi.cv.CvApiV4(cv='cv', cwd=None, context=None)#

Cv API bindings for CiviCRM APIv4.

Parameters
  • cv (str) – cv command

  • cwd (str) – working directory for cv

  • context (str) – If a context is given the original command will be tokenized and given to the context as positional argument. The simplest context migth be a ‘sh -c’. But it could also be a docker-exec- or ssh-command to run the api call within a docker container or on a remote machine.

API v3 module#

This module defines default entities and actions for CiviCRM APIv3.

civicrmapi.v3.ENTITIES = ['Acl', 'AclRole', 'ActionSchedule', 'Activity', 'ActivityContact', 'ActivityType', 'Address', 'Attachment', 'Batch', 'Campaign', 'Case', 'CaseContact', 'CaseType', 'Constant', 'Contact', 'ContactType', 'Contribution', 'ContributionPage', 'ContributionProduct', 'ContributionRecur', 'ContributionSoft', 'Country', 'CustomField', 'CustomGroup', 'CustomSearch', 'CustomValue', 'Cxn', 'CxnApp', 'Dashboard', 'DashboardContact', 'Dedupe', 'Domain', 'Email', 'Entity', 'EntityBatch', 'EntityFinancialAccount', 'EntityFinancialTrxn', 'EntityTag', 'Event', 'Exception', 'Extension', 'File', 'FinancialAccount', 'FinancialItem', 'FinancialTrxn', 'FinancialType', 'Group', 'GroupContact', 'GroupNesting', 'GroupOrganization', 'Im', 'Job', 'JobLog', 'LineItem', 'LocBlock', 'LocationType', 'Logging', 'MailSettings', 'Mailing', 'MailingAB', 'MailingComponent', 'MailingContact', 'MailingEventConfirm', 'MailingEventQueue', 'MailingEventResubscribe', 'MailingEventSubscribe', 'MailingEventUnsubscribe', 'MailingGroup', 'MailingJob', 'MailingRecipients', 'Mapping', 'MappingField', 'Membership', 'MembershipBlock', 'MembershipLog', 'MembershipPayment', 'MembershipStatus', 'MembershipType', 'MessageTemplate', 'Navigation', 'Note', 'OpenID', 'OptionGroup', 'OptionValue', 'Order', 'Participant', 'ParticipantPayment', 'ParticipantStatusType', 'Payment', 'PaymentProcessor', 'PaymentProcessorType', 'PaymentToken', 'Pcp', 'Phone', 'Pledge', 'PledgePayment', 'Premium', 'PriceField', 'PriceFieldValue', 'PriceSet', 'PrintLabel', 'Product', 'Profile', 'RecurringEntity', 'Relationship', 'RelationshipType', 'ReportInstance', 'ReportTemplate', 'Rule', 'RuleGroup', 'SavedSearch', 'Setting', 'SmsProvider', 'StateProvince', 'StatusPreference', 'Survey', 'SurveyRespondant', 'System', 'SystemLog', 'Tag', 'UFField', 'UFGroup', 'UFJoin', 'UFMatch', 'User', 'Website', 'WordReplacement']#

All standard entities for CiviCRM APIv3.

civicrmapi.v3.ACTIONS = ['create', 'delete', 'get', 'getsingle', 'getvalue', 'getcount', 'getrefcount', 'getfields', 'getlist', 'getoptions', 'replace', 'getunique']#

All standard actions for CiviCRM APIv3.

API v4 module#

This module defines default entities and actions for CiviCRM APIv4.

civicrmapi.v4.ENTITIES = ['ACL', 'ACLEntityRole', 'ActionSchedule', 'Activity', 'ActivityContact', 'Address', 'Batch', 'Contact', 'ContactType', 'Contribution', 'ContributionPage', 'ContributionProduct', 'ContributionRecur', 'ContributionSoft', 'Country', 'County', 'CustomField', 'CustomGroup', 'Dashboard', 'DashboardContact', 'DedupeException', 'DedupeRule', 'DedupeRuleGroup', 'Domain', 'Email', 'Entity', 'EntityBatch', 'EntityFinancialAccount', 'EntityFinancialTrxn', 'EntityTag', 'Event', 'ExampleData', 'Extension', 'File', 'FinancialAccount', 'FinancialItem', 'FinancialTrxn', 'FinancialType', 'Group', 'GroupContact', 'GroupNesting', 'GroupOrganization', 'IM', 'Job', 'JobLog', 'LineItem', 'LocBlock', 'LocationType', 'Log', 'MailSettings', 'Mailing', 'MailingEventBounce', 'MailingEventConfirm', 'MailingEventOpened', 'MailingEventQueue', 'MailingEventSubscribe', 'MailingEventUnsubscribe', 'MailingGroup', 'MailingJob', 'Managed', 'Mapping', 'MappingField', 'Membership', 'MembershipBlock', 'MembershipStatus', 'MembershipType', 'MessageTemplate', 'Navigation', 'Note', 'OpenID', 'OptionGroup', 'OptionValue', 'PCP', 'PCPBlock', 'Participant', 'PaymentProcessor', 'PaymentProcessorType', 'PaymentToken', 'Permission', 'Phone', 'PriceField', 'PriceFieldValue', 'PriceSet', 'PriceSetEntity', 'PrintLabel', 'Product', 'Queue', 'RecentItem', 'Relationship', 'RelationshipCache', 'RelationshipType', 'ReportInstance', 'Route', 'SavedSearch', 'SearchDisplay', 'SearchSegment', 'Setting', 'StateProvince', 'StatusPreference', 'SubscriptionHistory', 'System', 'Tag', 'Translation', 'UFField', 'UFGroup', 'UFJoin', 'UFMatch', 'UserJob', 'Website', 'WordReplacement', 'WorkflowMessage', 'WorldRegion']#

All standard entities for CiviCRM APIv4.

civicrmapi.v4.ACTIONS = ['checkAccess', 'getActions', 'getFields', 'get', 'create', 'update', 'save', 'delete', 'replace']#

All standard actions for CiviCRM APIv4.

Exceptions#

Exceptions raised by civicrmapi.

There are three main levels where errors can occur when performing an api call:

  • The api cannot be reached.

  • Invalid api credentials are used.

  • Missing permissions.

  • The api call is invalid due to malformed parameters.

  • The api call cannot be processed by CiviCRM..

Exceptions raised by the first level are subprocess or requests related. We leave them alone. If we got valid Responses but do not get valid json formatted result data we raise InvalidResponse. This for sure can have many different reasons.

For all api related exceptions (level 2, 3 and 4) we use either AccessDenied or ApiError. (We try hard to distinguish them from not api related ones… which is not always possible.)

exception civicrmapi.errors.ApiCallError#

Bases: Exception

Base class for all civicrmapi exceptions.

exception civicrmapi.errors.ApiError#

Bases: ApiCallError

Raised when CiviCRM’s api returns an error-code, respectively the cv api v4 command returns a specific stderr indicating a malformed api call.

Params data

api result data as dict or error message as string

property data#

Result data the exception was initialized with.

exception civicrmapi.errors.AccessDenied#

Bases: ApiError

Raised by HTTP api on access denied due to invalid credentials. This class uses the ApiError as base class.

Params data

api result data as dict or error message as string

exception civicrmapi.errors.InvalidResponse#

Bases: ApiCallError

Raised for valid responses with for - which reason ever - invalid response data. For example a subprocess call which succeeds but do not return valid json data. This may happen if the command does not reach the api at all, but do not exit with a proper return code.

Params value

Either requests or subprocess response

property response#

Response object the exception was initialized with.


Indices and tables#