Skip to content

Commit

Permalink
feat(release)!: Improve stac integration tests, add optional web acl …
Browse files Browse the repository at this point in the history
…configuration for cloudfront, titiler-pgstac v1 upgrade (#405)

### 📣 Breaking  
- [feat!: titiler-pgstac v1 upgrade
#398](#398) introduces
breaking endpoint changes; see [titiler-pgstac v0.8 -> v1.0 migration
docs](https://stac-utils.github.io/titiler-pgstac/latest/migrations/v1_migration/)

### ✨  Added
- [feat: add optional web acl configuration for cloudfront
#396](#396)

### 🪙  Changed/Updated
- [chore: Improve stac integration tests
#395](#395)
- [chore: add gitignore entry for Jetbrains IDEs
#409](#409)


### 🩹 Fixed
- [fix: render fix for titiler-pgstac v1 upgrade
#408](#408)
  • Loading branch information
botanical authored Aug 1, 2024
2 parents 19f308e + 450c082 commit cdb0370
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 107 deletions.
1 change: 1 addition & 0 deletions .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ CERT_ARN=
VEDA_CLOUDFRONT=
VEDA_CLOUDFRONT_OAC=[OPTIONAL, CONFIGURES ORIGIN ACCESS CONTROL, DEFAULTS TO TRUE]
VEDA_CUSTOM_HOST=
VEDA_SHARED_WEB_ACL_ID=[OPTIONAL ID ARN for WEB ACL]
60 changes: 29 additions & 31 deletions .github/workflows/tests/test_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,31 @@ def test_raster_api():
def test_mosaic_api():
"""test mosaic."""
query = {"collections": ["noaa-emergency-response"], "filter-lang": "cql-json"}
resp = httpx.post(f"{raster_endpoint}/mosaic/register", json=query)
resp = httpx.post(f"{raster_endpoint}/searches/register", json=query)
assert resp.headers["content-type"] == "application/json"
assert resp.status_code == 200
assert resp.json()["searchid"]
assert resp.json()["id"]
assert resp.json()["links"]

searchid = resp.json()["searchid"]
searchid = resp.json()["id"]

resp = httpx.get(f"{raster_endpoint}/mosaic/{searchid}/-85.6358,36.1624/assets")
resp = httpx.get(f"{raster_endpoint}/searches/{searchid}/-85.6358,36.1624/assets")
assert resp.status_code == 200
assert len(resp.json()) == 1
assert list(resp.json()[0]) == ["id", "bbox", "assets", "collection"]
assert resp.json()[0]["id"] == "20200307aC0853900w361030"

resp = httpx.get(f"{raster_endpoint}/mosaic/{searchid}/tiles/15/8589/12849/assets")
resp = httpx.get(
f"{raster_endpoint}/searches/{searchid}/tiles/15/8589/12849/assets"
)
assert resp.status_code == 200
assert len(resp.json()) == 1
assert list(resp.json()[0]) == ["id", "bbox", "assets", "collection"]
assert resp.json()[0]["id"] == "20200307aC0853900w361030"

z, x, y = 15, 8589, 12849
resp = httpx.get(
f"{raster_endpoint}/mosaic/{searchid}/tiles/{z}/{x}/{y}",
f"{raster_endpoint}/searches/{searchid}/tiles/{z}/{x}/{y}",
params={"assets": "cog"},
headers={"Accept-Encoding": "br, gzip"},
timeout=10.0,
Expand Down Expand Up @@ -105,11 +107,11 @@ def test_mosaic_search():
},
]
for search in searches:
resp = httpx.post(f"{raster_endpoint}/mosaic/register", json=search)
resp = httpx.post(f"{raster_endpoint}/searches/register", json=search)
assert resp.status_code == 200
assert resp.json()["searchid"]
assert resp.json()["id"]

resp = httpx.get(f"{raster_endpoint}/mosaic/list")
resp = httpx.get(f"{raster_endpoint}/searches/list")
assert resp.headers["content-type"] == "application/json"
assert resp.status_code == 200
assert (
Expand All @@ -118,16 +120,18 @@ def test_mosaic_search():
assert resp.json()["context"]["returned"] == 10 # default limit is 10

# Make sure all mosaics returned have
for mosaic in resp.json()["searches"]:
assert mosaic["search"]["metadata"]["type"] == "mosaic"
for search in resp.json()["searches"]:
assert search["search"]["metadata"]["type"] == "mosaic"

links = resp.json()["links"]
assert len(links) == 2
assert links[0]["rel"] == "self"
assert links[1]["rel"] == "next"
assert links[1]["href"] == f"{raster_endpoint}/mosaic/list?limit=10&offset=10"
assert links[1]["href"] == f"{raster_endpoint}/searches/list?limit=10&offset=10"

resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"limit": 1, "offset": 1})
resp = httpx.get(
f"{raster_endpoint}/searches/list", params={"limit": 1, "offset": 1}
)
assert resp.status_code == 200
assert resp.json()["context"]["matched"] > 10
assert resp.json()["context"]["limit"] == 1
Expand All @@ -136,62 +140,56 @@ def test_mosaic_search():
links = resp.json()["links"]
assert len(links) == 3
assert links[0]["rel"] == "self"
assert links[0]["href"] == f"{raster_endpoint}/mosaic/list?limit=1&offset=1"
assert links[0]["href"] == f"{raster_endpoint}/searches/list?limit=1&offset=1"
assert links[1]["rel"] == "next"
assert links[1]["href"] == f"{raster_endpoint}/mosaic/list?limit=1&offset=2"
assert links[1]["href"] == f"{raster_endpoint}/searches/list?limit=1&offset=2"
assert links[2]["rel"] == "prev"
assert links[2]["href"] == f"{raster_endpoint}/mosaic/list?limit=1&offset=0"
assert links[2]["href"] == f"{raster_endpoint}/searches/list?limit=1&offset=0"

# Filter on mosaic metadata
resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"owner": "vincent"})
resp = httpx.get(f"{raster_endpoint}/searches/list", params={"owner": "vincent"})
assert resp.status_code == 200
assert resp.json()["context"]["matched"] == 7
assert resp.json()["context"]["limit"] == 10
assert resp.json()["context"]["returned"] == 7

# sortBy
resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"sortby": "lastused"})
resp = httpx.get(f"{raster_endpoint}/searches/list", params={"sortby": "lastused"})
assert resp.status_code == 200

resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"sortby": "usecount"})
resp = httpx.get(f"{raster_endpoint}/searches/list", params={"sortby": "usecount"})
assert resp.status_code == 200

resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"sortby": "-owner"})
resp = httpx.get(f"{raster_endpoint}/searches/list", params={"sortby": "-owner"})
assert resp.status_code == 200
assert (
"owner" not in resp.json()["searches"][0]["search"]["metadata"]
) # some mosaic don't have owners

resp = httpx.get(f"{raster_endpoint}/mosaic/list", params={"sortby": "owner"})
resp = httpx.get(f"{raster_endpoint}/searches/list", params={"sortby": "owner"})
assert resp.status_code == 200
assert "owner" in resp.json()["searches"][0]["search"]["metadata"]


def test_item():
"""test stac endpoints."""
collection_id = "noaa-emergency-response"
item_id = "20200307aC0853300w361200"
resp = httpx.get(
f"{raster_endpoint}/stac/assets",
params={
"collection": "noaa-emergency-response",
"item": "20200307aC0853300w361200",
},
f"{raster_endpoint}/collections/{collection_id}/items/{item_id}/assets"
)
assert resp.status_code == 200
assert resp.headers["content-type"] == "application/json"
assert resp.json() == ["cog"]

resp = httpx.get(
f"{raster_endpoint}/stac/tilejson.json",
f"{raster_endpoint}/collections/{collection_id}/items/{item_id}/WebMercatorQuad/tilejson.json",
params={
"collection": "noaa-emergency-response",
"item": "20200307aC0853300w361200",
"assets": "cog",
},
)
assert resp.status_code == 200
assert resp.headers["content-type"] == "application/json"
assert resp.json()["tilejson"]
assert "assets=cog" in resp.json()["tiles"][0]
assert "item=20200307aC0853300w361200" in resp.json()["tiles"][0]
assert "collection=noaa-emergency-response" in resp.json()["tiles"][0]
assert resp.json()["bounds"] == [-85.5501, 36.1749, -85.5249, 36.2001]
95 changes: 84 additions & 11 deletions .github/workflows/tests/test_stac.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,125 @@

import httpx

seeded_collection = "noaa-emergency-response"
seeded_id = "20200307aC0853300w361200"
stac_endpoint = "http://0.0.0.0:8081"
index_endpoint = "index.html"
docs_endpoint = "docs"
health_endpoint = "_mgmt/ping"
search_endpoint = "search"
collections_endpoint = "collections"


def test_stac_health():
"""test stac health endpoint."""

assert httpx.get(f"{stac_endpoint}/{health_endpoint}").status_code == 200


def test_stac_viewer():
"""test stac viewer."""
resp = httpx.get(f"{stac_endpoint}/{index_endpoint}")
assert resp.status_code == 200
assert resp.headers.get("x-correlation-id") == "local"
assert "<title>Simple STAC API Viewer</title>" in resp.text


