1+
12"""
23Enhancing Piccolo integration with FastAPI.
34"""
89from collections import defaultdict
910from decimal import Decimal
1011from enum import Enum
11- from inspect import Parameter , Signature
12+ from inspect import Parameter , Signature , iscoroutinefunction
1213
1314from fastapi import APIRouter , FastAPI , Request
1415from fastapi .params import Query
1516from pydantic import BaseModel as PydanticBaseModel
1617from pydantic .main import BaseModel
18+ from pydantic import parse_obj_as
1719from starlette .responses import JSONResponse
1820
1921from piccolo_api .crud .endpoints import PiccoloCRUD
@@ -25,6 +27,9 @@ class HTTPMethod(str, Enum):
2527 get = "GET"
2628 delete = "DELETE"
2729
30+ class TableRowDataSchema (PydanticBaseModel ):
31+ table_name : str
32+ row_ids : list [str ]
2833
2934class FastAPIKwargs :
3035 """
@@ -76,12 +81,13 @@ class ReferencesModel(BaseModel):
7681 references : t .List [ReferenceModel ]
7782
7883
79- class CallbackModel (BaseModel ):
80- callback_name : str
84+ class ActionsModel (BaseModel ):
85+ action_id : int
86+ action_name : str
8187
8288
83- class ExecuteCallbackModel (BaseModel ):
84- callback_response : str
89+ class ExecuteActionsModel (BaseModel ):
90+ actions_response : str
8591
8692
8793class FastAPIWrapper :
@@ -103,8 +109,8 @@ class FastAPIWrapper:
103109 and ``allow_bulk_delete``.
104110 :param fastapi_kwargs:
105111 Specifies the extra kwargs to pass to FastAPI's ``add_api_route``.
106- :param callback
107- Callback fn passed in via create_admin TableConfig
112+ :param actions
113+ List of action handlers passed in via create_admin TableConfig
108114
109115 """
110116
@@ -114,15 +120,16 @@ def __init__(
114120 fastapi_app : t .Union [FastAPI , APIRouter ],
115121 piccolo_crud : PiccoloCRUD ,
116122 fastapi_kwargs : t .Optional [FastAPIKwargs ] = None ,
117- callback : t .Optional [t .Callable ] = None ,
123+ actions : t .Optional [t .List [ t . Callable ] ] = None ,
118124 ):
119125 fastapi_kwargs = fastapi_kwargs or FastAPIKwargs ()
120126
121127 self .root_url = root_url
122128 self .fastapi_app = fastapi_app
123129 self .piccolo_crud = piccolo_crud
124130 self .fastapi_kwargs = fastapi_kwargs
125- self .callback = callback
131+ self .actions = actions
132+ self ._actions_map = []
126133
127134 self .ModelOut = piccolo_crud .pydantic_model_output
128135 self .ModelIn = piccolo_crud .pydantic_model
@@ -257,55 +264,69 @@ async def references(request: Request):
257264 )
258265
259266 #######################################################################
260- # Root - Callback
267+ # Root - Actions
261268
262- async def get_callback (request : Request ) -> JSONResponse :
269+ async def get_actions (request : Request ) -> JSONResponse :
263270 """
264- Return the name of the callback function
271+ Return the names of the actions
265272 This is specified on the table config
266273 """
267- if self .callback :
268- return JSONResponse (
269- f"Configured callback for table: { self .callback .__name__ } "
270- )
274+ if self .actions :
275+ actions_list = []
276+ for action in self ._actions_map :
277+ actions_list .append ({"action_id" : action ['action_id' ], "action_name" : action ['action_handler' ].__name__ })
278+
279+ print (actions_list )
280+ return actions_list
271281 else :
272282 return JSONResponse (
273- content = "No callback configured" , status_code = 500
283+ content = "No actions configured" , status_code = 500
274284 )
275285
276- if self .callback :
286+ if self .actions :
287+ for action_id , action in enumerate (actions ):
288+ self ._actions_map .append ({"action_id" : action_id , "action_handler" : action })
289+
277290 fastapi_app .add_api_route (
278- path = self .join_urls (root_url , "/callback " ),
279- endpoint = get_callback ,
291+ path = self .join_urls (root_url , "/actions " ),
292+ endpoint = get_actions ,
280293 methods = ["GET" ],
281- response_model = CallbackModel ,
294+ response_model = t . List [ ActionsModel ] ,
282295 ** fastapi_kwargs .get_kwargs ("get" ),
283296 )
284297
285298 #######################################################################
286- # Root - Callback execute
299+ # Root - Actions execute
287300
288- async def run_callback (request : Request ) -> JSONResponse :
301+ async def run_action (request : Request ) -> JSONResponse :
289302 """
290- Execute the configured callback for this table
303+ Execute the configured actions for this table
291304 :param request_params:
292305 The request params must contain the arguments
293- required by the callback
306+ required by the actions handler function
294307 """
295- if self .callback :
296- return await self .callback (request_params = request .json ())
308+ action_id = request .path_params .get ("action_id" , None )
309+ if self ._actions_map and action_id :
310+ for action in self ._actions_map :
311+ if action ['action_id' ] == int (action_id ):
312+ action_handler = action ['action_handler' ]
313+ req_data = await request .json ()
314+ if iscoroutinefunction (action_handler ):
315+ return await action_handler (data = parse_obj_as (TableRowDataSchema , req_data ))
316+ else :
317+ return action_handler (data = parse_obj_as (TableRowDataSchema , req_data ))
297318 else :
298319 return JSONResponse (
299- content = "No callback configured " , status_code = 500
320+ content = "No actions registered " , status_code = 500
300321 )
301322
302- if self .callback :
323+ if self .actions :
303324 fastapi_app .add_api_route (
304- path = self .join_urls (root_url , "/callback /execute" ),
305- endpoint = run_callback ,
325+ path = self .join_urls (root_url , "/actions/{action_id:str} /execute" ),
326+ endpoint = run_action ,
306327 methods = ["POST" ],
307- response_model = ExecuteCallbackModel ,
308- ** fastapi_kwargs .get_kwargs ("post " ),
328+ response_model = ExecuteActionsModel ,
329+ ** fastapi_kwargs .get_kwargs ("POST " ),
309330 )
310331 #######################################################################
311332 # Root - DELETE
0 commit comments