defmodule Demografix do @moduledoc """ Official Elixir client for the Demografix APIs: genderize, agify, and nationalize. One client covers all three services. Each call returns the prediction fields plus a `Demografix.Quota` read from the response rate-limit headers. Batch calls return a `Demografix.Batch` of per-name predictions in input order plus one quota for the whole response. ## Construction client = Demografix.new("YOUR_API_KEY") client = Demografix.new("YOUR_API_KEY", timeout: 5_000) An `api_key` is required. A `nil` or blank key raises `ArgumentError`. ## Results and errors Each function returns `{:ok, result}` or `{:error, %Demografix.Error{}}`. The bang variants (`genderize!/3` and so on) return the result or raise the error. {:ok, result} = Demografix.genderize(client, "peter") result.gender # => "male" result.quota.remaining # => 24987 ## Aggregate over a list The services are built for summarizing a group of names, not labeling one person. {:ok, batch} = Demografix.genderize_batch(client, ["peter", "lois", "kim"]) batch.results |> Enum.frequencies_by(& &1.gender) # => %{"male" => 1, "female" => 2} """ alias Demografix.{Agify, Batch, Client, Error, Genderize, Nationalize} @type t :: Client.t() @doc """ Build a client. `api_key` is required; a `nil` or blank key raises `ArgumentError` before any request. The same key works across all three services. ## Options * `:timeout` — receive timeout in milliseconds. Defaults to `10_000`. """ @spec new(String.t(), keyword()) :: t() defdelegate new(api_key, opts \\ []), to: Client @doc """ Predict the gender of one name. ## Options * `:country_id` — ISO 3166-1 alpha-2 code to scope the prediction. Echoed back uppercase on the result. """ @spec genderize(t(), String.t(), keyword()) :: {:ok, Genderize.t()} | {:error, Error.t()} defdelegate genderize(client, name, opts \\ []), to: Client @doc """ Predict the gender of up to 10 names. More than 10 names raises a client-side `Demografix.Error` of kind `:validation` before any request. Accepts the same `:country_id` option as `genderize/3`. """ @spec genderize_batch(t(), [String.t()], keyword()) :: {:ok, Batch.t()} | {:error, Error.t()} defdelegate genderize_batch(client, names, opts \\ []), to: Client @doc """ Predict the age of one name. Accepts the same `:country_id` option as `genderize/3`. """ @spec agify(t(), String.t(), keyword()) :: {:ok, Agify.t()} | {:error, Error.t()} defdelegate agify(client, name, opts \\ []), to: Client @doc """ Predict the age of up to 10 names. More than 10 names raises a client-side validation error before any request. """ @spec agify_batch(t(), [String.t()], keyword()) :: {:ok, Batch.t()} | {:error, Error.t()} defdelegate agify_batch(client, names, opts \\ []), to: Client @doc """ Predict the nationality of one name. Nationalize takes no `country_id`. """ @spec nationalize(t(), String.t(), keyword()) :: {:ok, Nationalize.t()} | {:error, Error.t()} defdelegate nationalize(client, name, opts \\ []), to: Client @doc """ Predict the nationality of up to 10 names. More than 10 names raises a client-side validation error before any request. """ @spec nationalize_batch(t(), [String.t()], keyword()) :: {:ok, Batch.t()} | {:error, Error.t()} defdelegate nationalize_batch(client, names, opts \\ []), to: Client @doc "Like `genderize/3`, but returns the result or raises `Demografix.Error`." @spec genderize!(t(), String.t(), keyword()) :: Genderize.t() def genderize!(client, name, opts \\ []), do: unwrap(genderize(client, name, opts)) @doc "Like `genderize_batch/3`, but returns the result or raises `Demografix.Error`." @spec genderize_batch!(t(), [String.t()], keyword()) :: Batch.t() def genderize_batch!(client, names, opts \\ []), do: unwrap(genderize_batch(client, names, opts)) @doc "Like `agify/3`, but returns the result or raises `Demografix.Error`." @spec agify!(t(), String.t(), keyword()) :: Agify.t() def agify!(client, name, opts \\ []), do: unwrap(agify(client, name, opts)) @doc "Like `agify_batch/3`, but returns the result or raises `Demografix.Error`." @spec agify_batch!(t(), [String.t()], keyword()) :: Batch.t() def agify_batch!(client, names, opts \\ []), do: unwrap(agify_batch(client, names, opts)) @doc "Like `nationalize/3`, but returns the result or raises `Demografix.Error`." @spec nationalize!(t(), String.t(), keyword()) :: Nationalize.t() def nationalize!(client, name, opts \\ []), do: unwrap(nationalize(client, name, opts)) @doc "Like `nationalize_batch/3`, but returns the result or raises `Demografix.Error`." @spec nationalize_batch!(t(), [String.t()], keyword()) :: Batch.t() def nationalize_batch!(client, names, opts \\ []), do: unwrap(nationalize_batch(client, names, opts)) defp unwrap({:ok, result}), do: result defp unwrap({:error, %Error{} = error}), do: raise(error) end