metadata-asf
Python library and CLI to collect SAR acquisition metadata from the
ASF API (asf_search) and export it as
daily Parquet catalogs.
metadata-asf is read-only by design: it never downloads products, stores no Earthdata
credentials, and ships without any heavy I/O dependency. The daily Parquet files it
produces are the interface contract with the companion repository [fetch-asf]
(planned), which performs the actual product transfer.
Scope
- Provider: ASF, through
asf_search. - Multi-mission by construction; first target mission is NISAR.
- NISAR products collected: L1 — RSLC, L2 — GSLC.
- Geographic filter configurable via WKT (oceans by default).
- Output: one Parquet file per acquisition day,
{mission}_ocean_YYYYMMDD.parquet.
Out of scope (see AGENTS.md): downloading products, Earthdata authentication, and any
scientific SAR processing. These live in fetch-asf.
Installation (development)
pip install -e ".[dev]"
pre-commit install
Python ≥ 3.10 is required. The project uses a src/ layout with Hatchling as build
backend, version derived from the Git history via hatch-vcs, and an entry point
metadata-asf registering metadata_asf.cli:main.
Usage
CLI — harvest
Query the ASF API and write the daily Parquet catalogs:
metadata-asf harvest \
--mission NISAR \
--outputdir ./out \
--log-verbosity INFO \
--date 2025-01-01:2025-01-31 \
--conf config.yaml
| Option | Required | Description |
|---|---|---|
--mission |
no | Target mission (default: NISAR). |
--outputdir |
yes | Directory where daily Parquet files are written. |
--log-verbosity |
no | DEBUG, INFO, WARNING or ERROR (default: INFO). |
--date |
no | YYYY-MM-DD or range YYYY-MM-DD:YYYY-MM-DD. |
--conf |
no | YAML configuration file (see config.example.yaml). |
Precedence is CLI > --conf file > mission profile defaults. See config.example.yaml
for a complete working example.
CLI — report
Render a self-contained HTML report on a directory of daily Parquet catalogs (read-only, no API calls, no JavaScript in the output):
metadata-asf report \
--catalogdir ./out \
--outputfile ./out/report.html
The report covers volume & completeness (records, daily files, span, missing/empty days), the product/instrument mix (platform, product type, level, beam, polarization) and footprint geometry quality (invalid / antimeridian / near-polar).
| Option | Required | Description |
|---|---|---|
--catalogdir |
yes | Directory of daily Parquet files to report on. |
--outputfile |
no | HTML report path (default: catalog_report.html). |
--mission |
no | Mission label for the header (default: inferred from the data). |
--log-verbosity |
no | DEBUG, INFO, WARNING or ERROR (default: INFO). |
Python API
The public, versioned API consumed by fetch-asf:
from pathlib import Path
import datetime as dt
from metadata_asf import search, extract, export
products = search.search(
mission="NISAR",
start=dt.date(2025, 1, 1),
end=dt.date(2025, 1, 31),
intersects_with=None, # falls back to the profile's ocean WKT
max_results=10_000,
)
df = extract.to_dataframe(products, mission="NISAR")
written = export.write_daily_parquet(df, output_dir=Path("./out"))
Parquet schema (guaranteed)
| Column | Type | Content |
|---|---|---|
granule_id |
str | file_name / granuleName |
platform |
str | e.g. NISAR, SENTINEL-1A |
geometry |
str (WKT) | acquisition footprint |
start_time |
datetime | UTC |
stop_time |
datetime | UTC |
polarization |
list[str] | e.g. ["HH", "HV"] |
beam_mode |
str | acquisition mode |
product_type |
str | e.g. RSLC, GSLC |
processing_level |
str | L1, L2 |
Files are written with the PyArrow engine, Snappy compression and no index; every
timestamp is UTC. Any schema change implies a major version bump plus migration notes
(see AGENTS.md, section 7).
Adding a mission
A mission is fully described by a profile in src/metadata_asf/profiles/. Adding one
amounts to: creating the module, registering it in the MISSIONS dict and adding tests.
The core code (search, extract, export) never changes — see AGENTS.md, section 3.
Development
make install # editable install + dev dependencies
make test # pytest with branch coverage (>= 80 % required)
make check-codestyle # ruff + black --check
make mypy # mypy --strict on src/ and tests/
Integration tests performing real ASF API calls opt in explicitly: pytest -m integration.
License
MIT — see LICENSE.
Metadata
Release files for metadata-asf 2026.10.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| metadata_asf-2026.10.9.tar.gz | 42.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| metadata_asf-2026.10.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.3 kB
Release files / metadata_asf-2026.10.9.tar.gz
| Download URL | metadata_asf-2026.10.9.tar.gz |
|---|---|
| Size | 42.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d6a989169ce05d6dce538ad0c87e11320c65aff98f95fc5718787276f4bc9fd9
|
|
BLAKE2b-256 checksum How to use checksums |
41bbb84d22cbfcfd88872e79360fa41b3804f5c084ef9a50cd566eb6093027b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 9, 2026.
Transparency logRelease files / metadata_asf-2026.10.9-py3-none-any.whl
| Download URL | metadata_asf-2026.10.9-py3-none-any.whl |
|---|---|
| Size | 32.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
43a85182d0dac693b19845737cf1b8093deb3fa0f918612d05a8982b700ff17d
|
|
BLAKE2b-256 checksum How to use checksums |
7614ecf89148a35877a4f2b8364880969ab103d3bc7e1caf1e8e654372982ca9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 9, 2026.
Transparency log