您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么向s3cmd服務上傳數據”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么向s3cmd服務上傳數據”吧!
操作流程:
1.客戶端向presign server提交上傳操作請求,生成對應的presign URL
2.使用生成的presign URL構造HTTP請求,向S3服務上傳數據。
優點:
1. accesskey和secretkey不會存儲在客戶端,避免key泄露
2. 每個presignURL對應一個keyname,在有效時間內可以任意上傳和覆蓋已有文件,比較靈活。
3. 服務端可以結合各種Auth系統完成客戶端的認證和授權,方便集成現有業務。
4. 客戶端上傳下載方式靈活,拿到presignURL以后,可以通過任意支持HTTP協議的客戶端進行上傳下載操作。
缺點:
1. 上傳和下載的交互比普通上傳要多出一個步驟。
2. 文中的presign是以單次PUT方式上傳,大文件不適用這個方法。
安裝服務端依賴
pip install boto pip install flask-restful
服務端demo代碼如下:
# -*- coding: utf-8 -*- import boto import boto.s3.connection from flask import Flask, request from flask_restful import Resource, Api import re s3enpoint = 's3.ceph.work' #S3服務的endpoint access_key = '' #access_key secret_key = '' #secret_key bucket = 'multi-upload' #上傳數據存放的bucket名稱 class Presign_Upload(Resource): def __init__(self): self.s3enpoint = s3enpoint self.access_key = access_key self.secret_key = secret_key self.bucket = bucket # super(Presign_Upload,self).__init__() self.headers = {} def presign(self,key_name,expires_in): conn = boto.connect_s3( aws_access_key_id = self.access_key, aws_secret_access_key = self.secret_key, host = self.s3enpoint, port = 80 , is_secure = False, # uncommmnt if you are not using ssl # calling_format = boto.s3.connection.OrdinaryCallingFormat(), #use path-style calling_format = boto.s3.connection.SubdomainCallingFormat(), #use virtual-hosted-style ) presigened_url = conn.generate_url(expires_in, "PUT", self.bucket, key_name,headers=self.headers) return presigened_url def get(self): if not request.args.get("keyname"): return "no keyname", 404 else: keyname = request.args.get("keyname") if not request.args.get("expires"): return "no expires", 404 else: expires = int(request.args.get("expires")) if request.args.get("contentype"): contentype = request.args.get("contentype") self.headers['Content-Type'] = contentype if request.args.get("policy"): policy = request.args.get("policy") self.headers['x-amz-acl'] = policy meatadata_rule = 'x-amz-meta-' for parm in request.args: if re.match(meatadata_rule, parm): self.headers[parm] = request.args.get(parm) return {"PresignURL": self.presign(keyname, expires)} class Presign_Download(Resource): def __init__(self): Resource.__init__(self) self.s3enpoint = s3enpoint self.access_key = access_key self.secret_key = secret_key self.bucket = bucket self.headers = {} def presign(self,key_name,expires_in): conn = boto.connect_s3( aws_access_key_id = self.access_key, aws_secret_access_key = self.secret_key, host = self.s3enpoint, port = 80 , is_secure = False, # uncommmnt if you are not using ssl # calling_format = boto.s3.connection.OrdinaryCallingFormat(), #use path-style calling_format = boto.s3.connection.SubdomainCallingFormat(), #use virtual-hosted-style ) presigened_url = conn.generate_url(expires_in, "GET", self.bucket, key_name) return presigened_url def get(self): if not request.args.get("keyname"): return "no keyname", 400 else: keyname = request.args.get("keyname") if not request.args.get("expires"): return "no expires", 400 else: expires = int(request.args.get("expires")) return {"PresignURL": self.presign(keyname, expires)} app = Flask(__name__) api = Api(app) api.add_resource(Presign_Upload, '/upload') api.add_resource(Presign_Download, '/download') if __name__ == '__main__': app.run(debug=True)
安裝客戶端依賴
pip install requests
客戶端demo代碼如下:
# -*- coding: utf-8 -*- import requests import json class Presign_client(): def __init__(self, server_url): self.server_url = server_url self.headers = {} def get_upload_presignURL(self, keyname, expires, policy=None, contentype=None, metadata=None): base_url_ = "{server_url}/upload?keyname={keyname}&expires={expires}".format(server_url=server_url,keyname=keyname,expires=expires) if contentype: self.headers['Content-Type'] = contentype base_url_ = "{base_url_}&contentype={contentype}".format(base_url_=base_url_,contentype=contentype) if policy: self.headers['x-amz-acl'] = policy base_url_ = "{base_url_}&policy={policy}".format(base_url_=base_url_,policy=policy) if metadata: for k in metadata: metadata_key = k metadata_value = metadata[k] self.headers[metadata_key] = str(metadata_value) base_url_ = "{base_url_}&{metadata_key}={metadata_value}".format(base_url_=base_url_,metadata_key=str(metadata_key),metadata_value=metadata_value) res = requests.get(base_url_) return json.loads(res.content)['PresignURL'] def upload_file(self,SignURL,filepath): with open(filepath) as fh: mydata = fh.read() response = requests.put(SignURL,data=mydata,headers=self.headers) if response.status_code == 200: print "Upload {} Successful!".format(filepath) else: print "Failed! status_code={}".format(response.status_code) def get_download_presignURL(self, keyname, expires): base_url_ = "{server_url}/download?keyname={keyname}&expires={expires}".format(server_url=server_url,keyname=keyname,expires=expires) response = requests.get(base_url_) return json.loads(response.content)['PresignURL'] def download_file(self,SignURL,filepath): response = requests.get(SignURL) if response.status_code == 200: with open(filepath,'wb') as fh: fh.write(response.content) print "Download {} Successful!".format(filepath) else: print "Failed! status_code={}".format(response.status_code) server_url = 'http://localhost:5000' #填服務端地址 metadata ={'x-amz-meta-abc':333,'x-amz-meta-key':'value'} #上傳文件的自定義metadata contentype = 'abc/pdf' #設置上傳文件的Content-Type policy = 'public-read' #設置上傳文件的ACL expires = 300 #設置presignURL有效時長,單位秒 file_path = '/Users/demouser/Downloads/1.pdf' #上傳文件路徑 save_path = '/tmp/download.pdf' #下載文件存儲路徑 keyname = 'upload.pdf' #上傳文件的名稱,對應object的keyname client = Presign_client(server_url) #生成上傳presignURL,并上傳文件 Upload_SignURL = client.get_upload_presignURL(keyname=keyname, expires=expires, policy=policy, contentype=contentype, metadata=metadata) client.upload_file(Upload_SignURL,file_path) #下載presignURL,并下載文件 Download_SignURL = client.get_download_presignURL(keyname=keyname, expires=expires) client.download_file(Download_SignURL,save_path)
到此,相信大家對“怎么向s3cmd服務上傳數據”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。