FastAPI路由中能否传入函数并调用?尝试实现遇问题
无法在FastAPI路由中直接传入Callable类型的原因及解决办法
你当前的实现无法工作,核心原因是:FastAPI依赖请求体的序列化/反序列化,而Callable类型(函数对象)无法被序列化为JSON格式——HTTP请求只能传输文本、JSON这类结构化数据,没法直接传递内存中的函数对象。
下面是两种可行的解决思路:
思路1:调用服务端预定义的函数
如果要执行的函数是服务端已经存在的,可以通过传递函数名称字符串来间接调用:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() # 定义服务端的函数集合 def hello(): return "Hello world" def greet(name: str): return f"Hello, {name}!" # 建立函数名到函数对象的映射 function_map = { "hello": hello, "greet": greet } # 请求模型:传递函数名和可选参数 class FunctionCall(BaseModel): function_name: str args: dict = {} @app.post("/datalore") def datalore(call: FunctionCall): # 检查函数是否存在 if call.function_name not in function_map: return {"error": "函数不存在"} target_func = function_map[call.function_name] # 调用函数并返回结果 try: result = target_func(**call.args) return {"result": result} except Exception as e: return {"error": str(e)}
请求示例(JSON体):
{ "function_name": "hello" }
或者带参数的:
{ "function_name": "greet", "args": {"name": "Alice"} }
思路2:执行客户端传来的代码(不推荐)
如果一定要执行客户端传来的自定义代码,虽然可以用exec或eval实现,但这存在极大的安全风险(恶意代码可能直接控制你的服务器),仅在完全信任请求来源的场景下考虑:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class FunctionCode(BaseModel): code: str @app.post("/datalore") def datalore(func_code: FunctionCode): try: # 执行代码并获取函数 local_namespace = {} exec(func_code.code, globals(), local_namespace) # 假设代码中定义了名为func的函数 if "func" not in local_namespace: return {"error": "代码中未定义func函数"} result = local_namespace["func"]() return {"result": result} except Exception as e: return {"error": str(e)}
请求示例(JSON体):
{ "code": "def func():\n return 'Hello from client code'" }
内容的提问来源于stack exchange,提问作者kirastel
相关产品推荐
相关产品推荐

