七牛云存储
需求
在头条项目中,如用户头像、文章图片等数据需要使用文件存储系统来保存
方案
- 自己搭建文件系统服务
- 选用第三方对象存储服务
我们在头条项目中使用七牛云对象存储服务 http://www.qiniu.com。
使用
- 注册
- 新建存储空间
- 使用七牛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