geni

package module
v1.21.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

go-geni

Go client for the Geni.com genealogy API. Extracted from terraform-provider-genealogy so the same HTTP layer is usable from CLI tools, migration scripts, and other projects.

Disclaimer

This library uses the Geni API but is not endorsed, operated, or sponsored by Geni.com.

Install

go get github.com/dmalch/go-geni

Usage

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/dmalch/go-geni"
    "golang.org/x/oauth2"
)

func main() {
    token := os.Getenv("GENI_ACCESS_TOKEN")
    if token == "" {
        log.Fatal("set GENI_ACCESS_TOKEN")
    }

    client := geni.NewClient(
        oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token}),
        true, // true = sandbox, false = production
    )

    profile, err := client.Profile().Get(context.Background(), "profile-1")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("name: %s %s\n",
        derefString(profile.FirstName), derefString(profile.LastName))
}

func derefString(p *string) string {
    if p == nil {
        return ""
    }
    return *p
}

A runnable version of this example lives in examples/getprofile/.

Command-line tool

cmd/geni is a CLI façade over the library — handy for OAuth login and quick read queries (geni profile get, geni profile search, geni whoami, …) without writing Go:

go install github.com/dmalch/go-geni/cmd/geni@latest
geni login
geni profile get <id>

See cmd/geni/README.md for the full command list, auth, flags, and examples.

OAuth

The auth subpackage offers a browser-based OAuth implicit-flow helper and a token cache, suitable for interactive CLI tools:

import (
    "golang.org/x/oauth2"
    "github.com/dmalch/go-geni/auth"
)

source := oauth2.ReuseTokenSource(nil,
    auth.NewCachingTokenSource("~/.geni/token.json",
        auth.NewAuthTokenSource(&oauth2.Config{
            ClientID: "1855",
            Endpoint: oauth2.Endpoint{
                AuthURL: "https://www.geni.com/platform/oauth/authorize",
            },
        })))

Headless callers can skip auth entirely and supply any oauth2.TokenSource to geni.NewClient.

Web (AJAX) client

Works around documented gaps in Geni's OAuth API (revision list, document text r/w, merge-center matches list, merge data conflicts) for personal genealogy tooling. The web/ sub-tree is a separate client that talks to the same private AJAX endpoints geni.com itself uses from a logged-in browser — cookie auth, per-form CSRF token, HTML responses.

⚠️ These endpoints are undocumented, unsupported by Geni.com, and may change or break without notice. Using web/ may violate geni.com's Terms of Service — review them before use. The package never logs in for you; it requires cookies from a logged-in browser session you established yourself.

import (
    "context"
    "github.com/dmalch/go-geni/web"
    "github.com/dmalch/go-geni/web/revision"
    "github.com/dmalch/go-geni/web/document"
    "github.com/dmalch/go-geni/web/matches"
    "github.com/dmalch/go-geni/web/conflicts"
)

c, _ := web.NewClient(web.Options{
    Cookies: web.CookiesFromHeader("_geni_session=...; remember_user_token=..."),
})

// List a profile's revision IDs (the OAuth API can't).
ids, _ := revision.NewClient(c).ForProfile(context.Background(), "<profile-guid>")

// Read / write a document's text body (the OAuth API returns text:null).
text, _ := document.NewClient(c).GetText(context.Background(), "<doc-guid>")
err := document.NewClient(c).SaveText(context.Background(), "<doc-guid>", "new body")

// List the merge-center matches (the OAuth API has no equivalent).
res, _ := matches.NewClient(c).List(context.Background(), matches.ListOptions{
    Collection: matches.CollectionManaged,
    Filter:     matches.FilterTreeMatches,
})

// Drill into one profile's tree-match candidates.
fp, _ := matches.NewClient(c).ForProfile(context.Background(), "<profile-guid>",
    matches.ForProfileOptions{})

// List profiles with unresolved merge data conflicts, then clear one by
// keeping the surviving (primary) profile's values.
cl, _ := conflicts.NewClient(c).List(context.Background(), conflicts.ListOptions{})
err = conflicts.NewClient(c).Resolve(context.Background(), "<profile-guid>", nil)

Cookies can also be pulled directly from a logged-in browser on the host via the opt-in web/browsercookies sub-package (uses steipete/sweetcookie — Chrome / Firefox / Safari / Edge / Brave on macOS, Windows, Linux):

import "github.com/dmalch/go-geni/web/browsercookies"

cookies, err := browsercookies.FromGeniCom()
c, _ := web.NewClient(web.Options{Cookies: cookies})

The Web client ships with a conservative 1 req/sec rate limit by default (web.Options.RateLimit overrides it on your own account). Runnable examples live in examples/webrevisions and examples/webdocumenttext.

Behaviour

  • 1 request/second rate limit, adjusted on the fly from X-API-Rate-Limit response headers.
  • Retries on 429 (rate limited), 401 (token expired), and transient transport errors via github.com/avast/retry-go.
  • Bulk-read coalescing for profile/document/union endpoints when multiple concurrent reads target the same family of resources.
  • Sandbox or production environment selectable per client.

