1
+
1
2
"""
2
3
Enhancing Piccolo integration with FastAPI.
3
4
"""
8
9
from collections import defaultdict
9
10
from decimal import Decimal
10
11
from enum import Enum
11
- from inspect import Parameter , Signature
12
+ from inspect import Parameter , Signature , iscoroutinefunction
12
13
13
14
from fastapi import APIRouter , FastAPI , Request
14
15
from fastapi .params import Query
@@ -76,12 +77,13 @@ class ReferencesModel(BaseModel):
76
77
references : t .List [ReferenceModel ]
77
78
78
79
79
- class CallbackModel (BaseModel ):
80
- callback_name : str
80
+ class ActionsModel (BaseModel ):
81
+ action_id : int
82
+ action_name : str
81
83
82
84
83
- class ExecuteCallbackModel (BaseModel ):
84
- callback_response : str
85
+ class ExecuteActionsModel (BaseModel ):
86
+ actions_response : str
85
87
86
88
87
89
class FastAPIWrapper :
@@ -103,8 +105,8 @@ class FastAPIWrapper:
103
105
and ``allow_bulk_delete``.
104
106
:param fastapi_kwargs:
105
107
Specifies the extra kwargs to pass to FastAPI's ``add_api_route``.
106
- :param callback
107
- Callback fn passed in via create_admin TableConfig
108
+ :param actions
109
+ List of action handlers passed in via create_admin TableConfig
108
110
109
111
"""
110
112
@@ -114,15 +116,16 @@ def __init__(
114
116
fastapi_app : t .Union [FastAPI , APIRouter ],
115
117
piccolo_crud : PiccoloCRUD ,
116
118
fastapi_kwargs : t .Optional [FastAPIKwargs ] = None ,
117
- callback : t .Optional [t .Callable ] = None ,
119
+ actions : t .Optional [t .List [ t . Callable ] ] = None ,
118
120
):
119
121
fastapi_kwargs = fastapi_kwargs or FastAPIKwargs ()
120
122
121
123
self .root_url = root_url
122
124
self .fastapi_app = fastapi_app
123
125
self .piccolo_crud = piccolo_crud
124
126
self .fastapi_kwargs = fastapi_kwargs
125
- self .callback = callback
127
+ self .actions = actions
128
+ self ._actions_map = []
126
129
127
130
self .ModelOut = piccolo_crud .pydantic_model_output
128
131
self .ModelIn = piccolo_crud .pydantic_model
@@ -257,55 +260,69 @@ async def references(request: Request):
257
260
)
258
261
259
262
#######################################################################
260
- # Root - Callback
263
+ # Root - Actions
261
264
262
- async def get_callback (request : Request ) -> JSONResponse :
265
+ async def get_actions (request : Request ) -> JSONResponse :
263
266
"""
264
- Return the name of the callback function
267
+ Return the names of the actions
265
268
This is specified on the table config
266
269
"""
267
- if self .callback :
268
- return JSONResponse (
269
- f"Configured callback for table: { self .callback .__name__ } "
270
- )
270
+ if self .actions :
271
+ actions_list = []
272
+ for action in self ._actions_map :
273
+ actions_list .append ({"action_id" : action ['action_id' ], "action_name" : action ['action_handler' ].__name__ })
274
+
275
+ print (actions_list )
276
+ return actions_list
271
277
else :
272
278
return JSONResponse (
273
- content = "No callback configured" , status_code = 500
279
+ content = "No actions configured" , status_code = 500
274
280
)
275
281
276
- if self .callback :
282
+ if self .actions :
283
+ for action_id , action in enumerate (actions ):
284
+ self ._actions_map .append ({"action_id" : action_id , "action_handler" : action })
285
+
277
286
fastapi_app .add_api_route (
278
- path = self .join_urls (root_url , "/callback " ),
279
- endpoint = get_callback ,
287
+ path = self .join_urls (root_url , "/actions " ),
288
+ endpoint = get_actions ,
280
289
methods = ["GET" ],
281
- response_model = CallbackModel ,
290
+ response_model = t . List [ ActionsModel ] ,
282
291
** fastapi_kwargs .get_kwargs ("get" ),
283
292
)
284
293
285
294
#######################################################################
286
- # Root - Callback execute
295
+ # Root - Actions execute
287
296
288
- async def run_callback (request : Request ) -> JSONResponse :
297
+ async def run_action (request : Request ) -> JSONResponse :
289
298
"""
290
- Execute the configured callback for this table
299
+ Execute the configured actions for this table
291
300
:param request_params:
292
301
The request params must contain the arguments
293
- required by the callback
302
+ required by the actions handler function
294
303
"""
295
- if self .callback :
296
- return await self .callback (request_params = request .json ())
304
+ action_id = request .path_params .get ("action_id" , None )
305
+ if self ._actions_map and action_id :
306
+ for action in self ._actions_map :
307
+ if action ['action_id' ] == int (action_id ):
308
+ action_handler = action ['action_handler' ]
309
+ req_data = await request .json ()
310
+ if iscoroutinefunction (action_handler ):
311
+ return await action_handler (request_params = req_data )
312
+ else :
313
+ return action_handler (request_params = req_data )
297
314
else :
298
315
return JSONResponse (
299
- content = "No callback configured " , status_code = 500
316
+ content = "No actions registered " , status_code = 500
300
317
)
301
318
302
- if self .callback :
319
+ if self .actions :
303
320
fastapi_app .add_api_route (
304
- path = self .join_urls (root_url , "/callback /execute" ),
305
- endpoint = run_callback ,
321
+ path = self .join_urls (root_url , "/actions/{action_id:str} /execute" ),
322
+ endpoint = run_action ,
306
323
methods = ["POST" ],
307
- response_model = ExecuteCallbackModel ,
308
- ** fastapi_kwargs .get_kwargs ("post " ),
324
+ response_model = ExecuteActionsModel ,
325
+ ** fastapi_kwargs .get_kwargs ("POST " ),
309
326
)
310
327
#######################################################################
311
328
# Root - DELETE
0 commit comments