Skip to content

Analytics

Reached as client.analytics.

Analytics does not return Box objects

Alma returns Analytics results as XML rather than JSON, paginated with a resumption token. This is the one namespace that returns XML text or plain dictionaries, and its methods take no model= argument.

Use get_full_report for parsed rows – it follows the resumption token for you – or get_raw_report for the untouched XML.

Report size costs requests

get_full_report issues one API request per limit rows, all of which count against the institution's daily quota. Raise limit (Alma caps it at 1000) to reduce the number of round trips.

AlmaClientAnalyticsNS

AlmaClientAnalyticsNS(client: _AlmaExecutable)

Bases: BaseNamespace

Namespace for analytics functionality.

Available as client.analytics. Unlike the other namespaces these methods return XML text or plain dictionaries rather than Box objects, and so do not accept a model= argument.

get_raw_report async Alma: Retrieve Analytics report

get_raw_report(
    path: str,
    limit: int = 100,
    *,
    token: str | None = None,
    report_filter: str | None = None,
) -> str

Fetch one page of an Analytics report as raw XML.

This is a single request – it does not follow the resumption token. Use get_full_report unless you need the untouched XML or want to drive pagination yourself.

Parameters:

Name Type Description Default
path str

Full path to the report in Alma Analytics, e.g. /shared/Institution/Reports/My Report.

required
limit int

Rows per page. Alma caps this at 1000 and rounds down to a multiple of 25.

100
token str | None

Resumption token from a previous page. When supplied, Alma ignores path and returns the next page of that result set.

None
report_filter str | None

An OBI XML filter expression applied to the report.

None

Returns:

Type Description
str

The raw XML body, including the IsFinished flag and

str

ResumptionToken needed to page through the result set.

Raises:

Type Description
APIClientError

If the report path does not exist or the filter is malformed.

Examples:

xml = await client.analytics.get_raw_report(
    "/shared/Institution/Reports/Loans by Library", limit=500
)

get_full_report async

get_full_report(
    path: str,
    limit: int = 100,
    header_override: dict[str, str] | None = None,
    report_filter: str | None = None,
) -> list[dict[str, str]]

Run an Analytics report and return every row, following pagination.

Repeatedly requests pages using Alma's resumption token until IsFinished is true, then maps each row onto the report's column headings. Alma's internal Column0 row index is dropped.

Note that a large report costs one API request per limit rows, all of which count against the institution's daily quota.

Parameters:

Name Type Description Default
path str

Full path to the report in Alma Analytics, e.g. /shared/Institution/Reports/My Report.

required
limit int

Rows per page. Alma caps this at 1000 and rounds down to a multiple of 25. Raise it to reduce the number of requests.

100
header_override dict[str, str] | None

Replaces individual column headings after they are read from the report schema, keyed by Alma's internal column name (Column1, Column2, ...). Useful when a report ships with blank or duplicate headings.

None
report_filter str | None

An OBI XML filter expression applied to the report.

None

Returns:

Type Description
list[dict[str, str]]

One dictionary per row, keyed by column heading. Values are strings –

list[dict[str, str]]

Analytics does not type its output, so numbers and dates arrive as text.

Raises:

Type Description
APIClientError

If the report path does not exist or the filter is malformed.

KeyError

If a row contains a column absent from the report schema and no header_override supplies a heading for it.

Examples:

rows = await client.analytics.get_full_report(
    "/shared/Institution/Reports/Loans by Library",
    limit=1000,
    header_override={"Column1": "Library Code"},
)
for row in rows:
    print(row["Library Code"], row["Loans"])