Skip to main content

xippios-faostat

Typed Python client, MCP server and FastAPI routes for FAOSTAT, part of the xippios SDK family. Names and semantics follow the upstream documentation; every response carries release metadata (source, endpoint, retrieved_at, published_at, vintage).

Install

uv add xippios-faostat            # client only
uv add "xippios-faostat[mcp]"     # + MCP server
uv add "xippios-faostat[http]"    # + FastAPI router

A FAO account is needed: FAOSTAT_USERNAME (the account's e-mail) and FAOSTAT_PASSWORD in the environment. The client logs in with them on its first request (POST /auth/login, FAOSTAT's auth_login), once per process, sends the access token with every request to the API, and logs in again when the token lapses (after an hour) or a request is refused with HTTP 401 or 403. Neither the credentials nor a token is logged, and the tasks return neither. The bulk downloads need none.

30-second example

from xippios.faostat import get_data, get_series, list_domains, list_elements

wheat = get_data("QCL", area="231", element="2510", item="15", year=range(2015, 2022))
row = wheat.data[0]  # wheat production in the United States of America, 2015
row.area, row.item, row.year  # ("United States of America", "Wheat", "2015")
row.element_code, row.element  # ("5510", "Production"): the answer's code, not the 2510 sent
row.value, row.unit, row.flag_description  # (Decimal("55839540"), "t", "Official value")
wheat.meta.vintage  # "2025-12-31": QCL's last update, as list_domains prints it
wheat.meta.request  # {"lang": "en", "domain_code": "QCL", "area": "231", ...}

series = get_series("QCL", "231", "15", "2510", since=2015, until=2021)  # the same seven rows
series.meta.request["year"], series.meta.request["since"]  # ("2015,2016,...,2021", 2015)

list_domains(search="prices").data  # PP, CP, PD, PE (group Prices) and PA, an archive
list_elements("QCL", search="production").data[0]  # code "2510", "Production Quantity"
get_data("QCL", area="231", element="5510")  # UnknownCode: did you mean 2510 (Production Quantity)?

get_data(domain, *, area, item, element, year, area_cs, item_cs, page_size, page_number) sends one request to FAOSTAT's data endpoint (get_data, GET /{lang}/data/{domain_code}), in English, with the output options the portal sends (codes, units, flags and notes shown); each filter is a code or a list of codes. At least one of area, item, element and year is needed: FAOSTAT refuses a query without a filter, and so does get_data, before sending. Without page_size every matching row comes in one answer; with page_size and page_number, one page. A query filters by the element codes of the domain's element list (2510, Production Quantity), and the rows print other codes (5510, Production). FAOSTAT answers a code it does not know with no rows, so for the five domains whose code tables ship with the package, QCL, TCL, FBS, PP and RL, get_data checks every area, element and item code before sending and refuses one the domain's table lacks with UnknownCode, naming the table, its fetch date and the closest codes; another domain's codes are sent unchecked, and a code that matches nothing there gives an empty list. An unknown domain raises NotFoundError. meta.vintage is the domain's date_update from list_domains (groupsanddomains); meta.published_at stays None, since a date is no release time.

get_series(domain, area, item, element, *, since, until) is one get_data request for a yearly series: since and until become the year filter, the years from one to the other as upstream's comma list, or no year filter when both are left out, which answers every year the domain holds; one without the other is refused before sending. The rows come in upstream's order, area, item, year ascending in the recorded answers, and a year the domain does not hold has no row. The codes are checked as get_data checks them, and meta is get_data's, with since and until added to meta.request.

list_areas(domain, *, search), list_elements(domain, *, search) and list_items(domain, *, search) list the codes those filters take, for the same five domains, from the package's copies of FAOSTAT's code lists (getCodeList, codes/<dimension>/<domain>, src/xippios/faostat/reference/), without a request; search keeps the codes whose code or label contains the text. The element lists hold the filter codes, not the codes the rows print. meta.retrieved_at is when the package fetched the list.

Bulk downloads

from pathlib import Path

from xippios.faostat import download_dataset, list_bulk_datasets
from xippios.faostat.parse import parse_bulk_csv

list_bulk_datasets(search="land use").data[0]  # dataset_code "RL", file_size "2902KB", ...
land = download_dataset("RL", Path("RL.zip"))  # 3 MB; TCL's ZIP is 267 MB
land.data.path  # PosixPath("RL.zip"): the ZIP as FAOSTAT serves it
land.meta.vintage  # "2026-10-02T00:00:00": the catalogue's DateUpdate as printed
land.meta.published_at  # 2026-10-02 00:00 without a zone, meta.published_at_naive set
rows = parse_bulk_csv(land.data.path)  # one BulkRecord per row of its table, read lazily
first = next(rows)
first.area, first.area_code_m49, first.item, first.year  # ("Afghanistan", "'004", ...)
first.value, first.unit  # (Decimal("65286.000000"), "1000 ha")

list_bulk_datasets(*, search) lists the datasets FAOSTAT publishes as files, 69 on 2026-10-29, from the bulk downloads' catalogue (production/datasets_E.json on bulks-faostat.fao.org), fetched without the account: each with its code, the domain code get_data takes, its name, last update, the ZIP's size and URL and the rows of its table; search keeps the datasets whose code or name contains the text.

