【问题标题】:More elegant way to call arbitrary Python functions from Flask从 Flask 调用任意 Python 函数的更优雅的方式
【发布时间】:2021-05-27 08:12:21
【问题描述】:

设置 Flask REST API 很容易。我使用以下方法:

from flask import Flask
from flask_cors import CORS

from utility import *

app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

@app.after_request
def add_headers(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Headers'] =  "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
    response.headers['Access-Control-Allow-Methods']=  "POST, GET, PUT, DELETE, OPTIONS"
    return response

@app.route("/", methods=["GET"])
def call_function():
    res = request_return()
    return(res)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

在本例中,我导入位于 utility.py 中的函数:

from flask import request, jsonify

def my_function(arg):
    return(arg)

def string_to_number(str):
    if("." in str):
        try:
            res = float(str)
        except:
            res = str
    elif(str.isdigit()):
        res = int(str)
    else:
        res = str
    return(res)

def request_return():
    passed_function = request.args.get('function')
    args = dict(request.args)
    values = list(args.values())[1:]
    values = list(map(string_to_number, values))
    res = globals()[passed_function](*tuple(values))
    return(jsonify(res))

这允许我将任何函数名称作为参数传递并返回结果。因此,如果我在浏览器中运行以下命令:

https:localhost:5000/?function=my_function&args=hello

我会看到:

"hello"

我处理请求的方式相当臃肿。您可以在 request_return 中看到,我必须采取一系列步骤才能从函数名称转移到执行并返回。我还使用 string_to_number 函数来处理可能传递的任何数字。 这确保我可以调用实用程序中的任何函数以及该函数的任意数量的参数

我见过的任何 Flask 教程都没有讨论如何调用这样的任意函数。有没有更优雅的方法来处理这个?具体来说,我的 request_return 函数中没有所有的臃肿。

【问题讨论】:

    标签: python flask


    【解决方案1】:

    允许客户端调用任何全局函数是危险的,他们可以调用open()来覆盖文件。

    创建应在您的应用程序中可调用的操作的字典。

    与其尝试自动转换数字,不如让各个函数决定他们希望如何解析其参数。

    my_operations = {'my_function': my_function, ...}
    
    def request_return():
        passed_function = request.args.get('function')
        try:
            args = dict(request.args)
            del args['function'] # This is processed above
            res = my_operations[passed_function](**args)
            return(jsonify(res))
        except:
            # report error to caller
    

    【讨论】:

    • 你遇到了什么异常?
    • 它采用 2 个位置参数。似乎需要从 args 中删除“功能”。
    • 我已在 15 分钟前将其添加到我的答案中。
    • 返回“args”而不是“hello”
    • 抱歉,需要使用**args按名称传递参数。
    猜你喜欢
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多