对象储存-七牛云存储
七牛云存储
需求
在头条项目中,如用户头像、文章图片等数据需要使用文件存储系统来保存
方案
- 自己搭建文件系统服务
- 选用第三方对象存储服务
我们在头条项目中使用七牛云对象存储服务 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
壬戌之秋,七月既望,苏子与客泛舟游于赤壁之下。清风徐来,水波不兴。举酒属客,诵明月之诗,歌窈窕之章。少焉,月出于东山之上,徘徊于斗牛之间。白露横江,水光接天。纵一苇之所如,凌万顷之茫然。浩浩乎如冯虚御风,而不知其所止;飘飘乎如遗世独立,羽化而登仙。
于是饮酒乐甚,扣舷而歌之。歌曰:“桂棹兮兰桨,击空明兮溯流光。渺渺兮予怀,望美人兮天一方。”客有吹洞箫者,倚歌而和之。其声呜呜然,如怨如慕,如泣如诉,余音袅袅,不绝如缕。舞幽壑之潜蛟,泣孤舟之嫠妇。
苏子愀然,正襟危坐而问客曰:“何为其然也?”客曰:“月明星稀,乌鹊南飞,此非曹孟德之诗乎?西望夏口,东望武昌,山川相缪,郁乎苍苍,此非孟德之困于周郎者乎?方其破荆州,下江陵,顺流而东也,舳舻千里,旌旗蔽空,酾酒临江,横槊赋诗,固一世之雄也,而今安在哉?况吾与子渔樵于江渚之上,侣鱼虾而友麋鹿,驾一叶之扁舟,举匏樽以相属。寄蜉蝣于天地,渺沧海之一粟。哀吾生之须臾,羡长江之无穷。挟飞仙以遨游,抱明月而长终。知不可乎骤得,托遗响于悲风。”
苏子曰:“客亦知夫水与月乎?逝者如斯,而未尝往也;盈虚者如彼,而卒莫消长也。盖将自其变者而观之,则天地曾不能以一瞬;自其不变者而观之,则物与我皆无尽也,而又何羡乎!且夫天地之间,物各有主,苟非吾之所有,虽一毫而莫取。惟江上之清风,与山间之明月,耳得之而为声,目遇之而成色,取之无禁,用之不竭,是造物者之无尽藏也,而吾与子之所共适。”
客喜而笑,洗盏更酌。肴核既尽,杯盘狼籍。相与枕藉乎舟中,不知东方之既白。

浙公网安备 33010602011771号