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

时间:2017-04-09 10:28:00

标签: 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

问题是我不知道在is_present端点呼叫new_user的最佳方法是什么。我应该使用requests.get吗?或者在Flask中还有其他特定的内容吗?

2 个答案:

答案 0 :(得分:3)

处理此问题的常用方法是将视图的逻辑分解为单独的内部函数(即不通过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

使用此方法的一个明显优势是可以完全避免HTTP请求,从而提高效率,减少错误(例如网络问题)解决方案。

将上述内容描述为一般处理从多个视图访问常用功能的方法,在创建新用户之前执行查找并不总能保证用户创建不会因重复记录而失败。有竞争条件;在第一次请求检查之后但在尝试创建操作之前,另一个请求可能会创建用户。

假设您的用户表具有主键,例如在(first_name, last_name, email)上,您可以简单地尝试创建新用户并处理由于重复而引发的任何异常。或者您可以查看this (old) question

答案 1 :(得分:2)

我会为你的用例做这样的事情:

@API.route('/users', defaults={'email': None} ,methods=['GET', 'POST'])
@API.route('/users/<string:email>', methods=['GET', 'POST'])
def new_user(email):
    if(email):
        user = User.query.filter_by(email=email).first()
        if user:
            return jsonify(user=user.to_json()), 200
        else:
            return jsonify(error=404), 404
    else:
        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 = 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