使用 Flask 从 API 调用端点的正确方法

mel*_*mel 6 python api flask

我正在尝试构建一个 Flask API,我有一个端点应该创建用户,另一个端点应该检查数据库中是否存在用户:

@API.route('/users/', methods=['POST'])
def new_user():
    user_json = json.loads(request.get_json())
    first_name = user_json.get('first_name')
    last_name = user_json.get('last_name')
    email = user_json.get('email')
    password = user_json.get('password')
    # Call the other endpoint here
    if response == 400:
        try:
           user = User(first_name=first_name, last_name=last_name, email=email, password=password)
           db.session.add(user)
           db.session.commit()
           return jsonify(user=user.to_json()), 200
       except:
           return jsonify(error=500), 500
    else:
       return jsonify(user=user.to_json()), 409



@API.route('/users/<string:email>', methods=['GET'])
def is_present(email):
    user = User.query.filter_by(email=email).first()
    if user:
        print(user)
        return jsonify(user=user.to_json()), 200
    else:
        return jsonify(error=404), 404
Run Code Online (Sandbox Code Playgroud)

问题是我不知道is_presentnew_user端点中调用我的最佳方法是什么。我应该使用吗requests.get?或者 Flask 中有其他特定的东西可以这样做吗?

mha*_*wke 5

处理此问题的常见方法是将视图的逻辑分解为单独的内部函数(即不通过 API 公开),并调用该内部函数。然后视图将处理请求,根据需要调用内部函数。尽管在本例中这很简单(只是数据库查找),但可以这样做:

def get_user(email):
    return User.query.filter_by(email=email).first()

@API.route('/users/', methods=['POST'])
def new_user():
    user_json = json.loads(request.get_json())
    first_name = user_json.get('first_name')
    last_name = user_json.get('last_name')
    email = user_json.get('email')
    password = user_json.get('password')
    user = get_user(email)
    if not user:
        try:
           user = User(first_name=first_name, last_name=last_name, email=email, password=password)
           db.session.add(user)
           db.session.commit()
           return jsonify(user=user.to_json()), 200
       except:
           return jsonify(error=500), 500
    else:
       return jsonify(user=user.to_json()), 409

@API.route('/users/<string:email>', methods=['GET'])
def is_present(email):
    user = get_user(email)
    if user:
        print(user)
        return jsonify(user=user.to_json()), 200
    else:
        return jsonify(error=404), 404
Run Code Online (Sandbox Code Playgroud)

使用此方法的一个明显优点是完全避免了 HTTP 请求,从而形成一种更高效且不易出错(例如网络问题)的解决方案。


如上所述,作为通常处理从多个视图访问通用功能的一种方式,在创建新用户之前执行查找并不能总是保证用户创建不会由于重复记录而失败。有一个竞争条件;在第一个请求检查之后但在尝试创建操作之前,另一个请求可能会创建用户。

假设您的用户表有一个主键,例如 on (first_name, last_name, email),您可以简单地尝试创建一个新用户并处理由于重复而引发的任何异常。或者你可能想看看Session.merge()