#python #flask
#python #flask
Вопрос:
Настройка REST API Flask проста. Я использую следующий подход:
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_functionamp;args=hello
Я бы увидел:
"hello"
Способ обработки запроса довольно раздут. Вы можете видеть в request_return, что я должен выполнить ряд шагов, чтобы перейти от имени функции к ее выполнению и возврату. Я также использую функцию string_to_number для обработки любых чисел, которые могут быть переданы. Это гарантирует, что я могу вызвать любую функцию внутри утилиты и любое количество параметров для этой функции.
В любом руководстве по Flask, которое я видел, не обсуждается, как вызывать произвольные функции, подобные этому. Есть ли более элегантный способ справиться с этим? В частности, без всех наворотов в моей функции request_return .
Ответ №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
Комментарии:
1. Какие исключения вы получаете?
2. Он принимает 2 позиционных аргумента. Похоже, что «функция» должна быть удалена из аргументов.
3. Я уже добавил это к своему ответу 15 минут назад.
4. Это возвращает «аргументы», а не «привет»
5. Извините, нужно было использовать
**args
для передачи аргументов по имени.