Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加了python sdk三鉴功能 #312

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/video_pulp.py
Original file line number Diff line number Diff line change
@@ -0,0 1,18 @@
# -*- coding: utf-8 -*-
# flake8: noqa
from qiniu import QiniuMacAuth, video_pulp

# 对已经上传到七牛的视频发起异步转码操作
access_key = 'Access_Key'
secret_key = 'Secret_Key'
q = QiniuMacAuth(access_key, secret_key)


url = '' # 要鉴别的视频地址
video_id = '' # 视频的唯一ID


ret, info = video_pulp(q, video_id, url)

print(info)
assert 'pulp' in ret
12 changes: 12 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 1,12 @@
from qiniu import Auth, DomainManager

access_key = ''
secret_key = ''

at = Auth(access_key, secret_key)

dm = DomainManager(at)

for ret, resp_info in dm.get_domain_list(limit=100):
for domain in ret['domains']:
print(domain['name'])
1 change: 1 addition & 0 deletions qiniu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 24,7 @@
from .services.processing.cmd import build_op, pipe_cmd, op_save
from .services.compute.app import AccountClient
from .services.compute.qcos_api import QcosClient
from .services.appraisal.pulp import video_pulp, video_terror, video_politician, video_appraisal, AppraisalOperation

from .services.pili.rtc_server_manager import RtcServer, get_room_token

Expand Down
5 changes: 4 additions & 1 deletion qiniu/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 6,7 @@

from requests.auth import AuthBase

from .compat import urlparse, json, b
from .compat import urlparse, json, b, s
from .utils import urlsafe_base64_encode


Expand Down Expand Up @@ -56,6 56,9 @@ def __init__(self, access_key, secret_key):
self.__access_key = access_key
self.__secret_key = b(secret_key)

def get_secret_key(self):
return s(self.__secret_key)

def get_access_key(self):
return self.__access_key

Expand Down
1 change: 1 addition & 0 deletions qiniu/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,7 @@
RS_HOST = 'http://rs.qbox.me' # 管理操作Host
RSF_HOST = 'http://rsf.qbox.me' # 列举操作Host
API_HOST = 'http://api.qiniu.com' # 数据处理操作Host
BUCKET_RS_HOST = 'http://rs.qiniu.com' # 获取bucket信息

_BLOCK_SIZE = 1024 * 1024 * 4 # 断点续上传分块大小,该参数为接口规格,暂不支持修改

Expand Down
14 changes: 9 additions & 5 deletions qiniu/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 111,18 @@ def _post_with_auth_and_headers(url, data, auth, headers):
def _put_with_auth(url, data, auth):
return _put(url, data, None, qiniu.auth.RequestsAuth(auth))


def _put_with_auth_and_headers(url, data, auth, headers):
return _put(url, data, None, qiniu.auth.RequestsAuth(auth), headers)


def _post_with_qiniu_mac(url, data, auth):
def _post_with_qiniu_mac(url, data, auth, headers=None):
post_headers = _headers.copy()
if headers is not None:
for k, v in headers.items():
post_headers.update({k: v})
access_key = auth.get_access_key()
secret_key = auth.get_secret_key()
qn_auth = qiniu.auth.QiniuMacRequestsAuth(
auth) if auth is not None else None
qiniu.auth.QiniuMacAuth(access_key, secret_key)) if auth is not None else None
timeout = config.get_default('connection_timeout')

try:
Expand All @@ -127,7 131,7 @@ def _post_with_qiniu_mac(url, data, auth):
json=data,
auth=qn_auth,
timeout=timeout,
headers=_headers)
headers=post_headers)
except Exception as e:
return None, ResponseInfo(None, e)
return __return_wrapper(r)
Expand Down
Empty file.
102 changes: 102 additions & 0 deletions qiniu/services/appraisal/pulp.py
Original file line number Diff line number Diff line change
@@ -0,0 1,102 @@
# -*- coding: utf-8 -*-
from qiniu.http import _post_with_qiniu_mac
from qiniu.auth import QiniuMacAuth