download_dataset(domain, dest) looks the dataset up in the catalogue and streams its ZIP to dest, without the account, never holding it in memory or caching it; it returns core's Downloaded (path, size, content type, ETag, Last-Modified, retrieval time). It is a bulk task: Python only, so the MCP server and the router skip it and no agent is handed a file path. The files run from 12 KB (MDDW) to 410 MB (TM); TCL's is 267 MB. meta.vintage is the catalogue's DateUpdate as printed and meta.published_at the same time, which the catalogue prints without a zone. parse_bulk_csv(path) reads the ZIP's normalized table, the member <Name>_E_All_Data_(Normalized).csv, row by row, straight from the archive: each BulkRecord has the columns of the production files (area_code, area_code_m49 as printed with its apostrophe, area, item_code, item_code_cpc, item, element_code, element, year_code, year, unit, value as a Decimal, flag, note), None where a dataset does not print one, and every other column of a dataset under its header in columns, as MDDW's surveys and food groups.

MCP

{
  "mcpServers": {
    "faostat": {
      "command": "uvx",
      "args": ["--from", "xippios-faostat[mcp]", "xippios-faostat-mcp"]
    }
  }
}

Tools are read-only and named faostat_<verb>_<noun>. Results are capped, at 200 rows or 64 KB unless a tool has a cap of its own, with a note on how to see the rest. --http serves streamable HTTP instead of stdio.

Status

Upstream operation Task function MCP tool Status
get_data (GET /{lang}/data/{domain_code}), the release date from get_groupsanddomains get_data(domain, area, item, element, year, area_cs, item_cs, page_size, page_number), a domain's rows faostat_get_data alpha
get_data with a year list, the release date from get_groupsanddomains get_series(domain, area, item, element, since, until), one domain's series over a year range faostat_get_series alpha
get_groupsanddomains (GET /{lang}/groupsanddomains) list_domains(search), the domains and subgroups with their groups and release dates faostat_list_domains alpha
getCodeList (GET /{lang}/codes/{dimension_id}/{domain_code}), area, packaged for QCL, TCL, FBS, PP and RL list_areas(domain, search), a domain's area codes faostat_list_areas alpha
getCodeList, element, packaged for the same five domains list_elements(domain, search), a domain's element codes, the filter codes faostat_list_elements alpha
getCodeList, item, packaged for the same five domains list_items(domain, search), a domain's item codes faostat_list_items alpha
production/datasets_E.json on bulks-faostat.fao.org, the bulk downloads' catalogue list_bulk_datasets(search), the datasets FAOSTAT publishes as files, with sizes and last updates faostat_list_bulk_datasets alpha
The catalogue's FileLocation, a dataset's ZIP on bulks-faostat.fao.org download_dataset(domain, dest), a dataset's ZIP on disk, its normalized CSV read by parse_bulk_csv none: a bulk task, Python only, which the adapters skip alpha

Every request to the API logs in first where the process has no current token (auth_login, POST /auth/login); the login is the client's, no task's. The bulk downloads' catalogue and files are fetched without it.

Upstream terms and attribution

Data comes from FAOSTAT (https://www.fao.org/faostat/) under the FAO Statistical Database Terms of Use: unless their metadata or webpage say otherwise, the datasets FAO's corporate statistical databases disseminate, FAOSTAT among them (the terms' Annex 1), are licensed under the Creative Commons Attribution-4.0 International licence (CC BY 4.0), as complemented by those terms. The terms ask for this citation:

FAO. [YYYY (year of last update)]. [Name of database: Name of dataset OR Name of database]. [Accessed on [DD Month YYYY]]. [URL] Licence: CC-BY-4.0.

This package adds no rights to the data. Documentation snapshot and its attribution: docs/upstream/FETCHED.md.

Licence

Apache-2.0. See LICENSE.

Metadata

Release files for xippios-faostat 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xippios-faostat 0.1.0
File Size Uploaded Provenance Actions
xippios_faostat-0.1.0.tar.gz 120.0 kB With provenance Details for xippios_faostat-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for xippios-faostat 0.1.0
File Interpreter ABI Platform Actions
xippios_faostat-0.1.0-py3-none-any.whl Python 3 none any Details for xippios_faostat-0.1.0-py3-none-any.whl

Total release size: 212.6 kB

Release files / xippios_faostat-0.1.0.tar.gz

Download URL xippios_faostat-0.1.0.tar.gz
Size 120.0 kB
Tags Source
SHA-256 checksum
How to use checksums
186430d5a707f0ea6ecf15863fcf848988e4a84b165453076aeb90d8d6801303
BLAKE2b-256 checksum
How to use checksums
6491ea5902a287393b3438ae796f4843649007946bf6f0b719b4c47c93a6ba3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Release files / xippios_faostat-0.1.0-py3-none-any.whl

Download URL xippios_faostat-0.1.0-py3-none-any.whl
Size 92.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d9e0d580149929b964bdcf35a606770adc23c7635ef6f3cd57847ac21fed62af
BLAKE2b-256 checksum
How to use checksums
be95b6725083a8a7a570562d3cddfcf6b56c17e99366c94e43440e84bac74bdb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

Security for xippios-faostat 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for xippios_faostat-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page