def test_stac_docs():
"""test stac docs."""
resp = httpx.get(f"{stac_endpoint}/{docs_endpoint}")
assert resp.status_code == 200
assert "Swagger UI" in resp.text


def test_stac_get_search():
"""test stac get search."""
default_limit_param = "?limit=10"
resp = httpx.get(f"{stac_endpoint}/{search_endpoint}{default_limit_param}")
assert resp.status_code == 200
features = resp.json()["features"]
assert len(features) > 0
collections = [c["collection"] for c in features]
assert seeded_collection in collections


def test_stac_post_search():
"""test stac post search."""
request_body = {"collections": [seeded_collection]}
resp = httpx.post(f"{stac_endpoint}/{search_endpoint}", json=request_body)
assert resp.status_code == 200
features = resp.json()["features"]
assert len(features) > 0
collections = [c["collection"] for c in features]
assert seeded_collection in collections


def test_stac_get_collections():
"""test stac get collections"""
resp = httpx.get(f"{stac_endpoint}/{collections_endpoint}")
assert resp.status_code == 200
collections = resp.json()["collections"]
assert len(collections) > 0
id = [c["id"] for c in collections]
assert seeded_collection in id


def test_stac_get_collections_by_id():
"""test stac get collection by id"""
resp = httpx.get(f"{stac_endpoint}/{collections_endpoint}/{seeded_collection}")
assert resp.status_code == 200
collection = resp.json()
assert collection["id"] == seeded_collection


def test_stac_get_collection_items_by_id():
"""test stac get items in collection by collection id"""
resp = httpx.get(
f"{stac_endpoint}/{collections_endpoint}/{seeded_collection}/items"
)
assert resp.status_code == 200
collection = resp.json()
assert collection["type"] == "FeatureCollection"


def test_stac_api():
"""test stac."""
# Ping
assert httpx.get(f"{stac_endpoint}/_mgmt/ping").status_code == 200

# viewer
assert httpx.get(f"{stac_endpoint}/index.html").status_code == 200

# Collections
resp = httpx.get(f"{stac_endpoint}/collections")
assert resp.status_code == 200
collections = resp.json()["collections"]
assert len(collections) > 0
ids = [c["id"] for c in collections]
assert "noaa-emergency-response" in ids
assert seeded_collection in ids

# items
resp = httpx.get(f"{stac_endpoint}/collections/noaa-emergency-response/items")
resp = httpx.get(f"{stac_endpoint}/collections/{seeded_collection}/items")
assert resp.status_code == 200
items = resp.json()["features"]
assert len(items) == 10

# item
resp = httpx.get(
f"{stac_endpoint}/collections/noaa-emergency-response/items/20200307aC0853300w361200"
f"{stac_endpoint}/collections/{seeded_collection}/items/{seeded_id}"
)
assert resp.status_code == 200
item = resp.json()
assert item["id"] == "20200307aC0853300w361200"
assert item["id"] == seeded_id


def test_stac_to_raster():
"""test link to raster api."""
# tilejson
resp = httpx.get(
f"{stac_endpoint}/collections/noaa-emergency-response/items/20200307aC0853300w361200/tilejson.json",
f"{stac_endpoint}/collections/{seeded_collection}/items/{seeded_id}/tilejson.json",
params={"assets": "cog"},
)
assert resp.status_code == 307

# viewer
resp = httpx.get(
f"{stac_endpoint}/collections/noaa-emergency-response/items/20200307aC0853300w361200/viewer",
f"{stac_endpoint}/collections/{seeded_collection}/items/{seeded_id}/viewer",
params={"assets": "cog"},
)
assert resp.status_code == 307
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,6 @@ cdk-dev.out
stac-browser

container_logs.log

# Jetbrains IDEs
.idea
8 changes: 4 additions & 4 deletions raster_api/runtime/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
inst_reqs = [
"boto3",
"rio-tiler==6.5.0",
"titiler.pgstac==0.8.3",
"titiler.core>=0.15.5,<0.16",
"titiler.mosaic>=0.15.5,<0.16",
"titiler.extensions[cogeo]>=0.15.5,<0.16",
"titiler.pgstac==1.3.0",
"titiler.core>=0.18.5,<0.19",
"titiler.mosaic>=0.18.5,<0.19",
"titiler.extensions[cogeo]>=0.18.5,<0.19",
"starlette-cramjam>=0.3,<0.4",
"aws_xray_sdk>=2.6.0,<3",
"aws-lambda-powertools>=1.18.0",
Expand Down
Loading

0 comments on commit cdb0370

Please sign in to comment.