sewen-H

七牛云存储

需求

在头条项目中,如用户头像、文章图片等数据需要使用文件存储系统来保存

方案

  • 自己搭建文件系统服务
  • 选用第三方对象存储服务

我们在头条项目中使用七牛云对象存储服务 http://www.qiniu.com

使用

  1. 注册
  2. 新建存储空间
  3. 使用七牛SDK完成代码实现

七牛Python SDK 网址 https://developer.qiniu.com/kodo/sdk/1242/python

安装SDK
pip install qiniu

 

编码

七牛提供的上传代码参考示例

from qiniu import Auth, put_file, etag
import qiniu.config

#需要填写你的 Access Key 和 Secret Key
access_key = \'Access_Key\'
secret_key = \'Secret_Key\'

#构建鉴权对象
q = Auth(access_key, secret_key)

#要上传的空间
bucket_name = \'Bucket_Name\'

#上传后保存的文件名
key = \'my-python-logo.png\'

#生成上传 Token,可以指定过期时间等
token = q.upload_token(bucket_name, key, 3600)

#要上传文件的本地路径
localfile = \'./sync/bbb.jpg\'

ret, info = put_file(token, key, localfile)
print(info)
assert ret[\'key\'] == key
assert ret[\'hash\'] == etag(localfile)

 

头条项目实现

from qiniu import Auth, put_file, etag, put_data
import qiniu.config
from flask import current_app


def upload_image(file_data):
    """
    上传图片到七牛
    :param file_data: bytes 文件
    :return: file_name
    """
    # 需要填写你的 Access Key 和 Secret Key
    access_key = current_app.config[\'QINIU_ACCESS_KEY\']
    secret_key = current_app.config[\'QINIU_SECRET_KEY\']

    # 构建鉴权对象
    q = Auth(access_key, secret_key)

    # 要上传的空间
    bucket_name = current_app.config[\'QINIU_BUCKET_NAME\']

    # 上传到七牛后保存的文件名
    # key = \'my-python-七牛.png\'
    key = None

    # 生成上传 Token,可以指定过期时间等
    token = q.upload_token(bucket_name, expires=1800)

    # # 要上传文件的本地路径
    # localfile = \'/Users/jemy/Documents/qiniu.png\'

    # ret, info = put_file(token, key, localfile)
    ret, info = put_data(token, key, file_data)

    return ret[\'key\']

 

上传头像、身份证图片接口

在common/utils/parser.py

import imghdr

def image_file(value):
    """
    检查是否是图片文件
    :param value:
    :return:
    """
    try:
        file_type = imghdr.what(value)
    except Exception:
        raise ValueError(\'Invalid image.\')
    else:
        if not file_type:
            raise ValueError(\'Invalid image.\')
        else:
            return value

 

toutiao/resources/user/profle.py

class PhotoResource(Resource):
    """
    用户图像 (头像,身份证)
    """
    method_decorators = [login_required]

    def patch(self):
        file_parser = RequestParser()
        file_parser.add_argument(\'photo\', type=parser.image_file, required=False, location=\'files\')
        file_parser.add_argument(\'id_card_front\', type=parser.image_file, required=False, location=\'files\')
        file_parser.add_argument(\'id_card_back\', type=parser.image_file, required=False, location=\'files\')
        file_parser.add_argument(\'id_card_handheld\', type=parser.image_file, required=False, location=\'files\')
        files = file_parser.parse_args()

        user_id = g.user_id
        new_user_values = {}
        new_profile_values = {}
        return_values = {\'id\': user_id}

        if files.photo:
            try:
                photo_url = upload_image(files.photo.read())
            except Exception as e:
                current_app.logger.error(\'upload failed {}\'.format(e))
                return {\'message\': \'Uploading profile photo image failed.\'}, 507
            new_user_values[\'profile_photo\'] = photo_url
            return_values[\'photo\'] = current_app.config[\'QINIU_DOMAIN\'] + photo_url
            need_delete_profile = True

        if files.id_card_front:
            try:
                id_card_front_url = upload_image(files.id_card_front.read())
            except Exception as e:
                current_app.logger.error(\'upload failed {}\'.format(e))
                return {\'message\': \'Uploading id_card_front image failed.\'}, 507
            new_profile_values[\'id_card_front\'] = id_card_front_url
            return_values[\'id_card_front\'] = current_app.config[\'QINIU_DOMAIN\'] + id_card_front_url

        if files.id_card_back:
            try:
                id_card_back_url = upload_image(files.id_card_back.read())
            except Exception as e:
                current_app.logger.error(\'upload failed {}\'.format(e))
                return {\'message\': \'Uploading id_card_back image failed.\'}, 507
            new_profile_values[\'id_card_back\'] = id_card_back_url
            return_values[\'id_card_back\'] = current_app.config[\'QINIU_DOMAIN\'] + id_card_back_url

        if files.id_card_handheld:
            try:
                id_card_handheld_url = upload_image(files.id_card_handheld.read())
            except Exception as e:
                current_app.logger.error(\'upload failed {}\'.format(e))
                return {\'message\': \'Uploading id_card_handheld image failed.\'}, 507
            new_profile_values[\'id_card_handheld\'] = id_card_handheld_url
            return_values[\'id_card_handheld\'] = current_app.config[\'QINIU_DOMAIN\'] + id_card_handheld_url

        if new_user_values:
            User.query.filter_by(id=user_id).update(new_user_values)
        if new_profile_values:
            UserProfile.query.filter_by(id=user_id).update(new_profile_values)

        db.session.commit()

        return return_values, 201

 

分类:

技术点:

相关文章: