Skip to content

Commit 4bf1a40

Browse files
committed
update transaction endpoint
1 parent 1260543 commit 4bf1a40

File tree

6 files changed

+50
-18
lines changed

6 files changed

+50
-18
lines changed

stac_fastapi/pgstac/core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ async def _get_base_item(collection_id: str) -> Dict[str, Any]:
226226

227227
for feature in collection.get("features") or []:
228228
base_item = await base_item_cache.get(feature.get("collection"))
229+
230+
# Exclude None values
231+
base_item = {k: v for k, v in base_item.items() if v is not None}
232+
229233
feature = hydrate(base_item, feature)
230234

231235
# Grab ids needed for links that may be removed by the fields extension.

stac_fastapi/pgstac/extensions/query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def operator(self) -> Callable[[Any, Any], bool]:
3434
class QueryExtensionPostRequest(BaseModel):
3535
"""Query Extension POST request model."""
3636

37-
query: Optional[Dict[str, Dict[Operator, Any]]]
37+
query: Optional[Dict[str, Dict[Operator, Any]]] = None
3838

3939

4040
class QueryExtension(QueryExtensionBase):

stac_fastapi/pgstac/transactions.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
)
1515
from stac_fastapi.types import stac as stac_types
1616
from stac_fastapi.types.core import AsyncBaseTransactionsClient
17+
from stac_pydantic import Collection, Item, ItemCollection
1718
from starlette.responses import JSONResponse, Response
1819

1920
from stac_fastapi.pgstac.config import Settings
@@ -69,11 +70,13 @@ def _validate_item(
6970
async def create_item(
7071
self,
7172
collection_id: str,
72-
item: Union[stac_types.Item, stac_types.ItemCollection],
73+
item: Union[Item, ItemCollection],
7374
request: Request,
7475
**kwargs,
7576
) -> Optional[Union[stac_types.Item, Response]]:
7677
"""Create item."""
78+
item = item.model_dump(mode="json")
79+
7780
if item["type"] == "FeatureCollection":
7881
valid_items = []
7982
for item in item["features"]: # noqa: B020
@@ -100,6 +103,7 @@ async def create_item(
100103
).get_links(extra_links=item.get("links"))
101104

102105
return stac_types.Item(**item)
106+
103107
else:
104108
raise HTTPException(
105109
status_code=400,
@@ -111,10 +115,12 @@ async def update_item(
111115
request: Request,
112116
collection_id: str,
113117
item_id: str,
114-
item: stac_types.Item,
118+
item: Item,
115119
**kwargs,
116120
) -> Optional[Union[stac_types.Item, Response]]:
117121
"""Update item."""
122+
item = item.model_dump(mode="json")
123+
118124
self._validate_item(request, item, collection_id, item_id)
119125
item["collection"] = collection_id
120126

@@ -130,31 +136,49 @@ async def update_item(
130136
return stac_types.Item(**item)
131137

132138
async def create_collection(
133-
self, collection: stac_types.Collection, request: Request, **kwargs
139+
self,
140+
collection: Collection,
141+
request: Request,
142+
**kwargs,
134143
) -> Optional[Union[stac_types.Collection, Response]]:
135144
"""Create collection."""
145+
collection = collection.model_dump(mode="json")
146+
136147
self._validate_collection(request, collection)
148+
137149
async with request.app.state.get_connection(request, "w") as conn:
138150
await dbfunc(conn, "create_collection", collection)
151+
139152
collection["links"] = await CollectionLinks(
140153
collection_id=collection["id"], request=request
141-
).get_links(extra_links=collection.get("links"))
154+
).get_links(extra_links=collection["links"])
142155

143156
return stac_types.Collection(**collection)
144157

145158
async def update_collection(
146-
self, collection: stac_types.Collection, request: Request, **kwargs
159+
self,
160+
collection: Collection,
161+
request: Request,
162+
**kwargs,
147163
) -> Optional[Union[stac_types.Collection, Response]]:
148164
"""Update collection."""
165+
col = collection.model_dump(mode="json")
166+
149167
async with request.app.state.get_connection(request, "w") as conn:
150-
await dbfunc(conn, "update_collection", collection)
151-
collection["links"] = await CollectionLinks(
152-
collection_id=collection["id"], request=request
153-
).get_links(extra_links=collection.get("links"))
154-
return stac_types.Collection(**collection)
168+
await dbfunc(conn, "update_collection", col)
169+
170+
col["links"] = await CollectionLinks(
171+
collection_id=col["id"], request=request
172+
).get_links(extra_links=col.get("links"))
173+
174+
return stac_types.Collection(**col)
155175

156176
async def delete_item(
157-
self, item_id: str, collection_id: str, request: Request, **kwargs
177+
self,
178+
item_id: str,
179+
collection_id: str,
180+
request: Request,
181+
**kwargs,
158182
) -> Optional[Union[stac_types.Item, Response]]:
159183
"""Delete item."""
160184
q, p = render(
@@ -164,6 +188,7 @@ async def delete_item(
164188
)
165189
async with request.app.state.get_connection(request, "w") as conn:
166190
await conn.fetchval(q, *p)
191+
167192
return JSONResponse({"deleted item": item_id})
168193

169194
async def delete_collection(
@@ -172,6 +197,7 @@ async def delete_collection(
172197
"""Delete collection."""
173198
async with request.app.state.get_connection(request, "w") as conn:
174199
await dbfunc(conn, "delete_collection", collection_id)
200+
175201
return JSONResponse({"deleted collection": collection_id})
176202

177203

tests/clients/test_postgres.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ async def test_create_collection(app_client, load_test_data: Callable):
2121
"/collections",
2222
json=in_json,
2323
)
24-
assert resp.status_code == 200
24+
assert resp.status_code == 201
2525
post_coll = Collection.parse_obj(resp.json())
2626
assert in_coll.dict(exclude={"links"}) == post_coll.dict(exclude={"links"})
27+
2728
resp = await app_client.get(f"/collections/{post_coll.id}")
2829
assert resp.status_code == 200
2930
get_coll = Collection.parse_obj(resp.json())
@@ -66,6 +67,7 @@ async def test_create_item(app_client, load_test_data: Callable, load_test_colle
6667
assert resp.status_code == 200
6768
post_item = Item.parse_obj(resp.json())
6869
assert in_item.dict(exclude={"links"}) == post_item.dict(exclude={"links"})
70+
6971
resp = await app_client.get(f"/collections/{coll.id}/items/{post_item.id}")
7072
assert resp.status_code == 200
7173
get_item = Item.parse_obj(resp.json())
@@ -86,7 +88,7 @@ async def test_create_item_no_collection_id(
8688
json=item,
8789
)
8890

89-
assert resp.status_code == 200
91+
assert resp.status_code == 201
9092

9193
resp = await app_client.get(f"/collections/{coll.id}/items/{item['id']}")
9294

tests/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ async def load_test_collection(app_client, load_test_data):
186186
"/collections",
187187
json=data,
188188
)
189-
assert resp.status_code == 200
189+
assert resp.status_code == 201
190190
return Collection.parse_obj(resp.json())
191191

192192

@@ -198,7 +198,7 @@ async def load_test_item(app_client, load_test_data, load_test_collection):
198198
f"/collections/{coll.id}/items",
199199
json=data,
200200
)
201-
assert resp.status_code == 200
201+
assert resp.status_code == 201
202202

203203
return Item.parse_obj(resp.json())
204204

tests/data/test_item.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@
504504
{
505505
"href": "preview.html",
506506
"rel": "preview",
507-
"type": "application/html"
507+
"type": "text/html"
508508
}
509509
]
510-
}
510+
}

0 commit comments

Comments
 (0)