Skip to content

Commit 676704f

Browse files
committed
create AtomicViewHandler
1 parent 298a2c3 commit 676704f

File tree

1 file changed

+48
-19
lines changed

1 file changed

+48
-19
lines changed

fastapi_jsonapi/atomic/atomic.py

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Literal,
88
Optional,
99
Type,
10+
TypedDict,
1011
Union,
1112
)
1213

@@ -48,15 +49,19 @@ class PreparedOperation:
4849
] = None
4950

5051

51-
class AtomicOperations:
52+
#
53+
54+
AtomicResponseDict = TypedDict("AtomicResponseDict", {"atomic:results": list[Any]})
55+
56+
57+
class AtomicViewHandler:
5258
def __init__(
5359
self,
54-
url_path: str = "/operations",
55-
router: Optional[APIRouter] = None,
60+
request: Request,
61+
operations_request: AtomicOperationRequest,
5662
):
57-
self.router = router or APIRouter(tags=["Atomic Operations"])
58-
self.url_path = url_path
59-
self._register_view()
63+
self.request = request
64+
self.operations_request = operations_request
6065

6166
async def handle_view_dependencies(
6267
self,
@@ -76,21 +81,17 @@ def handle_dependencies(**dep_kwargs):
7681
dependencies_result: Dict[str, Any] = await DependencyHelper(request=request).run(handle_dependencies)
7782
return dependencies_result
7883

79-
async def view_atomic(
80-
self,
81-
request: Request,
82-
operations_request: AtomicOperationRequest,
83-
):
84+
async def prepare_operations(self) -> List[PreparedOperation]:
8485
prepared_operations: List[PreparedOperation] = []
8586

86-
for operation in operations_request.operations:
87+
for operation in self.operations_request.operations:
8788
jsonapi = RoutersJSONAPI.all_jsonapi_routers[operation.data.type]
8889
view_cls: Type["ViewBase"] = jsonapi.detail_view_resource
8990
if operation.op == "add":
9091
view_cls = jsonapi.list_view_resource
91-
view = view_cls(request=request, jsonapi=jsonapi)
92+
view = view_cls(request=self.request, jsonapi=jsonapi)
9293
dependencies_result: Dict[str, Any] = await self.handle_view_dependencies(
93-
request=request,
94+
request=self.request,
9495
jsonapi=jsonapi,
9596
)
9697
dl: "BaseDataLayer" = await view.get_data_layer(dependencies_result)
@@ -104,6 +105,10 @@ async def view_atomic(
104105
)
105106
prepared_operations.append(one_operation)
106107

108+
return prepared_operations
109+
110+
async def handle(self) -> Union[AtomicResponseDict, AtomicResultResponse]:
111+
prepared_operations = await self.prepare_operations()
107112
results = []
108113

109114
# TODO: try/except, catch schema ValidationError
@@ -114,20 +119,20 @@ async def view_atomic(
114119
await dl.atomic_start(previous_dl=previous_dl)
115120
previous_dl = dl
116121
if operation.action == "add":
117-
data = operation.jsonapi.schema_in_post(data=operation.data)
122+
data_in = operation.jsonapi.schema_in_post(data=operation.data)
118123
assert isinstance(operation.view, ListViewBase)
119124
view: "ListViewBase" = operation.view
120-
response = await view.process_create_object(dl=operation.data_layer, data_create=data)
125+
response = await view.process_create_object(dl=operation.data_layer, data_create=data_in.data)
121126
# response.data.id
122127
results.append({"data": response.data})
123128
elif operation.action == "update":
124-
data = operation.jsonapi.schema_in_patch(data=operation.data)
129+
data_in = operation.jsonapi.schema_in_patch(data=operation.data)
125130
assert isinstance(operation.view, DetailViewBase)
126131
view: "DetailViewBase" = operation.view
127132
response = await view.process_update_object(
128133
dl=dl,
129-
obj_id=data.data.id,
130-
data_update=data.data,
134+
obj_id=data_in.data.id,
135+
data_update=data_in.data,
131136
)
132137
# response.data.id
133138
results.append({"data": response.data})
@@ -148,6 +153,30 @@ async def view_atomic(
148153

149154
return {"atomic:results": results}
150155

156+
157+
class AtomicOperations:
158+
atomic_handler: Type[AtomicViewHandler] = AtomicViewHandler
159+
160+
def __init__(
161+
self,
162+
url_path: str = "/operations",
163+
router: Optional[APIRouter] = None,
164+
):
165+
self.router = router or APIRouter(tags=["Atomic Operations"])
166+
self.url_path = url_path
167+
self._register_view()
168+
169+
async def view_atomic(
170+
self,
171+
request: Request,
172+
operations_request: AtomicOperationRequest,
173+
):
174+
atomic_handler = self.atomic_handler(
175+
request=request,
176+
operations_request=operations_request,
177+
)
178+
return await atomic_handler.handle()
179+
151180
def _register_view(self):
152181
self.router.add_api_route(
153182
path=self.url_path,

0 commit comments

Comments
 (0)