Skip to main content

civicrm-py

CI PyPI version Python Version License: MIT

A Python client for CiviCRM's API v4. Async by default, with a query interface that'll feel familiar if you've used Django's ORM.

What it does

  • Async HTTP via httpx (sync wrappers available)
  • Type-safe models using msgspec
  • Chainable queries: client.Contact.filter(is_deleted=False).limit(10).all()
  • Integrations for Django, Litestar, FastAPI, Flask, and others

Install

pip install civicrm-py

With a framework:

pip install civicrm-py[django]
pip install civicrm-py[litestar]
pip install civicrm-py[fastapi]

Optional extras:

pip install civicrm-py[sqlspec]    # Local database caching
pip install civicrm-py[workflows]  # Workflow automation

See docs for sqlspec, workflows, and pytest-databases.

Setup

export CIVI_BASE_URL=https://your-site.org/civicrm/ajax/api4
export CIVI_API_KEY=your-api-key
export CIVI_SITE_KEY=your-site-key

Usage

import asyncio
from civicrm_py import CiviClient

async def main():
    async with CiviClient() as client:
        # Get all active contacts
        contacts = await client.Contact.filter(is_deleted=False).all()

        # Single contact by ID
        contact = await client.Contact.get(id=123)

        # Create
        new_contact = await client.Contact.create(
            first_name="John",
            last_name="Doe",
            contact_type="Individual",
        )

        # Update
        await client.Contact.update(id=123, first_name="Jane")

        # Delete
        await client.Contact.delete(id=123)

asyncio.run(main())

Queries

# Select specific fields, filter, sort, paginate
contacts = await (
    client.Contact
    .select("id", "display_name", "email_primary.email")
    .filter(is_deleted=False, contact_type="Individual")
    .order_by("-created_date")
    .limit(25)
    .all()
)

# Operators
contacts = await (
    client.Contact
    .filter_by("created_date", ">=", "2024-01-01")
    .filter_by("display_name", "LIKE", "%Smith%")
    .all()
)

# Count and exists
total = await client.Contact.filter(is_deleted=False).count()
exists = await client.Contact.filter(id=123).exists()

Litestar

from litestar import Litestar, get
from civicrm_py import CiviClient
from civicrm_py.contrib.litestar import CiviPlugin

@get("/contacts")
async def get_contacts(civi: CiviClient) -> list[dict]:
    return await civi.Contact.filter(is_deleted=False).all()

app = Litestar(
    route_handlers=[get_contacts],
    plugins=[CiviPlugin()],
)

Django

# settings.py
CIVI_SETTINGS = {
    "BASE_URL": "https://example.org/civicrm/ajax/api4",
    "API_KEY": env("CIVI_API_KEY"),
    "SITE_KEY": env("CIVI_SITE_KEY"),
}

# views.py
from civicrm_py.contrib.django import get_civi_client

async def contact_list(request):
    async with get_civi_client() as client:
        contacts = await client.Contact.all()
        return JsonResponse({"contacts": contacts})

Development

git clone https://github.com/JacobCoffee/civicrm-py.git
cd civicrm-py

make install  # dependencies
make test     # tests
make check    # lint + typecheck

Docs

civi.scriptr.dev

Alternatives

  • civipy - Another Python client for CiviCRM. No built-in web framework integrations.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

civicrm_py-0.1.2.tar.gz (211.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

civicrm_py-0.1.2-py3-none-any.whl (261.2 kB view details)

Uploaded Python 3

File details

Details for the file civicrm_py-0.1.2.tar.gz.

File metadata

  • Download URL: civicrm_py-0.1.2.tar.gz
  • Upload date:
  • Size: 211.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for civicrm_py-0.1.2.tar.gz
Algorithm Hash digest
SHA256 a914cc5ab0a70afd8ff0d534085d2370dcd7d75cb35a3c6037c5525a809859f7
MD5 f7d93e2e8f7a4a6db001281bcb9be7ee
BLAKE2b-256 c4e03437a0f742b52a9f2b8bd8537b75494379606f42cb5e8d9f75586f182f4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for civicrm_py-0.1.2.tar.gz:

Publisher: publish.yml on JacobCoffee/civicrm-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file civicrm_py-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: civicrm_py-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 261.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for civicrm_py-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 45d679417e3d9204562e31d77867a205a6fd62809f4fb0d864b8508ddcb3b4ed
MD5 c4f14ce26c3bffd7c26d9c2fb33bbd23
BLAKE2b-256 f8ab70845e19bbb4fd0b5f46901640d62ab120f9e3d27754a25b719ca325c75c

See more details on using hashes here.

Provenance

The following attestation bundles were made for civicrm_py-0.1.2-py3-none-any.whl:

Publisher: publish.yml on JacobCoffee/civicrm-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 files

0.1.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page