Skip to content

Authentication

egms_client.auth

Access tokens from a CLMS service key.

The EGMS archive answers {"status": false, "message": "Please log in to perform archive API calls."} to every anonymous call, releases included. The way in that needs no browser is a service key of the Copernicus Land Monitoring Service: land.copernicus.eu, EU Login, profile → "API Tokens" → "Create new token". It is a JSON document with client_id, user_id, private_key (RSA, PEM) and token_uri, and it does not expire.

The key signs a short JWT (RS256), which the token endpoint exchanges for a bearer token valid one hour (OAuth 2.0 JWT bearer grant, RFC 7523).

A malformed assertion is answered with HTTP 500 and a DecodeError, not 401: a retry policy on 5xx will retry it pointlessly.

ServiceKey dataclass

A CLMS service key, as downloaded from the land.copernicus.eu profile.

from_json classmethod

from_json(text: str) -> ServiceKey

Parse the JSON document; raise ValueError if a field is missing or empty.

from_file classmethod

from_file(path: str | PathLike[str]) -> ServiceKey

Read the JSON file saved from the profile page (~ is expanded).

from_env classmethod

from_env(environ: Mapping[str, str] | None = None) -> ServiceKey

The key named by the environment, so no application hard-codes a path.

EGMS_SERVICE_KEY holds the JSON itself (for containers and CI secrets); EGMS_SERVICE_KEY_FILE holds the path of the file. The first one set wins; neither is LookupError.

Token dataclass

A bearer token and the Unix time it expires at.

assertion

assertion(key: ServiceKey, *, now: int, lifetime: int = ASSERTION_LIFETIME) -> str

The RS256 JWT the service key signs to ask for a token.

token_request

token_request(key: ServiceKey, *, now: int) -> dict[str, str]

The form body to POST to key.token_uri.

parse_token

parse_token(status_code: int, body: bytes | str, *, now: float) -> Token

The token from the endpoint's answer; :class:EgmsError if it was refused.