ks33requests Documentations

Release

0.1

Date

2019 年 06 月 26 日

Version

0.1.3


Docs

ks33requests

https://img.shields.io/pypi/v/ks33requests.svgPyPI https://img.shields.io/pypi/l/ks33requests.svgPyPI - License https://readthedocs.org/projects/ks33requests/badge/?version=stableDocumentation Status https://circleci.com/gh/tanbro/ks33requests.svg?style=svgCircleCI https://codecov.io/gh/tanbro/ks33requests/branch/master/graph/badge.svgcodecov https://img.shields.io/pypi/format/ks33requests.svgPyPI - Format https://img.shields.io/pypi/status/ks33requests.svgPyPI - Status https://img.shields.io/pypi/pyversions/ks33requests.svgPyPI - Python Version https://img.shields.io/pypi/implementation/ks33requests.svgPyPI - Implementation

概述

一个很简单的、适用于 金山云 对象存储(KS3)的 Python3 客户端。

金山云 官方提供了 KS3Python SDK,但在我启动这个项目(2019-06-10)时,仅提供 Python2 SDK。

考虑到 Python2 已经接近其生命周期的终点,我制作了这个简单的 Python3 KS3 客户端用于相关项目。

安装

  • pip 安装

    pip install ks33requests
    
  • 源代码安装

    python setuptools.py install
    
  • Pipenv 安装

    pipenv install ks33requests
    

如何使用

参见 notebooks 中的笔记

CHANGELOG

0.1.3

📅 Date : 2019-06-26

  • New:

    • get_content_md5(): 获取 KS3 样式的 MD5 BASE64 校验值

  • Fix:

    • 修订 condapip 的定义文件中的几处错误

    • 修订几处文档错误

0.1.2.1

📅 Date : 2019-06-25

  • Change:

    • 构造 Client 时,如果不指定密钥对,将从环境变量 KSYUN_ACCESS_KEYKSYUN_SECRET_KEY 获得

    • Client.send() 增加 encoding 参数,用于对文本数据上传的支持

  • Fix:

    • 几个有关文本数据上传 bug

  • New:

0.1

📅 Date : 2019-06-12

这实际上还是一个 Alpha 版本,但是为了在项目中顺利使用,且给它一个稳定的版本编号。

CONTRIBUTING

注意:

这个项目需要 Python 3.5 及以上版本。

复刻项目代码

复刻项目代码到工作目录,然后切换到项目的目录:

cd path/to/your/workspace/directory/
git clone https://github.com/tanbro/ks33requests.git
cd ks33requests

准备开发环境

强烈建议在 virtual environment 中进行开发工作。

  • 如果使用标准库:

    使用标准库的 venvpip 直接新建名为venv的虚拟环境目录,将本项目以“开发模式”安装到这个环境,并安装开发工作所要使用的包:

    path/of/your/python -m venv venv
    venv/bin/python setup.py develop
    venv/bin/python -m pip install -r requires/dev.txt
    
  • 如果使用 Pipenv:

    使用 Pipenv 命令直接安装:

    pipenv install --dev
    
  • 如果使用 conda

    使用 conda 从配置文件新建一个专用于这个项目的、名为ks33requests-dev的环境,然后激活它,将本项目以“开发模式”安装到这个环境:

    conda env create -f environment.yml
    conda activate ks33requests-dev
    python setup.py develop
    
XML Schema

金山云 KS3 的 WebAPI 数据结构有许多与S3兼容。 所以,这个项目直接使用考虑来自 http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.xsd 的 Schema。

我们使用 generateDS 工具,从xsd文件生成 Python 类型定义:

mkdir -p schemas
wget http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.xsd -P schemas
generateDS.py -f -o s3_api.py -s s3_sub.py --super=s3_api  schemas/AmazonS3.xsd

生成的源代码文件复制到名称空间 ks33requests.schemas 中,小幅修改 s3_sub.py 即可使用。

运行测试用例
python setup.py test

测试用例很少,陆续补充中…

Docs

如果模块有增减,需要删除原来的 Sphinx-Docs API 自动文档并重新生成:

rm -rf docs/ks3requests.rst docs/api
sphinx-apidoc -e -f -o docs/api src/ks33requests src/ks33requests/schemas/s3_*.py

AUTHORS

Examples

入门

AccessKey 和 SecretKey

首先设定 KS3 的 AccessKey和SecretKey。

