Skip to content

Client

client

The MERMAID API client.

Classes:

Name Description
MermaidClient

Synchronous client for the MERMAID API.

Attributes:

Name Type Description
DEFAULT_BASE_URL
DEV_BASE_URL
BASE_URL_ENV_VAR
DEFAULT_ZONAL_STATS_URL
ZONAL_STATS_URL_ENV_VAR
DEFAULT_COVARIATES_URL
COVARIATES_URL_ENV_VAR

DEFAULT_BASE_URL module-attribute

DEFAULT_BASE_URL = 'https://api.datamermaid.org/v1/'

DEV_BASE_URL module-attribute

DEV_BASE_URL = 'https://dev-api.datamermaid.org/v1/'

BASE_URL_ENV_VAR module-attribute

BASE_URL_ENV_VAR = 'MERMAID_API_URL'

DEFAULT_ZONAL_STATS_URL module-attribute

DEFAULT_ZONAL_STATS_URL = "https://api.zonalstats.datamermaid.org/api/v1/zonal-stats/"

ZONAL_STATS_URL_ENV_VAR module-attribute

ZONAL_STATS_URL_ENV_VAR = 'MERMAID_ZONAL_STATS_URL'

DEFAULT_COVARIATES_URL module-attribute

DEFAULT_COVARIATES_URL = (
    "https://mermaid.prescient.earth/stac/"
)

COVARIATES_URL_ENV_VAR module-attribute

COVARIATES_URL_ENV_VAR = 'MERMAID_COVARIATES_URL'

DEFAULT_TIMEOUT module-attribute

DEFAULT_TIMEOUT = 30.0

DEFAULT_MAX_RETRIES module-attribute

DEFAULT_MAX_RETRIES = 3

DEFAULT_BACKOFF_FACTOR module-attribute

DEFAULT_BACKOFF_FACTOR = 0.5

MAX_BACKOFF module-attribute

MAX_BACKOFF = 30.0

PUBLIC_HEADERS module-attribute

PUBLIC_HEADERS = frozenset(
    {
        "accept",
        "accept-encoding",
        "connection",
        "content-length",
        "content-type",
        "host",
        "user-agent",
    }
)

MermaidClient

MermaidClient(
    *,
    auth: Auth | None = None,
    api_key: str | None = None,
    base_url: str | None = None,
    zonal_stats_url: str | None = None,
    covariates_url: str | None = None,
    timeout: float | Timeout = DEFAULT_TIMEOUT,
    max_retries: int = DEFAULT_MAX_RETRIES,
    backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
    headers: dict[str, str] | None = None,
    user_agent: str | None = None,
    transport: BaseTransport | None = None,
)

Synchronous client for the MERMAID API.

Owns the base URL, the timeouts, the User-Agent, the retry-with-backoff policy and the JSON decoding. Credentials are never inspected here: the client only ever asks an Auth to stamp an outgoing request.

Each endpoint group is a property returning a wrapper whose list() gives a lazy PaginatedList. Reference data needs no credentials; /me/, /projects/, /sites/ and /managements/ do.

Use it as a context manager so the connection pool is closed.

The client is safe to share between threads, which is how a Batch fans requests out. Throttling is cooperative: a 429 seen on any thread sets a client-wide deadline (Retry-After, or the computed backoff, capped at 30 seconds) that every request waits on before it is sent, so the workers back off together instead of one at a time. The deadline is shared by both hosts: a 429 from the Zonal Stats service also pauses MERMAID API calls on the same client, and the reverse.

Parameters:

Name Type Description Default
auth Auth | None

Credential provider. Mutually exclusive with api_key.

None
api_key str | None

A MERMAID API key, mmd_<key_id>.<secret>. Defaults to MERMAID_API_KEY, then to tokens left by datamermaid.login, then to anonymous access.

None
base_url str | None

API root. Defaults to MERMAID_API_URL, then to DEFAULT_BASE_URL. A trailing slash is added if missing.

None
zonal_stats_url str | None

Root of the separate Zonal Stats service. Defaults to MERMAID_ZONAL_STATS_URL, then to DEFAULT_ZONAL_STATS_URL. A trailing slash is added if missing.

None
covariates_url str | None

Root of the covariates STAC API. Defaults to MERMAID_COVARIATES_URL, then to DEFAULT_COVARIATES_URL. A trailing slash is added if missing.

None
timeout float | Timeout

Seconds, or an httpx.Timeout for per-phase control.

DEFAULT_TIMEOUT
max_retries int

Extra attempts after a 429 or 5xx. 0 disables retrying.

DEFAULT_MAX_RETRIES
backoff_factor float

Base delay of the exponential backoff, in seconds. A Retry-After header wins over it.

DEFAULT_BACKOFF_FACTOR
headers dict[str, str] | None

Extra headers sent with every request to the MERMAID API. Requests to the Zonal Stats service and the covariates catalog carry none of them.

None
user_agent str | None

Overrides default_user_agent.

None
transport BaseTransport | None

An httpx transport, mainly for tests.

None

Raises:

Type Description
ValueError

If max_retries is negative, or both auth and api_key are given.

Attributes:

Name Type Description
auth

The credential provider in use.

base_url

The resolved API root, always ending in /.

zonal_stats_url

