Skip to content

Commit 3e5fc1c

Browse files
fix AsyncBaseCoreClient urls (#675)
1 parent 24fd258 commit 3e5fc1c

File tree

4 files changed

+146
-2
lines changed

4 files changed

+146
-2
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## [Unreleased]
44

5+
## [2.5.5.post1] - 2024-04-25
6+
7+
### Fixed
8+
9+
* Fix `service-doc` and `service-desc` url in landing page when using router prefix for `AsyncBaseCoreClient`
10+
511
## [2.5.5] - 2024-04-24
612

713
### Fixed

stac_fastapi/api/tests/conftest.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,61 @@ def item_collection(
116116
)
117117

118118
return CoreClient
119+
120+
121+
@pytest.fixture
122+
def AsyncTestCoreClient(collection_dict, item_dict):
123+
class AsyncCoreClient(core.AsyncBaseCoreClient):
124+
async def post_search(
125+
self, search_request: BaseSearchPostRequest, **kwargs
126+
) -> stac.ItemCollection:
127+
return stac.ItemCollection(
128+
type="FeatureCollection", features=[stac.Item(**item_dict)]
129+
)
130+
131+
async def get_search(
132+
self,
133+
collections: Optional[List[str]] = None,
134+
ids: Optional[List[str]] = None,
135+
bbox: Optional[List[NumType]] = None,
136+
intersects: Optional[str] = None,
137+
datetime: Optional[Union[str, datetime]] = None,
138+
limit: Optional[int] = 10,
139+
**kwargs,
140+
) -> stac.ItemCollection:
141+
return stac.ItemCollection(
142+
type="FeatureCollection", features=[stac.Item(**item_dict)]
143+
)
144+
145+
async def get_item(
146+
self, item_id: str, collection_id: str, **kwargs
147+
) -> stac.Item:
148+
return stac.Item(**item_dict)
149+
150+
async def all_collections(self, **kwargs) -> stac.Collections:
151+
return stac.Collections(
152+
collections=[stac.Collection(**collection_dict)],
153+
links=[
154+
{"href": "test", "rel": "root"},
155+
{"href": "test", "rel": "self"},
156+
{"href": "test", "rel": "parent"},
157+
],
158+
)
159+
160+
async def get_collection(self, collection_id: str, **kwargs) -> stac.Collection:
161+
return stac.Collection(**collection_dict)
162+
163+
async def item_collection(
164+
self,
165+
collection_id: str,
166+
bbox: Optional[List[Union[float, int]]] = None,
167+
datetime: Optional[Union[str, datetime]] = None,
168+
limit: int = 10,
169+
token: str = None,
170+
**kwargs,
171+
) -> stac.ItemCollection:
172+
return stac.ItemCollection(
173+
type="FeatureCollection", features=[stac.Item(**item_dict)]
174+
)
175+
176+
return AsyncCoreClient

stac_fastapi/api/tests/test_app_prefix.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,89 @@ def test_api_prefix(TestCoreClient, prefix):
4646
conformance = client.get(f"{prefix}/conformance")
4747
assert conformance.status_code == 200, conformance.json()
4848

49+
# NOTE: The collections/collection/items/item links do not have the prefix
50+
# because they are created in the fixtures
51+
collections = client.get(f"{prefix}/collections")
52+
assert collections.status_code == 200, collections.json()
53+
collection_id = collections.json()["collections"][0]["id"]
54+
print(collections.json()["links"])
55+
collection = client.get(f"{prefix}/collections/{collection_id}")
56+
assert collection.status_code == 200, collection.json()
57+
58+
items = client.get(f"{prefix}/collections/{collection_id}/items")
59+
assert items.status_code == 200, items.json()
60+
61+
item_id = items.json()["features"][0]["id"]
62+
item = client.get(f"{prefix}/collections/{collection_id}/items/{item_id}")
63+
assert item.status_code == 200, item.json()
64+
65+
link_tests = [
66+
("root", "application/json", "/"),
67+
("conformance", "application/json", "/conformance"),
68+
("data", "application/json", "/collections"),
69+
("search", "application/geo+json", "/search"),
70+
("service-doc", "text/html", "/api.html"),
71+
("service-desc", "application/vnd.oai.openapi+json;version=3.0", "/api"),
72+
]
73+
74+
for rel_type, expected_media_type, expected_path in link_tests:
75+
link = get_link(landing.json(), rel_type)
76+
77+
assert link is not None, f"Missing {rel_type} link in landing page"
78+
assert link.get("type") == expected_media_type
79+
80+
link_path = urllib.parse.urlsplit(link.get("href")).path
81+
assert link_path == prefix + expected_path
82+
83+
resp = client.get(prefix + expected_path)
84+
assert resp.status_code == 200
85+
86+
87+
@pytest.mark.parametrize("prefix", ["", "/a_prefix"])
88+
def test_async_api_prefix(AsyncTestCoreClient, prefix):
89+
api_settings = ApiSettings(
90+
openapi_url=f"{prefix}/api",
91+
docs_url=f"{prefix}/api.html",
92+
)
93+
94+
api = StacApi(
95+
settings=api_settings,
96+
client=AsyncTestCoreClient(),
97+
router=APIRouter(prefix=prefix),
98+
)
99+
100+
with TestClient(api.app, base_url="http://stac.io") as client:
101+
landing = client.get(f"{prefix}/")
102+
assert landing.status_code == 200, landing.json()
103+
104+
service_doc = client.get(f"{prefix}/api.html")
105+
assert service_doc.status_code == 200, service_doc.text
106+
107+
service_desc = client.get(f"{prefix}/api")
108+
assert service_desc.status_code == 200, service_desc.json()
109+
110+
conformance = client.get(f"{prefix}/conformance")
111+
assert conformance.status_code == 200, conformance.json()
112+
113+
collections = client.get(f"{prefix}/collections")
114+
assert collections.status_code == 200, collections.json()
115+
collection_id = collections.json()["collections"][0]["id"]
116+
117+
collection = client.get(f"{prefix}/collections/{collection_id}")
118+
assert collection.status_code == 200, collection.json()
119+
120+
items = client.get(f"{prefix}/collections/{collection_id}/items")
121+
assert items.status_code == 200, items.json()
122+
123+
item_id = items.json()["features"][0]["id"]
124+
item = client.get(f"{prefix}/collections/{collection_id}/items/{item_id}")
125+
assert item.status_code == 200, item.json()
126+
49127
link_tests = [
50128
("root", "application/json", "/"),
51129
("conformance", "application/json", "/conformance"),
130+
("data", "application/json", "/collections"),
131+
("search", "application/geo+json", "/search"),
52132
("service-doc", "text/html", "/api.html"),
53133
("service-desc", "application/vnd.oai.openapi+json;version=3.0", "/api"),
54134
]

stac_fastapi/types/stac_fastapi/types/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ async def landing_page(self, **kwargs) -> stac_types.LandingPage:
612612
"rel": "service-desc",
613613
"type": "application/vnd.oai.openapi+json;version=3.0",
614614
"title": "OpenAPI service description",
615-
"href": urljoin(base_url, request.app.openapi_url.lstrip("/")),
615+
"href": str(request.url_for("openapi")),
616616
}
617617
)
618618

@@ -622,7 +622,7 @@ async def landing_page(self, **kwargs) -> stac_types.LandingPage:
622622
"rel": "service-doc",
623623
"type": "text/html",
624624
"title": "OpenAPI service documentation",
625-
"href": urljoin(base_url, request.app.docs_url.lstrip("/")),
625+
"href": str(request.url_for("swagger_ui_html")),
626626
}
627627
)
628628

0 commit comments

Comments
 (0)