Skip to main content

Python client library for the Clann family-tree API

Project description

pyclann

Python client library for the Clann family-tree API.

Installation

pip install pyclann

Quick start

from pyclann import ClannClient

client = ClannClient(
    api_url="http://localhost:8090",
    auth_url="http://localhost:8081",   # ullav-user-management service
)
client.login(email="user@example.com", password="secret")

# Family trees
trees = client.trees.list(owner="alice")
tree = client.trees.create("walsh-family", "Walsh Family", owner="alice")

# Persons
father = client.persons.create(
    "Walsh", "Patrick", "Male",
    trees=["walsh-family"],
    date_of_birth="1820-06-01",
    created_by="alice",
)
son = client.persons.create(
    "Walsh", "Michael", "Male",
    trees=["walsh-family"],
    created_by="alice",
)

# Relationships
client.relationships.add(son.id, "Father", father.id)
rels = client.relationships.get(son.id)       # RelationshipsResponse

# Life events
client.life_events.create(
    father.id, "Born in Galway", "Birth",
    date="1820-06-01",
    created_by="alice",
)

# Research notes
note = client.notes.create(
    "Walsh Family Research",
    trees=["walsh-family"],
    body="Found records at Galway archives.",
    is_shared=True,
    created_by="alice",
)
client.notes.create_reply(note.id, "Also check Dublin records.", created_by="alice")

# Profile picture
with open("patrick.jpg", "rb") as f:
    client.persons.upload_image(father.id, f.read(), "image/jpeg")

image_bytes = client.persons.get_image(father.id)   # public endpoint, no auth needed

Authentication

ClannClient authenticates against the ullav-user-management service, which issues the JWT accepted by the Clann server.

  • api_url — Clann server base URL (e.g. http://clann-server:8090)
  • auth_url — auth service base URL (e.g. http://ullav-user-management:8081); omit if both services are behind the same proxy

Call client.login(email, password) before any other method. Tokens expire according to the server's configuration; call login() again to refresh.

Resource clients

Attribute Resource
client.trees Family tree CRUD, primary flag, team assignment, avatar image
client.persons Person CRUD, tree membership, profile/life-story media
client.relationships Add/remove father/mother/sibling/spouse edges, family-tree view
client.life_events Life event CRUD per person
client.notes Research note CRUD, folder assignment, replies
client.folders Research folder CRUD
client.chat AI chat session and message management
client.ai_settings Per-user AI provider settings (encrypted BYOK)

Error handling

from pyclann import ClannAuthError, ClannNotFoundError, ClannValidationError

try:
    tree = client.trees.get("non-existent-tree")
except ClannNotFoundError:
    print("tree not found")
except ClannAuthError:
    client.login(email, password)   # token expired — re-authenticate
except ClannValidationError as e:
    print("bad request:", e)
Exception HTTP status
ClannAuthError 401 / 403, or login() not called
ClannNotFoundError 404
ClannValidationError 400
ClannServerError 5xx
ClannError base class

Record IDs

The Clann API uses SurrealDB record IDs of the form "table:ulid", e.g. "person:01jd4a8xyz". All client methods that take an *_id parameter accept either the full form or the bare ULID — the library strips the table prefix when building URL paths.

person = client.persons.get("person:01jd4a8xyz")   # full ID
person = client.persons.get("01jd4a8xyz")           # bare ULID — both work

Note: when specifying a related_id in relationship calls, always pass the full record ID ("person:01jd4a8xyz"), since the server uses it verbatim in URL paths.

Relationship types

from pyclann import RelationshipType, SiblingType

# Add a father
client.relationships.add(child.id, RelationshipType.FATHER, father.id)

# Add a sibling — sibling_type is required
client.relationships.add(
    person.id,
    RelationshipType.SIBLING,
    sibling.id,
    sibling_type=SiblingType.BROTHER,
)

# Add a spouse with dates
client.relationships.add(
    person.id,
    RelationshipType.SPOUSE,
    spouse.id,
    spouse_from="1845-09-14",
)

# Remove a relationship
client.relationships.remove(child.id, RelationshipType.FATHER, father.id)

Image uploads

Profile pictures accept JPEG or PNG only (max 2 MB). Life-story media accepts the same image formats on Individual/Family plans; Professional/Enterprise plans also allow video (MP4, MOV, WebM), audio (MP3, WAV, OGG), and PDF.

# Upload
with open("profile.jpg", "rb") as f:
    client.persons.upload_image(person.id, f.read(), "image/jpeg")

# Download — no login() required
data = client.persons.get_image(person.id)
with open("downloaded.jpg", "wb") as f:
    f.write(data)

Licence

MIT

Project details


Download files

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

Source Distribution

pyclann-26.1.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

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

pyclann-26.1.0-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

Details for the file pyclann-26.1.0.tar.gz.

File metadata

  • Download URL: pyclann-26.1.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pyclann-26.1.0.tar.gz
Algorithm Hash digest
SHA256 e8f24c8af579da9630e08c61bb14579d60378ec398313f740073a2902d31bf27
MD5 5cf713162eb62008a525ba2fd479c32b
BLAKE2b-256 820769e3cd82b22d7c353c7c87ca521a1ef5a11650ef60c093442cd8f5d3ad85

See more details on using hashes here.

File details

Details for the file pyclann-26.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyclann-26.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pyclann-26.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8873417e30e8924d83e9ab313fa569a53d44ae92545350f66f0a6d3fee287f0
MD5 d97a8ececfa6410817584cadba8f725d
BLAKE2b-256 d2375f1ed9a884bd38d8a7b2042be09c1d64fff529e9728252c4660c00afe49f

See more details on using hashes here.

Supported by

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