usgsxplore
Python client for the USGS M2M API — search, download, and process Earth observation imagery from EarthExplorer.
Supports 100+ datasets (Landsat, Hexagon KH-9, declassified imagery, aerial photos, and more). Provides both a CLI and a Python API.
Inspired by landsatxplore, with broader dataset support and additional features.
Installation
pip install usgsxplore
# or with pipx (recommended for CLI use)
pipx install usgsxplore
Credentials
You need a USGS ERS account with M2M API access enabled.
- Register at ers.cr.usgs.gov/register
- Request M2M API access at ers.cr.usgs.gov/profile/access — specify the datasets you plan to use
- Use your username and M2M token (not your password)
Set credentials as environment variables to avoid typing them every time:
export USGS_USERNAME=<your_username>
export USGS_TOKEN=<your_token>
Quick start
# Search for Landsat scenes at a location between 2010 and 2020
usgsxplore search landsat_tm_c2_l1 --location 5.7074 45.1611 --interval-date 2010-01-01 2020-01-01
# Search for Hexagon KH-9 scenes, export to GeoPackage and visualize them on an HTML map
usgsxplore search declassii --filter "camera=H" --output results.gpkg
usgsxplore viz map results.gpkg --output-file map.html
# Download the first 10 results
usgsxplore search landsat_tm_c2_l1 --limit 10 --output results.txt
usgsxplore download results.txt
CLI Reference
usgsxplore [OPTIONS] COMMAND [ARGS]...
Commands:
search Search scenes in a dataset
download Download scenes from a text file of entity IDs
download-browse Download individual browse (preview) images from a vector file
viz Visualize scenes from a vector file (map, footprint, density, strip)
info List available datasets and metadata filters
search
Search scenes in a dataset, with optional spatial, temporal, and metadata filters.
usgsxplore search [OPTIONS] DATASET
| Option | Description |
|---|---|
-o / --output |
Output file — repeatable, format inferred from extension |
-vf / --vector-file |
Vector file for spatial filter (.gpkg, .shp, .geojson) |
-l / --location |
Point filter: longitude latitude |
-b / --bbox |
Bounding box: xmin ymin xmax ymax |
-c / --clouds |
Max cloud cover percentage (1–100) |
-i / --interval-date |
Date range: YYYY-MM-DD YYYY-MM-DD |
-f / --filter |
Metadata filter string (see Filter syntax) |
-m / --limit |
Max number of results (default: all) |
--entity-ids-file |
Text file of entity IDs to fetch metadata for, instead of searching (other filters are ignored) |
--pbar |
Show progress bar |
Output formats:
| Extension | Content |
|---|---|
.txt |
Entity IDs, one per line — usable with download |
.json |
Raw API response with full metadata |
.gpkg / .shp / .geojson |
Vector file with scene footprints |
.html |
Deprecated, will be removed in a future release — use usgsxplore viz map on a vector output instead |
Multiple outputs can be specified simultaneously:
usgsxplore search declassii --filter "camera=H" --output scenes.gpkg --output scenes.txt
download
Download scenes from a .txt file of entity IDs (produced by search).
usgsxplore download [OPTIONS] TEXTFILE
| Option | Description |
|---|---|
-d / --dataset |
Dataset name (auto-read from file header if present) |
-p / --product-number |
Product index when multiple products are available |
-o / --output-dir |
Output directory (default: .) |
-m / --max-workers |
Parallel download threads (default: 5) |
--overwrite |
Overwrite existing files |
--hide-pbar |
Hide progress bar |
--no-extract |
Skip extraction of downloaded archives |
The .txt file header line #dataset=<name> is read automatically, so passing -d is optional if the file was generated by search.
download-browse
Download individual browse (preview) images from a vector file. Each scene is saved as a separate file named after its entity_id.
usgsxplore download-browse [OPTIONS] VECTOR_FILE
TIF files are georeferenced using corner coordinate columns from the vector file. JPG files are saved without georeferencing.
| Option | Description |
|---|---|
-o / --output-dir |
Output directory (default: ./browse_images/) |
-f / --format |
Output format: tif (default) or jpg |
-m / --max-workers |
Parallel download threads (default: 4) |
--overwrite |
Overwrite existing files |
--hide-pbar |
Hide progress bar |
# Download as georeferenced GeoTIFF (default)
usgsxplore download-browse results.gpkg -o ./previews/
# Download as JPEG
usgsxplore download-browse results.gpkg -o ./previews/ --format jpg
viz
Visualize scenes from a vector file (produced by search).
usgsxplore viz COMMAND [OPTIONS] VECTOR_FILE
| Command | Output |
|---|---|
map |
Interactive HTML map, with the browse image in each popup (default: scenes_map.html) |
footprint |
Scene footprints over a satellite basemap, as PNG/JPG (default: scenes_footprint.png) |
density |
Scene overlap density over a satellite basemap, as PNG/JPG (default: scenes_density.png) |
strip |
One <strip_id>.jpg per strip: browse-image mosaic next to a context map (default dir: ./strip_viz/) |
Options shared by every viz command:
| Option | Description |
|---|---|
-roi / --roi-vector-file |
Region Of Interest as a vector file, drawn in red |
--roi-location |
ROI as a point: longitude latitude |
--roi-bbox |
ROI as a bounding box: xmin ymin xmax ymax |
--available-only |
Keep only scenes available for download |
--overwrite |
Regenerate existing outputs |
Only one ROI option can be given. map, footprint and density take -o / --output-file; strip takes -o / --output-dir, plus:
| Option | Description |
|---|---|
-m / --max-workers |
Strips rendered in parallel (default: 4) |
--work-dir |
Where browse images are downloaded (default: OUTPUT_DIR/browse_images) |
--clean / --no-clean |
Delete downloaded browse images once figures are saved (default: on) |
usgsxplore viz map results.gpkg -o map.html --roi-bbox 5.5 45 6 45.5
usgsxplore viz strip results.gpkg -o ./strips/ -roi roi.geojson --no-clean
See docs/figures.md for example outputs.
info
# List all available datasets
usgsxplore info dataset
# List available metadata filters for a dataset
usgsxplore info filters DATASET
Tip: Trigger filter help directly from a search by using an invalid value:
# List all filter fields for the declassii dataset
usgsxplore search declassii -f "whatever=?"
# List all valid values for the "camera" filter
usgsxplore search declassii -f "camera=?"
Filter syntax
The --filter option accepts a human-readable expression:
"field1=value1 & field2=value2 | field3=value3"
Fields can be identified by their filter ID, label, or SQL field name. Values can be the raw value or the display label. All of the following are equivalent:
usgsxplore search declassii --filter "camera=L"
usgsxplore search declassii --filter "Camera Type=L"
usgsxplore search declassii --filter "5e839ff8cfa94807=L"
usgsxplore search declassii --filter "camera=KH-9 Lower Resolution Mapping Camera"
Combine multiple filters:
# KH-9 scenes that are available for download
usgsxplore search declassii --filter "camera=L & DOWNLOAD_AVAILABLE=Y"
Python API
All CLI commands have equivalent Python functions in usgsxplore.core:
from usgsxplore.core import (
search_scenes,
download_scenes,
download_browse_images,
list_datasets,
list_dataset_filters,
)
Search
# Print entity IDs to stdout
search_scenes(
"landsat_tm_c2_l1",
location=(5.7074, 45.1611),
interval_date=("2010-01-01", "2020-01-01"),
)
# Save to multiple formats
search_scenes(
"declassii",
output_files=["results.gpkg", "results.txt"],
filter_str="camera=H",
limit=500,
show_progress=True,
)
Credentials are read from USGS_USERNAME / USGS_TOKEN environment variables by default, or can be passed explicitly:
search_scenes("declassii", username="myuser", token="mytoken", ...)
Download
download_scenes(
"results.txt",
output_dir="./data",
max_workers=8,
)
Browse images
# Download as georeferenced GeoTIFF (default)
download_browse_images("results.gpkg", output_dir="./previews")
# Download as JPEG
download_browse_images("results.gpkg", output_dir="./previews", fmt="jpg")
# Advanced: use BrowseDownloader directly with a custom strategy
from usgsxplore.browse import BrowseDownloader, TifSaveStrategy, JpgSaveStrategy
downloader = BrowseDownloader("./previews", TifSaveStrategy(), max_workers=8)
downloader.download("results.gpkg")
Figures
from usgsxplore.viz.html_map import generate_html_map
from usgsxplore.viz.scenes_density import generate_scenes_density
from usgsxplore.viz.scenes_footprint import generate_scenes_footprint
from usgsxplore.viz.strip_figures import generate_strip_figures
# Interactive map of scene footprints, with browse images in popups
generate_html_map("results.gpkg", "map.html")
# One image of all scene footprints, with the ROI outlined (the output directory must exist)
generate_scenes_footprint("results.gpkg", "footprint.png", roi="roi.geojson")
# The ROI can also be a GeoDataFrame or a shapely geometry in longitude/latitude
from shapely import box
generate_scenes_footprint("results.gpkg", "footprint.png", roi=box(5.5, 45, 6, 45.5))
# Scene overlap density, with a 1 km pixel size (in Web Mercator meters)
generate_scenes_density("results.gpkg", "density.png", roi="roi.geojson", resolution=1000)
# One figure per strip
generate_strip_figures("results.gpkg", "./strips", roi="roi.geojson")
Inspect datasets and filters
# List datasets
datasets = list_datasets()
# List filters for a dataset
filters = list_dataset_filters("declassii")
for f in filters:
print(f["fieldLabel"], "→", f["searchSql"])
For a full example notebook, see examples/download.ipynb.
Contributing
See CONTRIBUTING.md.
Metadata
Release files for usgsxplore 1.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| usgsxplore-1.2.1.tar.gz | 338.1 kB | Without provenance | Details for usgsxplore-1.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| usgsxplore-1.2.1-py3-none-any.whl | Python 3 | none | any | Details for usgsxplore-1.2.1-py3-none-any.whl |
Total release size: 382.3 kB
Release files / usgsxplore-1.2.1.tar.gz
| Download URL | usgsxplore-1.2.1.tar.gz |
|---|---|
| Size | 338.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b14fe56ffa0f81d66bb8b82579f2a48e3a827f42997bceb84b0b0751db65577c
|
|
BLAKE2b-256 checksum How to use checksums |
09494b0eb6f9ed157037d86d2ba0df2ae3ec72b45de75d1b3cd5965ad48e57c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.11.17"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.11.17","system":{"name":"Linux","release":"6.17.0-1022-azure"}} HTTPX2/2.13.1
|
Release files / usgsxplore-1.2.1-py3-none-any.whl
| Download URL | usgsxplore-1.2.1-py3-none-any.whl |
|---|---|
| Size | 44.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5f533a6d207ae9858daf9cab5618ede370615cb701e09be7cad9ff97cb71e8a
|
|
BLAKE2b-256 checksum How to use checksums |
cfc2bc785d6d8b03f39430011425439229132b0ee360a671a9b657ca022bb020
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.18.1 {"ci":true,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.11.17"},"installer":{"name":"hatch","version":"1.18.1"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.11.17","system":{"name":"Linux","release":"6.17.0-1022-azure"}} HTTPX2/2.13.1
|
Security for usgsxplore 1.2.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.