demografix

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 9 Imported by: 0

README

demografix-go

Run demographic analysis over names — predicted gender, age, and nationality — from one Go client. The package covers genderize.io, agify.io, and nationalize.io.

Install

go get github.com/DemografixGenderize/demografix-go

Requires Go 1.21 or later. The package has no third-party dependencies.

Quickstart

Construct a client, run a batch over a list of names, read the predictions, and read the remaining quota.

package main

import (
	"context"
	"fmt"

	demografix "github.com/DemografixGenderize/demografix-go"
)

func main() {
	client := demografix.New("YOUR_API_KEY")

	names := []string{"peter", "lois", "michael", "matthew"}

	res, err := client.GenderizeBatch(context.Background(), names)
	if err != nil {
		panic(err)
	}

	split := map[string]int{}
	for _, p := range res.Results {
		split[p.Gender]++
	}

	fmt.Println(split)               // gender split of the list
	fmt.Println(res.Quota.Remaining) // 24987
}

New takes the API key as its first argument. The base URLs and the User-Agent are hardcoded constants, not options. Quota is read from a returned value or a raised error, never cached on the client.

genderize

Single name and batch. Both return prediction fields plus a quota.

g, err := client.Genderize(ctx, "peter")
// g.Name, g.Gender ("male"/"female"/""), g.Probability, g.Count, g.Quota.Remaining

batch, err := client.GenderizeBatch(ctx, []string{"peter", "lois", "michael"})
counts := map[string]int{}
for _, p := range batch.Results {
	counts[p.Gender]++ // aggregate into a gender split
}

Gender is the empty string when the API returns null. The batch maximum is ten names; a larger batch raises a ValidationError before any HTTP call.

agify

a, err := client.Agify(ctx, "michael")
// a.Age (*int, nil when null), a.Count, a.Quota.Remaining

batch, err := client.AgifyBatch(ctx, []string{"michael", "matthew", "jane"})
buckets := map[int]int{}
for _, p := range batch.Results {
	if p.Age != nil {
		buckets[(*p.Age/10)*10]++ // aggregate into an age distribution
	}
}

Age is a *int and is nil when the API returns null.

nationalize

n, err := client.Nationalize(ctx, "nguyen")
// n.Country is up to five {CountryID, Probability} candidates, descending probability

batch, err := client.NationalizeBatch(ctx, []string{"nguyen", "schmidt", "rossi"})
mix := map[string]int{}
for _, p := range batch.Results {
	if len(p.Country) > 0 {
		mix[p.Country[0].CountryID]++ // aggregate into a nationality mix
	}
}

Country is empty on no match. The nationalize methods do not accept a country option.

country_id

Genderize and Agify accept WithCountry to scope a prediction to an ISO 3166-1 alpha-2 country. The value is echoed back uppercase on each prediction as CountryID.

g, err := client.Genderize(ctx, "kim", demografix.WithCountry("US"))
// g.CountryID == "US"

batch, err := client.AgifyBatch(ctx, names, demografix.WithCountry("US"))

The nationalize methods do not take WithCountry.

Quota

Every result and every typed error carries a Quota read from the response headers.

Field Meaning
Limit names allowed in the current window
Remaining names left in the current window
Reset seconds until the window resets
res, _ := client.GenderizeBatch(ctx, names)
fmt.Println(res.Quota.Remaining)

Errors

Methods return (T, error). Non-2xx responses map by status code to a typed error; transport failures map to TransportError. Discover a type with errors.As.

Type Cause
AuthError 401, invalid or rejected API key
SubscriptionError 402, inactive or expired subscription
ValidationError 422, or a batch over ten names (client-side, no HTTP call)
RateLimitError 429, quota exhausted
DemografixError base type for any other non-2xx response
TransportError network failure, timeout, or non-JSON body

Each type embeds DemografixError, which carries Status, Message, and *Quota. errors.As matches both the concrete type and the base.

A TransportError wraps the underlying cause in its Err field, so errors.Is reaches it:

_, err := client.Genderize(ctx, "peter")
if errors.Is(err, context.DeadlineExceeded) {
	// the request timed out
}

A RateLimitError always carries quota. Read Quota.Reset to back off before retrying.

res, err := client.GenderizeBatch(ctx, names)
if err != nil {
	var rate *demografix.RateLimitError
	if errors.As(err, &rate) {
		time.Sleep(time.Duration(rate.Quota.Reset) * time.Second)
		res, err = client.GenderizeBatch(ctx, names)
	}
}

Methods