Documentation

API reference: https://pkg.go.dev/github.com/dmalch/go-geni

Contributing

make test                # unit + Ginkgo integration (in-process)
make lint                # golangci-lint
make check               # build + vet + lint + test (CI parity)

The sandbox E2E suite under test/acceptance/ self-skips unless GENI_ACCESS_TOKEN is exported. Mint a sandbox token at https://sandbox.geni.com/platform/developer/api_explorer and run make test-acceptance before pushing changes that touch endpoint or request-shape code. CI does not run E2E.

License

Apache-2.0. See LICENSE.

Documentation

Overview

Package geni is a Go client for the Geni.com genealogy API.

geni.Client is a thin façade: it constructs one shared HTTP transport and exposes a per-resource client for each of Geni's resources via an accessor method (Profile, Union, Document, Photo, Video, PhotoAlbum, Project, Surname, Revision, Stats, User, Search, Tree). Each accessor returns a *Client from the matching sub-package — e.g. Client.Profile() returns a *profile.Client.

Callers that only need one resource can import that sub-package directly and construct its client from a *transport.Client; the façade is an ergonomic aggregate, not a required entry point.

Index

Constants

This section is empty.

Variables

View Source
var ErrAccessDenied = transport.ErrAccessDenied

ErrAccessDenied is returned for 403 responses from the Geni API. Re-exported from the transport package.

View Source
var ErrResourceNotFound = transport.ErrResourceNotFound

ErrResourceNotFound is returned for 404 responses from the Geni API. Re-exported from the transport package so callers can errors.Is against geni.ErrResourceNotFound without importing transport.

Functions

func BaseURL

func BaseURL(useSandboxEnv bool) string

BaseURL returns the prod or sandbox HTTP host (with trailing slash).

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the Geni API façade. It owns one shared transport and one client per resource; reach a resource through its accessor (e.g. Client.Profile).

func NewClient

func NewClient(tokenSource oauth2.TokenSource, useSandboxEnv bool) *Client

NewClient constructs a Client. useSandboxEnv selects between sandbox.geni.com (true) and www.geni.com (false).

func (*Client) Document added in v1.0.0

func (c *Client) Document() *document.Client

Document returns the client for the Document resource — including the profile-scoped ForProfile / AddToProfile listings and the project-scoped AddToProject.

func (*Client) Photo added in v1.0.0

func (c *Client) Photo() *photo.Client

Photo returns the client for the Photo resource — including the profile-scoped ForProfile / AddToProfile / AddMugshotToProfile operations.

func (*Client) PhotoAlbum added in v1.0.0

func (c *Client) PhotoAlbum() *photoalbum.Client

PhotoAlbum returns the client for the PhotoAlbum resource.

func (*Client) Profile added in v1.0.0

func (c *Client) Profile() *profile.Client

Profile returns the client for the Profile resource — CRUD, relationship adds (partner / child / sibling / parent), merge, follow / unfollow, basics-update, and event-date wiping.

func (*Client) Project added in v1.0.0

func (c *Client) Project() *project.Client

Project returns the client for the Project resource.

func (*Client) Revision added in v1.0.0

func (c *Client) Revision() *revision.Client

Revision returns the client for the Revision resource.

func (*Client) Search added in v1.0.0

func (c *Client) Search() *search.Client

Search returns the client for /profile/search.

func (*Client) Stats added in v1.0.0

func (c *Client) Stats() *stats.Client

Stats returns the client for the platform-wide statistics endpoint.

func (*Client) Surname added in v1.0.0

func (c *Client) Surname() *surname.Client

Surname returns the client for the Surname resource.

func (*Client) Tree added in v1.0.0

func (c *Client) Tree() *tree.Client

Tree returns the client for Geni's family-graph endpoints — immediate-family, ancestors, path-to, and compare.

func (*Client) Union added in v1.0.0

func (c *Client) Union() *union.Client

Union returns the client for the Union resource.

func (*Client) User added in v1.0.0

func (c *Client) User() *user.Client

