def stream_upload(self,ucloud_file_name,stream): """ 文件上传 ucloud_file_name: 在ucloud的名字 localfile_path_name:在本地的路径和名字 状态码描述: 200:文件或者数据上传成功 400:上传到不存在的空间 403:API公私钥错误 401:上传凭证错误 :return: """ public_bucket = 'louxia' # 公共空间名称 # localfile = 'C:/Users/86130/Pictures/BlueDream_4k.jpg' # 本地文件名 putufile_handler = filemanager.FileManager(self.public_key, self.private_key) # 普通上传二进制数据流至公共空间 # with open(localfile_path_name, 'rb') as f: # a = f.read() byte_stream = BytesIO(stream) # 二进制数据流 stream_key = '{}'.format(ucloud_file_name) # 上传数据流在空间中的名称 ret, resp = putufile_handler.putstream(public_bucket, stream_key, byte_stream) print(resp.status_code) if resp.status_code == 200: return True else: return False
def upload(self,ucloud_file_name,localfile_path_name): """ 文件上传 ucloud_file_name: 在ucloud的名字 localfile_path_name:在本地的路径和名字 状态码描述: 200:文件或者数据上传成功 400:上传到不存在的空间 403:API公私钥错误 401:上传凭证错误 :return: """ public_bucket = 'louxia' # 公共空间名称 # localfile = 'C:/Users/86130/Pictures/BlueDream_4k.jpg' # 本地文件名 put_key = '{}'.format(ucloud_file_name) # 上传文件在空间中的名称,是目录 putufile_handler = filemanager.FileManager(self.public_key, self.private_key) # 普通上传文件至公共空间 ret, resp = putufile_handler.putfile(public_bucket, put_key, localfile_path_name, header=None) print(resp.status_code) # assert resp.status_code == 200 if resp.status_code == 200: return True else: return False
class RenameUFileTestCase(unittest.TestCase): renameufile_handler = filemanager.FileManager(public_key, private_key) def test_renamefile(self): self.renameufile_handler.set_keys(public_key, private_key) logger.info('start rename file') ret, resp = self.renameufile_handler.rename(public_bucket, key, newkey, force) assert resp.status_code == 200
def head(bucket, key, header): # 构造下载对象,并设置公私钥 handler = filemanager.FileManager(PUBLIC_KEY, PRIVATE_KEY) _, resp = handler.head_file(bucket, key, header=header) if resp.status_code != 200: print(resp.error) raise HeadFailed() print("Success: ", bucket, key, resp)
class CopyUFileTestCase(unittest.TestCase): copyufile_handler = filemanager.FileManager(public_key, private_key) def test_copyfile(self): self.copyufile_handler.set_keys(public_key, private_key) logger.info('start copy file') ret, resp = self.copyufile_handler.copy(public_bucket, key, srcbucket, srckey) assert resp.status_code == 200
def all_delect(public_bucket, public_key, private_key): hello_file = filemanager.FileManager(public_key, private_key) ret, resp = hello_file.getfilelist(public_bucket) while dict(ret)["DataSet"]: for i in dict(ret)["DataSet"]: cloudfile_name = dict(i)["FileName"] hello_file.deletefile(public_bucket, cloudfile_name) # print(cloudfile_name) ret, resp = hello_file.getfilelist(public_bucket) print('删除完成,请移步控制台手动删除bucket')
def download(bucket, key, local_file, header): # 构造下载对象,并设置公私钥 handler = filemanager.FileManager(PUBLIC_KEY, PRIVATE_KEY) if local_file == '-': local_file = '/dev/stdout' _, resp = handler.download_file(bucket, key, local_file, header=header) if resp.status_code != 200: print(resp.error) raise DownloadFailed()
def qiniu_test( access_key, secret_key, bucket_name, bucket_domain, u_bucket_name, u_publickey, u_privatekey): PickleDBPathSucc = os.path.join(BASE_DIR, bucket_name + 'succ.db') PickleDBPathFail = os.path.join(BASE_DIR, bucket_name + 'fail.db') db_succ = pickledb.load(PickleDBPathSucc, False) db_fail = pickledb.load(PickleDBPathFail, False) q = Auth(access_key, secret_key) u_handler = filemanager.FileManager(u_publickey, u_privatekey) # 枚举当前bucket下所有文件 bucket = BucketManager(q) ret, eof, info = bucket.list(bucket_name) base_url_pattern = 'http://%s/%s' for item in ret['items']: # 对已抓取过的七牛(bucket,key)进行dedup去重 if db_succ.get(item['key']) == True: continue base_url = base_url_pattern % (bucket_domain, item['key']) private_url = q.private_download_url(base_url) print(private_url) try: print(item['key'], '正在抓取') r = requests.get(private_url, stream=True) if r.status_code == 200: file_path = os.path.join(TMP_DIR, item['key']) f = open(file_path, 'wb') for chunk in r.iter_content(chunk_size=4096): if chunk: f.write(chunk) f.close() print(item['key'], '结束写入') ret, resp = u_handler.putfile(u_bucket_name, item['key'], file_path) if resp.status_code == 200: # 本地记录ufile写入成功的key db_succ.set(item['key'], True) else: db_fail.set(item['key'], True) else: db_fail.set(item['key'], True) except: db_fail.set(item['key'], True) db_succ.dump() db_fail.dump()
def poke(self, context): self.log.info('Poking for file ufile://%s/%s', self.bucket_name, self.filepath) config.set_default(uploadsuffix=self.upload_suffix) filemanager_handler=filemanager.FileManager(self.public_key, self.private_key) try: ret, resp=filemanager_handler.getfilelist(self.bucket_name, self.filepath) return bool('DataSet' in ret and len(ret['DataSet'])>0) except Exception: e = sys.exc_info() self.log.debug("Caught an exception !: %s", str(e)) return False
def put_file(localfile: str, put_key: str): # 传入本地文件路径、文件云上空间名称,将文件上传至ufile putufile_handler = filemanager.FileManager(public_key, private_key) # 普通上传文件至公共空间 ret, resp = putufile_handler.putfile(public_bucket, put_key, localfile, header=None) assert resp.status_code == 200 download_addr = 'http://high-quality-sausages.cn-sh2.ufileos.com/' + put_key return download_addr
def download(self,ucloud_file_name,localfile_path_name): """ 文件下载 ucloud_file_name: 在ucloud的名字 localfile_path_name:在本地的路径和名字 状态码描述: 200:文件或者数据下载成功 206:文件或者数据范围下载成功 400:不存在的空间 403:API公私钥错误 401:下载签名错误 404:下载文件或数据不存在 416:文件范围请求不合法 :return: 改成数据流形式的下载(改源码): httprequest.py文件的185行改成以下 blocks = bytes() if response.status_code in [200, 206]: # with open(localfile, 'wb') as fd: for block in response.iter_content(config.BLOCKSIZE): # fd.write(block) blocks += block else: return __return_wraper(response) return __return_wraper(response, True),BytesIO(blocks) # 二进制数据流blocks 改本方法的代码: (ret, resp),byte_stream = downloadufile_handler.download_file(public_bucket, put_key,localfile_path_name, isprivate=False) print(resp.status_code) roiImg = Image.open(byte_stream) # 图片保存 roiImg.save(localfile_path_name) if resp.status_code == 200: return byte_stream else: return False """ public_bucket = 'louxia' # 公共空间名称 public_savefile = '' # 保存文件名 range_savefile = '' # 保存文件名 # put_key = 'store_ass/{}'.format(ucloud_file_name) # 文件在空间中的名称 put_key = '{}'.format(ucloud_file_name) # 文件在空间中的名称,是目录 stream_key = '' # 文件在空间中的名称 downloadufile_handler = filemanager.FileManager(self.public_key, self.private_key) # 从公共空间下载文件 ret, resp = downloadufile_handler.download_file(public_bucket, put_key,localfile_path_name, isprivate=False) print(resp.status_code) if resp.status_code == 200: return True else: return False
def put_file(localfile: str, put_key: str): # 增 传入本地文件路径、文件云上空间名称,将文件上传至ufile putufile_handler = filemanager.FileManager(public_key, private_key) # 普通上传文件至公共空间 ret, resp = putufile_handler.putfile(public_bucket, put_key, localfile, header=None) assert resp.status_code == 200 download_addr = 'http://{0}.{1}.ufileos.com/'.format( public_bucket, region) + put_key print('下载链接:', download_addr) return download_addr
class DownloadUFileTestCase(unittest.TestCase): downloadufile_handler = filemanager.FileManager(public_key, private_key) def test_downloadpublic(self): self.downloadufile_handler.set_keys(public_key, private_key) # download the small file logger.info('\nstart download small file from public bucket') ret, resp = self.downloadufile_handler.download_file(public_bucket, put_key, public_download, isprivate=False) assert resp.status_code == 200 def test_downloadprivate(self): self.downloadufile_handler.set_keys(public_key, private_key) # download the small file logger.info('start download small file from private bucket') ret, resp = self.downloadufile_handler.download_file( private_bucket, put_key, private_download) assert resp.status_code == 200 def test_downloadwithrange(self): self.downloadufile_handler.set_keys(public_key, private_key) logger.info('start download with range condition from public bucket') ret, resp = self.downloadufile_handler.download_file( public_bucket, put_range_key, public_range_download, isprivate=False, expires=get_default('expires'), content_range=(0, 15), header=None) assert resp.status_code == 206 logger.info('start download with range condition from private bucket') ret, resp = self.downloadufile_handler.download_file( private_bucket, put_range_key, private_range_download, isprivate=True, expires=get_default('expires'), content_range=(0, 15), header=None) assert resp.status_code == 206 @classmethod def tearDownClass(cls): os.remove(public_download) os.remove(public_range_download) os.remove(private_download) os.remove(private_range_download)
class UploadHitUFileTestCase(unittest.TestCase): uploadhitufile_handler = filemanager.FileManager(public_key, private_key) def test_uploadhitexistfile(self): self.uploadhitufile_handler.set_keys(public_key, private_key) logger.info('start uploadhit existfile') ret, resp = self.uploadhitufile_handler.uploadhit(public_bucket, existkey, existfile) assert resp.status_code == 200 def test_uploadhitnonexistfile(self): self.uploadhitufile_handler.set_keys(public_key, private_key) logger.info('start uploadhit existfile') ret, resp = self.uploadhitufile_handler.uploadhit(public_bucket, nonexistkey, nonexistfile) assert resp.status_code == 404
class GetFileListTestCase(unittest.TestCase): getfilelist_hander = filemanager.FileManager(public_key, private_key) def test_getfilelist(self): self.getfilelist_hander.set_keys(public_key, private_key) prefix = '' limit = 100 marker = '' ret, resp = self.getfilelist_hander.getfilelist(bucket, prefix=prefix, limit=limit, marker=marker) assert resp.status_code == 200 for item in ret['DataSet']: key = item['FileName'].encode('utf-8') logger.info(key) nextMarker = ret['NextMarker'] logger.info('NextMarker is {0}'.format(nextMarker))
class DeleteUFileTestCase(unittest.TestCase): deleteufile_handler = filemanager.FileManager(public_key, private_key) def test_deleteufile(self): self.deleteufile_handler.set_keys(public_key, private_key) # delete file from public bucket logger.info('\ndelete file from public bucket') ret, resp = self.deleteufile_handler.deletefile(public_bucket, delete_key) logger.info(resp.error) logger.info(resp.status_code) #assert resp.status_code == 204 # delete file from private bucket logger.info('\ndelete file from private bucket') ret, resp = self.deleteufile_handler.deletefile(private_bucket, delete_key) logger.info(resp.error) logger.info(resp.status_code)
class PostUFileTestCase(unittest.TestCase): postfile_handler = filemanager.FileManager(public_key, private_key) def test_postufile(self): self.postfile_handler.set_keys(public_key, private_key) # post small file to public bucket logger.info('\nstart post small file to public bucket') ret, resp = self.postfile_handler.postfile(public_bucket, post_small_key, small_local_file) assert resp.status_code == 200 # post small file to private bucket logger.info('\nstart post small file to private bucket') ret, resp = self.postfile_handler.postfile(private_bucket, post_small_key, small_local_file) assert resp.status_code == 200
def upload_put(bucket, key, local_file, header): # 构造上传对象,并设置公私钥 handler = filemanager.FileManager(PUBLIC_KEY, PRIVATE_KEY) if local_file == '-': fileno = sys.stdin.fileno() with open(fileno, "rb", closefd=False) as input_stream: _, resp = handler.putstream(bucket, key, input_stream, header=header, mime_type='application/octec-stream') else: _, resp = handler.putfile(bucket, key, local_file, header=header) if resp.status_code != 200: print(resp.error) raise UploadFailed()
class BatchUploadUFileTestCase(unittest.TestCase): putufile_handler = filemanager.FileManager(public_key, private_key) def putfile_thread(self, sem, bucket, key, local_file, header=None): for i in range(1, 4): try: ret, resp = self.putufile_handler.putfile( bucket, key, local_file, header) if resp.status_code != 200: logger.error( 'put file {0} failed. err: {1}, retry {2}'.format( key, resp, i)) continue else: logger.info('put file {0} succeed.'.format(key)) break except Exception as e: logger.error('put file {0} failed. exception: {1}'.format( key, e)) sem.release() def test_batchupload(self): self.putufile_handler.set_keys(public_key, private_key) path = "/home/temp/" dirs = os.listdir(path) sem = threading.Semaphore(maxthreads) for root, dirs, files in os.walk(path): for file in files: sem.acquire() local_file = os.path.join(root, file) thread = threading.Thread(target=self.putfile_thread, args=(sem, bucket, put_key_prefix + local_file, local_file)) thread.start() while threading.active_count() > 1: time.sleep(1)
def delete(self,ucloud_file_name): """ 删除文件 状态码含义: 204: 文件或者数据删除成功 403: API公私钥错误 401: 签名错误 :return: """ public_bucket = 'louxia' # 公共空间名称 delete_key = '{}'.format(ucloud_file_name) # 文件在空间中的名称,是目录 deleteufile_handler = filemanager.FileManager(self.public_key, self.private_key) # 删除公共空间的文件 ret, resp = deleteufile_handler.deletefile(public_bucket, delete_key) # assert resp.status_code == 204 print(resp.status_code) if resp.status_code == 204: return True else: return False
class PutUFileTestCase(unittest.TestCase): putufile_handler = filemanager.FileManager(PUBLIC_KEY, PRIVATE_KEY) def test_putufile(self): self.putufile_handler.set_keys(PUBLIC_KEY, PRIVATE_KEY) # put small file to public bucket logger.info('\nput small file to public bucket') ret, resp = self.putufile_handler.putfile(PUBLIC_BUCKET, put_small_key, small_local_file) assert resp.status_code == 200 # put small file to private bucket logger.info('\nput small file to private bucket') ret, resp = self.putufile_handler.putfile(PRIVATE_BUCKET, put_small_key, small_local_file) assert resp.status_code == 200 def test_putstream(self): self.putufile_handler.set_keys(PUBLIC_KEY, PRIVATE_KEY) logger.info('\nput stream to public bucket') ret, resp = self.putufile_handler.putstream(PUBLIC_BUCKET, put_stream_key, bio) assert resp.status_code == 200 bio.seek(0, os.SEEK_SET) logger.info('\nput stream to private bucket') ret, resp = self.putufile_handler.putstream(PRIVATE_BUCKET, put_stream_key, bio) logger.info('response code:{0}'.format(resp.status_code)) assert resp.status_code == 200 def test_compareetag(self): result = self.putufile_handler.compare_file_etag( PUBLIC_BUCKET, put_small_key, small_local_file) if result == True: logger.info('\netag are the same!') else: logger.info('\netag are different!')
class ListObjectsTestCase(unittest.TestCase): listobjects_hander = filemanager.FileManager(public_key, private_key) def test_listobjects(self): self.listobjects_hander.set_keys(public_key, private_key) prefix = '' marker = '' maxkeys = 100 ret, resp = self.listobjects_hander.listobjects(bucket, prefix=prefix, maxkeys=maxkeys, marker=marker, delimiter='/') assert resp.status_code == 200 logger.info('Contents:') for item in ret['Contents']: key = item['Key'].encode('utf-8') logger.info('key: {0}'.format(key)) logger.info('CommonPrefixes: ') for item in ret['CommonPrefixes']: pre = item['Prefix'].encode('utf-8') logger.info('prefix: {0}'.format(pre)) nextMarker = ret['NextMarker'] logger.info('NextMarker is {0}'.format(nextMarker))
class ArchiveOperateTestCase(unittest.TestCase): """ 目前支持三种存储类型:STANDARD(标准)、IA(低频)、ARCHIVE(冷存) 上传时需要携带 X-Ufile-Storage-Class http请求头指定上传文件的存储类型 """ putufile_handler = filemanager.FileManager(public_key, private_key) multipartuploadufile_handler = multipartuploadufile.MultipartUploadUFile( public_key, private_key) postfile_handler = filemanager.FileManager(public_key, private_key) restorefile_handler = filemanager.FileManager(public_key, private_key) classswitch_handler = filemanager.FileManager(public_key, private_key) def test_upload_ia_ufile(self): #使用put方式上传低频文件 self.putufile_handler.set_keys(public_key, private_key) #设置header header = dict() header['X-Ufile-Storage-Class'] = IA # upload file to public bucket logger.info('\nstart put small file to public bucket') ret, resp = self.putufile_handler.putfile(public_bucket, put_ia_key, small_local_file, header) assert resp.status_code == 200 # put small file to private bucket logger.info('\nstart put small file to private bucket') ret, resp = self.putufile_handler.putfile(private_bucket, put_ia_key, small_local_file, header) assert resp.status_code == 200 def test_upload_archive_ufile(self): #使用分片上传方式上传冷存文件 self.multipartuploadufile_handler.set_keys(public_key, private_key) #设置header header = dict() header['X-Ufile-Storage-Class'] = ARCHIVE # upload big file to public bucket logger.info('start sharding upload big file to public bucket') ret, resp = self.multipartuploadufile_handler.uploadfile( public_bucket, mput_archive_key, big_local_file, header=header) print(resp.error) assert resp.status_code == 200 # upload big file to private bucket logger.info('start sharding upload big file to private bucket') ret, resp = self.multipartuploadufile_handler.uploadfile( private_bucket, mput_archive_key, big_local_file, header=header) print(resp.error) assert resp.status_code == 200 def test_upload_standard_ufile(self): #使用post方式上传标准文件 self.postfile_handler.set_keys(public_key, private_key) #设置header header = dict() header['X-Ufile-Storage-Class'] = STANDARD # post small file to public bucket logger.info('\nstart post small file to public bucket') ret, resp = self.postfile_handler.postfile(public_bucket, post_standard_key, small_local_file, header) assert resp.status_code == 200 # post small file to private bucket logger.info('\nstart post small file to private bucket') ret, resp = self.postfile_handler.postfile(private_bucket, post_standard_key, small_local_file, header) assert resp.status_code == 200 def test_restore_file(self): #解冻冷存文件 self.restorefile_handler.set_keys(public_key, private_key) # restore archive file in public bucket logger.info('start restore archive file to public bucket') ret, resp = self.restorefile_handler.restore_file( public_bucket, mput_archive_key) print(resp.error) assert resp.status_code == 200 def test_classswitch_file(self): #转换文件存储类型 self.classswitch_handler.set_keys(public_key, private_key) # file storage class switch to IA in private bucket logger.info('start switch file storage class in private bucket') ret, resp = self.classswitch_handler.class_switch_file( private_bucket, post_standard_key, IA) print(resp.error) assert resp.status_code == 200
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 head_key = '' #文件在空间中的名称 from ufile import filemanager headfile_handler = filemanager.FileManager(public_key, private_key) # 查询文件基本信息 ret, resp = headfile_handler.head_file(bucket, head_key) assert resp.status_code == 200 print(resp)
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 local_file = '' #本地文件名 put_key = '' #上传文件在空间中的名称 STANDARD = 'STANDARD' #标准文件类型 IA = 'IA' #低频文件类型 from ufile import filemanager putufile_handler = filemanager.FileManager(public_key, private_key) classswitch_handler = filemanager.FileManager(public_key, private_key) # 普通上传文件至空间 header = dict() header['X-Ufile-Storage-Class'] = STANDARD ret, resp = putufile_handler.putfile(bucket, put_key, local_file, header=header) assert resp.status_code == 200 # 标准文件类型转换为低频文件类型 ret, resp = classswitch_handler.class_switch_file(bucket, put_key, IA) assert resp.status_code == 200
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 local_file = '' #本地文件名 put_key = '' #上传文件在空间中的名称 from ufile import filemanager putufile_handler = filemanager.FileManager(public_key, private_key) # 普通上传文件至空间 ret, resp = putufile_handler.putfile(bucket, put_key, local_file, header=None) assert resp.status_code == 200 # 普通上传二进制数据流至空间 from io import BytesIO bio = BytesIO(u'Do be a good man'.encode('utf-8')) #二进制数据流 stream_key = '' #上传数据流在空间中的名称 ret, resp = putufile_handler.putstream(bucket, stream_key, bio) assert resp.status_code == 200 # 普通上传文件到所在region为上海二的空间 SH2_bucket = '' SH2_UPLOAD_SUFFIX = '.cn-sh2.ufileos.com' filemgr_sh = filemanager.FileManager(public_key, private_key, upload_suffix=SH2_UPLOAD_SUFFIX) ret, resp = filemgr_sh.putfile(SH2_bucket, put_key, local_file, header=None) assert resp.status_code == 200
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 local_file = '' #本地文件名 put_key = '' #上传文件在空间中的名称 ARCHIVE = 'ARCHIVE' #归档文件类型 from ufile import filemanager putufile_handler = filemanager.FileManager(public_key, private_key) restorefile_handler = filemanager.FileManager(public_key, private_key) # 普通上传归档类型的文件至空间 header = dict() header['X-Ufile-Storage-Class'] = ARCHIVE ret, resp = putufile_handler.putfile(bucket, put_key, local_file, header=header) assert resp.status_code == 200 # 解冻归档类型的文件 ret, resp = restorefile_handler.restore_file(bucket, put_key) assert resp.status_code == 200 # 文件解冻一般在10s以内 time.sleep(10) # 查看归档文件解冻状态 ret, resp = restorefile_handler.getfilelist(bucket, put_key)
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 from ufile import filemanager getfilelist_hander = filemanager.FileManager(public_key, private_key) prefix = '' #文件前缀 limit = 10 #文件列表数目 marker = '' #返回以字母排序后,大于marker的文件列表 ret, resp = getfilelist_hander.getfilelist(bucket, prefix=prefix, limit=limit, marker=marker) assert resp.status_code == 200 for object in ret["DataSet"]: print(object) # 根据返回值'NextMarker'循环遍历获得所有结果(若一次查询无法获得所有结果) while True: ret, resp = getfilelist_hander.getfilelist(bucket, prefix=prefix, limit=limit, marker=marker) assert resp.status_code == 200 for object in ret["DataSet"]: # print(object)
# coding:utf-8 from ufile import filemanager from ufile import config import os config.set_default(uploadsuffix='.cn-gd.ufileos.com') config.set_default(connection_timeout=60) public_key = 'TOKEN_84e97dbe-7092-47aa-8d1a-f131ebcbb944' private_key = '02878b78-9957-4943-ac8e-54c661612a87' public_bucket = 'letugame' upload_handler = filemanager.FileManager(public_key, private_key) project_name = "letugame" source_res_dir = "update_build" class SearchFile: def __init__(self): self.fileList = [] self.recursiveDir(source_res_dir) def recursiveDir(self, srcPath): ''' 递归指定目录下的所有文件''' dirList = [] # 所有文件夹 # print srcPath files = os.listdir(srcPath) # 返回指定目录下的所有文件,及目录(不含子目录) # print files for f in files:
public_key = '' #账户公钥 private_key = '' #账户私钥 bucket = '' #空间名称 from ufile import filemanager listobjects_hander = filemanager.FileManager(public_key, private_key) prefix = '' #以prefix作为前缀的目录文件列表 maxkeys = 100 #指定返回目录文件列表的最大数量,默认值为100,不超过1000 marker = '' #返回以字母排序后,大于marker的目录文件列表 delimiter = '/' #delimiter是目录分隔符,当前只支持"/"和"",当Delimiter设置为"/"且prefiex以"/"结尾时,返回prefix目录下的子文件,当delimiter设置为""时,返回以prefix作为前缀的文件 # 普通使用(一次查询即可得到所有结果) def once_list(): ret, resp = listobjects_hander.listobjects(bucket, prefix=prefix, maxkeys=maxkeys, marker=marker, delimiter=delimiter) assert resp.status_code == 200 for object in ret['Contents']: #子文件列表 print(object) for object in ret['CommonPrefixes']: #子目录列表 print(object)