DuckDB backend for the stac-fastapi project built on top of the sfeos core api library.
This project is built on the following technologies: STAC, stac-fastapi, SFEOS core, FastAPI, DuckDB, Python
The easiest way to get started is using Docker and the provided Makefile:
-
Clone the repository (if you haven't already):
git clone https://github.com/Healy-Hyperspatial/stac-fastapi-duckdb.git cd stac-fastapi-duckdb
-
Build and start the Docker container:
make up
This will:
- Build the Docker image
- Start the STAC API server on http://localhost:8085
- Mount the
stac_collections
directory into the container
-
Access the API:
- Browse collections: http://localhost:8085/collections
- View collection items: http://localhost:8085/collections/io-lulc-9-class/items
- Get a specific item: http://localhost:8085/collections/io-lulc-9-class/items/{item_id}
-
Other useful commands:
# Run in detached mode (background) make up-d # View logs make logs # Stop the container make down
The following STAC API endpoints are implemented:
GET /collections
- List all collectionsGET /collections/{collection_id}
- Get a specific collectionGET /collections/{collection_id}/items
- Get items in a collection with filtering support (bbox, datetime)GET /collections/{collection_id}/items/{item_id}
- Get a specific itemPOST /search
- Search across collections with advanced filtering (bbox, datetime, etc.)
Both the GET items endpoint and POST search endpoint support bbox filtering. The GET endpoint accepts bbox as a comma-separated string query parameter, while the POST endpoint accepts bbox as either a comma-separated string or an array of numbers in the request body.
bbox
- Filter items by bounding box in formatwest,south,east,north
- Example:
bbox=-66,-16,-60,-8
- Uses DuckDB's spatial extension with ST_Intersects for efficient filtering
- Example:
datetime
- Filter items by temporal extent using RFC3339 datetime strings:- Single datetime:
datetime=2022-01-01T00:00:00Z
- Date range:
datetime=2022-01-01T00:00:00Z/2023-01-01T00:00:00Z
- Open-ended ranges:
datetime=2022-01-01T00:00:00Z/..
ordatetime=../2023-01-01T00:00:00Z
- Single datetime:
limit
- Maximum number of items to return (default: 10)bbox
- Spatial bounding box filter:bbox=west,south,east,north
ids
- Filter by specific item IDs:ids=item1,item2,item3
# Get items from a specific time range
curl "http://localhost:8085/collections/io-lulc-9-class/items?datetime=2019-01-01T00:00:00Z/2023-01-01T00:00:00Z&limit=5"
# Get items with spatial filtering (bbox format: west,south,east,north)
curl "http://localhost:8085/collections/io-lulc-9-class/items?bbox=-66,-16,-60,-8"
# Get items with both spatial and temporal filters
curl "http://localhost:8085/collections/io-lulc-9-class/items?bbox=-66,-16,-60,-8&datetime=2020-01-01T00:00:00Z/2022-01-01T00:00:00Z"
# Search across all collections
curl -X POST "http://localhost:8085/search" \
-H "Content-Type: application/json" \
-d '{"datetime": "2019-01-01T00:00:00Z/2023-01-01T00:00:00Z", "limit": 10}'
# Search with bbox filter in POST request
curl -X POST "http://localhost:8085/search" \
-H "Content-Type: application/json" \
-d '{"bbox": [-66, -16, -60, -8], "limit": 10}'
-
PARQUET_URLS_JSON
(required): JSON object mapping collection IDs to Parquet file paths/URLs- Local file example:
{"io-lulc-9-class": "file:///app/stac_collections/io-lulc-9-class/io-lulc-9-class.parquet"}
- S3 example:
{"landsat": "s3://public-bucket/path/landsat.parquet"}
- When running with Docker, use container paths (e.g.,
/app/stac_collections/...
)
- Local file example:
-
STAC_FILE_PATH
(optional, default:/app/stac_collections
): Directory containing STAC collection JSON files
The project includes a Makefile with commands to run tests:
# Build and run tests in Docker
make test-build
# Run tests in existing Docker container
make test
Install pre-commit.
Prior to commit, run:
pre-commit run --all-files
docker compose build
docker compose up