class AppraisalOperation(object):
'''视频审核的动作(鉴黄,鉴恐, 鉴政治人物)'''
ops = ("pulp", "terror", "politician")

def __init__(self, op, hook_url="", params=None):
if op not in self.ops:
raise ValueError("op must be in %s" % self.ops)
if params is not None and not isinstance(params, dict):
raise TypeError("params must be dict: %s" % params)
self.op = op
self.hook_url = hook_url
self.params = params

def __str__(self):
return 'op: %s\nhook_url: %s\nparams: %s\n' % (self.op, self.hook_url, self.params)


def video_appraisal(auth, vid, url, ops, params=None):
"""
@vid 视频唯一的ID
@url 视频鉴黄的地址
@params 字典,视频处理的参数
@ops 视频检测命令 [AppraisalOperation...]
具体参数格式参考:
https://developer.qiniu.com/dora/manual/4258/video-pulp'''
"""
if params is not None:
if not isinstance(params, dict):
raise TypeError("params must be instance of dict, invalid params: %s" % params)
if not isinstance(ops, list):
raise TypeError("ops must be instance of list, invalid ops: %s" % ops)
if len(ops) <= 0:
raise ValueError("length of ops must greater than zero")
if not isinstance(auth, QiniuMacAuth):
raise TypeError("auth must be instance of QiniuMacAuth")

def getop(operation):
d = {
"op": operation.op,
}
if operation.hook_url:
d["hookURL"] = operation.hook_url
if operation.params:
d["params"] = operation.params
return d

ops = [getop(op) for op in ops]

if params:
data = {
"data": {
"uri": url,
},
"params": params
}
else:
data = {
"data": {
"uri": url,
},
}
data['ops'] = ops

return _post_with_qiniu_mac("http://argus.atlab.ai/v1/video/%s" % vid, data, auth)


def video_pulp(auth, vid, url, op=None, params=None):
if op is None:
op = AppraisalOperation("pulp")
else:
if not isinstance(op, AppraisalOperation):
raise TypeError("op must be instance of AppraisalOperation: %s" % op)
if op.op != "pulp":
raise ValueError("pulp appraisal operation must be pulp: %s" % op.op)
return video_appraisal(auth, vid, url, [op], params)


def video_terror(auth, vid, url, op=None, params=None):
if op is None:
op = AppraisalOperation("terror")
else:
if not isinstance(op, AppraisalOperation):
raise TypeError("op must be instance of AppraisalOperation: %s" % op)
if op.op != "politician":
raise ValueError("terror appraisal operation must be terror: %s" % op.op)
return video_appraisal(auth, vid, url, [op], params)


def video_politician(auth, vid, url, op=None, params=None):
if op is None:
op = AppraisalOperation("politician")
else:
if not isinstance(op, AppraisalOperation):
raise TypeError("op must be instance of AppraisalOperation: %s" % op)
if op.op != "politician":
raise ValueError("politician appraisal operation must be politician: %s" % op.op)
return video_appraisal(auth, vid, url, [op], params)
25 changes: 24 additions & 1 deletion qiniu/services/cdn/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 212,26 @@ def get_domain(self, name):
- ResponseInfo 请求的Response信息
"""
url = '{0}/domain/{1}'.format(self.server, name)
return self.__post(url)
return self.__get(url)

def get_domain_list(self, marker="", limit=100):
"""
获取域名信息,文档 https://developer.qiniu.com/fusion/api/4246/the-domain-name

Args:
name: 域名, 如果是泛域名,必须以点号 . 开头
Returns:
返回一个tuple对象,其格式为(<result>, <ResponseInfo>)
- result 成功返回dict{},失败返回{"error": "<errMsg string>"}
- ResponseInfo 请求的Response信息
"""
url = '{0}/domain'.format(self.server)
ret, respInfo = self.__get(url, params={"marker": marker, "limit": limit})
yield ret, respInfo

if ret.get("marker", ""):
for result in self.get_domain_list(marker=ret['marker'], limit=limit):
yield result

def put_httpsconf(self, name, certid, forceHttps):
"""
Expand Down Expand Up @@ -264,6 283,10 @@ def __post(self, url, data=None):
headers = {'Content-Type': 'application/json'}
return http._post_with_auth_and_headers(url, data, self.auth, headers)

