Skip to content

Commit bab44e7

Browse files
committed
Fix Item PUT endpoint per #385
1 parent e5251ba commit bab44e7

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

stac_fastapi/extensions/stac_fastapi/extensions/core/transaction.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,15 @@
1616

1717

1818
@attr.s
19-
class PostOrPutItem(CollectionUri):
20-
"""Create or update Item."""
19+
class PostItem(CollectionUri):
20+
"""Create Item."""
21+
22+
item: stac_types.Item = attr.ib(default=Body())
23+
24+
25+
@attr.s
26+
class PutItem(ItemUri):
27+
"""Update Item."""
2128

2229
item: stac_types.Item = attr.ib(default=Body())
2330

@@ -84,20 +91,20 @@ def register_create_item(self):
8491
response_model_exclude_unset=True,
8592
response_model_exclude_none=True,
8693
methods=["POST"],
87-
endpoint=self._create_endpoint(self.client.create_item, PostOrPutItem),
94+
endpoint=self._create_endpoint(self.client.create_item, PostItem),
8895
)
8996

9097
def register_update_item(self):
9198
"""Register update item endpoint (PUT /collections/{collection_id}/items)."""
9299
self.router.add_api_route(
93100
name="Update Item",
94-
path="/collections/{collection_id}/items",
101+
path="/collections/{collection_id}/items/{item_id}",
95102
response_model=Item if self.settings.enable_response_models else None,
96103
response_class=self.response_class,
97104
response_model_exclude_unset=True,
98105
response_model_exclude_none=True,
99106
methods=["PUT"],
100-
endpoint=self._create_endpoint(self.client.update_item, PostOrPutItem),
107+
endpoint=self._create_endpoint(self.client.update_item, PutItem),
101108
)
102109

103110
def register_delete_item(self):

stac_fastapi/pgstac/stac_fastapi/pgstac/transactions.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,22 @@ async def create_item(
4040
return item
4141

4242
async def update_item(
43-
self, collection_id: str, item: stac_types.Item, **kwargs
43+
self, collection_id: str, item_id: str, item: stac_types.Item, **kwargs
4444
) -> Optional[Union[stac_types.Item, Response]]:
4545
"""Update item."""
46-
item_collection_id = item.get("collection")
47-
if item_collection_id is not None and collection_id != item_collection_id:
46+
body_collection_id = item.get("collection")
47+
if body_collection_id is not None and collection_id != body_collection_id:
4848
raise HTTPException(
4949
status_code=409,
50-
detail=f"Collection ID from path parameter ({collection_id}) does not match Collection ID from Item ({item_collection_id})",
50+
detail=f"Collection ID from path parameter ({collection_id}) does not match Collection ID from Item ({body_collection_id})",
5151
)
5252
item["collection"] = collection_id
53+
body_item_id = item["id"]
54+
if body_item_id != item_id:
55+
raise HTTPException(
56+
status_code=409,
57+
detail=f"Item ID from path parameter ({item_id}) does not match Item ID from Item ({body_item_id})",
58+
)
5359
request = kwargs["request"]
5460
pool = request.app.state.writepool
5561
await dbfunc(pool, "update_item", item)

stac_fastapi/pgstac/tests/api/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"POST /collections",
1818
"POST /collections/{collection_id}/items",
1919
"PUT /collections",
20-
"PUT /collections/{collection_id}/items",
20+
"PUT /collections/{collection_id}/items/{item_id}",
2121
]
2222

2323

stac_fastapi/pgstac/tests/clients/test_postgres.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ async def test_update_item(app_client, load_test_collection, load_test_item):
7676

7777
item.properties.description = "Update Test"
7878

79-
resp = await app_client.put(f"/collections/{coll.id}/items", content=item.json())
79+
resp = await app_client.put(
80+
f"/collections/{coll.id}/items/{item.id}", content=item.json()
81+
)
8082
assert resp.status_code == 200
8183

8284
resp = await app_client.get(f"/collections/{coll.id}/items/{item.id}")

stac_fastapi/pgstac/tests/resources/test_item.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ async def test_update_item(
135135

136136
item.properties.description = "Update Test"
137137

138-
resp = await app_client.put(f"/collections/{coll.id}/items", content=item.json())
138+
resp = await app_client.put(
139+
f"/collections/{coll.id}/items/{item.id}", content=item.json()
140+
)
139141
assert resp.status_code == 200
140142

141143
resp = await app_client.get(f"/collections/{coll.id}/items/{item.id}")
@@ -156,8 +158,10 @@ async def test_update_item_mismatched_collection_id(
156158
in_json["collection"] = random.choice(ascii_letters)
157159
assert in_json["collection"] != coll.id
158160

161+
item_id = in_json["id"]
162+
159163
resp = await app_client.put(
160-
f"/collections/{coll.id}/items",
164+
f"/collections/{coll.id}/items/{item_id}",
161165
json=in_json,
162166
)
163167
assert resp.status_code == 409
@@ -250,7 +254,9 @@ async def test_update_new_item(
250254
item = load_test_item
251255
item.id = "test-updatenewitem"
252256

253-
resp = await app_client.put(f"/collections/{coll.id}/items", content=item.json())
257+
resp = await app_client.put(
258+
f"/collections/{coll.id}/items/{item.id}", content=item.json()
259+
)
254260
assert resp.status_code == 404
255261

256262

@@ -261,7 +267,9 @@ async def test_update_item_missing_collection(
261267
item = load_test_item
262268
item.collection = None
263269

264-
resp = await app_client.put(f"/collections/{coll.id}/items", content=item.json())
270+
resp = await app_client.put(
271+
f"/collections/{coll.id}/items/{item.id}", content=item.json()
272+
)
265273
assert resp.status_code == 200
266274

267275
put_item = resp.json()

0 commit comments

Comments
 (0)