The resolved Zonal Stats service root, always ending in /.

covariates_url

The resolved covariates STAC API root, always ending in /.

max_retries

Extra attempts made after a retryable status code.

backoff_factor

Base delay of the exponential backoff, in seconds.

Example
from datamermaid import MermaidClient

with MermaidClient(api_key="mmd_abc.def") as client:
    me = client.me()
    for project in client.projects.list():
        print(project.name)

Reference data is public, so it needs no credentials at all:

with MermaidClient() as client:
    species = client.fish_species.list(genus=genus_id)
    reef_types = client.choices("reeftypes")

Methods:

Name Description
close

Close the underlying connection pool.

me

Return the profile that owns the credentials in use (GET /me/).

choices

Return the API's controlled vocabularies (GET /choices/).

request

Issue a request, retrying transient failures and mapping errors.

request_json

Issue a request and decode the JSON body (None when empty).

auth instance-attribute
auth = resolve_auth(auth, api_key)
base_url instance-attribute
base_url = resolve_base_url(base_url)
zonal_stats_url instance-attribute
zonal_stats_url = resolve_zonal_stats_url(zonal_stats_url)
covariates_url instance-attribute
covariates_url = resolve_covariates_url(covariates_url)
max_retries instance-attribute
max_retries = max_retries
backoff_factor instance-attribute
backoff_factor = backoff_factor
projects cached property
projects: ProjectsResource

Access to the /projects/ endpoints.

Call it with a project id (client.projects(project_id)) for that project's own sites, sample events and survey collections.

sites cached property

Reef sites, /sites/ (requires authentication).

managements cached property
managements: ManagementsResource

Management regimes, /managements/ (requires authentication).

project_tags cached property
project_tags: ProjectTagsResource

Organisation tags, /projecttags/.

fish_sizes cached property
fish_sizes: FishSizesResource

Fish size bins, /fishsizes/.

fish_families cached property
fish_families: FishFamiliesResource

Fish families, /fishfamilies/.

fish_genera cached property
fish_genera: FishGeneraResource

Fish genera, /fishgenera/.

fish_species cached property
fish_species: FishSpeciesResource

Fish species, /fishspecies/.

benthic_attributes cached property
benthic_attributes: BenthicAttributesResource

Benthic attributes, /benthicattributes/.

invert_attributes cached property
invert_attributes: InvertAttributesResource

Macroinvertebrate attributes, /invertattributes/.

invert_species cached property
invert_species: InvertSpeciesResource

Macroinvertebrate species, /invertspecies/.

summary_sample_events cached property
summary_sample_events: SummarySampleEventsResource

Public sample event summaries, /summarysampleevents/.

label_mappings cached property
label_mappings: LabelMappingsResource

Classifier label mappings, /classification/labelmappings/.

zonal_stats cached property
zonal_stats: ZonalStats

The Zonal Stats service, a separate public host (client.zonal_stats.raster).

Requests to it carry no MERMAID credentials. See ZonalStats.

covariates cached property
covariates: Covariates

The covariates catalog, a public STAC API (client.covariates.collections()).

Requests to it carry no MERMAID credentials. See Covariates.

close
close() -> None

Close the underlying connection pool.

me
me() -> Me

Return the profile that owns the credentials in use (GET /me/).

choices
choices() -> dict[str, list[dict[str, Any]]]
choices(name: str) -> list[dict[str, Any]]
choices(name: str | None = None) -> Any

Return the API's controlled vocabularies (GET /choices/).

Without an argument, every choice set keyed by name (countries, reeftypes, managementparties, ...). With one, just that set's rows, fetched from /choices/<name>/.

Unlike the list endpoints this one is not paginated, so it returns plain dictionaries rather than a PaginatedList of models.

Parameters:

Name Type Description Default
name str | None

A single choice set to fetch. Omit it for all of them.

None

Returns:

Type Description
Any

Every choice set keyed by name, or one set's rows.

Example
>>> client.choices()["reeftypes"]  # doctest: +SKIP
[{'id': '...', 'name': 'atoll', 'updated_on': '...'}, ...]
request
request(
    method: str,
    url: str,
    *,
    params: dict[str, Any] | None = None,
    json: Any = None,
    public: bool = False,
    **kwargs: Any,
) -> Response

Issue a request, retrying transient failures and mapping errors.

url may be relative to the base URL or absolute (as in the next link of a paginated response). public=True is for another host: the request is sent without the client's auth, and with only the headers in PUBLIC_HEADERS.

request_json
request_json(
    method: str,
    url: str,
    *,
    params: dict[str, Any] | None = None,
    json: Any = None,
    public: bool = False,
    **kwargs: Any,
) -> Any

Issue a request and decode the JSON body (None when empty).

default_user_agent

default_user_agent() -> str

The User-Agent sent with every request.

resolve_base_url

resolve_base_url(base_url: str | None = None) -> str

Resolve the API root: explicit argument, then env var, then default.

resolve_zonal_stats_url

resolve_zonal_stats_url(url: str | None = None) -> str

Resolve the Zonal Stats service root: argument, then env var, then default.

resolve_covariates_url

resolve_covariates_url(url: str | None = None) -> str

Resolve the covariates STAC API root: argument, then env var, then default.