使用Python+阿里云OSS实现个人图床(图片存储)

完整项目代码见GitHub
本项目教程见CSDN博客


阿里云OSS

阿里云OSS选择
  • 阿里云: 0-5GB(含)部分 免费 只限香港地区
  • 新建Bucket时, 所属区域选香港
阿里云OSS API使用
  • 阿里云OSS API官方参考
  • OSS通过使用AccessKeyId/ AccessKeySecret对称加密的方法来验证某个请求的发送者身份
  • 建议使用RAM账户AccessKey:RAM账户由阿里云账号授权生成,所拥有的AccessKey拥有对特定资源限定的操作权限
  • 根据官方文档封装阿里云OSS API
    • 安装Python SDK: pip install oss2
    • 最高仅支持Python3.6
import oss2
import time


class RunOSS:
    def __init__(self, AccessKeyId=None, AccessKeySecret=None, Endpoint=None, BuckerName=None, filename=None):
        self.AccessKeyId = AccessKeyId
        self.AccessKeySecret = AccessKeySecret
        self.Endpoint = Endpoint  # Endpoint(香港, 其他地区根据实际情况修改): 'http://oss-cn-hongkong.aliyuncs.com'
        self.BuckerName = BuckerName
        self.filename = filename or str(int(time.time()))

    def getBucket(self):
        auth = oss2.Auth(self.AccessKeyId, self.AccessKeySecret)
        bucket = oss2.Bucket(auth, self.Endpoint, self.BuckerName)
        return bucket

    def uploadFIle(self, objectfile, isFile=True):
        bucket = self.getBucket()
        if isinstance(objectfile, str):
            objectname = self.filename+'.'+objectfile.split('.')[-1]
        else:
            objectname = self.filename
        try:
            if isFile:
                with open(objectfile, mode='rb') as f:
                    ret = bucket.put_object(objectname, f)
            else:
                ret = bucket.put_object(objectname, objectfile)
            link = "http://{}.oss-cn-hongkong.aliyuncs.com/".format(self.BuckerName) + objectname
            return {'status': ret.status, 'link': link}
        except Exception as e:
            return e
    
    ...

使用Flask封装API实现本地图片上传

代码
import json
from flask import Flask, request, jsonify, Response
from aliyunOSSRun import RunOSS

# Flask对象
app = Flask(__name__)

def response_headers(content):
    resp = Response(content)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp


@app.route('/oss_upload/', methods=['POST'])
def upload_oss_file():
    if request.files.get('objectfile'):
        objectfile = request.files['objectfile']
        filename = str(request.args.get('filename', ""))
        ret = RunOSS(filename=filename).uploadFIle(objectfile=objectfile, isFile=False)
        print(ret[key] for key in ret)
        return jsonify(ret)
    else:
        content = json.dumps({"error_code": "1001"})
        resp = response_headers(content)
        return resp

if __name__ == '__main__':
    app.run(debug=False, port=5000, host='0.0.0.0')   # 启动服务

可以在阿里云服务器上后台开启该任务, 用于接收OSS上传任务

Flask Bug
  • 高并发报错:
requests.exceptions.ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe'))
  • 解决方案:

使用Flask+gevent异步WEB架构解决
代码修改如下:

import json

from flask import Flask, request, jsonify, Response
from gevent import pywsgi
from gevent import monkey

from aliyunOSSRun import RunOSS

monkey.patch_all()
# Flask对象
app = Flask(__name__)

        ...

if __name__ == '__main__':

    port = 5000
    server = pywsgi.WSGIServer(('0.0.0.0', port), app)
    server.serve_forever()

Windows右键实现一键上传文件并返回文件OSS路径

编写Python脚本获取文件路径, 并上传至阿里云Flask接口
import sys
import time
import requests
import json


class WindowsOSSUpload:

    def __init__(self, filename=None, ip=None, port=None):
        self.ip = ip
        self.port = port
        self.url = None
        self.filename = filename

    def winUpload(self):
        timestr = str(int(time.time()))
        objectfile = sys.argv[1]
        file = objectfile.split("\\")[-1]
        filename = ".".join(file.split(".")[:-1]) + "_" + timestr + "." + file.split(".")[-1]
        self.filename = self.filename or filename
        self.url = "http://{}:{}/oss_upload?filename={}".format(self.ip, self.port, self.filename)
        files = {'objectfile': (filename, open(objectfile, 'rb'), 'application/octet-stream')}
        res = requests.post(url=self.url, files=files)
        rest = json.loads(res.text)
        print(rest['link'])
        input()  # 用于cmd窗口停留


if __name__ == '__main__':

    ip = "xxx.xxx.xxx.xxx"
    port = "xxxx"
    WindowsOSSUpload(ip=ip, port=port).winUpload()

其中sys.argv[1]用于读取cmd中传递的参数, 该处是获取待上传文件的路径
最后加input(), 防止cmd窗口自动关闭

增加右键任务按钮
  • Win + R打开命令行, 输入regedit打开注册表
  • 找到HKEY_CLASSES_ROOT\*\shell目录, 新建name项, 命名即为右键显示的任务名称
  • 进入name项目录, 新建command
  • 进入command项目录, 新建一个字符串值
  • 输入值: D:\Anaconda3\envs\pyenv35\python D:\OSSRun\winOSSUpload.py %1
    • 其中前者为python路径, 后者为项目文件路径
    • 在注册表的指定打开方式路径后加上(空格)%1, 表示系统向其传递的文件路径

参考

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值