本例中,将它们放在环境变量配置文件 .env 中,名为 KSYUN_ACCESS_KEYKSYUN_SECRET_KEY,然后使用 `python-dotenv <https://github.com/theskumar/python-dotenv>`__ 加载

加载环境变量:

[1]:
%load_ext dotenv

# Use find_dotenv to locate the file
%dotenv

指定Endpoint

我自己的测试实例在上海,因此:

[2]:
ENDPOINT = 'ks3-cn-shanghai.ksyun.com'

初始化客户端

[3]:
from ks33requests.client import get_s3obj, Client

c = Client(endpoint=ENDPOINT)

如何使用

列出默认项目第一个 Bucket 的 Name

发送 API 请求,并等待其返回状态码

[4]:
res = c.send(params={'projectIds': '0'})
res
[4]:
<Response [200]>
[5]:
obj = get_s3obj(res)
obj
[5]:
<ks33requests.schemas.s3_sub.ListAllMyBucketsResultSub at 0x7f790b8c99e8>
[6]:
bucket_name = obj.Buckets.Bucket[0].Name
bucket_name
[6]:
'huameoi-newcutter-develop'
获取这个BUCKET 的 Location
[7]:
res = c.send('GET', bucket_name=bucket_name, sub_resources='location').s3obj()
[8]:
res.valueOf_
[8]:
'SHANGHAI'
上传一个文本文件

在内存新建一段文本,作为文件内容上传

[9]:
import io

key = 'test'
text = '金山云对象存储服务(Kingsoft Standard Storage Service),简称KS3,是金山云为开发者提供无限制、多备份、分布式的低成本存储空间解决方案。目前提供多种语言SDK,替开发者解决存储扩容、数据可靠安全以及分布式访问等相关复杂问题,开发者可以快速的开发出涉及存储业务的程序或服务。'

stream = io.BytesIO(text.encode())
[10]:
resp = c.send('put', bucket_name=bucket_name, object_key=key, data=stream)
resp
[10]:
<Response [200]>
下载上一个文本文件

下载到内存,看看内容是否一致

[11]:
resp = c.send('get', bucket_name=bucket_name, object_key=key)
resp
[11]:
<Response [200]>

断言 - 字符串相同:

[12]:
assert resp.text==text
删除这个文件
[13]:
resp = c.send('delete', bucket_name=bucket_name, object_key=key)
resp
[13]:
<Response [204]>
确定该文件不存在
[14]:
resp = c.send('head', bucket_name=bucket_name, object_key=key, check_status=False)
resp
[14]:
<Response [404]>

断言 - 404 不存在:

[15]:
assert resp.status_code == 404

API

ks33requests

ks33requests package

Subpackages
ks33requests.schemas package
Module contents
Submodules
ks33requests.auth module
ks33requests.auth.generate_auth_headers(http_verb: str, access_key: str, secret_key: str, canonical_resource: str, content_md5: str = '') → Dict[str, str]

生成公共响应头的签名

参数
  • http_verb (str) – 请求的方法,如: GET, PUT, POST, DELETE

  • access_key (str) – KS3 颁发给您的 AccessKey (长度为20个字符的ASCII字符串)。用于标识客户的身份。

  • secret_key (str) – KS3 颁发给您的 SecretKey (长度为40个字符的ASCII字符串)。作为私钥形式存放于客户服务器不在网络中传递。

  • canonical_resource (str) –

    表示用户访问的资源

  • content_md5 (str) –

    表示请求内容数据的MD5值, 使用Base64编码。

    当请求的header中包含Content-MD5时,需要在StringToSign中包含,否则用(“”)替代。

    注解

    Content-MD5 的算法为先对数据做MD5摘要,再将MD5摘要做Base64编码。 中间不需要做HEX编码,由于部分语言或工具包的MD5是默认做HEX编码的,所以当MD5算出来的结果为HEX编码的,首先需要对算出来的结果做HEX解码,然后再做Base64编码。

    参见

    详解见 RFC2616

返回

HTTP 请求中的 DateAuthorization 头域

返回类型

Dict[str,str]

ks33requests.auth.make_canonical_resource_string(bucket_name: str = '', object_key: str = '', sub_resources: Union[str, List[str], None] = None) → str

CanonicalizedResource 的计算方法

参数
  • bucket_name (str) – 用户请求的Bucket名称。

  • object_key (str) – 用户请求的Object名称,需要对Object名称做URL编码。

  • sub_resources (Optional[Union[str,List[str]]]) – 用户请求的子资源列表。

