|
1 | 1 | from collections import defaultdict |
2 | 2 | from collections.abc import AsyncIterator |
3 | 3 | from contextlib import asynccontextmanager |
4 | | -from datetime import datetime, timezone |
5 | 4 | from typing import Any, Literal, Self |
6 | | -from uuid import uuid4 |
7 | 5 |
|
8 | | -from fastapi import FastAPI, Request |
| 6 | +from fastapi import FastAPI |
9 | 7 | from pydantic import BaseModel, Field, model_validator |
10 | | -from returns.maybe import Maybe, Nothing, Some |
11 | | -from returns.result import Failure, ResultE, Success |
12 | 8 |
|
13 | 9 | from stapi_fastapi.models.conformance import CORE |
14 | 10 | from stapi_fastapi.models.opportunity import ( |
15 | | - Opportunity, |
16 | 11 | OpportunityProperties, |
17 | | - OpportunityRequest, |
18 | 12 | ) |
19 | 13 | from stapi_fastapi.models.order import ( |
20 | 14 | Order, |
21 | 15 | OrderParameters, |
22 | | - OrderPayload, |
23 | | - OrderProperties, |
24 | | - OrderSearchParameters, |
25 | 16 | OrderStatus, |
26 | | - OrderStatusCode, |
27 | 17 | ) |
28 | 18 | from stapi_fastapi.models.product import ( |
29 | 19 | Product, |
30 | 20 | Provider, |
31 | 21 | ProviderRole, |
32 | 22 | ) |
33 | | -from stapi_fastapi.routers.product_router import ProductRouter |
34 | 23 | from stapi_fastapi.routers.root_router import RootRouter |
35 | 24 |
|
| 25 | +from .backends import ( |
| 26 | + mock_create_order, |
| 27 | + mock_get_order, |
| 28 | + mock_get_order_statuses, |
| 29 | + mock_get_orders, |
| 30 | + mock_search_opportunities, |
| 31 | +) |
| 32 | + |
36 | 33 |
|
37 | 34 | class InMemoryOrderDB: |
38 | 35 | def __init__(self) -> None: |
39 | 36 | self._orders: dict[str, Order] = {} |
40 | 37 | self._statuses: dict[str, list[OrderStatus]] = defaultdict(list) |
41 | 38 |
|
42 | 39 |
|
43 | | -async def mock_get_orders( |
44 | | - request: Request, next: str | None, limit: int |
45 | | -) -> ResultE[tuple[list[Order], Maybe[str]]]: |
46 | | - """ |
47 | | - Return orders from backend. Handle pagination/limit if applicable |
48 | | - """ |
49 | | - try: |
50 | | - start = 0 |
51 | | - limit = min(limit, 100) |
52 | | - order_ids = [*request.state._orders_db._orders.keys()] |
53 | | - |
54 | | - if next: |
55 | | - start = order_ids.index(next) |
56 | | - end = start + limit |
57 | | - ids = order_ids[start:end] |
58 | | - orders = [request.state._orders_db._orders[order_id] for order_id in ids] |
59 | | - |
60 | | - if end > 0 and end < len(order_ids): |
61 | | - return Success( |
62 | | - (orders, Some(request.state._orders_db._orders[order_ids[end]].id)) |
63 | | - ) |
64 | | - return Success((orders, Nothing)) |
65 | | - except Exception as e: |
66 | | - return Failure(e) |
67 | | - |
68 | | - |
69 | | -async def mock_get_order(order_id: str, request: Request) -> ResultE[Maybe[Order]]: |
70 | | - """ |
71 | | - Show details for order with `order_id`. |
72 | | - """ |
73 | | - |
74 | | - return Success(Maybe.from_optional(request.state._orders_db._orders.get(order_id))) |
75 | | - |
76 | | - |
77 | | -async def mock_get_order_statuses( |
78 | | - order_id: str, request: Request, next: str | None, limit: int |
79 | | -) -> ResultE[tuple[list[OrderStatus], Maybe[str]]]: |
80 | | - try: |
81 | | - start = 0 |
82 | | - limit = min(limit, 100) |
83 | | - statuses = request.state._orders_db._statuses[order_id] |
84 | | - |
85 | | - if next: |
86 | | - start = int(next) |
87 | | - end = start + limit |
88 | | - stati = statuses[start:end] |
89 | | - |
90 | | - if end > 0 and end < len(statuses): |
91 | | - return Success((stati, Some(str(end)))) |
92 | | - return Success((stati, Nothing)) |
93 | | - except Exception as e: |
94 | | - return Failure(e) |
95 | | - |
96 | | - |
97 | | -async def mock_search_opportunities( |
98 | | - product_router: ProductRouter, |
99 | | - search: OpportunityRequest, |
100 | | - request: Request, |
101 | | - next: str | None, |
102 | | - limit: int, |
103 | | -) -> ResultE[tuple[list[Opportunity], Maybe[str]]]: |
104 | | - try: |
105 | | - start = 0 |
106 | | - limit = min(limit, 100) |
107 | | - if next: |
108 | | - start = int(next) |
109 | | - end = start + limit |
110 | | - opportunities = [ |
111 | | - o.model_copy(update=search.model_dump()) |
112 | | - for o in request.state._opportunities[start:end] |
113 | | - ] |
114 | | - if end > 0 and end < len(request.state._opportunities): |
115 | | - return Success((opportunities, Some(str(end)))) |
116 | | - return Success((opportunities, Nothing)) |
117 | | - except Exception as e: |
118 | | - return Failure(e) |
119 | | - |
120 | | - |
121 | | -async def mock_create_order( |
122 | | - product_router: ProductRouter, payload: OrderPayload, request: Request |
123 | | -) -> ResultE[Order]: |
124 | | - """ |
125 | | - Create a new order. |
126 | | - """ |
127 | | - try: |
128 | | - status = OrderStatus( |
129 | | - timestamp=datetime.now(timezone.utc), |
130 | | - status_code=OrderStatusCode.received, |
131 | | - ) |
132 | | - order = Order( |
133 | | - id=str(uuid4()), |
134 | | - geometry=payload.geometry, |
135 | | - properties=OrderProperties( |
136 | | - product_id=product_router.product.id, |
137 | | - created=datetime.now(timezone.utc), |
138 | | - status=status, |
139 | | - search_parameters=OrderSearchParameters( |
140 | | - geometry=payload.geometry, |
141 | | - datetime=payload.datetime, |
142 | | - filter=payload.filter, |
143 | | - ), |
144 | | - order_parameters=payload.order_parameters.model_dump(), |
145 | | - opportunity_properties={ |
146 | | - "datetime": "2024-01-29T12:00:00Z/2024-01-30T12:00:00Z", |
147 | | - "off_nadir": 10, |
148 | | - }, |
149 | | - ), |
150 | | - links=[], |
151 | | - ) |
152 | | - |
153 | | - request.state._orders_db._orders[order.id] = order |
154 | | - request.state._orders_db._statuses[order.id].insert(0, status) |
155 | | - return Success(order) |
156 | | - except Exception as e: |
157 | | - return Failure(e) |
158 | | - |
159 | | - |
160 | 40 | class MyProductConstraints(BaseModel): |
161 | 41 | off_nadir: int |
162 | 42 |
|
|
0 commit comments