def dict_to_xml(data): """V5使用xml格式,将输入的dict转换为xml""" doc = xml.dom.minidom.Document() root = doc.createElement('CompleteMultipartUpload') doc.appendChild(root) if 'Part' not in data.keys(): raise CosClientError("Invalid Parameter, Part Is Required!") for i in data['Part']: nodePart = doc.createElement('Part') if 'PartNumber' not in i.keys(): raise CosClientError("Invalid Parameter, PartNumber Is Required!") nodeNumber = doc.createElement('PartNumber') nodeNumber.appendChild(doc.createTextNode(str(i['PartNumber']))) if 'ETag' not in i.keys(): raise CosClientError("Invalid Parameter, ETag Is Required!") nodeETag = doc.createElement('ETag') nodeETag.appendChild(doc.createTextNode(str(i['ETag']))) nodePart.appendChild(nodeNumber) nodePart.appendChild(nodeETag) root.appendChild(nodePart) return doc.toxml('utf-8')
def format_path(path): """检查path是否合法,格式化path""" if not isinstance(path, str): raise CosClientError("your Key is not str") if path == "": raise CosClientError("Key can't be empty string") if path[0] == '/': path = path[1:] # 提前对path进行encode path = quote(path, '/-_.~') return path
def gen_copy_source_url(self, CopySource): """拼接拷贝源url""" if 'Bucket' in CopySource.keys(): bucket = CopySource['Bucket'] else: raise CosClientError('CopySource Need Parameter Bucket') if 'Key' in CopySource.keys(): key = CopySource['Key'] else: raise CosClientError('CopySource Need Parameter Key') url = self._conf.uri(bucket=bucket, path=key).encode('utf8') url = url[7:] # copysource不支持http://开头,去除 return url
def format_region(region): """格式化地域""" if not region: raise CosClientError("region is required not empty!") if region.find('cos.') != -1: return region # 传入cos.ap-beijing-1这样显示加上cos.的region if region == 'cn-north' or region == 'cn-south' or region == 'cn-east' or region == 'cn-south-2' or region == 'cn-southwest' or region == 'sg': return region # 老域名不能加cos. # 支持v4域名映射到v5 if region == 'cossh': return 'cos.ap-shanghai' if region == 'cosgz': return 'cos.ap-guangzhou' if region == 'cosbj': return 'cos.ap-beijing' if region == 'costj': return 'cos.ap-beijing-1' if region == 'coscd': return 'cos.ap-chengdu' if region == 'cossgp': return 'cos.ap-singapore' if region == 'coshk': return 'cos.ap-hongkong' if region == 'cosca': return 'cos.na-toronto' if region == 'cosger': return 'cos.eu-frankfurt' return 'cos.' + region # 新域名加上cos.
def mapped(headers): """S3到COS参数的一个映射""" _headers = dict() for i in headers.keys(): if i in maplist: _headers[maplist[i]] = headers[i] else: raise CosClientError('No Parameter Named '+i+' Please Check It') return _headers
def format_bucket(bucket, appid): """兼容新老bucket长短命名,appid为空默认为长命名,appid不为空则认为是短命名""" if not isinstance(bucket, str): raise CosClientError("bucket is not str") # appid为空直接返回bucket if not appid: return bucket # appid不为空,检查是否以-appid结尾 if bucket.endswith("-"+appid): return bucket return bucket + "-" + appid
def get_copy_source_info(CopySource): """获取拷贝源的所有信息""" appid = "" if 'Appid' in CopySource.keys(): appid = CopySource['Appid'] if 'Bucket' in CopySource.keys(): bucket = CopySource['Bucket'] bucket = format_bucket(bucket, appid) else: raise CosClientError('CopySource Need Parameter Bucket') if 'Region' in CopySource.keys(): region = CopySource['Region'] region = format_region(region) else: raise CosClientError('CopySource Need Parameter Region') if 'Key' in CopySource.keys(): path = CopySource['Key'] else: raise CosClientError('CopySource Need Parameter Key') return bucket, path, region
def get_content_md5(body): body_type = type(body) if body_type == str: return get_md5(body) elif body_type == file: if hasattr(body, 'tell') and hasattr(body, 'seek') and hasattr(body, 'read'): file_position = body.tell() # 记录文件当前位置 md5_str = get_md5(body.read()) body.seek(file_position) # 恢复初始的文件位置 return md5_str else: raise CosClientError('can not get md5 digest for file without necessary attrs, including tell, seek and read') return None
def send_request(self, method, url, timeout=30, **kwargs): if self._conf._token is not None: kwargs['headers']['x-cos-security-token'] = self._conf._token kwargs['headers']['User-Agent'] = 'cos-python-sdk-v5' try: for j in range(self._retry): if method == 'POST': res = self._session.post(url, timeout=timeout, **kwargs) elif method == 'GET': res = self._session.get(url, timeout=timeout, **kwargs) elif method == 'PUT': res = self._session.put(url, timeout=timeout, **kwargs) elif method == 'DELETE': res = self._session.delete(url, timeout=timeout, **kwargs) elif method == 'HEAD': res = self._session.head(url, timeout=timeout, **kwargs) if res.status_code < 300: return res except Exception as e: # 捕获requests抛出的如timeout等客户端错误,转化为客户端错误 logger.exception('url:%s, exception:%s' % (url, str(e))) raise CosClientError(str(e)) if res.status_code >= 400: # 所有的4XX,5XX都认为是COSServiceError if method == 'HEAD' and res.status_code == 404: # Head 需要处理 info = dict() info['code'] = 'NoSuchResource' info['message'] = 'The Resource You Head Not Exist' info['resource'] = url info['requestid'] = res.headers['x-cos-request-id'] info['traceid'] = res.headers['x-cos-trace-id'] logger.error(info) raise CosServiceError(method, info, res.status_code) else: msg = res.text if msg == '': # 服务器没有返回Error Body时 给出头部的信息 msg = res.headers logger.error(msg) raise CosServiceError(method, msg, res.status_code)