Skip to content

Commit 202c9f5

Browse files
committed
chore: updated readme
1 parent 395ad06 commit 202c9f5

File tree

2 files changed

+166
-39
lines changed

2 files changed

+166
-39
lines changed

README.md

Lines changed: 85 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,104 @@
1-
# SuperSTAC
1+
# SuperSTAC
22

3-
a Python library designed for high-availability satellite imagery retrieval. If one data source lacks the requested imagery, DeepEO seamlessly queries alternative sources until it finds a valid result.
3+
[![PyPI version](https://img.shields.io/pypi/v/superstac.svg)](https://pypi.org/project/superstac/)
4+
[![License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)
45

6+
**SuperSTAC** is a Python library (with planned Rust backend) for **high-availability satellite imagery retrieval**.
7+
Instead of relying on a single STAC endpoint (e.g., Sentinel from Element84), SuperSTAC can query **multiple catalogs** and automatically fall back to alternatives when a source is missing data or unavailable.
58

6-
# Dependencies
9+
⚠️ **Note:** This is an **early work-in-progress**. The initial release is to start iterating in public. Expect breaking changes.
710

8-
- pystac-client.
11+
---
912

13+
## Features (planned)
1014

11-
### Configuration YML
15+
- Query multiple STAC catalogs through a single unified API.
16+
- Automatic fallback when a catalog has no data or is down.
17+
- Configurable authentication for protected catalogs.
18+
- Resolution & band matching across heterogeneous catalogs.
19+
- CLI and Python API for flexible workflows.
20+
- Optional LLM-assisted natural language queries.
21+
- Rust backend (planned)
1222

13-
Template:
23+
---
1424

25+
## Installation
26+
27+
```bash
28+
pip install superstac
1529
```
30+
31+
## Configuration
32+
33+
SuperSTAC loads its catalog configuration from a YAML file, typically referenced via the environment variable `SUPERSTAC_CATALOG_CONFIG`.
34+
35+
Example `.superstac.yml`:
36+
37+
```bash
1638
catalogs:
17-
Catalog Name:
18-
url: Catalog URL
39+
Element84 Sentinel:
40+
url: https://earth-search.aws.element84.com/v0
41+
Planet:
42+
url: https://api.planet.com/stac/v1
1943
auth:
20-
type: bearer
21-
token: "YOUR_MICROSOFT_PC_TOKEN"
22-
Catalog Name:
23-
url: Catalog URL
24-
type: basic
44+
type: basic
2545
username: youruser
2646
password: yourpass
47+
Microsoft PC:
48+
url: https://planetarycomputer.microsoft.com/api/stac/v1
49+
auth:
50+
type: bearer
51+
token: "YOUR_MICROSOFT_PC_TOKEN"
2752
```
28-
# load from the environment variable - SUPERSTAC_CATALOG_CONFIG
53+
See [superstac/.superstac.yml](superstac/.superstac.yml) for an example config file.
54+
55+
56+
## Usage (very early draft)
57+
58+
```python
59+
from superstac import get_catalog_registry, federated_search_async
60+
61+
cr = get_catalog_registry()
62+
cr.load_catalogs_from_config()
63+
64+
print("\nRunning asynchronous federated_search_async...")
65+
start_async = time.perf_counter()
66+
results_async = asyncio.run(
67+
federated_search_async(
68+
registry=cr,
69+
collections=["sentinel-2-l2a"],
70+
bbox=[6.0, 49.0, 7.0, 50.0],
71+
datetime="2024-01-01/2024-01-31",
72+
query={"eo:cloud_cover": {"lt": 20}},
73+
sortby=[{"field": "properties.datetime", "direction": "desc"}],
74+
)
75+
)
76+
end_async = time.perf_counter()
77+
print(
78+
f"Asynchronous search found {len(results_async)} items in {end_async - start_async:.2f} seconds."
79+
)
80+
81+
for x in results_async:
82+
print(x.self_href)
83+
```
84+
85+
Also see [main.py](./main.py).
86+
87+
## Development Status / Roadmap
2988

30-
# Todo - auth configuration documentation.
89+
Planned enhancements:
90+
- Authentication configuration & documentation
91+
- Retry logic
92+
- Result modifiers
93+
- Catalog refresh & health checks
94+
- Latency tracking and fallback ranking
95+
- Band matching across heterogeneous catalogs
96+
- CLI tool
97+
- Example notebooks (illegal mining detection, disaster response, LLM-assisted search)
3198

32-
See [.superstac.yml](./superstac/.superstac.yml) for an example configuration file.
3399

100+
## License
34101

35-
# todo
102+
MIT License. See [LICENSE](LICENSE).
36103

37-
- retries - https://pystac-client.readthedocs.io/en/stable/usage.html#configuring-retry-behavior
38-
- modifier - https://pystac-client.readthedocs.io/en/stable/usage.html#automatically-modifying-results
39-
- refresh
40-
- auth
41-
- ues cases e.g when a catalog is offline - store latency ?
42-
- when a catalog is specified and changed it still works - band matching
104+
Feedback, issues, and contributions are welcome! This package is at a very early stage, so opening issues for missing features or edge cases will directly shape the roadmap.

superstac/assets_mapper.py

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,82 @@
1-
planetary_mapping = {
2-
"B01": "coastal",
3-
"B02": "blue",
4-
"B03": "green",
5-
"B04": "red",
6-
"B05": "rededge1",
7-
"B06": "rededge2",
8-
"B07": "rededge3",
9-
"B08": "nir",
10-
"B8A": "nir08",
11-
"B09": "nir09",
12-
"B11": "swir16",
13-
"B12": "swir22",
14-
"AOT": "aot",
15-
"SCL": "scl",
16-
"WVP": "wvp",
1+
from typing import Union
2+
from superstac._logging import logger
3+
from pystac import Item
4+
5+
unified_band_mapper = {
6+
# Sentinel-2 L2A mapping
7+
# Retrieved from ''
8+
"sentinel-2-l2a": {
9+
"coastal": "B01",
10+
"blue": "B02",
11+
"green": "B03",
12+
"red": "B04",
13+
"rededge1": "B05",
14+
"rededge2": "B06",
15+
"rededge3": "B07",
16+
"nir": "B08",
17+
"nir08": "B8A",
18+
"nir09": "B09",
19+
"swir16": "B11",
20+
"cirrus": "B10",
21+
"swir22": "B12",
22+
"aot": "AOT",
23+
"scl": "SCL",
24+
"wvp": "WVP",
25+
},
26+
# Landsat 8/9 Collection 2 Level 2 mapping
27+
"landsat-8-c2l2": {
28+
"coastal": "SR_B1",
29+
"blue": "SR_B2",
30+
"green": "SR_B3",
31+
"red": "SR_B4",
32+
"nir": "SR_B5",
33+
"swir16": "SR_B6",
34+
"swir22": "SR_B7",
35+
"thermal_infrared": "ST_B10",
36+
"pixel_qa": "QA_PIXEL",
37+
},
38+
"landsat-9-c2l2": {
39+
"coastal": "SR_B1",
40+
"blue": "SR_B2",
41+
"green": "SR_B3",
42+
"red": "SR_B4",
43+
"nir": "SR_B5",
44+
"swir16": "SR_B6",
45+
"swir22": "SR_B7",
46+
"thermal_infrared": "ST_B10",
47+
"pixel_qa": "QA_PIXEL",
48+
},
1749
}
50+
51+
52+
def get_asset_by_standard_name(
53+
stac_item: Item, standard_band_name: str
54+
) -> Union[str, None]:
55+
"""
56+
Retrieves a STAC asset from an item using a standardized band name.
57+
58+
Args:
59+
stac_item (pystac.Item): The STAC item to search.
60+
standard_band_name (str): The common, standardized name of the band (e.g., 'red', 'nir').
61+
62+
Returns:
63+
pystac.Asset or None: The asset object if found, otherwise None.
64+
"""
65+
66+
collection_id = stac_item.collection_id or ""
67+
68+
band_mapping = unified_band_mapper.get(collection_id)
69+
70+
if band_mapping is None:
71+
logger.info(f"Warning: No mapping found for collection '{collection_id}'.")
72+
return None
73+
74+
asset_key = band_mapping.get(standard_band_name)
75+
76+
if asset_key is None:
77+
logger.info(
78+
f"Warning: No asset key found for standard band '{standard_band_name}' in collection '{collection_id}'."
79+
)
80+
return None
81+
82+
return stac_item.assets.get(asset_key) # type: ignore

0 commit comments

Comments
 (0)