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 APIv3HttpApiV4- HTTP API bindings for CiviCRM’s APIv4CvApiV3- cv API bindings for CiviCRM’s APIv3CvApiV4- 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 implementationsBaseEntity- Base class for CiviCRM entitiesBaseAction- 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.ENTITIESandcivicrmapi.v4.ENTITIES.)- Raises
NotImplemented – when
VERSIONis not definedNotImplemented – when
_perform_api_call()is not implemented
- __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.ACTIONSandcivicrmapi.v4.ACTIONS.)
- 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
NAMEis 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:
ExceptionBase class for all civicrmapi exceptions.
- exception civicrmapi.errors.ApiError#
Bases:
ApiCallErrorRaised 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:
ApiErrorRaised by HTTP api on access denied due to invalid credentials. This class uses the
ApiErroras base class.- Params data
api result data as dict or error message as string
- exception civicrmapi.errors.InvalidResponse#
Bases:
ApiCallErrorRaised 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.