Skip to main content

A lightweight, fidelity-preserving GEDCOM parser, writer, and CLI for genealogy files (5.5.1, 5.5.5, and FamilySearch GEDCOM 7).

Project description

gedcom-lite

A lightweight, fidelity-preserving GEDCOM parser, writer, and command-line toolkit for genealogy files. Supports GEDCOM 5.5.1, 5.5.5, and the current FamilySearch GEDCOM 7.0+ standard.

The "lite" in the name is a deliberate scope choice: pure Python, no runtime dependencies, no schema validation, no genealogy domain modelling beyond what the file format itself defines. The library models GEDCOM as a tree of Structure records and exposes search and mutation primitives that round-trip every file in the official sample suite byte-for-byte.

Why use it

  • Round-trip fidelity. Parse a file and write it back unchanged: BOM, line endings, CONC/CONT choice, sibling order, and unknown extension tags are all preserved.
  • Targeted edits. Mutation primitives mark only the structures you change as dirty; every other line emits byte-identical to the source. An update that touches a single NAME produces a one-line diff.
  • Encoding coverage. Detects UTF-8 (with or without BOM), UTF-16 LE/BE (with BOM), and ANSEL (legacy 5.5.1) — the ANSEL codec ships in-package.
  • No dependencies. Pure Python 3.11+ standard library.
  • Three CLI tools. gedcom-read, gedcom-search, gedcom-update cover the common verbs without scripting.

Install

# from PyPI
pip install gedcom-lite

# from git
pip install "git+https://github.com/vaelen/gedcom-lite@v0.1.0"

# editable, for hacking
git clone https://github.com/vaelen/gedcom-lite
cd gedcom-lite
pip install -e ".[dev]"

Library usage

from gedcom_lite import GedcomDocument

doc = GedcomDocument.parse("tree.ged")

print(doc.version)               # '7.0'
print(doc.encoding)              # 'utf-8-sig'
print(doc.record_counts())       # {'INDI': 142, 'FAM': 47, ...}

indi = doc.resolve("@I1@")
name = indi.find("NAME")
name.set_payload("Jane /Doe/")

doc.write("tree-edited.ged")

The full surface is documented in src/gedcom_lite/__init__.py. Common helpers:

from gedcom_lite import (
    GedcomDocument, Structure,
    parse_date_value, DateValue,
    parents_of, children_of, ancestors_of, descendants_of,
    document_to_dict, structure_to_dict,
)

CLI usage

Three console scripts are installed:

gedcom-read   FILE [...]
gedcom-search FILE [filters...]
gedcom-update FILE [-o OUT | --in-place] SUBCOMMAND ...

Examples:

# overview of a file
gedcom-read tree.ged

# list every individual
gedcom-read tree.ged list INDI

# show one record with pointers resolved
gedcom-read tree.ged record @I1@

# JSON dump for piping into jq
gedcom-read tree.ged --json | jq '.records | length'

# find people named Smith
gedcom-search tree.ged --person Smith

# people born between 1900 and 1910
gedcom-search tree.ged --born-between 1900 1910

# died before 1776 (MIN/MAX work as unbounded sentinels on either side)
gedcom-search tree.ged --died-between MIN 1776

# combine person/date/place filters — they AND together
gedcom-search tree.ged --person Smith --born-between 1800 1850 --died-in Boston

# children, parents, ancestors, descendants
gedcom-search tree.ged --children-of @I1@
gedcom-search tree.ged --ancestors-of @I1@ --depth 4

# traversal composes with person/date/place filters as a post-filter
gedcom-search tree.ged --ancestors-of @I1@ --born-in Boston --facts

# ancestor records carry their generation in JSON (subject = 0, parents = 1, …)
gedcom-search tree.ged --ancestors-of @I1@ --json | jq '.[].generation'

# canonical per-INDI facts (xref, name, birth, death, parents, famc)
gedcom-search tree.ged --xref @I1@ --facts
gedcom-search tree.ged --ancestors-of @I1@ --facts | jq '.[] | {xref, name, generation}'

# Sosa-Stradonitz numbered ancestors (subject = 1, father of N = 2N, mother = 2N+1)
gedcom-search tree.ged --ahnentafel @I1@ --primary-famc-only