返回

CanonicalizedResource 字符串表示用户访问的资源,将作为 HTTP 请求的 URL 的一部分

返回类型

str

计算方法如下:

  1. CanonicalizedResource="/"

  2. 如果 BucketName 不为空,则 CanonicalizedResource = CanonicalizedResource + BucketName + "/"

  3. 如果 ObjectKey 不为空,则 CanonicalizedResource = CanonicalizedResource + ObjectKey

  4. 替换 CanonicalizedResource 中的双斜杠("//")为 "/%2F"

  5. 如果 SubResource 不为空,则 CanonicalizedResource = CanonicalizedResource + "?" + SubResource

ks33requests.client module
ks33requests.client.get_s3obj(resp: requests.models.Response)

读取 KS3 返回的 HTTP 响应正文,并转换为 Amazon S3 结构的对象

参数

resp (requests.Response) – 由 Client.send() 返回的 HTTP 响应对象

返回

S3 对象

参见

返回对象的结构定义来自 http://s3.amazonaws.com/doc/2006-03-01/AmazonS3.xsd

注解

如果返回的 HTTP 响应没有正文,该函数返回值为 None

class ks33requests.client.Client(access_key: str = None, secret_key: str = None, endpoint: str = 'kss.ksyun.com', session: requests.sessions.Session = None, use_https: bool = True)

基类:object

KS3 的“客户端”

它提供了对 金山云对象存储(KS3)的 HTTP API 的简单封装,轻微提升了操作方便性。

API 详见 https://docs.ksyun.com/documents/2321

参数
  • access_key (str) – KS3 颁发给您的 AccessKey (长度为20个字符的ASCII字符串)。用于标识客户的身份。

  • secret_key (str) – KS3 颁发给您的 SecretKey (长度为40个字符的ASCII字符串)。作为私钥形式存放于客户服务器不在网络中传递。

  • endpoint (str) – endpoint 对应 Region(区域)

  • session (requests.Session) – requests 会话。如果不指定,将由 requests 自动管理。

  • use_https (bool) – 是否使用 HTTPS。默认启用。

property endpoint

Endpoint

返回类型

str

send(method: str = 'get', bucket_name: str = None, object_key: str = None, sub_resources: Union[str, List[str]] = None, data=None, encoding: str = None, content_md5: str = None, headers: Dict[str, str] = None, params: Dict[str, str] = None, check_status: bool = True, session: requests.sessions.Session = None, **kwargs) → requests.models.Response

向 KS3 发送一个 HTTP API 请求,并返回对应的 HTTP 响应对象

参数
  • method (str) – HTTP 方法

  • bucket_name (str) –

    Bucket是存放Object的容器,所有的Object都必须存放在特定的Bucket中。

    每个用户最多可以创建30个Bucket,每个Bucket中可以存放无限多个Object。 Bucket不能嵌套,每个Bucket中只能存放Object,不能再存放Bucket,Bucket下的Object是一个平级的结构。 Bucket的名称全局唯一且命名规则与DNS命名规则相同:

    • 仅包含小写英文字母(a-z),数字,点(.),中线,即: abcdefghijklmnopqrstuvwxyz0123456789.-

    • 必须由字母或数字开头

    • 长度在3和63个字符之间

    • 不能是IP的形式,类似 192.168.0.1

    • 不能以 kss 开头

  • object_key (str) –

    在KS3中,用户操作的基本数据单元是Object。

    单个Object允许存储0~50TB的数据。 Object 包含key和data。 其中,key是Object的名字;data是Object 的数据。 key为UTF-8编码,且编码后的长度不得超过1024个字节。

  • sub_resources (Union[str, List[str]]) –

    用户请求的子资源

    把URL参数中的:

    "acl","lifecycle","location","logging","notification","partNumber","policy","requestPayment","torrent","uploadId","uploads","versionId","versioning","versions","website","delete","thumbnail","cors","queryadp","adp","asyntask","querytask","domain","response-content-type","response-content-language","response-expires","response-cache-control","response-content-disposition","response-content-encoding"
    

    筛选出来,将这些查询字符串及其请求值(不做URL编码的请求值)按照字典序,从小到大排列,以&为分隔符排列,即可得到SubResource。

    使用时,可以传入:

    • 单个子资源字符串

    • 子资源字符串的列表

    • 计算好了的 SubResource 字符串

  • data

    上传内容。可以使 requestsPOSTPUT 支持的任何类型

    如: 要写入的文件,要设置的 ACL 规则,等等……

    注解

    仅在 method 参数 为 "PUT""POST" 时有效。

  • encoding (str) – 上传内容编码,对字符类型有效。默认自动获取。

  • content_md5 (str) –

    用户自行计算的上传内容的 MD5 散列值对应的 BASE64 字符串。默认自动计算。

    注解

    默认值为 None ,将自动计算。但是,如果传入空字符串 ("") ,将以空字符串覆盖校验值(不校验)。

  • headers (Dict[str, str]) – 自定义 HTTP 头域键值对

  • params (Dict[str, str]) – 自定义 URL 参数键值对

  • check_status (bool) – 是否在收到 HTTP 回复的第一行时检查状态码

  • session (requests.Session) – 使用指定的会话发送 API 请求。默认自动分配。

  • kwargs – 其它传给 requests 的参数

