@@ -34,11 +34,25 @@ async def invoke_func(func: Callable, kwargs: Optional[dict[str, Any]] = None) -
3434 return func (** kwargs )
3535
3636
37+ def check_precheck_func (precheck_func : Callable ):
38+ sig = inspect .signature (precheck_func )
39+ inputs = sig .parameters .values ()
40+ outputs = sig .return_annotation
41+ if len (inputs ) == 1 :
42+ i = inputs [0 ]
43+ if i .name != "usage" or i .annotation is list :
44+ raise ValueError ("the only input available for precheck is usage which must be a list" )
45+ if outputs not in [None , sig .empty ]:
46+ raise ValueError (f"no output should exist for precheck function, found: { outputs } " )
47+
48+
3749def generate_fast_api (
3850 app : str ,
3951 method_name : Optional [str ] = None ,
4052 id_str : Optional [str ] = None ,
4153 id_method : Optional [str ] = None ,
54+ precheck_str : Optional [str ] = None ,
55+ precheck_method : Optional [str ] = None ,
4256) -> FastAPI :
4357 instance = import_from_string (app )
4458 func = get_func (instance , method_name )
@@ -49,6 +63,16 @@ def generate_fast_api(
4963 plugin_id = hashlib .sha256 (
5064 json .dumps (get_schema_dict (func ), sort_keys = True ).encode ()
5165 ).hexdigest ()[:32 ]
66+
67+ precheck_func = None
68+ if precheck_str :
69+ precheck_instance = import_from_string (precheck_str )
70+ precheck_func = get_func (precheck_instance , precheck_method )
71+ elif precheck_method :
72+ precheck_func = get_func (instance , precheck_method )
73+ if precheck_func is not None :
74+ check_precheck_func (precheck_func = precheck_func )
75+
5276 logger .debug (f"set static id response to: { plugin_id } " )
5377
5478 fastapi_app = FastAPI ()
@@ -66,9 +90,8 @@ class InvokeResponse(BaseModel):
6690
6791 logging .getLogger ("etl_uvicorn.fastapi" )
6892
69- usage : list [UsageData ] = []
70-
7193 async def wrap_fn (func : Callable , kwargs : Optional [dict [str , Any ]] = None ) -> InvokeResponse :
94+ usage : list [UsageData ] = []
7295 request_dict = kwargs if kwargs else {}
7396 if "usage" in inspect .signature (func ).parameters :
7497 request_dict ["usage" ] = usage
@@ -114,12 +137,29 @@ class SchemaOutputResponse(BaseModel):
114137 async def docs_redirect ():
115138 return RedirectResponse ("/docs" )
116139
140+ class InvokePrecheckResponse (BaseModel ):
141+ usage : list [UsageData ]
142+ status_code : int
143+ status_code_text : Optional [str ] = None
144+
117145 @fastapi_app .get ("/schema" )
118146 async def get_schema () -> SchemaOutputResponse :
119147 schema = get_schema_dict (func )
120148 resp = SchemaOutputResponse (inputs = schema ["inputs" ], outputs = schema ["outputs" ])
121149 return resp
122150
151+ @fastapi_app .get ("/precheck" )
152+ async def run_precheck () -> InvokePrecheckResponse :
153+ if precheck_func :
154+ fn_response = await wrap_fn (func = precheck_func )
155+ return InvokePrecheckResponse (
156+ status_code = fn_response .status_code ,
157+ status_code_text = fn_response .status_code_text ,
158+ usage = fn_response .usage ,
159+ )
160+ else :
161+ return InvokePrecheckResponse (status_code = status .HTTP_200_OK , usage = [])
162+
123163 @fastapi_app .get ("/id" )
124164 async def get_id () -> str :
125165 return plugin_id
0 commit comments