# list individuals with conflicting (multiple) FAMC links
gedcom-search tree.ged --famc-conflicts --facts

# edit a name (default writes to stdout)
gedcom-update tree.ged set-payload @I1@ NAME "Jane /Doe/" > new.ged

# add a NOTE to a record (write to a file)
gedcom-update tree.ged -o new.ged add-substructure @I1@ "" NOTE "Met at reunion"

# delete a record, voiding inbound pointers
gedcom-update tree.ged -o new.ged delete-record @I7@ --orphan-pointers void

# overwrite the source (be sure)
gedcom-update tree.ged --in-place set-payload @I1@ NAME "Jane /Doe/"

gedcom-update never modifies the input file unless --in-place is given.

Run any tool with --help for the full flag list.

Tests

pip install -e ".[dev]"
pytest

The suite covers:

  • Tokenizer edge cases (xref slot, missing payload, malformed lines)
  • Encoding detection (BOM-first, then 1 CHAR, then ANSEL)
  • ANSEL codec round-trips, including combining-mark ordering
  • Date parsing across ABT, BET … AND …, FROM … TO …, calendar escapes
  • Round-trip of every fixture in examples/ (the gating test)
  • Mutation primitives, including the "only-touched-lines-change" property
  • Ancestry/descendancy traversal
  • CLI smoke tests for gedcom-read, gedcom-search, gedcom-update

Releasing

Maintainer notes — releases publish to PyPI from .github/workflows/release.yml via OIDC trusted publishing (no stored tokens).

  1. Bump the version in pyproject.toml, src/gedcom_lite/__init__.py, and CHANGELOG.md. Push the changes to the main branch.
  2. (Optional) Rehearse to TestPyPI: gh workflow run release.yml.
  3. Cut the release: gh release create vX.Y.Z --generate-notes. The workflow builds and uploads to PyPI on the release: published event.

The PyPI / TestPyPI trusted-publisher entries and the matching pypi / testpypi GitHub Environments are one-time setup, documented at the top of release.yml. CI runs pytest on push and PR across Python 3.11/3.12/3.13.

Versions in scope

  • GEDCOM 5.5.1 (1999) — the de-facto interchange format used by virtually every genealogy app shipped before 2022.
  • GEDCOM 5.5.5 (2019) — cleanup release of the 5.5.x line.
  • FamilySearch GEDCOM 7.0+ (2021–) — current, actively maintained. UTF-8 only, real extension mechanism, GEDZIP packaging, no CONC.

GEDCOM 7 is a breaking change from 5.5.x. gedcom-lite reads any of the three; on write it never silently promotes a file to a different version.

License

MIT — see LICENSE.

References

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

gedcom_lite-0.2.0.tar.gz (143.5 kB view details)

Uploaded Source

Built Distribution

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

gedcom_lite-0.2.0-py3-none-any.whl (30.6 kB view details)

Uploaded Python 3

File details

Details for the file gedcom_lite-0.2.0.tar.gz.

File metadata

  • Download URL: gedcom_lite-0.2.0.tar.gz
  • Upload date:
  • Size: 143.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gedcom_lite-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b7fdddbdc469abaae00163ccddf5848d48d99fb677741ee6f936f1d50b7c6b1c
MD5 d67536c8366dece485ca45610aaac2f4
BLAKE2b-256 174d3f2b7bd901190cf668826f050c30d9b19ecf2a45650c0058af9e6706eb60

See more details on using hashes here.

Provenance

The following attestation bundles were made for gedcom_lite-0.2.0.tar.gz:

Publisher: release.yml on vaelen/gedcom-lite

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

File details

Details for the file gedcom_lite-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: gedcom_lite-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 30.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gedcom_lite-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f71a3e77e6c451c900c7fc5030f437f9fc9d49dbd525dc222ae0197cc310559
MD5 0321e90a070bca9d96ce655571ae6eec
BLAKE2b-256 78a1a47fdbb7eb8ed5ef45c8d426dc227324e778d6c2e988a90a4425be9649e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for gedcom_lite-0.2.0-py3-none-any.whl:

Publisher: release.yml on vaelen/gedcom-lite

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

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