如何使用七牛Python SDK写一个同步脚本及使用教程


Posted in Python onAugust 23, 2015

七牛云存储的 Python 语言版本 SDK(本文以下称 Python-SDK)是对七牛云存储API协议的一层封装,以提供一套对于 Python 开发者而言简单易用的开发工具。Python 开发者在对接 Python-SDK 时无需理解七牛云存储 API 协议的细节,原则上也不需要对 HTTP 协议和原理做非常深入的了解,但如果拥有基础的 HTTP 知识,对于出错场景的处理可以更加高效。

最近刚搭了个markdown静态博客,想把图片放到云存储中。

经过调研觉得七牛可以满足我个人的需求,就选它了。

要引用图片就要先将图片上传到云上。

虽然七牛网站后台可以上传文件,但每次上传都需要先登录,然后选择图片,设置连接地址,才能上传。

这个过程有些繁琐,所以我便想用七牛云提供的SDK写个一同步工具,方便增量同步文件。

有了这个想法,就马上行动。花了大概一个上午的时间,总算把这个工具给写出来,并放到GitOSC和github上。

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# 
# AUTHOR = "heqingpan"
# AUTHOR_EMAIL = "heqingpan@126.com"
# URL = "http://git.oschina.net/hqp/qiniu_sync"
import qiniu
from qiniu import Auth
from qiniu import BucketManager
import os
import re
access_key = ''
secret_key = ''
bucket_name = ''
bucket_domain = ''
q = Auth(access_key, secret_key)
bucket = BucketManager(q)
basedir=os.path.realpath(os.path.dirname(__file__))
filename=__file__
ignore_paths=[filename,"{0}c".format(filename)]
ignore_names=[".DS_Store",".git",".gitignore"]
charset="utf8"
diff_time=2*60

def list_all(bucket_name, bucket=None, prefix="", limit=100):
 rlist=[]
 if bucket is None:
  bucket = BucketManager(q)
 marker = None
 eof = False
 while eof is False:
  ret, eof, info = bucket.list(bucket_name, prefix=prefix, marker=marker, limit=limit)
  marker = ret.get('marker', None)
  for item in ret['items']:
   rlist.append(item["key"])
 if eof is not True:
  # 错误处理
  #print "error"
  pass
 return rlist
def get_files(basedir="",fix="",rlist=None,ignore_paths=[],ignore_names=[]):
 if rlist is None:
  rlist=[]
 for subfile in os.listdir(basedir):
  temp_path=os.path.join(basedir,subfile)
  tp=os.path.join(fix,subfile)
  if tp in ignore_names:
   continue
  if tp in ignore_paths:
   continue
  if os.path.isfile(temp_path):
   rlist.append(tp)
  elif os.path.isdir(temp_path):
   get_files(temp_path,tp,rlist,ignore_paths,ignore_names)
 return rlist
def get_valid_key_files(subdir=""):
 basedir=subdir or basedir
 files = get_files(basedir=basedir,ignore_paths=ignore_paths,ignore_names=ignore_names)
 return map(lambda f:(f.replace("\\","/"),f),files)

def sync():
 qn_keys=list_all(bucket_name,bucket)
 qn_set=set(qn_keys)
 l_key_files=get_valid_key_files(basedir)
 k2f={}
 update_keys=[]
 u_count=500
 u_index=0
 for k,f in l_key_files:
  k2f[k]=f
  str_k=k
  if isinstance(k,str):
   k=k.decode(charset)
  if k in qn_set:
   update_keys.append(str_k)
   u_index+=1
   if u_index > u_count:
    u_index-=u_count
    update_file(k2f,update_keys)
    update_keys=[]
  else:
   # upload
   upload_file(k,os.path.join(basedir,f))
 if update_keys:
  update_file(k2f,update_keys)
 print "sync end"
def update_file(k2f,ulist):
 ops=qiniu.build_batch_stat(bucket_name,ulist)
 rets,infos = bucket.batch(ops)
 for i in xrange(len(ulist)):
  k=ulist[i]
  f=k2f.get(k)
  ret=rets[i]["data"]
  size=ret.get("fsize",None)
  put_time = int(ret.get("putTime")/10000000)
  local_size=os.path.getsize(f)
  local_time=int(os.path.getatime(f))
  if local_size==size:
   continue
  if put_time >= local_time - diff_time:
   # is new
   continue
  # update
  upload_file(k,os.path.join(basedir,f))
def upload_file(key,localfile):
 print "upload_file:"
 print key
 token = q.upload_token(bucket_name, key)
 mime_type = get_mime_type(localfile)
 params = {'x:a': 'a'}
 progress_handler = lambda progress, total: progress
 ret, info = qiniu.put_file(token, key, localfile, params, mime_type, progress_handler=progress_handler)
def get_mime_type(path):
 mime_type = "text/plain"
 return mime_type
def main():
 sync()
if __name__=="__main__":
 main()

这个同步脚本支持批量比较文件,差异增量更新、批量更新。

使用方式

安装七牛Python SDK

pip install qiniu

填写脚本文件(qiniusync.py)的配置信息

access_key = ''
secret_key = ''
bucket_name = ''

注册后可以拿到对应的信息

将脚本文件(qiniusync.py)拷贝到待同步根目录

运行脚本

python qiniusync.py

后记

写完提交之后才发现,七牛已经提供相应的工具,我这个算是重复造轮子吧。

既然已经写,就发出来,当做熟悉一下七牛的SDK也不错,说不定以后还能用的上。

七牛云存储Python SDK使用教程

本教程旨在介绍如何使用七牛的Python SDK来快速地进行文件上传,下载,处理,管理等工作。

安装

首先,要使用Python的SDK必须要先安装。七牛的Python SDK是开源的,托管在Github上面,项目地址为 https://github.com/qiniu/python-sdk 。

安装的方式可以如项目的说明上所说,用 pip install qiniu 。当然也可以直接 clone 一份源代码下来直接使用。我一般喜欢直接 clone 源代码,这样的话,如果要对SDK做一些改动也是十分容易的。

最新版本的Python SDK需要依赖 requests 库,所以要提前安装好。安装方式当然也可以用 pip install requests 。

开发环境

Python的开发环境有很多种选择,如果喜欢文本的方式,比如vim,emacs,sublime text等都是很好的选择,如果你喜欢IDE,那么最流行的莫过于 PyCharm 了。 PyCharm 的最新版本到 这里下载。

Access Key和Secret Key

我们知道七牛云存储的权限校验机制基于一对密钥,分别称为 Access Key 和 Secret Key 。其中 Access Key 是公钥, Secret Key 是私钥。这一对密钥可以从七牛的后台获取。

如何使用七牛Python SDK写一个同步脚本及使用教程

小试牛刀

好了,做了上面的这些准备工作,我们就去上传一个简单的文件,练练手。

python
#coding=utf-8
__author__ = 'jemy'
'''

本例演示了一个简单的文件上传。

这个例子里面,sdk根据文件的大小选择是Form方式上传还是分片上传。

'''
import qiniu
accessKey = "<Your Access Key>"
secretKey = "<Your Secret Key>"
#解析结果
def parseRet(retData, respInfo):
 if retData != None:
 print("Upload file success!")
 print("Hash: " + retData["hash"])
 print("Key: " + retData["key"])
 #检查扩展参数
 for k, v in retData.items():
  if k[:2] == "x:":
  print(k + ":" + v)
 #检查其他参数
 for k, v in retData.items():
  if k[:2] == "x:" or k == "hash" or k == "key":
  continue
  else:
  print(k + ":" + str(v))
 else:
 print("Upload file failed!")
 print("Error: " + respInfo.text_body)
#无key上传,http请求中不指定key参数
def upload_without_key(bucket, filePath):
 #生成上传凭证
 auth = qiniu.Auth(accessKey, secretKey)
 upToken = auth.upload_token(bucket, key=None)
 #上传文件
 retData, respInfo = qiniu.put_file(upToken, None, filePath)
 #解析结果
 parseRet(retData, respInfo)
def main():
 bucket = "if-pbl"
 filePath = "/Users/jemy/Documents/jemy.png"
 upload_without_key(bucket, filePath)
if __name__ == "__main__":
 main()

运行结果为:

Upload file success!
Hash: Fp0XR6tM4yZmeiKXw7eZzmeyYsq8
Key: Fp0XR6tM4yZmeiKXw7eZzmeyYsq8

从上面我们可以看到,使用七牛的Python SDK上传文件的最基本的步骤是:

1.生成上传凭证

2.上传文件

3.解析回复结果

小结

综上所述,其实使用七牛的SDK来上传文件还是很简单的,接下来的教程,我们将在这个例子的基础上逐步了解更多关于文件上传的知识。

Python 相关文章推荐
python实现颜色rgb和hex相互转换的函数
Mar 19 Python
Python简单计算文件夹大小的方法
Jul 14 Python
python 读写中文json的实例详解
Oct 29 Python
python3 对list中每个元素进行处理的方法
Jun 29 Python
解决python 自动安装缺少模块的问题
Oct 22 Python
Python的条件表达式和lambda表达式实例
Jan 31 Python
浅析PyTorch中nn.Module的使用
Aug 18 Python
Linux下通过python获取本机ip方法示例
Sep 06 Python
django admin 添加自定义链接方式
Mar 11 Python
python装饰器实现对异常代码出现进行自动监控的实现方法
Sep 15 Python
属性与 @property 方法让你的python更高效
Sep 21 Python
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
Oct 12 Python
Python中for循环和while循环的基本使用方法
Aug 21 #Python
Python中条件判断语句的简单使用方法
Aug 21 #Python
Python编程中的异常处理教程
Aug 21 #Python
剖析Python的Tornado框架中session支持的实现代码
Aug 21 #Python
约瑟夫问题的Python和C++求解方法
Aug 20 #Python
在类Unix系统上开始Python3编程入门
Aug 20 #Python
Python中字典映射类型的学习教程
Aug 20 #Python
You might like
php实现简单的MVC框架实例
2015/09/23 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
Yii使用EasyWechat实现小程序获取用户的openID的方法
2020/04/29 PHP
nginx 设置多个站跨域
2021/03/09 Servers
js获取下拉列表框中的value和text的值示例代码
2014/01/11 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
javascript实现实时输出当前的时间
2015/04/27 Javascript
如何在Linux上安装Node.js
2016/04/01 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
关于js二维数组和多维数组的定义声明(详解)
2016/10/02 Javascript
JS字符串按逗号和回车分隔的方法
2017/04/25 Javascript
JavaScript简单实现合并两个Json对象的方法示例
2017/10/16 Javascript
js实现动态增加文件域表单功能
2018/10/22 Javascript
NodeJS读取分析Nginx错误日志的方法
2019/05/14 NodeJs
layui 地区三级联动 form select 渲染的实例
2019/09/27 Javascript
JavaScript实现京东放大镜效果
2019/12/03 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
NestJs使用Mongoose对MongoDB操作的方法
2021/02/22 Javascript
[06:07]辉夜杯现场观众互动 “比谁远送显示器”
2015/12/26 DOTA
Python使用cx_Oracle调用Oracle存储过程的方法示例
2017/10/07 Python
Python线程创建和终止实例代码
2018/01/20 Python
基于随机梯度下降的矩阵分解推荐算法(python)
2018/08/31 Python
分享8点超级有用的Python编程建议(推荐)
2019/10/13 Python
根据tensor的名字获取变量的值方式
2020/01/04 Python
基于Tensorflow:CPU性能分析
2020/02/10 Python
python 实现字符串下标的输出功能
2020/02/13 Python
Python爬虫防封ip的一些技巧
2020/08/06 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
美国现代家具网站:Design Within Reach
2018/07/19 全球购物
Bulk Powders意大利:运动补充在线商店
2019/02/09 全球购物
Looking4Parking美国:全球排名第一的机场停车比较品牌
2019/08/26 全球购物
电视购物广告词
2014/03/19 职场文书
成品库仓管员岗位职责
2014/04/06 职场文书
新闻工作者先进事迹
2014/05/26 职场文书
关于感恩的演讲稿400字
2014/08/26 职场文书
群众路线剖析材料怎么写
2014/10/09 职场文书