返回

HTTP 响应对象

警告

此时尚未接收 HTTP 响应的内容,可使用 requests.Response 的一系列方法/属性获取正文,如:

返回类型

requests.Response

引发
property session

用户指定的 requests.Session

返回类型

requests.Session

property use_https

是否启用 HTTPS

返回类型

bool

ks33requests.errors module
exception ks33requests.errors.Ks3Error(status: int, code: str, message: str, resource: str, request_id: str)

基类:Exception

KS3 返回的 HTTP 响应带有 HTTP 错误状态码

property code

错误编码

返回类型

int

property message

错误信息

返回类型

str

property request_id

引起错误的资源 ID

返回类型

str

property resource

引起错误的资源

返回类型

str

property status

HTTP 状态码

返回类型

int

ks33requests.errors.raise_for_ks3_status(resp: requests.models.Response)

检查 KS3 返回的 HTTP 响应,如果状态码可以识别为错误信息,则抛出异常

参数

resp (requests.Response) – 要检查的 HTTP 响应对象

引发

Ks3Error – 如果检查到了 KS3 定义的 HTTP 错误状态码

警告

这个函数仅检查可几个按照 KS3 文档定义的 HTTP 错误状态码,并 不检查其它错误 状态编码 。 可调用 requests.Response.raise_for_status() 检查其它 HTTP 错误状态码。

ks33requests.utils module
ks33requests.utils.http_format_date(dt: datetime.datetime = None) → str

生成 HTTP 头的日期时间字符串

参数

dt (datetime) –

要转换的时间日期

default

None - 当前时间

返回

转换后的满足 HTTP 格式要求的时间日期字符串

返回类型

str

ks33requests.utils.prepare_data(data: Union[bytes, bytearray, str, pathlib.Path, io.BufferedIOBase, io.TextIOBase], checking: bool = True, encoding: str = None) → Tuple[Union[bytes, bytearray, io.BufferedIOBase], Optional[str]]

为 API 准备要进行 POST 或 PUT 的数据,包括 KS3 API 的通用请求部分所需的 Content-MD5

参数
返回类型

Tuple[Union[bytes, bytearray, io.BufferedIOBase], Optional[str]]

返回

返回元组 (data, md5): 转换后的数据,以及该数据的MD5散列值的BASE64编码结果字符串

为了让 requests 上传数据,这个函数尝试转换 data 参数。 如果传入的 data 参数类型不支持,将直接原样返回 data,且 MD5 为 None

Content-MD5 的算法为先对数据做MD5摘要,再将MD5摘要做Base64编码。 中间不需要做HEX编码,由于部分语言或工具包的MD5是默认做HEX编码的,所以当MD5算出来的结果为HEX编码的,首先需要对算出来的结果做HEX解码,然后再做Base64编码。

ks33requests.utils.get_content_md5(data: Union[bytes, bytearray, str, pathlib.Path, io.BufferedIOBase, io.TextIOBase], encoding: str = None) → str

获取 KS3 API 的通用请求部分所需的 Content-MD5

参数
返回类型

str

返回

该数据的MD5散列值的BASE64编码结果字符串

Content-MD5 的算法为先对数据做MD5摘要,再将MD5摘要做Base64编码。 中间不需要做HEX编码,由于部分语言或工具包的MD5是默认做HEX编码的,所以当MD5算出来的结果为HEX编码的,首先需要对算出来的结果做HEX解码,然后再做Base64编码。

Module contents

Indices and tables