Method Returns
Genderize(ctx, name, ...Option) GenderizeResult
GenderizeBatch(ctx, names, ...Option) GenderizeBatchResult
Agify(ctx, name, ...Option) AgifyResult
AgifyBatch(ctx, names, ...Option) AgifyBatchResult
Nationalize(ctx, name) NationalizeResult
NationalizeBatch(ctx, names) NationalizeBatchResult

Option is WithCountry("US"), accepted by the genderize and agify methods only. A single result embeds its prediction fields and adds Quota. A batch result holds Results plus one Quota.

API keys

An API key is required. Creating one is free and includes 2,500 requests per month. Generate a key in your dashboard at genderize.io, agify.io, or nationalize.io. One key works across all three services. Full reference: https://genderize.io/documentation/api

Documentation

Overview

Package demografix is the official Go client for the Demografix APIs: genderize.io (gender), agify.io (age), and nationalize.io (nationality). One client covers all three services through the same shape and reports the remaining quota carried on every response.

Index

Constants

View Source
const (
	// Version is the SDK version, sent in the User-Agent on every request.
	Version = "0.1.0"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AgifyBatchResult

type AgifyBatchResult struct {
	Results []AgifyPrediction
	Quota   Quota
}

AgifyBatchResult holds the per-name agify predictions in input order plus one quota for the whole response.

type AgifyPrediction

type AgifyPrediction struct {
	Name      string `json:"name"`
	Age       *int   `json:"age"`
	Count     int    `json:"count"`
	CountryID string `json:"country_id"`
}

AgifyPrediction is one agify result for a single name. Age is nil when the API returns null. CountryID is populated only when the request sent a country_id.

type AgifyResult

type AgifyResult struct {
	AgifyPrediction
	Quota Quota
}

AgifyResult is a single agify prediction plus the response quota.

type AuthError

type AuthError struct{ DemografixError }

AuthError reports an invalid or rejected API key (HTTP 401).

func (*AuthError) Unwrap

func (e *AuthError) Unwrap() error

Unwrap exposes the embedded base, so errors.As matches *DemografixError too.

type Client

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

Client calls the three Demografix services. Construct one with New and reuse it; it is safe for concurrent use. The hosts and the User-Agent are hardcoded constants, not options.

func New

func New(apiKey string, opts ...Option) *Client

New builds a Client for the given API key. The key is required and is sent as the apikey query parameter on every request; an empty or blank key makes every request fail with a ValidationError before any HTTP call. Pass WithTimeout to override the default ten-second timeout. The same key works across all three services.

func (*Client) Agify

func (c *Client) Agify(ctx context.Context, name string, opts ...RequestOption) (AgifyResult, error)

Agify predicts the age for one name.

func (*Client) AgifyBatch

func (c *Client) AgifyBatch(ctx context.Context, names []string, opts ...RequestOption) (AgifyBatchResult, error)

AgifyBatch predicts the age for up to ten names. Results are returned in input order. A batch of more than ten names raises a ValidationError before any HTTP call.

func (*Client) Genderize

func (c *Client) Genderize(ctx context.Context, name string, opts ...RequestOption) (GenderizeResult, error)

Genderize predicts the gender for one name.

func (*Client) GenderizeBatch

func (c *Client) GenderizeBatch(ctx context.Context, names []string, opts ...RequestOption) (GenderizeBatchResult, error)

GenderizeBatch predicts the gender for up to ten names. Results are returned in input order. A batch of more than ten names raises a ValidationError before any HTTP call.

func (*Client) Nationalize

func (c *Client) Nationalize(ctx context.Context, name string) (NationalizeResult, error)

Nationalize predicts the nationality for one name.

func (*Client) NationalizeBatch

func (c *Client) NationalizeBatch(ctx context.Context, names []string) (NationalizeBatchResult, error)

NationalizeBatch predicts the nationality for up to ten names. Results are returned in input order. A batch of more than ten names raises a ValidationError before any HTTP call.

type DemografixError

type DemografixError struct {
	// Status is the HTTP status code, or 0 when no response was received.
	Status int
	// Message is the API error string passed through unchanged.
	Message string
	// Quota is the parsed rate-limit state, or nil when no headers were present.
	Quota *Quota
}

DemografixError is the base error type for every failure the SDK reports. Every typed error embeds it, so it carries the HTTP status, the API message, and the response quota when the rate-limit headers were present.

Discover a specific error type with errors.As:

var rate *demografix.RateLimitError
if errors.As(err, &rate) {
        time.Sleep(time.Duration(rate.Quota.Reset) * time.Second)
}

The base type itself is also matchable, so errors.As against *DemografixError succeeds for any SDK error.

func AsDemografixError

func AsDemografixError(err error) (*DemografixError, bool)

AsDemografixError reports whether err is a Demografix SDK error and, if so, returns the embedded base. It is a convenience over errors.As for callers that want the status, message, and quota without naming a concrete type.

func (*DemografixError) Error

func (e *DemografixError) Error() string

Error implements the error interface.

type GenderizeBatchResult

type GenderizeBatchResult struct {
	Results []GenderizePrediction
	Quota   Quota
}

GenderizeBatchResult holds the per-name genderize predictions in input order plus one quota for the whole response.

type GenderizePrediction

type GenderizePrediction struct {
	Name        string  `json:"name"`
	Gender      string  `json:"gender"`
	Probability float64 `json:"probability"`
	Count       int     `json:"count"`
	CountryID   string  `json:"country_id"`
}

GenderizePrediction is one genderize result for a single name. Gender is "male", "female", or "" when the API returns null. CountryID is populated only when the request sent a country_id.

type GenderizeResult

type GenderizeResult struct {
	GenderizePrediction
	Quota Quota
}

GenderizeResult is a single genderize prediction plus the response quota.

type NationalizeBatchResult

type NationalizeBatchResult struct {
	Results []NationalizePrediction
	Quota   Quota
}

NationalizeBatchResult holds the per-name nationalize predictions in input order plus one quota for the whole response.

type NationalizeCountry

type NationalizeCountry struct {
	CountryID   string  `json:"country_id"`
	Probability float64 `json:"probability"`
}

NationalizeCountry is one candidate country for a nationalize prediction.

type NationalizePrediction

type NationalizePrediction struct {
	Name    string               `json:"name"`
	Country []NationalizeCountry `json:"country"`
	Count   int                  `json:"count"`
}

NationalizePrediction is one nationalize result for a single name. Country holds up to five candidates in descending probability and is empty on no match.

type NationalizeResult

type NationalizeResult struct {
	NationalizePrediction
	Quota Quota
}

NationalizeResult is a single nationalize prediction plus the response quota.

type Option

type Option func(*Client)

Option configures a Client in New.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the per-request timeout. The default is ten seconds.

type Quota

type Quota struct {
	// Limit is the number of names allowed in the current window.
	Limit int
	// Remaining is the number of names left in the current window.
	Remaining int
	// Reset is the number of seconds until the window resets.
	Reset int
}

Quota reports the rate-limit state carried on every response, parsed from the x-rate-limit-* headers. It is read from a returned value or a raised error and is never cached on the Client.

type RateLimitError

type RateLimitError struct{ DemografixError }

RateLimitError reports an exhausted quota (HTTP 429). Quota is always populated; read Quota.Reset for the seconds to wait before retrying.

func (*RateLimitError) Unwrap

func (e *RateLimitError) Unwrap() error

Unwrap exposes the embedded base, so errors.As matches *DemografixError too.

type RequestOption

type RequestOption func(*requestConfig)

RequestOption configures a single genderize or agify request. The only option is WithCountry.

func WithCountry

func WithCountry(countryID string) RequestOption

WithCountry scopes a genderize or agify prediction to an ISO 3166-1 alpha-2 country. The nationalize methods do not accept it.

type SubscriptionError

type SubscriptionError struct{ DemografixError }

SubscriptionError reports an inactive or expired subscription (HTTP 402).

func (*SubscriptionError) Unwrap

func (e *SubscriptionError) Unwrap() error

Unwrap exposes the embedded base, so errors.As matches *DemografixError too.

type TransportError

type TransportError struct {
	DemografixError
	// Err is the underlying cause, or nil for a synthesized failure such as a
	// non-JSON response body.
	Err error
}

TransportError reports a network failure, a timeout, or a response body that is not JSON. Status and Quota may be absent. When the failure came from an underlying call, Err holds the original error, so errors.Is and errors.As reach it (for example errors.Is(err, context.DeadlineExceeded) on a timeout).

func (*TransportError) Unwrap

func (e *TransportError) Unwrap() []error

Unwrap exposes both the embedded base and the underlying cause, so errors.As matches *DemografixError and errors.Is reaches the wrapped transport error.

type ValidationError

type ValidationError struct{ DemografixError }

ValidationError reports a rejected request (HTTP 422). It is also raised client-side, before any HTTP call, when a batch holds more than ten names.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap exposes the embedded base, so errors.As matches *DemografixError too.

Directories

Path Synopsis
Command example reads a list of names and reports the aggregate demographic mix: a gender split, an age distribution, and a nationality breakdown.
Command example reads a list of names and reports the aggregate demographic mix: a gender split, an age distribution, and a nationality breakdown.

Jump to

Keyboard shortcuts

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