User returns the client for the User resource and all /user/* listings (followed-*, uploaded-*, managed-profiles, max-family, my-albums, my-labels, metadata).

func (*Client) Video added in v1.0.0

func (c *Client) Video() *video.Client

Video returns the client for the Video resource — including the profile-scoped AddToProfile operation.

Directories

Path Synopsis
cmd
geni command
Command geni is a command-line client for the Geni.com genealogy API.
Command geni is a command-line client for the Geni.com genealogy API.
Package comment carries the Comment resource's wire types.
Package comment carries the Comment resource's wire types.
Package document carries the Document resource's wire types.
Package document carries the Document resource's wire types.
examples
getprofile command
Command getprofile is a minimal smoke example that constructs a go-geni Client against the sandbox and fetches a single profile.
Command getprofile is a minimal smoke example that constructs a go-geni Client against the sandbox and fetches a single profile.
listmanaged command
Command listmanaged streams every Geni profile managed by the authenticated user as one JSON object per line on stdout.
Command listmanaged streams every Geni profile managed by the authenticated user as one JSON object per line on stdout.
refreshtoken command
Command refreshtoken runs the same OAuth implicit-flow handshake as the terraform-provider-genealogy uses, then writes the resulting token to ~/.genealogy/geni_token.json (prod) or geni_sandbox_token.json (sandbox).
Command refreshtoken runs the same OAuth implicit-flow handshake as the terraform-provider-genealogy uses, then writes the resulting token to ~/.genealogy/geni_token.json (prod) or geni_sandbox_token.json (sandbox).
webdocumenttext command
Command webdocumenttext is a smoke example for the AJAX Web client's document-text endpoints.
Command webdocumenttext is a smoke example for the AJAX Web client's document-text endpoints.
webrevisions command
Command webrevisions is a smoke example for the AJAX Web client's revision endpoint.
Command webrevisions is a smoke example for the AJAX Web client's revision endpoint.
Package photo carries the Photo resource's wire types.
Package photo carries the Photo resource's wire types.
Package photoalbum carries the PhotoAlbum resource's wire types.
Package photoalbum carries the PhotoAlbum resource's wire types.
Package profile carries the Profile resource's wire types.
Package profile carries the Profile resource's wire types.
Package project carries the Project resource's wire types.
Package project carries the Project resource's wire types.
Package revision wraps Geni's Revision resource — a single edit in a profile or tree's history.
Package revision wraps Geni's Revision resource — a single edit in a profile or tree's history.
Package search wraps Geni's /profile/search endpoint — name-based profile discovery.
Package search wraps Geni's /profile/search endpoint — name-based profile discovery.
Package stats wraps Geni's /stats endpoint — the platform-wide statistics list.
Package stats wraps Geni's /stats endpoint — the platform-wide statistics list.
Package surname wraps Geni's Surname resource — a tag for a family name.
Package surname wraps Geni's Surname resource — a tag for a family name.
Package transport owns the cross-cutting HTTP layer for go-geni: access-token injection, rate limiting (with dynamic re-tuning from X-API-Rate-* response headers), retry on transient errors / 429 / 401, error sentinels for 403 (ErrAccessDenied) and 404 (ErrResourceNotFound), and bulk-read coalescing via the Coalescer interface (see BulkCoalescer for the generic implementation).
Package transport owns the cross-cutting HTTP layer for go-geni: access-token injection, rate limiting (with dynamic re-tuning from X-API-Rate-* response headers), retry on transient errors / 429 / 401, error sentinels for 403 (ErrAccessDenied) and 404 (ErrResourceNotFound), and bulk-read coalescing via the Coalescer interface (see BulkCoalescer for the generic implementation).
Package tree wraps Geni's family-graph endpoints — immediate-family, ancestors, and path-to.
Package tree wraps Geni's family-graph endpoints — immediate-family, ancestors, and path-to.
Package union carries the Union resource's wire types.
Package union carries the Union resource's wire types.
Package user wraps Geni's User resource and all /user/* endpoints — the authenticated user's account plus their followed listings, uploaded media, and metadata.
Package user wraps Geni's User resource and all /user/* endpoints — the authenticated user's account plus their followed listings, uploaded media, and metadata.
Package video carries the Video resource's wire types.
Package video carries the Video resource's wire types.
web
Package web is a Go client for Geni.com's internal AJAX endpoints — the same calls the geni.com website makes from a logged-in browser.
Package web is a Go client for Geni.com's internal AJAX endpoints — the same calls the geni.com website makes from a logged-in browser.
browsercookies
Package browsercookies is an OPT-IN helper for bootstrapping Options.Cookies from a logged-in browser session on the host machine.
Package browsercookies is an OPT-IN helper for bootstrapping Options.Cookies from a logged-in browser session on the host machine.
conflicts
Package conflicts exposes the website-only "data conflicts" feature — the unresolved field disagreements Geni leaves behind after a profile merge (conflicting names, dates, residence).
Package conflicts exposes the website-only "data conflicts" feature — the unresolved field disagreements Geni leaves behind after a profile merge (conflicting names, dates, residence).
document
Package document exposes the website-only document text-body endpoints.
Package document exposes the website-only document text-body endpoints.
internal/htmlparse
Package htmlparse contains small HTML extraction helpers used by the AJAX Web client.
Package htmlparse contains small HTML extraction helpers used by the AJAX Web client.
matches
Package matches exposes the website-only Merge Center list.
Package matches exposes the website-only Merge Center list.
revision
Package revision exposes the website-only revision-history endpoint.
Package revision exposes the website-only revision-history endpoint.
unions
Package unions exposes the website-only "remove relationships" action.
Package unions exposes the website-only "remove relationships" action.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL