Skip to content
This repository was archived by the owner on Apr 2, 2025. It is now read-only.

Commit 068e4b2

Browse files
Merge branch 'main' into feat/tr/pagination
2 parents b690cf1 + 0a5d877 commit 068e4b2

File tree

7 files changed

+37
-78
lines changed

7 files changed

+37
-78
lines changed

CHANGELOG.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

88

9-
## [unreleased]
9+
## [v0.5.0] - 2025-01-08
1010

1111
### Added
1212

1313
- Endpoint `/orders/{order_id}/statuses` supporting `GET` for retrieving statuses. The entity returned by this conforms
1414
to the change proposed in [stapi-spec#239](https://github.com/stapi-spec/stapi-spec/pull/239).
15-
- Endpoint `/orders/{order_id}/statuses` supporting `POST` for updating current status
16-
- RootBackend has new methods `get_order_statuses` and `set_order_status`
15+
- RootBackend has new method `get_order_statuses`
16+
- `*args`/`**kwargs` support in RootRouter's `add_product` allows to configure underlyinging ProductRouter
1717

1818
### Changed
1919

@@ -25,17 +25,19 @@ none
2525

2626
### Removed
2727

28-
none
28+
- Endpoint `/orders/{order_id}/statuses` supporting `POST` for updating current status was added and then
29+
removed prior to release
30+
- RootBackend method `set_order_status` was added and then removed
2931

3032
### Fixed
3133

32-
none
34+
- Exception logging
3335

3436
### Security
3537

3638
none
3739

38-
## [0.4.0] - 2024-12-11
40+
## [v0.4.0] - 2024-12-11
3941

4042
### Added
4143

@@ -63,7 +65,7 @@ none
6365
none
6466

6567

66-
## [0.3.0] - 2024-12-6
68+
## [v0.3.0] - 2024-12-6
6769

6870
### Added
6971

@@ -137,7 +139,8 @@ Initial release
137139
- Add links `opportunities` and `create-order` to Product
138140
- Add link `create-order` to OpportunityCollection
139141

140-
[unreleased]: https://github.com/stapi-spec/stapi-fastapi/compare/v0.4.0...main
142+
[unreleased]: https://github.com/stapi-spec/stapi-fastapi/compare/v0.5.0...main
143+
[v0.4.0]: https://github.com/stapi-spec/stapi-fastapi/tree/v0.5.0
141144
[v0.4.0]: https://github.com/stapi-spec/stapi-fastapi/tree/v0.4.0
142145
[v0.3.0]: https://github.com/stapi-spec/stapi-fastapi/tree/v0.3.0
143146
[v0.2.0]: https://github.com/stapi-spec/stapi-fastapi/tree/v0.2.0

src/stapi_fastapi/backends/root_backend.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
Order,
99
OrderCollection,
1010
OrderStatus,
11-
OrderStatusPayload,
1211
)
1312

1413

@@ -37,7 +36,7 @@ async def get_order(self, order_id: str, request: Request) -> ResultE[Maybe[Orde
3736

3837
async def get_order_statuses(
3938
self, order_id: str, request: Request
40-
) -> ResultE[list[U]]:
39+
) -> ResultE[list[T]]:
4140
"""
4241
Get statuses for order with `order_id`.
4342
@@ -49,17 +48,3 @@ async def get_order_statuses(
4948
A Failure[Exception] will result in a 500.
5049
"""
5150
...
52-
53-
async def set_order_status(
54-
self, order_id: str, payload: T, request: Request
55-
) -> ResultE[U]:
56-
"""
57-
Set statuses for order with `order_id`.
58-
59-
Should return returns.results.Success[OrderStatus] if successful.
60-
61-
Should return returns.results.Failure[Exception] if the status was not able to be set.
62-
63-
A Failure[Exception] will result in a 500.
64-
"""
65-
...

src/stapi_fastapi/models/order.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,3 @@ class OrderPayload(BaseModel, Generic[ORP]):
122122
order_parameters: ORP
123123

124124
model_config = ConfigDict(strict=True)
125-
126-
127-
class OrderStatusPayload(BaseModel):
128-
status_code: OrderStatusCode | None = None
129-
reason_code: str | None = None
130-
reason_text: str | None = None
131-
132-
# todo: rework generic types to allow subclasses to be used correctly, and remove extra=allow
133-
model_config = ConfigDict(strict=True, extra="allow")

src/stapi_fastapi/routers/product_router.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import logging
4+
import traceback
45
from typing import TYPE_CHECKING, Self
56

67
from fastapi import APIRouter, HTTPException, Request, Response, status
@@ -22,6 +23,8 @@
2223
if TYPE_CHECKING:
2324
from stapi_fastapi.routers import RootRouter
2425

26+
logger = logging.getLogger(__name__)
27+
2528

2629
class ProductRouter(APIRouter):
2730
def __init__(
@@ -182,7 +185,10 @@ async def search_opportunities(
182185
case Failure(e) if isinstance(e, ConstraintsException):
183186
raise e
184187
case Failure(e):
185-
logging.exception("An error occurred while searching opportunities", e)
188+
logger.error(
189+
"An error occurred while searching opportunities: %s",
190+
traceback.format_exception(e),
191+
)
186192
raise HTTPException(
187193
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
188194
detail="Error searching opportunities",
@@ -221,7 +227,10 @@ async def create_order(
221227
case Failure(e) if isinstance(e, ConstraintsException):
222228
raise e
223229
case Failure(e):
224-
logging.exception("An error occurred while creating order", e)
230+
logger.error(
231+
"An error occurred while creating order: %s",
232+
traceback.format_exception(e),
233+
)
225234
raise HTTPException(
226235
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
227236
detail="Error creating order",

src/stapi_fastapi/routers/root_router.py

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import logging
2+
import traceback
23
from typing import Self
34

45
from fastapi import APIRouter, HTTPException, Request, status
56
from fastapi.datastructures import URL
6-
from fastapi.responses import Response
77
from returns.maybe import Maybe, Some
88
from returns.result import Failure, Success
99

@@ -15,14 +15,15 @@
1515
Order,
1616
OrderCollection,
1717
OrderStatuses,
18-
OrderStatusPayload,
1918
)
2019
from stapi_fastapi.models.product import Product, ProductsCollection
2120
from stapi_fastapi.models.root import RootResponse
2221
from stapi_fastapi.models.shared import Link
2322
from stapi_fastapi.responses import GeoJSONResponse
2423
from stapi_fastapi.routers.product_router import ProductRouter
2524

25+
logger = logging.getLogger(__name__)
26+
2627

2728
class RootRouter(APIRouter):
2829
def __init__(
@@ -98,14 +99,6 @@ def __init__(
9899
tags=["Orders"],
99100
)
100101

101-
self.add_api_route(
102-
"/orders/{order_id}/statuses",
103-
self.set_order_status,
104-
methods=["POST"],
105-
name=f"{self.name}:set-order-status",
106-
tags=["Orders"],
107-
)
108-
109102
def get_root(self, request: Request) -> RootResponse:
110103
return RootResponse(
111104
id="STAPI API",
@@ -205,8 +198,10 @@ async def get_order(self: Self, order_id: str, request: Request) -> Order:
205198
case Success(Maybe.empty):
206199
raise NotFoundException("Order not found")
207200
case Failure(e):
208-
logging.exception(
209-
f"An error occurred while retrieving order '{order_id}'", e
201+
logger.error(
202+
"An error occurred while retrieving order '%s': %s",
203+
order_id,
204+
traceback.format_exception(e),
210205
)
211206
raise HTTPException(
212207
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -236,8 +231,9 @@ async def get_order_statuses(
236231
],
237232
)
238233
case Failure(e):
239-
logging.exception(
240-
"An error occurred while retrieving order statuses", e
234+
logger.error(
235+
"An error occurred while retrieving order statuses: %s",
236+
traceback.format_exception(e),
241237
)
242238
raise HTTPException(
243239
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -246,24 +242,9 @@ async def get_order_statuses(
246242
case _:
247243
raise AssertionError("Expected code to be unreachable")
248244

249-
async def set_order_status(
250-
self, order_id: str, payload: OrderStatusPayload, request: Request
251-
) -> Response:
252-
match await self.backend.set_order_status(order_id, payload, request):
253-
case Success(_):
254-
return Response(status_code=status.HTTP_202_ACCEPTED)
255-
case Failure(e):
256-
logging.exception("An error occurred while setting order status", e)
257-
raise HTTPException(
258-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
259-
detail="Error setting Order Status",
260-
)
261-
case x:
262-
raise AssertionError(f"Expected code to be unreachable {x}")
263-
264-
def add_product(self: Self, product: Product) -> None:
245+
def add_product(self: Self, product: Product, *args, **kwargs) -> None:
265246
# Give the include a prefix from the product router
266-
product_router = ProductRouter(product, self)
247+
product_router = ProductRouter(product, self, *args, **kwargs)
267248
self.include_router(product_router, prefix=f"/products/{product.id}")
268249
self.product_routers[product.id] = product_router
269250

tests/application.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from collections import defaultdict
2-
from datetime import UTC, datetime, timezone
2+
from datetime import datetime, timezone
33
from typing import Literal, Self
44
from uuid import uuid4
55

@@ -23,7 +23,6 @@
2323
OrderPayload,
2424
OrderStatus,
2525
OrderStatusCode,
26-
OrderStatusPayload,
2726
)
2827
from stapi_fastapi.models.product import (
2928
Product,
@@ -84,16 +83,6 @@ async def get_order_statuses(
8483
) -> ResultE[list[OrderStatus]]:
8584
return Success(self._orders_db._statuses[order_id])
8685

87-
async def set_order_status(
88-
self, order_id: str, payload: OrderStatusPayload, request: Request
89-
) -> ResultE[OrderStatus]:
90-
input = payload.model_dump()
91-
input["timestamp"] = datetime.now(UTC)
92-
order_status = OrderStatus.model_validate(input)
93-
self._orders_db._orders[order_id].properties.status = order_status
94-
self._orders_db._statuses[order_id].insert(0, order_status)
95-
return Success(order_status)
96-
9786

9887
class MockProductBackend(ProductBackend):
9988
def __init__(self, orders: InMemoryOrderDB) -> None:

tests/test_order.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,4 @@ def test_token_not_found(stapi_client: TestClient):
247247
res = stapi_client.get("/orders", params={"next": "a_token"})
248248
# should return 404 as a result of bad token
249249
assert res.status_code == status.HTTP_404_NOT_FOUND
250+

0 commit comments

Comments
 (0)