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