def __get(self, url, params=None):
headers = {'Content-Type': 'application/json'}
return http._get(url, params, self.auth)

def __put(self, url, data=None):
headers = {'Content-Type': 'application/json'}
return http._put_with_auth_and_headers(url, data, self.auth, headers)
Expand Down
53 changes: 53 additions & 0 deletions qiniu/services/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 161,49 @@ def copy(self, bucket, key, bucket_to, key_to, force='false'):
to = entry(bucket_to, key_to)
return self.__rs_do('copy', resource, to, 'force/{0}'.format(force))

def async_fetch(self, urls, bucket, host=None, key=None, md5=None, etag=None, callback_url=None,
callback_body=None, callback_body_type=None, callback_host=None, file_type=0):
"""异步抓取文件:
从指定URL抓取资源,并将该资源存储到指定空间中,具体规格参考:
https://developer.qiniu.com/kodo/api/4097/asynch-fetch

Args:
url: 指定的URL
bucket: 目标资源空间
key: 目标资源文件名

Returns:
一个dict变量,成功返回NULL,失败返回{"error": "<errMsg string>"}
一个ResponseInfo对象
"""
data = {"url": ";".join(urls), "bucket": bucket}
if host:
data["host"] = host
if md5:
data["md5"] = md5
if key:
data["key"] = key
if etag:
data["etag"] = etag
if callback_url:
data["callbackurl"] = callback_url
if callback_body:
data["callbackbody"] = callback_body
if callback_body_type:
data["callbackbodytype"] = callback_body_type
if callback_host:
data["callbackhost"] = callback_host
if file_type:
data["file_type"] = file_type

api_host = self.zone.get_api_host(bucket, self.auth)
url = "http://%s/%s" % (api_host, "sisyphus/fetch")
return http._post_with_qiniu_mac(url, data, self.auth, headers={
"Host": api_host,
"Content-Type": "application/json",
})


def fetch(self, url, bucket, key=None):
"""抓取文件:
从指定URL抓取资源,并将该资源存储到指定空间中,具体规格参考:
Expand Down Expand Up @@ -348,3 391,13 @@ def _two_key_batch(operation, source_bucket, key_pairs, target_bucket, force='fa
target_bucket = source_bucket
return [_build_op(operation, entry(source_bucket, k), entry(target_bucket, v), 'force/{0}'.format(force)) for k, v
in key_pairs.items()]


def get_bucket_info(bucket, auth):
"""
Args:
bucket - 存储空间名字
获取存储空间所在的存储区域
"""
url = '%s/bucket/%s' % (config.BUCKET_RS_HOST, bucket)
return http._post_with_auth_and_headers(url, None, auth, headers={"Content-Type": "application/x-www-form-urlencoded"})
9 changes: 9 additions & 0 deletions qiniu/zone.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,7 @@
import requests
from qiniu import compat
from qiniu import utils
from qiniu.services.storage.bucket import get_bucket_info

UC_HOST = 'https://uc.qbox.me' # 获取空间信息Host

Expand All @@ -24,6 25,7 @@ def __init__(
up_host=None,
up_host_backup=None,
io_host=None,
api_host=None,
host_cache={},
scheme="http",
home_dir=os.getcwd()):
Expand Down Expand Up @@ -58,6 60,13 @@ def get_up_host(self, ak, bucket):
up_hosts = bucket_hosts['upHosts']
return up_hosts

def get_api_host(self, bucket, auth):
ret, resp_info = get_bucket_info(bucket, auth)
if ret:
return "api-%s.qiniu.com" % ret['region']
else:
raise ValueError(ret)

def unmarshal_up_token(self, up_token):
token = up_token.split(':')
if (len(token) != 3):
Expand Down