├── .github └── workflows │ └── auto-changelog.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── MANIFEST.in ├── README.rst ├── demo ├── ai_recognition_demo.py ├── batch_operation_demo.py ├── bucket_acl.py ├── bucket_cors.py ├── bucket_domain.py ├── bucket_inventory.py ├── bucket_lifecycle.py ├── bucket_logging.py ├── bucket_operation.py ├── bucket_policy.py ├── bucket_referer.py ├── bucket_replication.py ├── bucket_tagging.py ├── bucket_versioning.py ├── bucket_website.py ├── ci_audit.py ├── ci_compress.py ├── ci_doc_preview.py ├── ci_file_process.py ├── ci_image.py ├── ci_media.py ├── ci_speech_recognition.py ├── ci_template.py ├── ci_watermark.py ├── client_encrypt.py ├── copy_object.py ├── delete_object.py ├── demo.py ├── dir_download_demo.py ├── disaster_recovery_demo.py ├── download_object.py ├── fetch_demo.py ├── get_object_url.py ├── get_presigned_url.py ├── head_object.py ├── hls_decrypt_token.py ├── list_objects.py ├── meta_insight_demo.py ├── modify_object_meta.py ├── object_acl.py ├── object_exists.py ├── object_tagging.py ├── restore_object.py ├── select_object.py ├── server_bucket_encrypt.py ├── server_object_encrypt.py ├── tce_demo.py ├── traffic_limit.py └── upload_object.py ├── qcloud_cos ├── .travis.yml ├── __init__.py ├── ai_recognition.py ├── cos_auth.py ├── cos_client.py ├── cos_comm.py ├── cos_encryption_client.py ├── cos_exception.py ├── cos_threadpool.py ├── crypto.py ├── meta_insight.py ├── resumable_downloader.py ├── select_event_stream.py ├── streambody.py ├── version.py └── xml2dict.py ├── requirements.txt ├── setup.py └── ut ├── __init__.py └── test.py /.github/workflows/auto-changelog.yml: -------------------------------------------------------------------------------- 1 | name: ChangeLog 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [published] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/setup-node@v2-beta 15 | with: 16 | node-version: '12' 17 | - uses: actions/checkout@v2 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Checkout Tool 22 | uses: actions/checkout@v2 23 | with: 24 | repository: konakonall/auto-changelog 25 | path: 'auto-changelog' 26 | - name: Build Tool 27 | run: | 28 | cd auto-changelog 29 | npm install 30 | npm link 31 | 32 | - name: Generate ChangeLog 33 | env: # Or as an environment variable 34 | TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | run: | 36 | auto-changelog --token $TOKEN 37 | - name: Cat ChangeLog 38 | run: cat CHANGELOG.md 39 | 40 | - name: Commit files 41 | env: 42 | CI_USER: "gouki0123" 43 | CI_EMAIL: "gouki0123@gmail.com" 44 | run: | 45 | git config --local user.email "$CI_EMAIL" 46 | git config --local user.name "$CI_USER" 47 | git add CHANGELOG.md && git commit -m 'Updated CHANGELOG.md' && echo "push=1" >> $GITHUB_ENV || echo "No changes to CHANGELOG.md" 48 | 49 | - name: Push changes 50 | if: env.push == 1 51 | env: 52 | CI_USER: "gouki0123" 53 | CI_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | run: | 55 | git push "https://$CI_USER:$CI_TOKEN@github.com/$GITHUB_REPOSITORY.git" HEAD:master 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | ignore/ 3 | .vscode/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | dist: xenial 4 | python: 5 | - '2.7' 6 | - '3.5' 7 | - '3.6' 8 | - '3.8' 9 | - '3.9' 10 | - '3.9' 11 | dist: focal 12 | - '3.10' 13 | dist: focal 14 | install: 15 | - pip install requests 16 | - pip install six 17 | - pip install nose 18 | - pip install pycodestyle 19 | - pip install importlib_metadata 20 | - pip install xmltodict 21 | - pip install crcmod 22 | - pip install pycryptodome 23 | notifications: 24 | email: 25 | recipients: 26 | - wjielai@tencent.com 27 | - fysntian@tencent.com 28 | script: 29 | - pycodestyle --max-line-length=200 qcloud_cos/. 30 | - pycodestyle --max-line-length=200 ut/. 31 | - nosetests -s -v ut/ 32 | deploy: 33 | provider: pypi 34 | distributions: sdist bdist_wheel 35 | user: dt3310321 36 | password: 37 | secure: JCBE84C22lHElRm7HmIf//UI123EuiFznEFPoVMPlRGb/XBrtYb+x1SRaO7Dn165CfVDpXtdNbJYfD9s2p3FUKzxSqkwl7FkkSl2g1jwKO97gKBPGxozBN+9pOJLTQUXBwON+erJSpMCHxrUjKKZBi56mUYXPP+A1X8sIHFMF4rLdPSuobjx0VGm2qFWhFeuLFPNOfF5ZKQDCnieptBLhrMXRcxyhZja/HsQh/JOjnMKZAmgJep2w2hI7ScYeTF0Ljk3RQbSN88HjZ7XP+U3bhiy5IE2u0WhJr6Q1OwxIuw8EIP+5mBNELT8Q5AMDnR85ehOVf67nl8j0nCiLzS55t1wuFHWExwW4kKF0dLpeV/fj3huFwQuAYItgZzCA/h3Fne6D3omjknd1uvWcUQzzXU1ixdeuq8XoDYxF8eox3GWQ/jbZY8lLXQ1BhaMK5E/MY8DJs1S+i6I1mJ34rCcnRYS1R3zZAJryaFxI6UsEAniXu4ESI+da7KD4y4TC0hY4RlcFyqQ0OVeeXoclQytRfgIT+EPZHt1mAr8qinmy5K2GoVcWwEj54AXp4LwiOosve6vqdeXjR/EeGy3zWjEfhn5B4z8UMLyGS/S1k3rSpV85KB4nLuzKGlyUkC2sjGr/xiG7CBC1UCbqx1CGLlCZ/HvEmKvuSrbJNbsgBNU/og= 38 | on: 39 | tags: true 40 | branch: master 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 腾讯云 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | include *.md 3 | exclude ut/* 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Qcloud COSv5 SDK 2 | ####################### 3 | 4 | .. image:: https://img.shields.io/pypi/v/cos-python-sdk-v5.svg 5 | :target: https://pypi.org/search/?q=cos-python-sdk-v5 6 | :alt: Pypi 7 | .. image:: https://api.travis-ci.com/tencentyun/cos-python-sdk-v5.svg?branch=master 8 | :target: https://app.travis-ci.com/github/tencentyun/cos-python-sdk-v5 9 | :alt: Travis CI 10 | 11 | 介绍 12 | _______ 13 | 14 | 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x。 15 | 16 | 安装指南 17 | __________ 18 | 19 | 使用pip安装 :: 20 | 21 | pip install -U cos-python-sdk-v5 22 | 23 | 手动安装:: 24 | 25 | python setup.py install 26 | 27 | 使用方法 28 | __________ 29 | 30 | 使用python sdk,参照 https://github.com/tencentyun/cos-python-sdk-v5/blob/master/demo/demo.py 31 | 32 | cos最新可用地域,参照 https://cloud.tencent.com/document/product/436/6224 33 | 34 | python sdk 快速入门,参照 https://cloud.tencent.com/document/product/436/12269 35 | 36 | python sdk 接口文档,参照 https://cloud.tencent.com/document/product/436/12270 37 | -------------------------------------------------------------------------------- /demo/batch_operation_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | 3 | ''' 4 | 此demo演示批处理操作: 5 | 1. 删除cos目录 6 | 2. 多线程上传本地目录下的文件 7 | 3. 批量删除cos对象 8 | 4. 移动对象 9 | ''' 10 | 11 | from qcloud_cos import CosConfig 12 | from qcloud_cos import CosS3Client 13 | from qcloud_cos import CosServiceError 14 | from qcloud_cos import CosClientError 15 | from qcloud_cos.cos_exception import CosException 16 | from qcloud_cos.cos_threadpool import SimpleThreadPool 17 | 18 | import sys 19 | import os 20 | import logging 21 | 22 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 23 | 24 | # pip安装指南:pip install -U cos-python-sdk-v5 25 | 26 | # cos最新可用地域,参照https://www.qcloud.com/document/product/436/6224 27 | 28 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 29 | 30 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 31 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 32 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 33 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 34 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 35 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 36 | 37 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 38 | client = CosS3Client(config) 39 | 40 | bucket = 'examplebucket-1250000000' 41 | 42 | # 删除目录 43 | # 对象存储中,目录是特殊的路径以‘/’结尾的object。调用Delete Object接口即可 44 | try: 45 | to_delete_dir = 'path/to/delete/dir/' 46 | response = client.delete_object( 47 | Bucket=bucket, 48 | Key=to_delete_dir, 49 | ) 50 | print(response) 51 | except CosServiceError as e: 52 | print(e.get_status_code()) 53 | 54 | uploadDir = '/root/logs' 55 | 56 | g = os.walk(uploadDir) 57 | # 创建上传的线程池 58 | pool = SimpleThreadPool() 59 | for path, dir_list, file_list in g: 60 | for file_name in file_list: 61 | srcKey = os.path.join(path, file_name) 62 | cosObjectKey = srcKey.strip('/') 63 | # 判断COS上文件是否存在 64 | exists = False 65 | try: 66 | response = client.head_object(Bucket=bucket, Key=cosObjectKey) 67 | exists = True 68 | except CosServiceError as e: 69 | if e.get_status_code() == 404: 70 | exists = False 71 | else: 72 | print("Error happened, reupload it.") 73 | if not exists: 74 | print("File %s not exists in cos, upload it", srcKey) 75 | pool.add_task(client.upload_file, bucket, cosObjectKey, srcKey) 76 | 77 | pool.wait_completion() 78 | result = pool.get_result() 79 | if not result['success_all']: 80 | print("Not all files upload sucessed. you should retry") 81 | 82 | # 删除指定前缀 (prefix)的文件 83 | is_over = False 84 | marker = '' 85 | prefix = 'root/logs' 86 | while not is_over: 87 | try: 88 | response = client.list_objects(Bucket=bucket, Prefix=prefix, Marker=marker) 89 | if response['Contents']: 90 | for content in response['Contents']: 91 | print("delete object: ", content['Key']) 92 | client.delete_object(Bucket=bucket, Key=content['Key']) 93 | 94 | if response['IsTruncated'] == 'false': 95 | is_over = True 96 | marker = response['Marker'] 97 | 98 | except CosServiceError as e: 99 | print(e.get_origin_msg()) 100 | print(e.get_digest_msg()) 101 | print(e.get_status_code()) 102 | print(e.get_error_code()) 103 | print(e.get_error_msg()) 104 | print(e.get_resource_location()) 105 | print(e.get_trace_id()) 106 | print(e.get_request_id()) 107 | break 108 | 109 | # 移动对象 110 | srcKey = 'demo.py' # 原始的对象路径 111 | destKey = 'dest_object_key' # 目的对象路径 112 | 113 | try: 114 | response = client.copy_object( 115 | Bucket=bucket, 116 | Key=destKey, 117 | CopySource={ 118 | 'Bucket': bucket, 119 | 'Key': srcKey, 120 | 'Region': 'ap-guangzhou', 121 | }) 122 | client.delete_object(Bucket=bucket, Key=srcKey) 123 | except CosException as e: 124 | print(e.get_error_msg()) 125 | -------------------------------------------------------------------------------- /demo/bucket_acl.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置存储桶 ACL 23 | response = client.put_bucket_acl( 24 | Bucket='examplebucket-1250000000', 25 | ACL='public-read' 26 | ) 27 | 28 | # 查询存储桶 ACL 29 | response = client.get_bucket_acl( 30 | Bucket='examplebucket-1250000000' 31 | ) 32 | -------------------------------------------------------------------------------- /demo/bucket_cors.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置跨域配置 23 | response = client.put_bucket_cors( 24 | Bucket='examplebucket-1250000000', 25 | CORSConfiguration={ 26 | 'CORSRule': [ 27 | { 28 | 'ID': 'string', 29 | 'MaxAgeSeconds': 100, 30 | 'AllowedOrigin': [ 31 | 'string', 32 | ], 33 | 'AllowedMethod': [ 34 | 'string', 35 | ], 36 | 'AllowedHeader': [ 37 | 'string', 38 | ], 39 | 'ExposeHeader': [ 40 | 'string', 41 | ] 42 | } 43 | ] 44 | }, 45 | ) 46 | 47 | # 查询跨域配置 48 | response = client.get_bucket_cors( 49 | Bucket='examplebucket-1250000000', 50 | ) 51 | 52 | # 删除跨域配置 53 | response = client.delete_bucket_cors( 54 | Bucket='examplebucket-1250000000', 55 | ) 56 | -------------------------------------------------------------------------------- /demo/bucket_domain.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置自定义域名 23 | response = client.put_bucket_domain( 24 | Bucket='bucket', 25 | DomainConfiguration={ 26 | 'DomainRule': [ 27 | { 28 | 'Name': 'example.com', 29 | 'Type': 'REST'|'WEBSITE'|'ACCELERATE', 30 | 'Status': 'ENABLED'|'DISABLED', 31 | 'ForcedReplacement': 'CNAME'|'TXT' 32 | }, 33 | ] 34 | } 35 | ) 36 | 37 | # 查询自定义域名 38 | response = client.get_bucket_domain( 39 | Bucket='examplebucket-1250000000' 40 | ) 41 | 42 | # 删除自定义域名 43 | response = client.delete_bucket_domain( 44 | Bucket='examplebucket-1250000000' 45 | ) 46 | -------------------------------------------------------------------------------- /demo/bucket_inventory.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置清单任务 23 | response = client.put_bucket_inventory( 24 | Bucket='examplebucket-1250000000', 25 | Id='string', 26 | InventoryConfiguration={ 27 | 'Destination': { 28 | 'COSBucketDestination': { 29 | 'AccountId': '100000000001', 30 | 'Bucket': 'qcs::cos:ap-guangzhou::examplebucket-1250000000', 31 | 'Format': 'CSV', 32 | 'Prefix': 'string', 33 | 'Encryption': { 34 | 'SSECOS': {} 35 | } 36 | } 37 | }, 38 | 'IsEnabled': 'true'|'false', 39 | 'Filter': { 40 | 'Prefix': 'string' 41 | }, 42 | 'IncludedObjectVersions':'All'|'Current', 43 | 'OptionalFields': { 44 | 'Field': [ 45 | 'Size', 46 | 'LastModifiedDate', 47 | 'ETag', 48 | 'StorageClass', 49 | 'IsMultipartUploaded', 50 | 'ReplicationStatus' 51 | ] 52 | }, 53 | 'Schedule': { 54 | 'Frequency': 'Daily'|'Weekly' 55 | } 56 | } 57 | ) 58 | 59 | # 查询清单任务 60 | response = client.get_bucket_inventory( 61 | Bucket='examplebucket-1250000000', 62 | Id='string' 63 | ) 64 | 65 | # 列举清单任务 66 | continuation_token = '' 67 | while True: 68 | resp = client.list_bucket_inventory_configurations( 69 | Bucket='examplebucket-1250000000', 70 | ContinuationToken=continuation_token, 71 | ) 72 | if 'InventoryConfiguration' in resp: 73 | for conf in resp['InventoryConfiguration']: 74 | print(conf) 75 | 76 | if resp['IsTruncated'] == 'true': 77 | continuation_token = resp['NextContinuationToken'] 78 | else: 79 | break 80 | 81 | # 删除清单任务 82 | response = client.delete_bucket_inventory( 83 | Bucket='examplebucket-1250000000', 84 | Id='string' 85 | ) 86 | -------------------------------------------------------------------------------- /demo/bucket_lifecycle.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置生命周期 23 | response = client.put_bucket_lifecycle( 24 | Bucket='examplebucket-1250000000', 25 | LifecycleConfiguration={ 26 | 'Rule': [ 27 | { 28 | 'ID': 'string', # 设置规则的 ID,例如Rule-1 29 | 'Filter': { 30 | 'Prefix': '' # 配置前缀为空,桶内所有对象都会执行此规则 31 | }, 32 | 'Status': 'Enabled', # Enabled 表示启用规则 33 | 'Expiration': { 34 | 'Days': 200 # 设置对象的当前版本200天后过期删除 35 | }, 36 | 'Transition': [ 37 | { 38 | 'Days': 100, # 设置对象的当前版本100天后沉降 39 | 'StorageClass': 'Standard_IA' # 沉降为低频存储 40 | }, 41 | ], 42 | 'AbortIncompleteMultipartUpload': { 43 | 'DaysAfterInitiation': 7 # 设置7天后回收未合并的分块 44 | } 45 | } 46 | ] 47 | } 48 | ) 49 | 50 | # 查询生命周期 51 | response = client.get_bucket_lifecycle( 52 | Bucket='examplebucket-1250000000', 53 | ) 54 | 55 | # 删除生命周期 56 | response = client.delete_bucket_lifecycle( 57 | Bucket='examplebucket-1250000000', 58 | ) 59 | 60 | -------------------------------------------------------------------------------- /demo/bucket_logging.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置日志管理 23 | response = client.put_bucket_logging( 24 | Bucket='examplebucket-1250000000', 25 | BucketLoggingStatus={ 26 | 'LoggingEnabled': { 27 | 'TargetBucket': 'logging-bucket-1250000000', 28 | 'TargetPrefix': 'string' 29 | } 30 | } 31 | ) 32 | 33 | # 查询日志管理 34 | response = client.get_bucket_logging( 35 | Bucket='examplebucket-1250000000' 36 | ) 37 | -------------------------------------------------------------------------------- /demo/bucket_operation.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用INFO,需要定位时可以修改为DEBUG,此时SDK会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS支持的所有region列表参见https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 查询存储桶列表 23 | response = client.list_buckets() 24 | print(response) 25 | 26 | # 创建存储桶 27 | # 存储桶名称不支持大写字母,COS 后端会将用户传入的大写字母自动转换为小写字母用于创建存储桶 28 | response = client.create_bucket( 29 | Bucket='examplebucket-1250000000' 30 | ) 31 | 32 | # 检索存储桶及其权限 33 | response = client.head_bucket( 34 | Bucket='examplebucket-1250000000' 35 | ) 36 | 37 | # 删除存储桶 38 | response = client.delete_bucket( 39 | Bucket='examplebucket-1250000000' 40 | ) 41 | 42 | # 判断存储桶是否存在 43 | response = client.bucket_exists( 44 | Bucket='examplebucket-1250000000' 45 | ) 46 | print(response) 47 | -------------------------------------------------------------------------------- /demo/bucket_policy.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | import json 8 | 9 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 10 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 11 | 12 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 13 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 15 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 16 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 17 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 18 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 19 | 20 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 21 | client = CosS3Client(config) 22 | 23 | # 设置存储桶策略 24 | response = client.put_bucket_policy( 25 | Bucket='examplebucket-1250000000', 26 | Policy={ 27 | "Statement": [ 28 | { 29 | "Principal": { 30 | "qcs": [ 31 | "qcs::cam::uin/100000000001:uin/100000000011" 32 | ] 33 | }, 34 | "Effect": "allow", 35 | "Action": [ 36 | "name/cos:GetBucket" 37 | ], 38 | "Resource": [ 39 | "qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/*" 40 | ], 41 | "condition": { 42 | "ip_equal": { 43 | "qcs:ip": "10.121.2.10/24" 44 | } 45 | } 46 | } 47 | ], 48 | "version": "2.0" 49 | } 50 | ) 51 | 52 | # 查询存储桶策略 53 | response = client.get_bucket_policy( 54 | Bucket='examplebucket-1250000000', 55 | ) 56 | policy = json.loads(response['Policy']) 57 | 58 | # 删除存储桶策略 59 | response = client.delete_bucket_policy( 60 | Bucket='examplebucket-1250000000', 61 | ) 62 | -------------------------------------------------------------------------------- /demo/bucket_referer.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置存储桶 Referer 23 | referer_config = { 24 | 'Status': 'Enabled', 25 | 'RefererType': 'White-List', 26 | 'EmptyReferConfiguration': 'Allow', 27 | 'DomainList': { 28 | 'Domain': [ 29 | '*.qq.com', 30 | '*.qcloud.com' 31 | ] 32 | } 33 | } 34 | response = client.put_bucket_referer( 35 | Bucket='examplebucket-1250000000', 36 | RefererConfiguration=referer_config 37 | ) 38 | 39 | # 查询存储桶 Referer 40 | response = client.get_bucket_referer( 41 | Bucket='examplebucket-1250000000' 42 | ) 43 | 44 | # 删除存储桶 Referer 45 | response = client.delete_bucket_referer( 46 | Bucket='examplebucket-1250000000' 47 | ) -------------------------------------------------------------------------------- /demo/bucket_replication.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置存储桶复制 23 | response = client.put_bucket_replication( 24 | Bucket='examplebucket-1250000000', 25 | ReplicationConfiguration={ 26 | 'Role': 'qcs::cam::uin/100000000001:uin/100000000001', 27 | 'Rule': [ 28 | { 29 | 'ID': 'string', 30 | 'Status': 'Enabled', 31 | 'Destination': { 32 | 'Bucket': 'qcs::cos:ap-shanghai::destinationbucket-1250000000', 33 | 'StorageClass': 'STANDARD' 34 | } 35 | } 36 | ] 37 | } 38 | ) 39 | 40 | # 查询存储桶复制 41 | response = client.get_bucket_replication( 42 | Bucket='examplebucket-1250000000' 43 | ) 44 | print(response) 45 | 46 | # 删除存储桶复制 47 | response = client.delete_bucket_replication( 48 | Bucket='examplebucket-1250000000' 49 | ) 50 | -------------------------------------------------------------------------------- /demo/bucket_tagging.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置存储桶标签 23 | response = client.put_bucket_tagging( 24 | Bucket='examplebucket-1250000000', 25 | Tagging={ 26 | 'TagSet': { 27 | 'Tag': [ 28 | { 29 | 'Key': 'string', 30 | 'Value': 'string' 31 | }, 32 | ] 33 | } 34 | } 35 | ) 36 | 37 | # 查询存储桶标签 38 | response = client.get_bucket_tagging( 39 | Bucket='examplebucket-1250000000' 40 | ) 41 | 42 | # 删除存储桶标签 43 | response = client.delete_bucket_tagging( 44 | Bucket='examplebucket-1250000000' 45 | ) 46 | -------------------------------------------------------------------------------- /demo/bucket_versioning.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 开启版本控制 23 | response = client.put_bucket_versioning( 24 | Bucket='examplebucket-1250000000', 25 | Status='Enabled' 26 | ) 27 | 28 | # 暂停版本控制 29 | response = client.put_bucket_versioning( 30 | Bucket='examplebucket-1250000000', 31 | Status='Suspended' 32 | ) 33 | 34 | # 查询版本控制 35 | response = client.get_bucket_versioning( 36 | Bucket='examplebucket-1250000000', 37 | ) 38 | print(response) 39 | -------------------------------------------------------------------------------- /demo/bucket_website.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置静态网站 23 | response = client.put_bucket_website( 24 | Bucket='bucket', 25 | WebsiteConfiguration={ 26 | 'IndexDocument': { 27 | 'Suffix': 'string' 28 | }, 29 | 'ErrorDocument': { 30 | 'Key': 'string' 31 | }, 32 | 'RedirectAllRequestsTo': { 33 | 'Protocol': 'http'|'https' 34 | }, 35 | 'RoutingRules': [ 36 | { 37 | 'Condition': { 38 | 'HttpErrorCodeReturnedEquals': 'string', 39 | 'KeyPrefixEquals': 'string' 40 | }, 41 | 'Redirect': { 42 | 'HttpRedirectCode': 'string', 43 | 'Protocol': 'http'|'https', 44 | 'ReplaceKeyPrefixWith': 'string', 45 | 'ReplaceKeyWith': 'string' 46 | } 47 | } 48 | ] 49 | } 50 | ) 51 | 52 | # 查询静态网站配置 53 | response = client.get_bucket_website( 54 | Bucket='examplebucket-1250000000' 55 | ) 56 | 57 | # 删除静态网站配置 58 | response = client.delete_bucket_website( 59 | Bucket='examplebucket-1250000000' 60 | ) 61 | 62 | -------------------------------------------------------------------------------- /demo/ci_audit.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import base64 3 | import time 4 | 5 | from qcloud_cos import CosConfig 6 | from qcloud_cos import CosS3Client 7 | 8 | import os 9 | import sys 10 | import logging 11 | 12 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 13 | 14 | # 审核相关API 请参考如下文档 15 | # 图片审核 https://cloud.tencent.com/document/product/436/45434 16 | # 视频审核 https://cloud.tencent.com/document/product/436/47316 17 | # 音频审核 https://cloud.tencent.com/document/product/436/54063 18 | # 文本审核 https://cloud.tencent.com/document/product/436/56289 19 | # 文档审核 https://cloud.tencent.com/document/product/436/59381 20 | 21 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 22 | 23 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 24 | secret_id = os.environ["SECRETID"] # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 25 | secret_key = os.environ["SECRETKEY"] # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 26 | 27 | region = 'ap-chongqing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 28 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 29 | token = None 30 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme='https') # 获取配置对象 31 | client = CosS3Client(config) 32 | 33 | 34 | bucket_name = 'test-1250000000' 35 | 36 | 37 | def ci_auditing_video_submit(): 38 | freeze = { 39 | 'PornScore': 60, 40 | 'AdsScore': 50 41 | } 42 | response = client.ci_auditing_video_submit(Bucket=bucket_name, 43 | Key="test.mp4", 44 | Callback="http://www.demo.com", 45 | CallbackVersion='Simple', 46 | CallbackType=1, 47 | DetectContent=1, 48 | Mode='Interval', 49 | Count=1, 50 | TimeInterval=1, 51 | Freeze=freeze,) 52 | print(str(response)) 53 | 54 | 55 | def ci_auditing_video_query(): 56 | response = client.ci_auditing_video_query(Bucket=bucket_name, JobID="av6ef961d45c3711ee8ace525400198613") 57 | print(response) 58 | print(response['JobsDetail']['State']) 59 | 60 | 61 | def ci_auditing_image_batch(): 62 | user_info = { 63 | 'TokenId': '123456', # 一般用于表示账号信息,长度不超过128字节 64 | 'Nickname': '测试', # 一般用于表示昵称信息,长度不超过128字节 65 | 'DeviceId': '腾讯云', # 一般用于表示设备信息,长度不超过128字节 66 | 'AppId': '12500000', # 一般用于表示 App 的唯一标识,长度不超过128字节 67 | 'Room': '1', # 一般用于表示房间号信息,长度不超过128字节 68 | 'IP': '127.0.0.1', # 一般用于表示 IP 地址信息,长度不超过128字节 69 | 'Type': '测试', # 一般用于表示业务类型,长度不超过128字节 70 | 'ReceiveTokenId': '789123', # 一般用于表示接收消息的用户账号,长度不超过128字节 71 | 'Gender': '男', # 一般用于表示性别信息,长度不超过128字节 72 | 'Level': '100', # 一般用于表示等级信息,长度不超过128字节 73 | 'Role': '测试人员', # 一般用于表示角色信息,长度不超过128字节 74 | } 75 | input_info = [] 76 | input_info.append({ 77 | 'Object': 'test.png', # 存储在 COS 存储桶中的图片文件名称 78 | # 'Url': 'http://a-1250000.cos.ap-shanghai.myqcloud.com/image.jpg', # 图片文件的链接地址 79 | # 'Content': base64.b64encode('我是测试'.encode("utf-8")).decode('utf-8'), # 图片文件的内容,需要先经过 base64 编码 80 | # 'Interval': '5', # 截帧频率,GIF 图检测专用,默认值为5,表示从第一帧(包含)开始每隔5帧截取一帧。 81 | # 'MaxFrames': '5', # 最大截帧数量,GIF 图检测专用,默认值为5,表示只截取 GIF 的5帧图片进行审核,必须大于0。 82 | 'DataId': 'my data id', # 图片标识,该字段在结果中返回原始内容,长度限制为512字节。 83 | # 'LargeImageDetect': '0', # 对于超过大小限制的图片是否进行压缩后再审核,取值为: 0(不压缩),1(压缩)。默认为0。注:压缩最大支持32M的图片,且会收取压缩费用。 84 | 'UserInfo': user_info, # 用户业务字段。 85 | }) 86 | input_info.append({ 87 | 'Object': 'test.png', # 存储在 COS 存储桶中的图片文件名称 88 | # 'Url': 'http://a-1250000.cos.ap-shanghai.myqcloud.com/image.jpg', # 图片文件的链接地址 89 | # 'Content': base64.b64encode('我是测试1'.encode("utf-8")).decode('utf-8'), # 图片文件的内容,需要先经过 base64 编码 90 | # 'Interval': '5', # 截帧频率,GIF 图检测专用,默认值为5,表示从第一帧(包含)开始每隔5帧截取一帧。 91 | # 'MaxFrames': '5', # 最大截帧数量,GIF 图检测专用,默认值为5,表示只截取 GIF 的5帧图片进行审核,必须大于0。 92 | 'DataId': 'my data id', # 图片标识,该字段在结果中返回原始内容,长度限制为512字节。 93 | # 'LargeImageDetect': '0', # 对于超过大小限制的图片是否进行压缩后再审核,取值为: 0(不压缩),1(压缩)。默认为0。注:压缩最大支持32M的图片,且会收取压缩费用。 94 | 'UserInfo': user_info, # 用户业务字段。 95 | }) 96 | 97 | freeze = { 98 | 'PornScore': '50', # 取值为[0,100],表示当色情审核结果大于或等于该分数时,自动进行冻结操作。不填写则表示不自动冻结,默认值为空。 99 | 'AdsScore': '50' # 取值为[0,100],表示当广告审核结果大于或等于该分数时,自动进行冻结操作。不填写则表示不自动冻结,默认值为空。 100 | } 101 | response = client.ci_auditing_image_batch(Bucket=bucket_name, 102 | Input=input_info, 103 | BizType='', # 表示审核策略的唯一标识 104 | Async=0, # 是否异步进行审核 105 | Callback="http://www.demo.com", 106 | Freeze=freeze 107 | ) 108 | print(str(response)) 109 | 110 | 111 | def ci_live_video_auditing(): 112 | # 提交视频流审核任务 113 | storage_conf = { 114 | 'Path': '/test/' 115 | } 116 | response = client.ci_auditing_live_video_submit( 117 | Bucket=bucket_name, 118 | Url='rtmp://example.com/live/123', 119 | Callback='http://callback.com/', 120 | DataId='testdataid-111111', 121 | UserInfo={ 122 | 'TokenId': 'token', 123 | 'Nickname': 'test', 124 | 'DeviceId': 'DeviceId-test', 125 | 'AppId': 'AppId-test', 126 | 'Room': 'Room-test', 127 | 'IP': 'IP-test', 128 | 'Type': 'Type-test', 129 | }, 130 | BizType='d0292362d07428b4f6982a31bf97c246', 131 | CallbackType=1, 132 | StorageConf=storage_conf 133 | ) 134 | jobId = response['JobsDetail']['JobId'] 135 | time.sleep(5) 136 | kwargs = {"CacheControl": "no-cache", "ResponseCacheControl": "no-cache"} 137 | response = client.ci_auditing_live_video_cancle( 138 | Bucket=bucket_name, 139 | JobID=jobId, 140 | **kwargs 141 | ) 142 | print(response) 143 | 144 | 145 | def ci_auditing_virus_submit_and_query(): 146 | kwargs = {"CacheControl": "no-cache", "ResponseCacheControl": "no-cache"} 147 | response = client.ci_auditing_virus_submit(Bucket=bucket_name, 148 | Key="test.png", 149 | Callback="http://www.demo.com", 150 | **kwargs) 151 | jobId = response['JobsDetail']['JobId'] 152 | while True: 153 | time.sleep(5) 154 | kwargs = {"CacheControl": "no-cache", "ResponseCacheControl": "no-cache"} 155 | response = client.ci_auditing_virus_query(Bucket=bucket_name, JobID=jobId, **kwargs) 156 | print(response['JobsDetail']['State']) 157 | if response['JobsDetail']['State'] == 'Success': 158 | print(str(response)) 159 | break 160 | print(response) 161 | 162 | 163 | def ci_auditing_text_submit(): 164 | user_info = { 165 | 'TokenId': '123456', # 一般用于表示账号信息,长度不超过128字节 166 | 'Nickname': '测试', # 一般用于表示昵称信息,长度不超过128字节 167 | 'DeviceId': '腾讯云', # 一般用于表示设备信息,长度不超过128字节 168 | 'AppId': '12500000', # 一般用于表示 App 的唯一标识,长度不超过128字节 169 | 'Room': '1', # 一般用于表示房间号信息,长度不超过128字节 170 | 'IP': '127.0.0.1', # 一般用于表示 IP 地址信息,长度不超过128字节 171 | 'Type': '测试', # 一般用于表示业务类型,长度不超过128字节 172 | 'ReceiveTokenId': '789123', # 一般用于表示接收消息的用户账号,长度不超过128字节 173 | 'Gender': '男', # 一般用于表示性别信息,长度不超过128字节 174 | 'Level': '100', # 一般用于表示等级信息,长度不超过128字节 175 | 'Role': '测试人员', # 一般用于表示角色信息,长度不超过128字节 176 | } 177 | freeze = { 178 | 'PornScore': '50', # 取值为[0,100],表示当色情审核结果大于或等于该分数时,自动进行冻结操作。不填写则表示不自动冻结,默认值为空。 179 | 'AdsScore': '50' # 取值为[0,100],表示当广告审核结果大于或等于该分数时,自动进行冻结操作。不填写则表示不自动冻结,默认值为空。 180 | } 181 | response = client.ci_auditing_text_submit( 182 | Bucket=bucket_name, # 桶名称 183 | Content='123456test'.encode("utf-8"), # 需要审核的文本内容 184 | BizType='', # 表示审核策略的唯一标识 185 | UserInfo=user_info, # 用户业务字段 186 | DataId='456456456', # 待审核的数据进行唯一业务标识 187 | CallbackType=2, 188 | CallbackVersion='Detail', 189 | Callback='http://www.callback.com', 190 | Freeze=freeze 191 | ) 192 | print(response) 193 | 194 | 195 | def ci_auditing_text_txt_submit(): 196 | user_info = { 197 | 'TokenId': '123456', # 一般用于表示账号信息,长度不超过128字节 198 | 'Nickname': '测试', # 一般用于表示昵称信息,长度不超过128字节 199 | 'DeviceId': '腾讯云', # 一般用于表示设备信息,长度不超过128字节 200 | 'AppId': '12500000', # 一般用于表示 App 的唯一标识,长度不超过128字节 201 | 'Room': '1', # 一般用于表示房间号信息,长度不超过128字节 202 | 'IP': '127.0.0.1', # 一般用于表示 IP 地址信息,长度不超过128字节 203 | 'Type': '测试', # 一般用于表示业务类型,长度不超过128字节 204 | 'ReceiveTokenId': '789123', # 一般用于表示接收消息的用户账号,长度不超过128字节 205 | 'Gender': '男', # 一般用于表示性别信息,长度不超过128字节 206 | 'Level': '100', # 一般用于表示等级信息,长度不超过128字节 207 | 'Role': '测试人员', # 一般用于表示角色信息,长度不超过128字节 208 | } 209 | response = client.ci_auditing_text_submit( 210 | Bucket=bucket_name, # 桶名称 211 | # Content='123456test'.encode("utf-8"), # 需要审核的文本内容 212 | Key='shenhe.txt', 213 | Url='https://test-1250000000.cos.ap-chongqing.myqcloud.com/shenhe.txt?q-sign-algorithm=sha1&q-ak=AKIDPdbIjuoRt40g5D4ex0nKaaJlvoRKzNVN&q-sign-time=1690968685;1690975885&q-key-time=1690968685;1690975885&q-header-list=&q-url-param-list=&q-signature=c93b2350e946ad1d5336286221edc66e53f18989', 214 | BizType='', # 表示审核策略的唯一标识 215 | UserInfo=user_info, # 用户业务字段 216 | DataId='456456456', # 待审核的数据进行唯一业务标识 217 | ) 218 | print(response) 219 | 220 | 221 | def ci_auditing_text_txt_query(): 222 | 223 | response = client.ci_auditing_text_query( 224 | Bucket=bucket_name, # 桶名称 225 | JobID='st6a7d90fe311xxxxxxxxxxxxxxxxx', # 需要查询的文本文件审核任务ID 226 | ) 227 | print(response) 228 | 229 | 230 | def ci_get_object_sensitive_content_recognition(): 231 | """测试ci文件内容识别的接口""" 232 | kwargs = {"CacheControl": "no-cache", "ResponseCacheControl": "no-cache"} 233 | response = client.get_object_sensitive_content_recognition( 234 | Bucket=bucket_name, 235 | Key='test.jpg', 236 | Interval=3, 237 | MaxFrames=20, 238 | Async=1, 239 | CallBack="www.callback.com", 240 | # BizType='xxxx', 241 | **kwargs 242 | ) 243 | print(response) 244 | assert response 245 | 246 | 247 | def ci_auditing_audio_submit(): 248 | freeze = { 249 | 'PornScore': 60, 250 | 'AdsScore': 50 251 | } 252 | response = client.ci_auditing_audio_submit(Bucket=bucket_name, 253 | Key='test.mp4', 254 | Callback="http://www.demo.com", 255 | CallbackVersion='Simple', 256 | CallbackType=1, 257 | Freeze=freeze 258 | ) 259 | jobId = response['JobsDetail']['JobId'] 260 | print(response) 261 | while True: 262 | time.sleep(5) 263 | response = client.ci_auditing_audio_query(Bucket=bucket_name, JobID=jobId) 264 | print(response['JobsDetail']['State']) 265 | if response['JobsDetail']['State'] == 'Success': 266 | print(str(response)) 267 | break 268 | 269 | 270 | def ci_auditing_document_submit(): 271 | freeze = { 272 | 'PornScore': 60, 273 | 'AdsScore': 50 274 | } 275 | response = client.ci_auditing_document_submit(Bucket=bucket_name, 276 | Url='https://test-1250000000.cos.ap-guangzhou.myqcloud.com/test.txt', 277 | Key='1.txt', 278 | Type='txt', 279 | Callback="http://www.demo.com", 280 | CallbackType=2, 281 | Freeze=freeze) 282 | print(response) 283 | jobId = response['JobsDetail']['JobId'] 284 | while True: 285 | time.sleep(5) 286 | kwargs = {"CacheControl": "no-cache", "ResponseCacheControl": "no-cache"} 287 | response = client.ci_auditing_document_query(Bucket=bucket_name, JobID=jobId, **kwargs) 288 | print(response['JobsDetail']['State']) 289 | print(str(response)) 290 | if response['JobsDetail']['State'] == 'Success': 291 | print(str(response)) 292 | break 293 | 294 | 295 | def ci_auditing_report_badcase(): 296 | response = client.ci_auditing_report_badcase(Bucket=bucket_name, 297 | ContentType=2, 298 | Label='Ads', 299 | SuggestedLabel='Normal', 300 | Url='https://test-1250000000.cos.ap-chongqing.myqcloud.com/test.jpg') 301 | print(response) 302 | 303 | 304 | if __name__ == '__main__': 305 | # ci_auditing_video_submit() 306 | # ci_auditing_video_query() 307 | # ci_auditing_image_batch() 308 | # ci_live_video_auditing() 309 | # ci_auditing_virus_submit_and_query() 310 | # ci_auditing_text_submit() 311 | # ci_auditing_text_txt_submit() 312 | # ci_auditing_text_txt_query() 313 | # ci_get_object_sensitive_content_recognition() 314 | # ci_auditing_audio_submit() 315 | # ci_auditing_document_submit() 316 | ci_auditing_report_badcase() 317 | -------------------------------------------------------------------------------- /demo/ci_compress.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | 5 | import sys 6 | import logging 7 | import os 8 | 9 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 10 | 11 | # 高级图片压缩 TPG压缩相关API请参考 https://cloud.tencent.com/document/product/460/60526 12 | # 高级图片压缩 HEIF压缩相关API请参考 https://cloud.tencent.com/document/product/460/60525 13 | 14 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 15 | 16 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 17 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 18 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 19 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 20 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 21 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 22 | 23 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 24 | client = CosS3Client(config) 25 | 26 | bucket_name = 'examplebucket-1250000000' 27 | 28 | # TPG 压缩 29 | response = client.ci_download_compress_image( 30 | Bucket=bucket_name, 31 | Key='sample.png', 32 | DestImagePath='sample.tpg', 33 | CompressType='tpg' 34 | ) 35 | print(response['x-cos-request-id']) 36 | assert os.path.exists('sample.tpg') 37 | 38 | # HEIF 压缩 39 | response = client.ci_download_compress_image( 40 | Bucket=bucket_name, 41 | Key='sample.png', 42 | DestImagePath='sample.heif', 43 | CompressType='heif' 44 | ) 45 | print(response['x-cos-request-id']) 46 | assert os.path.exists('sample.heif') 47 | 48 | # AVIF 压缩 49 | response = client.ci_download_compress_image( 50 | Bucket=bucket_name, 51 | Key='sample.jpeg', 52 | DestImagePath='sample.avif', 53 | CompressType='avif' 54 | ) 55 | print(response['x-cos-request-id']) 56 | assert os.path.exists('sample.avif') 57 | 58 | # SVG 压缩 59 | response = client.ci_download_compress_image( 60 | Bucket=bucket_name, 61 | Key='sample.jpeg', 62 | DestImagePath='sample.svg', 63 | CompressType='svg' 64 | ) 65 | print(response['x-cos-request-id']) 66 | assert os.path.exists('sample.svg') 67 | -------------------------------------------------------------------------------- /demo/ci_doc_preview.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import base64 3 | import json 4 | 5 | from qcloud_cos import CosConfig 6 | from qcloud_cos import CosS3Client 7 | 8 | import os 9 | import sys 10 | import logging 11 | 12 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 13 | 14 | # 文档预览相关API请参考 https://cloud.tencent.com/document/product/460/46942 15 | 16 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 17 | 18 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 19 | secret_id = os.environ["SECRETID"] # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 20 | secret_key = os.environ["SECRETKEY"] # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 21 | region = 'ap-chongqing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 22 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 23 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 24 | 25 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, 26 | Token=token) # 获取配置对象 27 | client = CosS3Client(config) 28 | 29 | bucket_name = 'examplebucket-1250000000' 30 | 31 | 32 | def ci_get_doc_bucket(): 33 | # 查询文档预览开通状态 34 | response = client.ci_get_doc_bucket( 35 | Regions=region, 36 | # BucketName='demo', 37 | BucketNames=bucket_name, 38 | PageSize=1, 39 | PageNumber=1 40 | ) 41 | print(response) 42 | return response 43 | 44 | 45 | def ci_get_doc_queue(): 46 | # 查询文档预览队列信息 47 | response = client.ci_get_doc_queue( 48 | Bucket=bucket_name, 49 | # QueueIds='p4bdf22xxxxxxxxxxxxxxxxxxxxxxxxxf1', 50 | PageNumber=1, 51 | PageSize=1, 52 | ) 53 | print(response) 54 | return response 55 | 56 | 57 | def ci_put_doc_queue(): 58 | # 更新文档预览队列信息 59 | body = { 60 | 'Name': 'doc-queue', 61 | 'QueueID': 'p4bdf22xxxxxxxxxxxxxxxxxxxxxxxxxf1', 62 | 'State': 'Active', 63 | 'NotifyConfig': { 64 | 'Type': 'Url', 65 | 'Url': 'http://www.demo.callback.com', 66 | 'Event': 'TaskFinish', 67 | 'State': 'On', 68 | 'ResultFormat': 'JSON' 69 | } 70 | } 71 | response = client.ci_update_doc_queue( 72 | Bucket=bucket_name, 73 | QueueId='p4bdf22xxxxxxxxxxxxxxxxxxxxxxxxxf1', 74 | Request=body, 75 | ContentType='application/xml' 76 | ) 77 | print(response) 78 | return response 79 | 80 | 81 | def ci_create_doc_jobs(): 82 | # 创建文档预览异步任务 83 | response = client.ci_create_doc_job( 84 | Bucket=bucket_name, 85 | QueueId='p4bdf22xxxxxxxxxxxxxxxxxxxxxxxxxf1', 86 | InputObject='normal.pptx', 87 | OutputBucket=bucket_name, 88 | OutputRegion='ap-chongqing', 89 | OutputObject='/test_doc/normal/abc_${Number}.jpg', 90 | # DocPassword='123', 91 | Quality=109, 92 | PageRanges='1,3', 93 | ) 94 | print(response) 95 | return response 96 | 97 | 98 | def ci_get_doc_jobs(): 99 | # 获取文档预览异步任务信息 100 | response = client.ci_get_doc_job( 101 | Bucket=bucket_name, 102 | JobID='d18a9xxxxxxxxxxxxxxxxxxxxff1aa', 103 | ) 104 | print(response) 105 | return response 106 | 107 | 108 | def ci_list_doc_jobs(): 109 | # 获取文档预览异步任务信息列表 110 | response = client.ci_list_doc_jobs( 111 | Bucket=bucket_name, 112 | Size=10, 113 | ) 114 | print(response) 115 | return response 116 | 117 | 118 | def ci_doc_preview_process(): 119 | # 文档预览同步接口 120 | response = client.ci_doc_preview_process( 121 | Bucket=bucket_name, 122 | Key='1.txt', 123 | ) 124 | print(response) 125 | response['Body'].get_stream_to_file('result.png') 126 | 127 | 128 | def ci_doc_preview_to_html_process(): 129 | # 文档预览同步接口(生成html) 130 | html_params = { 131 | 'commonOptions': { 132 | 'isShowTopArea': 'true', 133 | 'isShowHeader': 'true', 134 | 'isBrowserViewFullscreen': 'true', 135 | 'isIframeViewFullscreen': 'true', 136 | }, 137 | 'wordOptions': { 138 | 'isShowDocMap': 'true', 139 | 'isBestScale': 'true', 140 | 'isShowBottomStatusBar': 'true', 141 | } 142 | } 143 | html_params_json = json.dumps(html_params) 144 | response = client.ci_doc_preview_html_process( 145 | Bucket=bucket_name, 146 | Key='1.txt', 147 | SrcType='txt', 148 | DstType='html', 149 | HtmlParams=base64.urlsafe_b64encode(html_params_json.encode('utf-8')).decode('utf-8').rstrip('='), 150 | HtmlWaterword=base64.urlsafe_b64encode("watermark".encode('utf-8')).decode('utf-8').rstrip('='), 151 | HtmlFillStyle=base64.urlsafe_b64encode("rgba(192,192,192,0.6)".encode('utf-8')).decode('utf-8').rstrip('='), 152 | HtmlFront=base64.urlsafe_b64encode("bold 20px Serif".encode('utf-8')).decode('utf-8').rstrip('='), 153 | HtmlRotate="180", 154 | HtmlHorizontal="100", 155 | HtmlVertical="50", 156 | HtmlTitle=base64.urlsafe_b64encode("title".encode('utf-8')).decode('utf-8').rstrip('='), 157 | ) 158 | print(response) 159 | response['Body'].get_stream_to_file('result.html') 160 | 161 | 162 | def ci_get_doc_preview_process_url(): 163 | # 获取文档预览同步URL 164 | params = { 165 | 'ci-process': 'doc-preview', 166 | 'DstType': 'pdf', 167 | } 168 | response = client.get_presigned_download_url( 169 | Bucket=bucket_name, 170 | Key='1.txt', 171 | Params=params, 172 | ) 173 | print(response) 174 | 175 | 176 | def ci_get_doc_preview_to_html_process_url(): 177 | # 获取文档预览同步URL(生成html) 178 | params = { 179 | 'ci-process': 'doc-preview', 180 | 'DstType': 'html', 181 | 'Copyable': '0', 182 | } 183 | response = client.get_presigned_download_url( 184 | Bucket=bucket_name, 185 | Key='1.txt', 186 | Params=params, 187 | ) 188 | print(response) 189 | 190 | 191 | if __name__ == '__main__': 192 | # ci_get_doc_bucket() 193 | # ci_get_doc_queue() 194 | # ci_put_doc_queue() 195 | # ci_create_doc_jobs() 196 | # ci_get_doc_jobs() 197 | # ci_list_doc_jobs() 198 | # ci_doc_preview_process() 199 | # ci_get_doc_preview_process_url() 200 | # ci_doc_preview_to_html_process() 201 | ci_get_doc_preview_to_html_process_url() 202 | -------------------------------------------------------------------------------- /demo/ci_file_process.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import base64 3 | 4 | from qcloud_cos import CosConfig 5 | from qcloud_cos import CosS3Client 6 | 7 | import os 8 | import sys 9 | import logging 10 | 11 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 12 | 13 | # 哈希计算相关API请参考 https://cloud.tencent.com/document/product/460/83084 14 | # 文件压缩相关API请参考 https://cloud.tencent.com/document/product/460/83091 15 | # 文件解压相关API请参考 https://cloud.tencent.com/document/product/460/83087 16 | 17 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 18 | 19 | secret_id = os.environ["SECRETID"] # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 20 | secret_key = os.environ["SECRETKEY"] # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 21 | region = 'ap-chongqing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 22 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 23 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 24 | 25 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme='https') # 获取配置对象 26 | client = CosS3Client(config) 27 | 28 | 29 | bucket_name = 'demo-1253960454' 30 | 31 | 32 | def ci_get_file_hash(): 33 | # 同步获取文件哈希值 34 | response = client.file_hash( 35 | Bucket=bucket_name, # 文件所在的桶名称 36 | Key="mytest.mp4", # 需要获取哈希值的文件名 37 | Type='md5', # 哈希算法类型,有效值:md5、sha1、sha256. 38 | AddToHeader=True # 是否将计算得到的哈希值,自动添加至文件的自定义header. 格式为:x-cos-meta-md5/sha1/sha256; 有效值: True、False,不填则默认为False. 39 | ) 40 | print(response) 41 | return response 42 | 43 | 44 | def ci_create_file_hash_job(): 45 | # 创建获取文件哈希值异步任务 46 | body = { 47 | # 获取文件哈希值配置详情 48 | 49 | # 哈希值的算法类型 50 | # 必选,有效值:MD5、SHA1、SHA256。 51 | 'Type': 'MD5', 52 | # 是否将计算得到的哈希值添加至文件自定义header,自定义header根据Type的值变化,例如Type值为MD5时,自定义header为 x-cos-meta-md5。 53 | # 非必选,有效值:true、false,默认值为 false。 54 | 'AddToHeader': 'true' 55 | } 56 | mq_config = { 57 | # 消息队列所属园区 58 | # 必选。目前支持园区 sh(上海)、bj(北京)、gz(广州)、cd(成都)、hk(中国香港) 59 | 'MqRegion': 'bj', 60 | # 消息队列使用模式 61 | # 必选。主题订阅:Topic 队列服务: Queue 62 | 'MqMode': 'Queue', 63 | # TDMQ 主题名称 必选。 64 | 'MqName': 'queueName' 65 | } 66 | response = client.ci_create_file_hash_job( 67 | Bucket=bucket_name, # 文件所在的桶名称 68 | InputObject="mytest.mp4", # 需要获取哈希值的文件名 69 | FileHashCodeConfig=body, # 获取文件哈希值配置详情 70 | CallBack="http://www.callback.com", # 回调url地址,当 CallBackType 参数值为 Url 时有效 71 | CallBackFormat="JSON", # 回调信息格式 JSON 或 XML,默认 XML 72 | CallBackType="Url", # 回调类型,Url 或 TDMQ,默认 Url 73 | CallBackMqConfig=mq_config, # 任务回调TDMQ配置,当 CallBackType 为 TDMQ 时必填 74 | UserData="this is my user data" # 透传用户信息, 可打印的 ASCII 码, 长度不超过1024 75 | ) 76 | print(response) 77 | return response 78 | 79 | 80 | def ci_create_file_uncompress_job(): 81 | # 创建获取文件解压异步任务 82 | body = { 83 | # 文件解压配置详情 84 | 85 | # 指定解压后输出文件的前缀,不填则默认保存在存储桶根路径,非必选 86 | 'Prefix': 'zip/', 87 | # 解压密钥,传入时需先经过 base64 编码。非必选 88 | 'UnCompressKey': base64.b64encode("123456".encode("utf-8")).decode('utf-8'), 89 | # 指定解压后的文件路径是否需要替换前缀,有效值: 90 | # - 0:不添加额外的前缀,解压缩将保存在Prefix指定的路径下(不会保留压缩包的名称,仅将压缩包内的文件保存至指定的路径)。 91 | # - 1:以压缩包本身的名称作为前缀,解压缩将保存在Prefix指定的路径下。 92 | # - 2:以压缩包完整路径作为前缀,此时如果不指定Prefix,就是解压到压缩包所在的当前路径(包含压缩包本身名称)。 93 | # - 非必选,默认值为0 94 | 'PrefixReplaced': '0' 95 | } 96 | mq_config = { 97 | # 消息队列所属园区 98 | # 必选。目前支持园区 sh(上海)、bj(北京)、gz(广州)、cd(成都)、hk(中国香港) 99 | 'MqRegion': 'bj', 100 | # 消息队列使用模式 101 | # 必选。主题订阅:Topic 队列服务: Queue 102 | 'MqMode': 'Queue', 103 | # TDMQ 主题名称 必选。 104 | 'MqName': 'queueName' 105 | } 106 | response = client.ci_create_file_uncompress_job( 107 | Bucket=bucket_name, # 文件所在的桶名称 108 | InputObject='zip/testmi.zip', # 需要解压的文件名 109 | OutputBucket=bucket_name, # 指定输出文件所在的桶名称 110 | OutputRegion=region, # 指定输出文件所在的地域 111 | FileUncompressConfig=body, # 文件解压配置详情 112 | CallBack="http://www.callback.com", # 回调url地址,当 CallBackType 参数值为 Url 时有效 113 | CallBackFormat="JSON", # 回调信息格式 JSON 或 XML,默认 XML 114 | CallBackType="Url", # 回调类型,Url 或 TDMQ,默认 Url 115 | CallBackMqConfig=mq_config, # 任务回调TDMQ配置,当 CallBackType 为 TDMQ 时必填 116 | UserData="this is my user data" # 透传用户信息, 可打印的 ASCII 码, 长度不超过1024 117 | ) 118 | print(response) 119 | return response 120 | 121 | 122 | def ci_create_file_compress_job(): 123 | # 创建获取文件压缩异步任务 124 | body = { 125 | # 文件打包时,是否需要去除源文件已有的目录结构 126 | # 必选,有效值: 127 | # 0:不需要去除目录结构,打包后压缩包中的文件会保留原有的目录结构 128 | # 1:需要,打包后压缩包内的文件会去除原有的目录结构,所有文件都在同一层级 129 | # 例如:源文件 URL 为 https://domain/source/test.mp4, 则源文件路径为 source/test.mp4 130 | # 如果为 1,则 ZIP 包中该文件路径为 test.mp4 131 | # 如果为 0,ZIP 包中该文件路径为 source/test.mp4 132 | 'Flatten': '0', 133 | # 打包压缩的类型 134 | # 必选,有效值:zip、tar、tar.gz。 135 | 'Format': 'zip', 136 | # 压缩类型,仅在Format为tar.gz或zip时有效。 137 | # faster:压缩速度较快 138 | # better:压缩质量较高,体积较小 139 | # default:适中的压缩方式 140 | # 非必选,默认值为default 141 | 'Type': 'faster', 142 | # 压缩包密钥,传入时需先经过 base64 编码, 编码后长度不能超过128。当 Format 为 zip 时生效 143 | # 非必选 144 | 'CompressKey': base64.b64encode("123456".encode("utf-8")).decode('utf-8'), 145 | 146 | # 下列参数UrlList、Prefix、Key 三者仅能选择一个,不能都为空,也不会同时生效。如果填了多个,会按优先级 UrlList > Prefix > Key 取最高优先级执行。 147 | 148 | # UrlList 支持将需要打包的文件整理成索引文件,后台将根据索引文件内提供的文件 url,打包为一个压缩包文件。 149 | # 索引文件需要保存在当前存储桶中,本字段需要提供索引文件的对象地址,例如:/test/index.csv。 150 | # 索引文件格式:仅支持 CSV 文件,一行一条 URL(仅支持本存储桶文件),如有多列字段,默认取第一列作为URL。最多不超过10000个文件,总大小不超过50G 151 | # 非必选 152 | 'UrlList': '', 153 | # 支持对存储桶中的某个前缀进行打包,如果需要对某个目录进行打包,需要加/, 154 | # 例如test目录打包,则值为:test/。最多不超过10000个文件,总大小不超过50G,否则会导致任务失败。 155 | # 非必选 156 | 'Prefix': 'zip/', 157 | # 支持对存储桶中的多个文件进行打包,个数不能超过 1000。 158 | # 非必选 159 | 'Key': ['zip/1.png', 'zip/2.png', 'zip/3.png'] 160 | } 161 | mq_config = { 162 | # 消息队列所属园区 163 | # 必选。目前支持园区 sh(上海)、bj(北京)、gz(广州)、cd(成都)、hk(中国香港) 164 | 'MqRegion': 'bj', 165 | # 消息队列使用模式 166 | # 必选。主题订阅:Topic 队列服务: Queue 167 | 'MqMode': 'Queue', 168 | # TDMQ 主题名称 必选。 169 | 'MqName': 'queueName' 170 | } 171 | response = client.ci_create_file_compress_job( 172 | Bucket=bucket_name, # 文件所在的桶名称 173 | OutputBucket=bucket_name, # 指定输出文件所在的桶名称 174 | OutputRegion=region, # 指定输出文件所在的地域 175 | OutputObject='zip/result.zip', # 指定输出文件名 176 | FileCompressConfig=body, # 指定压缩配置 177 | CallBack="http://www.callback.com", # 回调url地址,当 CallBackType 参数值为 Url 时有效 178 | CallBackFormat="JSON", # 回调信息格式 JSON 或 XML,默认 XML 179 | CallBackType="Url", # 回调类型,Url 或 TDMQ,默认 Url 180 | CallBackMqConfig=mq_config, # 任务回调TDMQ配置,当 CallBackType 为 TDMQ 时必填 181 | UserData="this is my user data" # 透传用户信息, 可打印的 ASCII 码, 长度不超过1024 182 | ) 183 | print(response) 184 | return response 185 | 186 | 187 | def ci_get_file_process_jobs(): 188 | # 获取文件处理异步任务结果详情 189 | response = client.ci_get_file_process_jobs( 190 | Bucket=bucket_name, # 任务所在桶名称 191 | JobIDs='f7325938a256611xxxxxxxxxxx', # 文件处理异步任务ID 192 | ) 193 | print(response) 194 | return response 195 | 196 | 197 | def ci_get_zip_preview(): 198 | # 压缩包预览同步请求 199 | response = client.ci_file_zip_preview( 200 | Bucket=bucket_name, # 压缩文件所在桶名称 201 | Key="zip/test.zip" # 需要预览的压缩文件名 202 | ) 203 | print(response) 204 | return response 205 | 206 | 207 | if __name__ == '__main__': 208 | # ci_get_file_hash() 209 | # ci_create_file_hash_job() 210 | # ci_create_file_uncompress_job() 211 | # ci_create_file_compress_job() 212 | ci_get_zip_preview() 213 | # ci_get_file_process_jobs() 214 | -------------------------------------------------------------------------------- /demo/ci_speech_recognition.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | 3 | from qcloud_cos import CosConfig 4 | from qcloud_cos import CosS3Client 5 | 6 | import os 7 | import sys 8 | import logging 9 | 10 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 11 | 12 | # https://cloud.tencent.com/document/product/436/46782 13 | 14 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 15 | 16 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 17 | secret_id = os.environ["SECRETID"] # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 18 | secret_key = os.environ["SECRETKEY"] # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 19 | region = 'ap-chongqing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 20 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 21 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 22 | 23 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, 24 | Token=token) # 获取配置对象 25 | client = CosS3Client(config) 26 | 27 | bucket_name = 'examplebucket-1250000000' 28 | 29 | 30 | def ci_open_asr_bucket(): 31 | # 开通智能语音服务 32 | response, data = client.ci_open_asr_bucket( 33 | Bucket=bucket_name 34 | ) 35 | print(response) 36 | print(data) 37 | return response, data 38 | 39 | 40 | def ci_get_asr_bucket(): 41 | # 查询语音识别开通状态 42 | response = client.ci_get_asr_bucket( 43 | Regions=region, 44 | BucketName=bucket_name, 45 | PageSize="10", 46 | PageNumber="1" 47 | ) 48 | print(response) 49 | return response 50 | 51 | 52 | def ci_close_asr_bucket(): 53 | # 关闭智能语音服务 54 | response, data = client.ci_close_asr_bucket( 55 | Bucket=bucket_name 56 | ) 57 | print(response) 58 | print(data) 59 | return response, data 60 | 61 | 62 | def ci_get_asr_queue(): 63 | # 查询语音识别队列信息 64 | response = client.ci_get_asr_queue( 65 | Bucket=bucket_name, 66 | ) 67 | print(response) 68 | return response 69 | 70 | 71 | def ci_put_asr_queue(): 72 | # 更新语音识别队列信息 73 | body = { 74 | 'Name': 'asr-queue', 75 | 'QueueID': 'p7369xxxxxxxxxxxxxxxxxdff5a', 76 | 'State': 'Active', 77 | 'NotifyConfig': { 78 | 'Type': 'Url', 79 | 'Url': 'http://www.demo.callback.com', 80 | 'Event': 'TaskFinish', 81 | 'State': 'On', 82 | 'ResultFormat': 'JSON' 83 | } 84 | } 85 | response = client.ci_update_asr_queue( 86 | Bucket=bucket_name, 87 | QueueId='p7369xxxxxxxxxxxxxxxxxdff5a', 88 | Request=body, 89 | ContentType='application/xml' 90 | ) 91 | print(response) 92 | return response 93 | 94 | 95 | def ci_create_asr_jobs(): 96 | # 创建语音识别异步任务 97 | body = { 98 | 'EngineModelType': '16k_zh', 99 | 'ChannelNum': '1', 100 | 'ResTextFormat': '1', 101 | # 'FlashAsr': 'true', 102 | # 'Format': 'mp3' 103 | } 104 | response = client.ci_create_asr_job( 105 | Bucket=bucket_name, 106 | # TemplateId='t1ada6f282d29742db83244e085e920b08', 107 | InputObject='normal.mp4', 108 | OutputBucket=bucket_name, 109 | OutputRegion='ap-chongqing', 110 | OutputObject='result.txt', 111 | SpeechRecognition=body 112 | ) 113 | print(response) 114 | return response 115 | 116 | 117 | def ci_get_asr_jobs(): 118 | # 获取语音识别任务信息 119 | response = client.ci_get_asr_job( 120 | Bucket=bucket_name, 121 | JobID='s0980xxxxxxxxxxxxxxxxff12', 122 | ) 123 | print(response) 124 | return response 125 | 126 | 127 | def ci_list_asr_jobs(): 128 | # 获取语音识别任务信息列表 129 | response = client.ci_list_asr_jobs( 130 | Bucket=bucket_name, 131 | Size=10, 132 | ) 133 | print(response) 134 | return response 135 | 136 | 137 | def ci_create_asr_template(): 138 | # 创建语音识别模板 139 | response = client.ci_create_asr_template( 140 | Bucket=bucket_name, 141 | Name='templateName', 142 | EngineModelType='16k_zh', 143 | ChannelNum=1, 144 | ResTextFormat=2, 145 | FlashAsr=True, 146 | Format='mp3', 147 | ) 148 | print(response) 149 | return response 150 | 151 | 152 | def ci_get_asr_template(): 153 | # 获取语音识别模板 154 | response = client.ci_get_asr_template( 155 | Bucket=bucket_name, 156 | ) 157 | print(response) 158 | return response 159 | 160 | 161 | def ci_update_asr_template(): 162 | # 修改语音识别模板 163 | response = client.ci_update_asr_template( 164 | Bucket=bucket_name, 165 | TemplateId='t1bdxxxxxxxxxxxxxxxxx94a9', 166 | Name='Template1', 167 | EngineModelType='16k_zh', 168 | ChannelNum=1, 169 | ResTextFormat=1, 170 | ) 171 | print(response) 172 | return response 173 | 174 | 175 | def ci_delete_asr_template(): 176 | # 删除指定语音识别模板 177 | response = client.ci_delete_asr_template( 178 | Bucket=bucket_name, 179 | TemplateId='t1bdxxxxxxxxxxxxxxxxx94a9', 180 | ) 181 | print(response) 182 | return response 183 | 184 | 185 | if __name__ == '__main__': 186 | # ci_get_asr_bucket() 187 | # ci_get_asr_queue() 188 | # ci_put_asr_queue() 189 | # ci_create_asr_template() 190 | # ci_get_asr_template() 191 | # ci_update_asr_template() 192 | # ci_delete_asr_template() 193 | # ci_create_asr_jobs() 194 | # ci_get_asr_jobs() 195 | # ci_list_asr_jobs() 196 | # ci_close_asr_bucket() 197 | # ci_open_asr_bucket() 198 | ci_get_asr_bucket() 199 | -------------------------------------------------------------------------------- /demo/ci_watermark.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | 5 | import sys 6 | import logging 7 | import base64 8 | 9 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 10 | 11 | # 图片盲水印相关API 请参考 https://cloud.tencent.com/document/product/436/46782 12 | 13 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 14 | 15 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 16 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 17 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 18 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 19 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 20 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 21 | 22 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 23 | client = CosS3Client(config) 24 | 25 | bucket_name = 'examplebucket-1250000000' 26 | # 添加盲水印 27 | watermark_url = 'http://{bucket}.cos.{region}.tencentcos.cn/watermark.png'.format(bucket=bucket_name, region=region) 28 | watermark_url_base64 = bytes.decode(base64.b64encode(str.encode(watermark_url))) 29 | print(watermark_url_base64) 30 | response, data = client.ci_put_object_from_local_file( 31 | Bucket=bucket_name, 32 | LocalFilePath='sample.png', 33 | Key="sample.png", 34 | # pic operation json struct 35 | PicOperations='{"is_pic_info":1,"rules":[{"fileid": "format.png","rule": "watermark/3/type/1/image/' + 36 | watermark_url_base64 + '" }]}' 37 | ) 38 | print(response['x-cos-request-id']) 39 | print(data['ProcessResults']['Object']['ETag']) 40 | 41 | # 下载时添加盲水印 42 | # download_url = http://examplebucket-1250000000.cos.ap-shanghai.tencentcos.cn/sample.jpeg?watermark/3/type/3/text/watermark_url_base64 43 | 44 | # 提取盲水印 45 | sample_url = 'http://{bucket}.cos.{region}.tencentcos.cn/sample.png'.format(bucket=bucket_name, region=region) 46 | sample_url_base64 = bytes.decode(base64.b64encode(str.encode(sample_url))) 47 | response, data = client.ci_put_object_from_local_file( 48 | Bucket=bucket_name, 49 | LocalFilePath='format.png', 50 | Key="format.png", 51 | # pic operation json struct 52 | PicOperations='{"is_pic_info":1,"rules":[{"fileid": "watermark.png","rule": "watermark/4/type/1/image/' + 53 | sample_url_base64 + '" }]}' 54 | ) 55 | print(response['x-cos-request-id']) 56 | print(data['ProcessResults']['Object']['ETag']) 57 | -------------------------------------------------------------------------------- /demo/client_encrypt.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos.cos_encryption_client import CosEncryptionClient 5 | from qcloud_cos.crypto import AESProvider, RSAKeyPair 6 | import sys 7 | import os 8 | import logging 9 | 10 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 11 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 12 | 13 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 14 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 15 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 16 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 17 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 18 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 19 | 20 | conf = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) 21 | 22 | '''使用对称 AES256 加密每次生成的随机密钥示例 23 | ''' 24 | 25 | # 方式一:通过密钥值初始化加密客户端 26 | # 注意:按照 AES 算法的要求,aes_key_value 需为 base64编码后的结果 27 | aes_provider = AESProvider(aes_key='aes_key_value') 28 | 29 | # 方式二:通过密钥路径初始化加密客户端 30 | aes_key_pair = AESProvider(aes_key_path='aes_key_path') 31 | 32 | client_for_aes = CosEncryptionClient(conf, aes_provider) 33 | 34 | # 上传对象,兼容非加密客户端的 put_object 的所有功能,具体使用可参考 put_object 35 | response = client_for_aes.put_object( 36 | Bucket='examplebucket-1250000000', 37 | Body=b'bytes', 38 | Key='exampleobject', 39 | EnableMD5=False) 40 | 41 | # 下载对象,兼容非加密客户端的 get_object 的所有功能,具体使用可参考 get_object 42 | response = client_for_aes.get_object( 43 | Bucket='examplebucket-1250000000', 44 | Key='exampleobject') 45 | 46 | # 分块上传,兼容非加密客户端的分块上传,除了最后一个part,每个 part 的大小必须为16字节的整数倍 47 | response = client_for_aes.create_multipart_upload( 48 | Bucket='examplebucket-1250000000', 49 | Key='exampleobject_upload') 50 | uploadid = response['UploadId'] 51 | client_for_aes.upload_part( 52 | Bucket='examplebucket-1250000000', 53 | Key='exampleobject_upload', 54 | Body=b'bytes', 55 | PartNumber=1, 56 | UploadId=uploadid) 57 | response = client_for_aes.list_parts( 58 | Bucket='examplebucket-1250000000', 59 | Key='exampleobject_upload', 60 | UploadId=uploadid) 61 | client_for_aes.complete_multipart_upload( 62 | Bucket='examplebucket-1250000000', 63 | Key='exampleobject_upload', 64 | UploadId=uploadid, 65 | MultipartUpload={'Part':response['Part']}) 66 | 67 | # 断点续传方式上传对象,`partsize`大小必须为16字节的整数倍 68 | response = client_for_aes.upload_file( 69 | Bucket='test04-123456789', 70 | LocalFilePath='local.txt', 71 | Key='exampleobject', 72 | PartSize=10, 73 | MAXThread=10 74 | ) 75 | 76 | '''使用非对称 RSA 加密每次生成的随机密钥示例 77 | ''' 78 | 79 | # 方式一:通过密钥值初始化加密客户端 80 | rsa_key_pair = RSAProvider.get_rsa_key_pair('public_key_value', 'private_key_value') 81 | 82 | # 方式二:通过密钥路径初始化加密客户端 83 | rsa_key_pair = RSAProvider.get_rsa_key_pair_path('public_key_path', 'private_key_path') 84 | 85 | rsa_provider = RSAProvider(key_pair_info=rsa_key_pair) 86 | client_for_rsa = CosEncryptionClient(conf, rsa_provider) 87 | 88 | # 上传对象,兼容非加密客户端的 put_object 的所有功能,具体使用可参考 put_object 89 | response = client_for_rsa.put_object( 90 | Bucket='examplebucket-1250000000', 91 | Body=b'bytes', 92 | Key='exampleobject', 93 | EnableMD5=False) 94 | 95 | # 下载对象,兼容非加密客户端的 get_object 的所有功能,具体使用可参考 get_object 96 | response = client_for_rsa.get_object( 97 | Bucket='examplebucket-1250000000', 98 | Key='exampleobject') 99 | 100 | # 分块上传,兼容非加密客户端的分块上传,除了最后一个 part,每个 part 的大小必须为16字节的整数倍 101 | response = client_for_rsa.create_multipart_upload( 102 | Bucket='examplebucket-1250000000', 103 | Key='exampleobject_upload') 104 | uploadid = response['UploadId'] 105 | client_for_rsa.upload_part( 106 | Bucket='examplebucket-1250000000', 107 | Key='exampleobject_upload', 108 | Body=b'bytes', 109 | PartNumber=1, 110 | UploadId=uploadid) 111 | response = client_for_rsa.list_parts( 112 | Bucket='examplebucket-1250000000', 113 | Key='exampleobject_upload', 114 | UploadId=uploadid) 115 | client_for_rsa.complete_multipart_upload( 116 | Bucket='examplebucket-1250000000', 117 | Key='exampleobject_upload', 118 | UploadId=uploadid, 119 | MultipartUpload={'Part':response['Part']}) 120 | 121 | # 断点续传方式上传对象,`partsize`大小必须为16字节的整数倍 122 | response = client_for_rsa.upload_file( 123 | Bucket='test04-123456789', 124 | LocalFilePath='local.txt', 125 | Key='exampleobject', 126 | PartSize=10, 127 | MAXThread=10 128 | ) -------------------------------------------------------------------------------- /demo/copy_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | 23 | '''高级接口-复制对象 24 | ''' 25 | 26 | response = client.copy( 27 | Bucket='examplebucket-1250000000', 28 | Key='exampleobject', 29 | CopySource={ 30 | 'Bucket': 'sourcebucket-1250000000', 31 | 'Key': 'sourceobject', 32 | 'Region': 'ap-guangzhou' 33 | } 34 | ) 35 | 36 | '''高级接口-移动对象 37 | ''' 38 | 39 | bucket = 'examplebucket-1250000000' 40 | srcKey = 'src_object_key' # 原始的对象路径 41 | destKey = 'dest_object_key' # 目的对象路径 42 | 43 | # COS本身没有移动对象的接口,所谓移动就是先拷贝老对象到新对象,再删除老对象。 44 | response = client.copy( 45 | Bucket=bucket, 46 | Key=destKey, 47 | CopySource={ 48 | 'Bucket':bucket, 49 | 'Key':srcKey, 50 | 'Region':'ap-guangzhou' 51 | }) 52 | client.delete_object(Bucket=bucket, Key=srcKey) 53 | 54 | '''简单接口-复制对象 55 | ''' 56 | 57 | response = client.copy_object( 58 | Bucket='examplebucket-1250000000', 59 | Key='exampleobject', 60 | CopySource={ 61 | 'Bucket': 'sourcebucket-1250000000', 62 | 'Key': 'sourceobject', 63 | 'Region': 'ap-guangzhou' 64 | } 65 | ) 66 | 67 | '''简单接口-移动对象 68 | ''' 69 | 70 | response = client.copy_object( 71 | Bucket='examplebucket-1250000000', 72 | Key='exampleobject', 73 | CopySource={ 74 | 'Bucket': 'sourcebucket-1250000000', 75 | 'Key': 'sourceobject', 76 | 'Region': 'ap-guangzhou' 77 | } 78 | ) 79 | client.delete_object(Bucket='sourcebucket-1250000000', Key='sourceobject') 80 | -------------------------------------------------------------------------------- /demo/delete_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos.cos_threadpool import SimpleThreadPool 5 | import sys 6 | import os 7 | import logging 8 | 9 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 10 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 11 | 12 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 13 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 15 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 16 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 17 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 18 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 19 | 20 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 21 | client = CosS3Client(config) 22 | 23 | # 删除单个对象 24 | response = client.delete_object( 25 | Bucket='examplebucket-1250000000', 26 | Key='exampleobject' 27 | ) 28 | print(response) 29 | 30 | # 删除目录 31 | to_delete_dir='path/to/delete/dir/' 32 | response = client.delete_object( 33 | Bucket='examplebucket-1250000000', 34 | Key=to_delete_dir 35 | ) 36 | print(response) 37 | 38 | # 前缀批量删除 39 | # 删除指定前缀 (prefix)的文件 40 | bucket = 'examplebucket-1250000000' 41 | marker = '' 42 | prefix = 'root/logs' 43 | while True: 44 | response = client.list_objects(Bucket=bucket, Prefix=prefix, Marker=marker) 45 | if 'Contents' in response: 46 | for content in response['Contents']: 47 | print("delete object: ", content['Key']) 48 | client.delete_object(Bucket=bucket, Key=content['Key']) 49 | 50 | 51 | if response['IsTruncated'] == 'false': 52 | break 53 | 54 | 55 | marker = response['NextMarker'] 56 | 57 | # 删除多个对象 58 | response = client.delete_objects( 59 | Bucket='examplebucket-1250000000', 60 | Delete={ 61 | 'Object': [ 62 | { 63 | 'Key': 'exampleobject1' 64 | }, 65 | { 66 | 'Key': 'exampleobject2' 67 | } 68 | ] 69 | } 70 | ) 71 | 72 | # 批量删除对象(删除目录) 73 | 74 | bucket = 'examplebucket-1250000000' 75 | folder = 'folder/' # 要删除的目录,'/'结尾表示目录 76 | 77 | def delete_cos_dir(): 78 | pool = SimpleThreadPool() 79 | marker = "" 80 | while True: 81 | file_infos = [] 82 | 83 | # 列举一页100个对象 84 | response = client.list_objects(Bucket=bucket, Prefix=folder, Marker=marker, MaxKeys=100) 85 | 86 | if "Contents" in response: 87 | contents = response.get("Contents") 88 | file_infos.extend(contents) 89 | pool.add_task(delete_files, file_infos) 90 | 91 | # 列举完成,退出 92 | if response['IsTruncated'] == 'false': 93 | break 94 | 95 | # 列举下一页 96 | marker = response["NextMarker"] 97 | 98 | pool.wait_completion() 99 | return None 100 | 101 | 102 | def delete_files(file_infos): 103 | # 构造批量删除请求 104 | delete_list = [] 105 | for file in file_infos: 106 | delete_list.append({"Key": file['Key']}) 107 | 108 | response = client.delete_objects(Bucket=bucket, Delete={"Object": delete_list}) 109 | print(response) 110 | 111 | delete_cos_dir() -------------------------------------------------------------------------------- /demo/demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos import CosServiceError 5 | from qcloud_cos import CosClientError 6 | 7 | import sys 8 | import logging 9 | 10 | # 基础图片处理相关API 请参考 https://cloud.tencent.com/document/product/460/36540 11 | 12 | def percentage(consumed_bytes, total_bytes): 13 | """进度条回调函数,计算当前上传的百分比 14 | 15 | :param consumed_bytes: 已经上传/下载的数据量 16 | :param total_bytes: 总数据量 17 | """ 18 | if total_bytes: 19 | rate = int(100 * (float(consumed_bytes) / float(total_bytes))) 20 | print('\r{0}% '.format(rate)) 21 | sys.stdout.flush() 22 | 23 | 24 | if __name__ == "__main__": 25 | 26 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 27 | 28 | # pip安装指南:pip install -U cos-python-sdk-v5 29 | 30 | # cos最新可用地域,参照https://www.qcloud.com/document/product/436/6224 31 | 32 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 33 | 34 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 35 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 36 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 37 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 38 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 39 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 40 | domain = None # domain可以不填,此时使用COS区域域名访问存储桶。domain也可以填写用户自定义域名,或者桶的全球加速域名 41 | # 填写用户自定义域名,比如user-define.example.com,需要先开启桶的自定义域名,具体请参见https://cloud.tencent.com/document/product/436/36638 42 | # 填写桶的全球加速域名,比如examplebucket-1250000000.cos.accelerate.tencentcos.cn,需要先开启桶的全球加速功能,请参见https://cloud.tencent.com/document/product/436/38864 43 | 44 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Domain=domain) # 获取配置对象 45 | client = CosS3Client(config) 46 | 47 | # 文件流 简单上传 48 | file_name = 'test.txt' 49 | with open('test.txt', 'rb') as fp: 50 | response = client.put_object( 51 | Bucket='test04-123456789', # Bucket由bucketname-appid组成 52 | Body=fp, 53 | Key=file_name, 54 | StorageClass='STANDARD', 55 | ContentType='text/html; charset=utf-8' 56 | ) 57 | print(response['ETag']) 58 | 59 | # 字节流 简单上传 60 | response = client.put_object( 61 | Bucket='test04-123456789', 62 | Body=b'abcdefg', 63 | Key=file_name 64 | ) 65 | print(response['ETag']) 66 | 67 | # 本地路径 简单上传 68 | response = client.put_object_from_local_file( 69 | Bucket='test04-123456789', 70 | LocalFilePath='local.txt', 71 | Key=file_name, 72 | ) 73 | print(response['ETag']) 74 | 75 | # 设置HTTP头部 简单上传 76 | response = client.put_object( 77 | Bucket='test04-123456789', 78 | Body=b'test', 79 | Key=file_name, 80 | ContentType='text/html; charset=utf-8' 81 | ) 82 | print(response['ETag']) 83 | 84 | # 设置自定义头部 简单上传 85 | response = client.put_object( 86 | Bucket='test04-123456789', 87 | Body=b'test', 88 | Key=file_name, 89 | Metadata={ 90 | 'x-cos-meta-key1': 'value1', 91 | 'x-cos-meta-key2': 'value2' 92 | } 93 | ) 94 | print(response['ETag']) 95 | 96 | # 高级上传接口(推荐) 97 | response = client.upload_file( 98 | Bucket='test04-123456789', 99 | LocalFilePath='local.txt', 100 | Key=file_name, 101 | PartSize=10, 102 | MAXThread=10, 103 | progress_callback=percentage 104 | ) 105 | print(response['ETag']) 106 | 107 | # 文件下载 获取文件到本地 108 | response = client.get_object( 109 | Bucket='test04-123456789', 110 | Key=file_name, 111 | ) 112 | response['Body'].get_stream_to_file('output.txt') 113 | 114 | # 文件下载 获取文件流 115 | response = client.get_object( 116 | Bucket='test04-123456789', 117 | Key=file_name, 118 | ) 119 | fp = response['Body'].get_raw_stream() 120 | print(fp.read(2)) 121 | 122 | # 文件下载 设置Response HTTP 头部 123 | response = client.get_object( 124 | Bucket='test04-123456789', 125 | Key=file_name, 126 | ResponseContentType='text/html; charset=utf-8' 127 | ) 128 | print(response['Content-Type']) 129 | fp = response['Body'].get_raw_stream() 130 | print(fp.read(2)) 131 | 132 | # 文件下载 指定下载范围 133 | response = client.get_object( 134 | Bucket='test04-123456789', 135 | Key=file_name, 136 | Range='bytes=0-10' 137 | ) 138 | fp = response['Body'].get_raw_stream() 139 | print(fp.read()) 140 | 141 | # ci interface 简单上传 142 | ci_file_name = 'local.jpg' 143 | response, data = client.ci_put_object_from_local_file( 144 | Bucket='test04-123456789', 145 | LocalFilePath='local.jpg', 146 | Key=ci_file_name, 147 | # pic operation json struct 148 | PicOperations='{"is_pic_info":1,"rules":[{"fileid":"format.png","rule":"imageView2/format/png"}]}' 149 | ) 150 | print(response['x-cos-request-id']) 151 | print(data['ProcessResults']['Object']['ETag']) 152 | 153 | with open('local.jpg', 'rb') as fp: 154 | response, data = client.ci_put_object( 155 | Bucket='test04-123456789', 156 | Body=fp, 157 | Key=ci_file_name, 158 | # pic operation json struct 159 | PicOperations='{"is_pic_info":1,"rules":[{"fileid":"format.png","rule":"imageView2/format/png"}]}' 160 | ) 161 | print(response['x-cos-request-id']) 162 | print(data['ProcessResults']['Object']['ETag']) 163 | 164 | # 查询 ci image process 165 | response, data = client.ci_image_process( 166 | Bucket='test04-123456789', 167 | Key=ci_file_name, 168 | # pic operation json struct 169 | PicOperations='{"is_pic_info":1,"rules":[{"fileid":"format.png","rule":"imageView2/format/png"}]}' 170 | ) 171 | print(response['x-cos-request-id']) 172 | print(data['ProcessResults']['Object']['ETag']) 173 | 174 | # 二维码图片上传时识别 175 | qrcode_file_name = 'test_object_sdk_qrcode.file' 176 | with open(qrcode_file_name, 'rb') as fp: 177 | # fp验证 178 | opts = '{"is_pic_info":1,"rules":[{"fileid":"format.jpg","rule":"QRcode/cover/1"}]}' 179 | response = client.put_ci_object_from_local_file_and_get_qrcode( 180 | Bucket='test04-123456789', 181 | LocalFilePath=qrcode_file_name, 182 | Key=qrcode_file_name, 183 | EnableMD5=False, 184 | PicOperations=opts 185 | ) 186 | print(response) 187 | 188 | # 二维码图片下载时识别 189 | response = client.get_ci_object_qrcode( 190 | Bucket='test04-123456789', 191 | Key=qrcode_file_name, 192 | Cover=0 193 | ) 194 | print(response) 195 | 196 | # 文件下载 捕获异常 197 | try: 198 | response = client.get_object( 199 | Bucket='test04-123456789', 200 | Key='not_exist.txt', 201 | ) 202 | fp = response['Body'].get_raw_stream() 203 | print(fp.read(2)) 204 | except CosServiceError as e: 205 | print(e.get_origin_msg()) 206 | print(e.get_digest_msg()) 207 | print(e.get_status_code()) 208 | print(e.get_error_code()) 209 | print(e.get_error_msg()) 210 | print(e.get_resource_location()) 211 | print(e.get_trace_id()) 212 | print(e.get_request_id()) 213 | -------------------------------------------------------------------------------- /demo/dir_download_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import logging 3 | import sys 4 | import json 5 | import os 6 | 7 | from qcloud_cos import CosConfig, CosServiceError 8 | from qcloud_cos import CosS3Client 9 | from qcloud_cos.cos_threadpool import SimpleThreadPool 10 | 11 | # 演示多线程方式下载COS目录下的文件 12 | 13 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 14 | 15 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 16 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 17 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 18 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 19 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 20 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 21 | scheme = 'http' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 22 | 23 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) # 获取配置对象 24 | client = CosS3Client(config) 25 | 26 | # 用户的 bucket 信息 27 | test_bucket = 'examplebucket-1250000000' 28 | start_prefix = 'data/' 29 | # 对象存储依赖 分隔符 '/' 来模拟目录语义, 30 | # 使用默认的空分隔符可以列出目录下面的所有子节点,实现类似本地目录递归的效果, 31 | # 如果 delimiter 设置为 "/",则需要在程序里递归处理子目录 32 | delimiter = '' 33 | 34 | 35 | # 列出当前目录子节点,返回所有子节点信息 36 | def listCurrentDir(prefix): 37 | file_infos = [] 38 | sub_dirs = [] 39 | marker = "" 40 | count = 1 41 | while True: 42 | response = client.list_objects(test_bucket, prefix, delimiter, marker) 43 | # 调试输出 44 | # json_object = json.dumps(response, indent=4) 45 | # print(count, " =======================================") 46 | # print(json_object) 47 | count += 1 48 | 49 | if "CommonPrefixes" in response: 50 | common_prefixes = response.get("CommonPrefixes") 51 | sub_dirs.extend(common_prefixes) 52 | 53 | if "Contents" in response: 54 | contents = response.get("Contents") 55 | file_infos.extend(contents) 56 | 57 | if "NextMarker" in response.keys(): 58 | marker = response["NextMarker"] 59 | else: 60 | break 61 | 62 | print("=======================================================") 63 | 64 | # 如果 delimiter 设置为 "/",则需要进行递归处理子目录, 65 | # sorted(sub_dirs, key=lambda sub_dir: sub_dir["Prefix"]) 66 | # for sub_dir in sub_dirs: 67 | # print(sub_dir) 68 | # sub_dir_files = listCurrentDir(sub_dir["Prefix"]) 69 | # file_infos.extend(sub_dir_files) 70 | 71 | print("=======================================================") 72 | 73 | sorted(file_infos, key=lambda file_info: file_info["Key"]) 74 | for file in file_infos: 75 | print(file) 76 | return file_infos 77 | 78 | 79 | # 下载文件到本地目录,如果本地目录已经有同名文件则会被覆盖; 80 | # 如果目录结构不存在,则会创建和对象存储一样的目录结构 81 | def downLoadFiles(file_infos): 82 | localDir = "./download/" 83 | 84 | pool = SimpleThreadPool() 85 | for file in file_infos: 86 | # 文件下载 获取文件到本地 87 | file_cos_key = file["Key"] 88 | localName = localDir + file_cos_key 89 | 90 | # 如果本地目录结构不存在,递归创建 91 | if not os.path.exists(os.path.dirname(localName)): 92 | os.makedirs(os.path.dirname(localName)) 93 | 94 | # skip dir, no need to download it 95 | if str(localName).endswith("/"): 96 | continue 97 | 98 | # 实际下载文件 99 | # 使用线程池方式 100 | pool.add_task(client.download_file, test_bucket, file_cos_key, localName) 101 | 102 | # 简单下载方式 103 | # response = client.get_object( 104 | # Bucket=test_bucket, 105 | # Key=file_cos_key, 106 | # ) 107 | # response['Body'].get_stream_to_file(localName) 108 | 109 | pool.wait_completion() 110 | return None 111 | 112 | 113 | # 功能封装,下载对象存储上面的一个目录到本地磁盘 114 | def downLoadDirFromCos(prefix): 115 | global file_infos 116 | 117 | try: 118 | file_infos = listCurrentDir(prefix) 119 | 120 | except CosServiceError as e: 121 | print(e.get_origin_msg()) 122 | print(e.get_digest_msg()) 123 | print(e.get_status_code()) 124 | print(e.get_error_code()) 125 | print(e.get_error_msg()) 126 | print(e.get_resource_location()) 127 | print(e.get_trace_id()) 128 | print(e.get_request_id()) 129 | 130 | downLoadFiles(file_infos) 131 | return None 132 | 133 | 134 | if __name__ == "__main__": 135 | downLoadDirFromCos(start_prefix) 136 | -------------------------------------------------------------------------------- /demo/disaster_recovery_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | # 3 | # ref to @shezhangjun 4 | # https://github.com/shezhangjun/TencentCOS/blob/master/Python_SDK/COS_Disaster_Recovery/DisasterRecovery.py 5 | # 6 | from qcloud_cos import CosConfig 7 | from qcloud_cos import CosS3Client 8 | import sys 9 | import os 10 | import logging 11 | 12 | # logging.basicConfig(level=logging.INFO, stream=sys.stdout) 13 | 14 | 15 | def _recover_main(src_region, src_secret_id, src_secret_key, src_bucket, prefix, 16 | dst_region, dst_secret_id, dst_secret_key, dst_bucket): 17 | src_client = CosS3Client(CosConfig(Region=src_region, SecretId=src_secret_id, SecretKey=src_secret_key)) 18 | dst_client = CosS3Client(CosConfig(Region=dst_region, SecretId=dst_secret_id, SecretKey=dst_secret_key)) 19 | 20 | key_marker = '' 21 | versionId_marker = '' 22 | while True: 23 | response = src_client.list_objects_versions( 24 | Bucket=src_bucket, 25 | Prefix=prefix, 26 | KeyMarker=key_marker, 27 | VersionIdMarker=versionId_marker, 28 | ) 29 | delete_marker_keys = list() 30 | recovered_keys = list() 31 | # 从 DeleteMarker 取出被删除的对象 32 | if 'DeleteMarker' in response: 33 | for version in response['DeleteMarker']: 34 | if version['IsLatest'] == 'true': 35 | delete_marker_keys.append(version['Key']) 36 | 37 | if len(delete_marker_keys) == 0: 38 | print('no delete markers found, no data to recover') 39 | return 40 | 41 | # 从 Version 取最新的版本号 42 | if 'Version' in response: 43 | for version in response['Version']: 44 | key = version['Key'] 45 | versionId = version['VersionId'] 46 | if key in delete_marker_keys and not key in recovered_keys: 47 | print('recover from key:{key}, versionId:{versionId}'.format(key=key, versionId=versionId)) 48 | try: 49 | dst_client.copy( 50 | Bucket=dst_bucket, 51 | Key=key, 52 | CopySource={ 53 | 'Bucket': src_bucket, 54 | 'Key': key, 55 | 'Region': src_region, 56 | 'VersionId': versionId, 57 | } 58 | ) 59 | recovered_keys.append(key) 60 | print("success recover object: {src_bucket}/{key}({versionId}) => {dst_bucket}/{key}".format( 61 | src_bucket=src_bucket, key=key, versionId=versionId, dst_bucket=dst_bucket)) 62 | except Exception as e: 63 | print(e) 64 | pass 65 | 66 | if response['IsTruncated'] == 'false': 67 | break 68 | 69 | key_marker = response['NextKeyMarker'] 70 | versionId_marker = response['NextVersionIdMarker'] 71 | 72 | 73 | if __name__ == '__main__': 74 | # 使用场景: 75 | # 根据源桶src_bucket的删除标记从历史版本里把文件恢复到dst_bucket 76 | # src_bucket和dst_bucket可以一致, 即原地恢复 77 | 78 | # 源桶信息 79 | src_region = 'ap-guangzhou' # 源地域 80 | src_secret_id = '' # 源桶SecretID 81 | src_secret_key = '' # 源桶SecretKey 82 | src_bucket = 'bucket-1200000000' # 源桶名 83 | 84 | # 目标桶信息 85 | dst_region = 'ap-guangzhou' # 目标桶地域 86 | dst_secret_id = '' # 目标桶SecretID 87 | dst_secret_key = '' # 目标桶SecretKey 88 | dst_bucket = 'bucket-1250000000' # 目标桶名 89 | 90 | prefix = '' # 设置要恢复的对象前缀 91 | 92 | _recover_main(src_region, src_secret_id, src_secret_key, src_bucket, prefix, 93 | dst_region, dst_secret_id, dst_secret_key, dst_bucket) -------------------------------------------------------------------------------- /demo/download_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos.cos_exception import CosClientError, CosServiceError 5 | from qcloud_cos.cos_threadpool import SimpleThreadPool 6 | 7 | import sys 8 | import os 9 | import json 10 | import logging 11 | 12 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 13 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 14 | 15 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 16 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 17 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 18 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 19 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 20 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 21 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 22 | 23 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 24 | client = CosS3Client(config) 25 | 26 | '''下载对象(断点续传) 27 | ''' 28 | 29 | # 使用高级接口下载一次,不重试,此时没有使用断点续传的功能 30 | response = client.download_file( 31 | Bucket='examplebucket-1250000000', 32 | Key='exampleobject', 33 | DestFilePath='local.txt' 34 | ) 35 | 36 | # 使用高级接口断点续传,失败重试时不会下载已成功的分块(这里重试10次) 37 | for i in range(0, 10): 38 | try: 39 | response = client.download_file( 40 | Bucket='examplebucket-1250000000', 41 | Key='exampleobject', 42 | DestFilePath='local.txt') 43 | break 44 | except CosClientError or CosServiceError as e: 45 | print(e) 46 | 47 | 48 | '''批量下载(从COS下载目录) 49 | ''' 50 | 51 | # 用户的 bucket 信息 52 | test_bucket = 'examplebucket-1250000000' 53 | start_prefix = 'data/' 54 | # 对象存储依赖 分隔符 '/' 来模拟目录语义, 55 | # 使用默认的空分隔符可以列出目录下面的所有子节点,实现类似本地目录递归的效果, 56 | # 如果 delimiter 设置为 "/",则需要在程序里递归处理子目录 57 | delimiter = '' 58 | 59 | 60 | # 列出当前目录子节点,返回所有子节点信息 61 | def listCurrentDir(prefix): 62 | file_infos = [] 63 | sub_dirs = [] 64 | marker = "" 65 | count = 1 66 | while True: 67 | response = client.list_objects(test_bucket, prefix, delimiter, marker) 68 | # 调试输出 69 | # json_object = json.dumps(response, indent=4) 70 | # print(count, " =======================================") 71 | # print(json_object) 72 | count += 1 73 | 74 | if "CommonPrefixes" in response: 75 | common_prefixes = response.get("CommonPrefixes") 76 | sub_dirs.extend(common_prefixes) 77 | 78 | if "Contents" in response: 79 | contents = response.get("Contents") 80 | file_infos.extend(contents) 81 | 82 | if "NextMarker" in response.keys(): 83 | marker = response["NextMarker"] 84 | else: 85 | break 86 | 87 | print("=======================================================") 88 | 89 | # 如果 delimiter 设置为 "/",则需要进行递归处理子目录, 90 | # sorted(sub_dirs, key=lambda sub_dir: sub_dir["Prefix"]) 91 | # for sub_dir in sub_dirs: 92 | # print(sub_dir) 93 | # sub_dir_files = listCurrentDir(sub_dir["Prefix"]) 94 | # file_infos.extend(sub_dir_files) 95 | 96 | print("=======================================================") 97 | 98 | sorted(file_infos, key=lambda file_info: file_info["Key"]) 99 | for file in file_infos: 100 | print(file) 101 | return file_infos 102 | 103 | 104 | # 下载文件到本地目录,如果本地目录已经有同名文件则会被覆盖; 105 | # 如果目录结构不存在,则会创建和对象存储一样的目录结构 106 | def downLoadFiles(file_infos): 107 | localDir = "./download/" 108 | 109 | pool = SimpleThreadPool() 110 | for file in file_infos: 111 | # 文件下载 获取文件到本地 112 | file_cos_key = file["Key"] 113 | localName = localDir + file_cos_key 114 | 115 | # 如果本地目录结构不存在,递归创建 116 | if not os.path.exists(os.path.dirname(localName)): 117 | os.makedirs(os.path.dirname(localName)) 118 | 119 | # skip dir, no need to download it 120 | if str(localName).endswith("/"): 121 | continue 122 | 123 | # 实际下载文件 124 | # 使用线程池方式 125 | pool.add_task(client.download_file, test_bucket, file_cos_key, localName) 126 | 127 | # 简单下载方式 128 | # response = client.get_object( 129 | # Bucket=test_bucket, 130 | # Key=file_cos_key, 131 | # ) 132 | # response['Body'].get_stream_to_file(localName) 133 | 134 | pool.wait_completion() 135 | return None 136 | 137 | 138 | # 功能封装,下载对象存储上面的一个目录到本地磁盘 139 | def downLoadDirFromCos(prefix): 140 | global file_infos 141 | 142 | try: 143 | file_infos = listCurrentDir(prefix) 144 | 145 | except CosServiceError as e: 146 | print(e.get_origin_msg()) 147 | print(e.get_digest_msg()) 148 | print(e.get_status_code()) 149 | print(e.get_error_code()) 150 | print(e.get_error_msg()) 151 | print(e.get_resource_location()) 152 | print(e.get_trace_id()) 153 | print(e.get_request_id()) 154 | 155 | downLoadFiles(file_infos) 156 | return None 157 | 158 | downLoadDirFromCos(start_prefix) 159 | 160 | 161 | '''简单下载 162 | ''' 163 | 164 | response = client.get_object( 165 | Bucket='examplebucket-1250000000', 166 | Key='exampleobject' 167 | ) 168 | response['Body'].get_stream_to_file('exampleobject') 169 | 170 | 171 | '''下载对象部分内容 172 | ''' 173 | 174 | response = client.get_object( 175 | Bucket='examplebucket-1250000000', 176 | Key='exampleobject', 177 | Range='bytes=0-100' 178 | ) 179 | response['Body'].get_stream_to_file('exampleobject') 180 | 181 | -------------------------------------------------------------------------------- /demo/fetch_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos import CosServiceError 5 | from qcloud_cos import CosClientError 6 | 7 | import sys 8 | import logging 9 | 10 | # Fetch接口异步拉取URL资源保存到COS 11 | 12 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 13 | 14 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 15 | secret_id = 'SecretId' # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 16 | secret_key = 'SecretKey' # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 17 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 18 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 19 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 20 | scheme = 'http' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 21 | 22 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) # 获取配置对象 23 | client = CosS3Client(config) 24 | 25 | test_bucket = 'examplebucket-1250000000' 26 | # 发起拉取任务 27 | response = client.put_async_fetch_task( 28 | Bucket=test_bucket, 29 | FetchTaskConfiguration={ 30 | 'Url': 'http://examplebucket-1250000000.cos.ap-beijing.tencentcos.cn/exampleobject', 31 | 'Key': 'exampleobject' 32 | } 33 | ) 34 | 35 | # 查询拉取任务 36 | response = client.get_async_fetch_task( 37 | Bucket=test_bucket, 38 | TaskId=response['data']['taskid'] 39 | ) 40 | -------------------------------------------------------------------------------- /demo/get_object_url.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | import requests 8 | 9 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 10 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 11 | 12 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 13 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 15 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 16 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 17 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 18 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 19 | 20 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 21 | client = CosS3Client(config) 22 | 23 | # 生成URL 24 | url = client.get_object_url( 25 | Bucket='examplebucket-1250000000', 26 | Key='exampleobject' 27 | ) 28 | print(url) 29 | 30 | # 使用URL 31 | response = requests.get(url) 32 | print(response) -------------------------------------------------------------------------------- /demo/get_presigned_url.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | import requests 8 | import time 9 | 10 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 11 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 12 | 13 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 14 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 15 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 16 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 17 | # COS 支持的所有 region 列表参见https://cloud.tencent.com/document/product/436/6224 18 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 19 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 20 | 21 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 22 | client = CosS3Client(config) 23 | 24 | '''生成上传预签名 URL 25 | ''' 26 | 27 | # 生成上传 URL,未限制请求头部和请求参数 28 | url = client.get_presigned_url( 29 | Method='PUT', 30 | Bucket='examplebucket-1250000000', 31 | Key='exampleobject', 32 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 33 | ) 34 | print(url) 35 | 36 | # 生成上传 URL,同时限制存储类型和上传速度 37 | url = client.get_presigned_url( 38 | Method='PUT', 39 | Bucket='examplebucket-1250000000', 40 | Key='exampleobject', 41 | Headers={ 42 | 'x-cos-storage-class':'STANDARD_IA', 43 | 'x-cos-traffic-limit':'819200' # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值 44 | }, 45 | Expired=300 # 300秒后过期,过期时间请根据自身场景定义 46 | ) 47 | print(url) 48 | 49 | # 生成上传 URL,只能上传指定的文件内容 50 | url = client.get_presigned_url( 51 | Method='PUT', 52 | Bucket='examplebucket-1250000000', 53 | Key='exampleobject', 54 | Headers={'Content-MD5':'string'}, # 约定使用此 URL 上传对象的人必须携带 MD5 请求头部,并且请求头部的值必须是这里指定的值,这样就限定了文件的内容 55 | Expired=300 # 300秒后过期,过期时间请根据自身场景定义 56 | ) 57 | print(url) 58 | 59 | # 生成上传 URL,只能用于上传 ACL 60 | url = client.get_presigned_url( 61 | Method='PUT', 62 | Bucket='examplebucket-1250000000', 63 | Key='exampleobject', 64 | Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值 65 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 66 | ) 67 | print(url) 68 | 69 | # 生成上传 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用 70 | url = client.get_presigned_url( 71 | Method='PUT', 72 | Bucket='examplebucket-1250000000', 73 | Key='exampleobject', 74 | SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险 75 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 76 | ) 77 | print(url) 78 | 79 | # 使用上传 URL 80 | retry = 1 # 简单重试1次 81 | for i in range(retry + 1): 82 | response = requests.put(url=url, data=b'123') 83 | if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试 84 | time.sleep(1) # 延迟 1s 后再重试 85 | continue 86 | # 请求结束, 打印结果并退出循环 87 | print(response) 88 | break 89 | 90 | 91 | '''生成下载预签名 URL 92 | ''' 93 | 94 | # 生成下载 URL,未限制请求头部和请求参数 95 | url = client.get_presigned_url( 96 | Method='GET', 97 | Bucket='examplebucket-1250000000', 98 | Key='exampleobject', 99 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 100 | ) 101 | print(url) 102 | 103 | # 生成下载 URL,同时指定响应的 content-disposition 头部,让文件在浏览器另存为,而不是显示 104 | url = client.get_presigned_url( 105 | Method='GET', 106 | Bucket='examplebucket-1250000000', 107 | Key='exampleobject', 108 | Params={ 109 | 'response-content-disposition':'attachment; filename=example.xlsx' # 下载时保存为指定的文件 110 | # 除了 response-content-disposition,还支持 response-cache-control、response-content-encoding、response-content-language、 111 | # response-content-type、response-expires 等请求参数,详见下载对象 API,https://cloud.tencent.com/document/product/436/7753 112 | }, 113 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 114 | ) 115 | print(url) 116 | 117 | # 生成下载 URL,同时限制下载速度 118 | url = client.get_presigned_url( 119 | Method='GET', 120 | Bucket='examplebucket-1250000000', 121 | Key='exampleobject', 122 | Headers={'x-cos-traffic-limit':'819200'}, # 预签名URL本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值 123 | Expired=300 # 300秒后过期,过期时间请根据自身场景定义 124 | ) 125 | print(url) 126 | 127 | # 生成下载 URL,只能用于下载 ACL 128 | url = client.get_presigned_url( 129 | Method='GET', 130 | Bucket='examplebucket-1250000000', 131 | Key='exampleobject', 132 | Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值 133 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 134 | ) 135 | print(url) 136 | 137 | # 生成下载 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用 138 | url = client.get_presigned_url( 139 | Method='GET', 140 | Bucket='examplebucket-1250000000', 141 | Key='exampleobject', 142 | SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险 143 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 144 | ) 145 | print(url) 146 | 147 | # 使用下载URL 148 | retry = 1 # 简单重试1次 149 | for i in range(retry + 1): 150 | response = requests.get(url) 151 | if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试 152 | time.sleep(1) # 延迟 1s 后再重试 153 | continue 154 | # 请求结束, 打印结果并退出循环 155 | print(response) 156 | break 157 | 158 | 159 | '''使用临时密钥生成下载预签名 URL 160 | ''' 161 | 162 | # 生成下载 URL 163 | url = client.get_presigned_url( 164 | Method='GET', 165 | Bucket='examplebucket-1250000000', 166 | Key='exampleobject', 167 | Headers={'x-cos-traffic-limit':'819200'}, # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值 168 | Params={ 169 | 'x-cos-security-token': 'string' # 使用临时密钥需要填入 Token 到请求参数 170 | }, 171 | Expired=120, # 120秒后过期,过期时间请根据自身场景定义 172 | SignHost=False # 请求域名不算入签名,签名后使用者需要修改请求域名时使用,有一定安全风险 173 | ) 174 | print(url) 175 | 176 | # 使用下载 URL 177 | retry = 1 # 简单重试1次 178 | for i in range(retry + 1): 179 | response = requests.get(url) 180 | if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试 181 | time.sleep(1) # 延迟 1s 后再重试 182 | continue 183 | # 请求结束, 打印结果并退出循环 184 | print(response) 185 | break 186 | 187 | 188 | '''生成下载对象的预签名 URL 189 | ''' 190 | 191 | # 生成下载 URL,未限制请求头部和请求参数 192 | url = client.get_presigned_download_url( 193 | Bucket='examplebucket-1250000000', 194 | Key='exampleobject', 195 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 196 | ) 197 | print(url) 198 | 199 | # 生成下载 URL,同时指定响应的 content-disposition 头部,让文件在浏览器另存为,而不是显示 200 | url = client.get_presigned_download_url( 201 | Bucket='examplebucket-1250000000', 202 | Key='exampleobject', 203 | Params={ 204 | 'response-content-disposition':'attachment; filename=example.xlsx' # 下载时保存为指定的文件 205 | # 除了 response-content-disposition,还支持 response-cache-control、response-content-encoding、response-content-language、 206 | # response-content-type、response-expires 等请求参数,详见下载对象 API,https://cloud.tencent.com/document/product/436/7753 207 | }, 208 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 209 | ) 210 | print(url) 211 | 212 | # 生成下载 URL,同时限制下载速度 213 | url = client.get_presigned_download_url( 214 | Bucket='examplebucket-1250000000', 215 | Key='exampleobject', 216 | Headers={'x-cos-traffic-limit':'819200'}, # 预签名 URL 本身是不包含请求头部的,但请求头部会算入签名,那么使用 URL 时就必须携带请求头部,并且请求头部的值必须是这里指定的值 217 | Expired=300 # 300秒后过期,过期时间请根据自身场景定义 218 | ) 219 | print(url) 220 | 221 | # 生成下载 URL,只能用于下载 ACL 222 | url = client.get_presigned_download_url( 223 | Bucket='examplebucket-1250000000', 224 | Key='exampleobject', 225 | Params={'acl':''}, # 指定了请求参数,则 URL 中会携带此请求参数,并且请求参数会算入签名,不允许使用者修改请求参数的值 226 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 227 | ) 228 | print(url) 229 | 230 | # 生成下载 URL,请求域名不算入签名,签名后使用者需要修改请求域名时使用 231 | url = client.get_presigned_download_url( 232 | Bucket='examplebucket-1250000000', 233 | Key='exampleobject', 234 | SignHost=False, # 请求域名不算入签名,允许使用者修改请求域名,有一定安全风险 235 | Expired=120 # 120秒后过期,过期时间请根据自身场景定义 236 | ) 237 | print(url) 238 | 239 | # 生成下载 URL,使用临时密钥签名 240 | url = client.get_presigned_download_url( 241 | Bucket='examplebucket-1250000000', 242 | Key='exampleobject', 243 | Params={ 244 | 'x-cos-security-token': 'string' # 使用永久密钥不需要填入 token,如果使用临时密钥需要填入 245 | } 246 | ) 247 | print(url) 248 | 249 | # 使用下载 URL 250 | retry = 1 # 简单重试1次 251 | for i in range(retry + 1): 252 | response = requests.get(url) 253 | if response.status_code == 400 or response.status_code >= 500: # 只对400和5xx错误码进行重试 254 | time.sleep(1) # 延迟 1s 后再重试 255 | continue 256 | # 请求结束, 打印结果并退出循环 257 | print(response) 258 | break 259 | -------------------------------------------------------------------------------- /demo/head_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | response = client.head_object( 23 | Bucket='examplebucket-1250000000', 24 | Key='exampleobject' 25 | ) 26 | print(response) -------------------------------------------------------------------------------- /demo/hls_decrypt_token.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import base64 3 | import jwt 4 | from urllib.parse import quote, quote_plus 5 | from qcloud_cos import CosConfig 6 | from qcloud_cos import CosS3Client 7 | from datetime import datetime, timedelta 8 | 9 | import sys 10 | import logging 11 | import os 12 | 13 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 14 | 15 | # 媒体处理相关API请参考 https://cloud.tencent.com/document/product/460/84790 16 | 17 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 18 | 19 | # 设置用户属性, 包括secret_id, secret_key, region 20 | # appid已在配置中移除,请在参数Bucket中带上appid。Bucket由bucketname-appid组成 21 | # 这里秘钥是从环境变量取得,如自己测试可改成自己对应的秘钥 22 | secret_id = os.environ["SECRETID"] # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 23 | secret_key = os.environ["SECRETKEY"] # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 24 | region = 'ap-chongqing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 25 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 26 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 27 | 28 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme='https') # 获取配置对象 29 | client = CosS3Client(config) 30 | 31 | 32 | bucket_name = 'demo-1250000000' 33 | play_key = 'play_key' 34 | object_name = 'test.m3u8' 35 | 36 | 37 | def generate_token(): 38 | now = datetime.now() 39 | expire_time = now + timedelta(minutes=30) 40 | path_encoded = quote(object_name) 41 | object = quote_plus(path_encoded) 42 | 43 | headers = { 44 | # 加密的算法,固定为 HS256 45 | "alg": "HS256", 46 | # 类型,固定为 JWT 47 | "typ": "JWT" 48 | } 49 | token_info = { 50 | # 固定为 CosCiToken, 必填参数 51 | 'Type': 'CosCiToken', 52 | # app id,必填参数 53 | 'AppId': '1250000000', 54 | # 播放文件所在的BucketId, 必填参数 55 | 'BucketId': bucket_name, 56 | # 播放文件名 57 | 'Object': object, 58 | # 固定为client,必填参数 59 | 'Issuer': 'client', 60 | # token颁发时间戳,必填参数 61 | 'IssuedTimeStamp': now.timestamp(), 62 | # token过期时间戳,非必填参数,默认1天过期 63 | 'ExpireTimeStamp': expire_time.timestamp(), 64 | # token使用次数限制,非必填参数,默认限制100000次 65 | 'UsageLimit': 20, 66 | # 是否加密解密密钥(播放时解密ts视频流的密钥),1表示对解密密钥加密,0表示不对解密密钥加密。 67 | 'ProtectContentKey': 1, 68 | } 69 | if token_info['ProtectContentKey'] == 1: 70 | public_key = """-----BEGIN PUBLIC KEY----- 71 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxBgQCj9GNktf2yA0Mp8aCzxxxxxxxx 72 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx54Jl4NVNewBLPZq1WFxxxxxxxxxx 73 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKpSCdl9hHxFZ732ixxxxxxxxxxxx 74 | xxxxxxxxxxxxxxxxxxxx 75 | -----END PUBLIC KEY-----""" 76 | base64_public_key = base64.urlsafe_b64encode(public_key.encode('utf-8')).decode('utf-8') 77 | token_info.update({ 78 | # 保护模式,填写为 rsa1024 ,则表示使用 RSA 非对称加密的方式保护,公私钥对长度为 1024 bit 79 | 'ProtectSchema': "rsa1024", 80 | # 公钥。1024 bit 的 RSA 公钥,需使用 Base64 进行编码 81 | 'PublicKey': base64_public_key, 82 | }) 83 | return jwt.encode(token_info, play_key, algorithm="HS256", headers=headers) 84 | 85 | 86 | def get_url(): 87 | url = client.get_presigned_download_url( 88 | Bucket=bucket_name, # 存储桶名称 89 | Key="/" + object_name, 90 | Expired=3600, # 预签名超时时间 91 | ) 92 | if token is not None: 93 | url = url + "&x-cos-security-token=" + token 94 | url = url + "&tokenType=JwtToken&expires=3600&ci-process=pm3u8&token=" + generate_token() 95 | return url 96 | 97 | 98 | if __name__ == '__main__': 99 | print(generate_token()) 100 | print(get_url()) 101 | -------------------------------------------------------------------------------- /demo/list_objects.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 分页列举桶内对象,每个分页10个对象 23 | marker = "" 24 | while True: 25 | response = client.list_objects( 26 | Bucket='examplebucket-1250000000', Prefix='folder1/', Marker=marker, MaxKeys=10) 27 | if 'Contents' in response: 28 | for content in response['Contents']: 29 | print(content['Key']) 30 | 31 | if response['IsTruncated'] == 'false': 32 | break 33 | 34 | marker = response["NextMarker"] 35 | 36 | 37 | # 列举 folder1 目录下的文件和子目录 38 | response = client.list_objects( 39 | Bucket='examplebucket-1250000000', Prefix='a/', Delimiter='/') 40 | # 打印文件列表 41 | if 'Contents' in response: 42 | for content in response['Contents']: 43 | print(content['Key']) 44 | # 打印子目录 45 | if 'CommonPrefixes' in response: 46 | for folder in response['CommonPrefixes']: 47 | print(folder['Prefix']) 48 | 49 | 50 | # 查询对象及其历史版本列表 51 | marker = "" 52 | while True: 53 | response = client.list_objects_versions( 54 | Bucket='examplebucket-1250000000', Prefix='folder1/', KeyMarker=marker, MaxKeys=10) 55 | if 'Version' in response: 56 | for version in response['Version']: 57 | print(version) 58 | 59 | if response['IsTruncated'] == 'false': 60 | break 61 | 62 | marker = response["NextMarker"] -------------------------------------------------------------------------------- /demo/meta_insight_demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | 3 | from qcloud_cos import CosConfig 4 | from qcloud_cos import MetaInsightClient 5 | 6 | import os 7 | import sys 8 | import logging 9 | 10 | # 腾讯云COSV5Python SDK, 目前可以支持Python2.6与Python2.7以及Python3.x 11 | 12 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 13 | 14 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 15 | # 替换为用户的 SecretId,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 16 | secret_id = os.environ["SECRETID"] 17 | # 替换为用户的 SecretKey,请登录访问管理控制台进行查看和管理,https://console.cloud.tencent.com/cam/capi 18 | secret_key = os.environ["SECRETKEY"] 19 | # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 20 | region = 'ap-chongqing' 21 | # COS支持的所有region列表参见https://www.qcloud.com/document/product/436/6224 22 | token = None # 如果使用永久密钥不需要填入token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见https://cloud.tencent.com/document/product/436/14048 23 | 24 | appid = '1250000000' 25 | 26 | config = CosConfig(Appid=appid, Region=region, SecretId=secret_id, 27 | SecretKey=secret_key, 28 | Token=token) # 获取配置对象 29 | client = MetaInsightClient(config) 30 | 31 | bucket_name = 'examplebucket-1250000000' 32 | 33 | 34 | def ci_create_dataset(): 35 | # 创建数据集 36 | body = { 37 | # 数据集名称,同一个账户下唯一。命名规则如下: 长度为1~32字符。 只能包含小写英文字母,数字,短划线(-)。 必须以英文字母和数字开头。 38 | # 是否必传:是 39 | 'DatasetName': "test", 40 | # 数据集描述信息。长度为1~256个英文或中文字符,默认值为空。 41 | # 是否必传:否 42 | 'Description': "test", 43 | # 与数据集关联的检索模板,在建立元数据索引时,后端将根据检索模板来决定采集文件的哪些元数据。每个检索模板都包含若干个算子,不同的算子表示不同的处理能力,更多信息请参见 [检索模板与算子](https://cloud.tencent.com/document/product/460/106018)。 默认值为空,即不关联检索模板,不进行任何元数据的采集。 44 | # 是否必传:否 45 | 'TemplateId': "Official:COSBasicMeta", 46 | } 47 | response, data = client.ci_create_dataset( 48 | Body=body, 49 | ContentType="application/json" 50 | ) 51 | print(response) 52 | print(data) 53 | return response, data 54 | 55 | 56 | def ci_create_dataset_binding(): 57 | # 绑定存储桶与数据集 58 | body = { 59 | # 数据集名称,同一个账户下唯一 60 | # 是否必传:是 61 | 'DatasetName': "test", 62 | # 资源标识字段,表示需要与数据集绑定的资源,当前仅支持COS存储桶,字段规则:cos://,其中BucketName表示COS存储桶名称,例如:cos://examplebucket-1250000000 63 | # 是否必传:是 64 | 'URI': "cos://examplebucket-1250000000", 65 | } 66 | response, data = client.ci_create_dataset_binding( 67 | Body=body, 68 | ContentType="application/json" 69 | ) 70 | print(response) 71 | print(data) 72 | return response, data 73 | 74 | 75 | def ci_create_file_meta_index(): 76 | # 创建元数据索引 77 | body = { 78 | # 数据集名称,同一个账户下唯一。 79 | # 是否必传:是 80 | 'DatasetName': "test001", 81 | # 用于建立索引的文件信息。 82 | # 是否必传:是 83 | 'File': { 84 | # 自定义ID。该文件索引到数据集后,作为该行元数据的属性存储,用于和您的业务系统进行关联、对应。您可以根据业务需求传入该值,例如将某个URI关联到您系统内的某个ID。推荐传入全局唯一的值。在查询时,该字段支持前缀查询和排序,详情请见[字段和操作符的支持列表](https://cloud.tencent.com/document/product/460/106154)。 85 | # 是否必传:否 86 | 'CustomId': "001", 87 | # 自定义标签。您可以根据业务需要自定义添加标签键值对信息,用于在查询时可以据此为筛选项进行检索,详情请见[字段和操作符的支持列表](https://cloud.tencent.com/document/product/460/106154)。 88 | # 是否必传:否 89 | 'CustomLabels': {"age": "18", "level": "18"}, 90 | # 可选项,文件媒体类型,枚举值: image:图片。 other:其他。 document:文档。 archive:压缩包。 video:视频。 audio:音频。 91 | # 是否必传:否 92 | 'MediaType': "image", 93 | # 可选项,文件内容类型(MIME Type),如image/jpeg。 94 | # 是否必传:否 95 | 'ContentType': "image/jpeg", 96 | # 资源标识字段,表示需要建立索引的文件地址,当前仅支持COS上的文件,字段规则:cos:///,其中BucketName表示COS存储桶名称,ObjectKey表示文件完整路径,例如:cos://examplebucket-1250000000/test1/img.jpg。 注意: 1、仅支持本账号内的COS文件 2、不支持HTTP开头的地址 97 | # 是否必传:是 98 | 'URI': "cos://examplebucket-1250000000/test.jpg", 99 | # 输入图片中检索的人脸数量,默认值为20,最大值为20。(仅当数据集模板 ID 为 Official:FaceSearch 有效)。 100 | # 是否必传:否 101 | 'MaxFaceNum': 20, 102 | # 自定义人物属性(仅当数据集模板 ID 为 Official:FaceSearch 有效)。 103 | # 是否必传:否 104 | 'Persons': [{ 105 | # 自定义人物 ID。 106 | # 是否必传:否 107 | 'PersonId': "xxxxx", 108 | }], 109 | }, 110 | } 111 | response, data = client.ci_create_file_meta_index( 112 | Body=body, 113 | ContentType="application/json" 114 | ) 115 | print(response) 116 | print(data) 117 | return response, data 118 | 119 | 120 | def ci_dataset_face_search(): 121 | # 人脸搜索 122 | body = { 123 | # 数据集名称,同一个账户下唯一。 124 | # 是否必传:是 125 | 'DatasetName': "test", 126 | # 资源标识字段,表示需要建立索引的文件地址。 127 | # 是否必传:是 128 | 'URI': "cos://examplebucket-1250000000/test.jpg", 129 | # 输入图片中检索的人脸数量,默认值为1(传0或不传采用默认值),最大值为10。 130 | # 是否必传:否 131 | 'MaxFaceNum': 1, 132 | # 检索的每张人脸返回相关人脸数量,默认值为10,最大值为100。 133 | # 是否必传:否 134 | 'Limit': 10, 135 | # 限制返回人脸的最低相关度分数,只有超过 MatchThreshold 值的人脸才会返回。默认值为0,推荐值为80。 例如:设置 MatchThreshold 的值为80,则检索结果中仅会返回相关度分数大于等于80分的人脸。 136 | # 是否必传:否 137 | 'MatchThreshold': 10, 138 | } 139 | response, data = client.ci_dataset_face_search( 140 | Body=body, 141 | ContentType="application/json" 142 | ) 143 | print(response) 144 | print(data) 145 | return response, data 146 | 147 | 148 | def ci_dataset_simple_query(): 149 | # 简单查询 150 | body = { 151 | # 数据集名称,同一个账户下唯一。 152 | # 是否必传:是 153 | 'DatasetName': "test", 154 | # 简单查询参数条件,可自嵌套。 155 | # 是否必传:否 156 | 'Query': { 157 | # 操作运算符。枚举值: not:逻辑非。 or:逻辑或。 and:逻辑与。 lt:小于。 lte:小于等于。 gt:大于。 gte:大于等于。 eq:等于。 exist:存在性查询。 prefix:前缀查询。 match-phrase:字符串匹配查询。 nested:字段为数组时,其中同一对象内逻辑条件查询。 158 | # 是否必传:是 159 | 'Operation': "and", 160 | # 子查询的结构体。 只有当Operations为逻辑运算符(and、or、not或nested)时,才能设置子查询条件。 在逻辑运算符为and/or/not时,其SubQueries内描述的所有条件需符合父级设置的and/or/not逻辑关系。 在逻辑运算符为nested时,其父级的Field必须为一个数组类的字段(如:Labels)。 子查询条件SubQueries组的Operation必须为and/or/not中的一个或多个,其Field必须为父级Field的子属性。 161 | # 是否必传:否 162 | 'SubQueries': [{ 163 | # 查询的字段值。当Operations为逻辑运算符(and、or、not或nested)时,该字段无效。 164 | # 是否必传:否 165 | 'Value': "image/jpeg", 166 | # 操作运算符。枚举值:not:逻辑非。or:逻辑或。and:逻辑与。lt:小于。lte:小于等于。gt:大于。gte:大于等于。eq:等于。exist:存在性查询。prefix:前缀查询。match-phrase:字符串匹配查询。nested:字段为数组时,其中同一对象内逻辑条件查询。 167 | # 是否必传:是 168 | 'Operation': "eq", 169 | # 字段名称。关于支持的字段,请参考字段和操作符的支持列表。 170 | # 是否必传:否 171 | 'Field': "ContentType", 172 | }], 173 | }, 174 | # 返回文件元数据的最大个数,取值范围为0200。 使用聚合参数时,该值表示返回分组的最大个数,取值范围为02000。 不设置此参数或者设置为0时,则取默认值100。 175 | # 是否必传:否 176 | 'MaxResults': 100, 177 | # 排序字段列表。请参考[字段和操作符的支持列表](https://cloud.tencent.com/document/product/460/106154)。 多个排序字段可使用半角逗号(,)分隔,例如:Size,Filename。 最多可设置5个排序字段。 排序字段顺序即为排序优先级顺序。 178 | # 是否必传:否 179 | 'Sort': "CustomId", 180 | # 排序字段的排序方式。取值如下: asc:升序; desc(默认):降序。 多个排序方式可使用半角逗号(,)分隔,例如:asc,desc。 排序方式不可多于排序字段,即参数Order的元素数量需小于等于参数Sort的元素数量。例如Sort取值为Size,Filename时,Order可取值为asc,desc或asc。 排序方式少于排序字段时,未排序的字段默认取值asc。例如Sort取值为Size,Filename,Order取值为asc时,Filename默认排序方式为asc,即升序排列 181 | # 是否必传:否 182 | 'Order': "desc", 183 | } 184 | response, data = client.ci_dataset_simple_query( 185 | Body=body, 186 | ContentType="application/json" 187 | ) 188 | print(response) 189 | print(data) 190 | return response, data 191 | 192 | 193 | def ci_delete_dataset(): 194 | # 删除数据集 195 | body = { 196 | # 数据集名称,同一个账户下唯一。 197 | # 是否必传:是 198 | 'DatasetName': "test", 199 | } 200 | response, data = client.ci_delete_dataset( 201 | Body=body, 202 | ContentType="application/json" 203 | ) 204 | print(response) 205 | print(data) 206 | return response, data 207 | 208 | 209 | def ci_delete_dataset_binding(): 210 | # 解绑存储桶与数据集 211 | body = { 212 | # 数据集名称,同一个账户下唯一。 213 | # 是否必传:是 214 | 'DatasetName': "test", 215 | # 资源标识字段,表示需要与数据集绑定的资源,当前仅支持COS存储桶,字段规则:cos://,其中BucketName表示COS存储桶名称,例如:cos://examplebucket-1250000000 216 | # 是否必传:是 217 | 'URI': "cos://examplebucket-1250000000", 218 | } 219 | response, data = client.ci_delete_dataset_binding( 220 | Body=body, 221 | ContentType="application/json" 222 | ) 223 | print(response) 224 | print(data) 225 | return response, data 226 | 227 | 228 | def ci_delete_file_meta_index(): 229 | # 删除元数据索引 230 | body = { 231 | # 数据集名称,同一个账户下唯一。 232 | # 是否必传:是 233 | 'DatasetName': "test", 234 | # 资源标识字段,表示需要建立索引的文件地址。 235 | # 是否必传:是 236 | 'URI': "cos://examplebucket-1250000000/test.jpg", 237 | } 238 | response, data = client.ci_delete_file_meta_index( 239 | Body=body, 240 | ContentType="application/json" 241 | ) 242 | print(response) 243 | print(data) 244 | return response, data 245 | 246 | 247 | def ci_describe_dataset(): 248 | # 查询数据集 249 | 250 | response, data = client.ci_describe_dataset( 251 | DatasetName="数据集名称", 252 | Statistics="", 253 | ContentType="application/json" 254 | ) 255 | print(response) 256 | print(data) 257 | return response, data 258 | 259 | 260 | def ci_describe_dataset_binding(): 261 | # 查询数据集与存储桶的绑定关系 262 | 263 | response, data = client.ci_describe_dataset_binding( 264 | DatasetName="数据集名称", 265 | Uri="uri", 266 | ContentType="application/json" 267 | ) 268 | print(response) 269 | print(data) 270 | return response, data 271 | 272 | 273 | def ci_describe_dataset_bindings(): 274 | # 查询绑定关系列表 275 | 276 | response, data = client.ci_describe_dataset_bindings( 277 | DatasetName="数据集名称", 278 | MaxResults=100, 279 | NextToken="下一页", 280 | ContentType="application/json" 281 | ) 282 | print(response) 283 | print(data) 284 | return response, data 285 | 286 | 287 | def ci_describe_datasets(): 288 | # 列出数据集 289 | 290 | response, data = client.ci_describe_datasets( 291 | MaxResults=100, 292 | NextToken="下一页", 293 | Prefix="数据集前缀", 294 | ContentType="application/json" 295 | ) 296 | print(response) 297 | print(data) 298 | return response, data 299 | 300 | 301 | def ci_describe_file_meta_index(): 302 | # 查询元数据索引 303 | 304 | response, data = client.ci_describe_file_meta_index( 305 | DatasetName="数据集名称", 306 | Uri="cos://facesearch-12500000000", 307 | ContentType="application/json" 308 | ) 309 | print(response) 310 | print(data) 311 | return response, data 312 | 313 | 314 | def ci_search_image(): 315 | # 图像检索 316 | body = { 317 | # 数据集名称,同一个账户下唯一。 318 | # 是否必传:是 319 | 'DatasetName': "ImageSearch001", 320 | # 指定检索方式为图片或文本,pic 为图片检索,text 为文本检索,默认为 pic。 321 | # 是否必传:否 322 | 'Mode': "pic", 323 | # 资源标识字段,表示需要建立索引的文件地址(Mode 为 pic 时必选)。 324 | # 是否必传:否 325 | 'URI': "cos://facesearch-1258726280/huge_base.jpg", 326 | # 返回相关图片的数量,默认值为10,最大值为100。 327 | # 是否必传:否 328 | 'Limit': 10, 329 | # 出参 Score(相关图片匹配得分) 中,只有超过 MatchThreshold 值的结果才会返回。默认值为0,推荐值为80。 330 | # 是否必传:否 331 | 'MatchThreshold': 1, 332 | } 333 | response, data = client.ci_search_image( 334 | Body=body, 335 | ContentType="application/json" 336 | ) 337 | print(response) 338 | print(data) 339 | return response, data 340 | 341 | 342 | def ci_update_dataset(): 343 | # 更新数据集 344 | body = { 345 | # 数据集名称,同一个账户下唯一。 346 | # 是否必传:是 347 | 'DatasetName': "test", 348 | # 数据集描述信息。长度为1~256个英文或中文字符,默认值为空。 349 | # 是否必传:否 350 | 'Description': "test", 351 | # 检与数据集关联的检索模板,在建立元数据索引时,后端将根据检索模板来决定采集文件的哪些元数据。 每个检索模板都包含若干个算子,不同的算子表示不同的处理能力,更多信息请参见 [检索模板与算子](https://cloud.tencent.com/document/product/460/106018)。 默认值为空,即不关联检索模板,不进行任何元数据的采集。 352 | # 是否必传:否 353 | 'TemplateId': "Official:COSBasicMeta", 354 | } 355 | response, data = client.ci_update_dataset( 356 | Body=body, 357 | ContentType="application/json" 358 | ) 359 | print(response) 360 | print(data) 361 | return response, data 362 | 363 | 364 | def ci_update_file_meta_index(): 365 | # 更新元数据索引 366 | body = { 367 | # 数据集名称,同一个账户下唯一。 368 | # 是否必传:是 369 | 'DatasetName': "test001", 370 | # 用于建立索引的文件信息。 371 | # 是否必传:是 372 | 'File': { 373 | # 自定义ID。该文件索引到数据集后,作为该行元数据的属性存储,用于和您的业务系统进行关联、对应。您可以根据业务需求传入该值,例如将某个URI关联到您系统内的某个ID。推荐传入全局唯一的值。在查询时,该字段支持前缀查询和排序,详情请见[字段和操作符的支持列表](https://cloud.tencent.com/document/product/460/106154)。 374 | # 是否必传:否 375 | 'CustomId': "001", 376 | # 自定义标签。您可以根据业务需要自定义添加标签键值对信息,用于在查询时可以据此为筛选项进行检索,详情请见[字段和操作符的支持列表](https://cloud.tencent.com/document/product/460/106154)。 377 | # 是否必传:否 378 | 'CustomLabels': {"age": "18", "level": "18"}, 379 | # 可选项,文件媒体类型,枚举值: image:图片。 other:其他。 document:文档。 archive:压缩包。 video:视频。 audio:音频。 380 | # 是否必传:否 381 | 'MediaType': "image", 382 | # 可选项,文件内容类型(MIME Type),如image/jpeg。 383 | # 是否必传:否 384 | 'ContentType': "image/jpeg", 385 | # 资源标识字段,表示需要建立索引的文件地址,当前仅支持COS上的文件,字段规则:cos:///,其中BucketName表示COS存储桶名称,ObjectKey表示文件完整路径,例如:cos://examplebucket-1250000000/test1/img.jpg。 注意: 1、仅支持本账号内的COS文件 2、不支持HTTP开头的地址 386 | # 是否必传:是 387 | 'URI': "cos://examplebucket-1250000000/test1/img.jpg", 388 | }, 389 | } 390 | response, data = client.ci_update_file_meta_index( 391 | Body=body, 392 | ContentType="application/json" 393 | ) 394 | print(response) 395 | print(data) 396 | return response, data 397 | 398 | 399 | if __name__ == '__main__': 400 | pass 401 | -------------------------------------------------------------------------------- /demo/modify_object_meta.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 修改对象元数据 23 | response = client.copy_object( 24 | Bucket='examplebucket-1250000000', 25 | Key='exampleobject', 26 | CopySource={ 27 | 'Bucket': 'sourcebucket-1250000000', 28 | 'Key': 'exampleobject', 29 | 'Region': 'ap-guangzhou' 30 | }, 31 | CopyStatus='Replaced', 32 | ContentType='text/plain', # 修改对象 ContentType 33 | Metadata={'x-cos-meta-key1': 'value1', 'x-cos-meta-key2': 'value2'} # 修改自定义元数据 34 | ) 35 | 36 | # 修改对象存储类型 37 | response = client.copy_object( 38 | Bucket='examplebucket-1250000000', 39 | Key='exampleobject', 40 | CopySource={ 41 | 'Bucket': 'examplebucket-1250000000', 42 | 'Key': 'exampleobject', 43 | 'Region': 'ap-guangzhou' 44 | }, 45 | CopyStatus='Replaced', 46 | StorageClass='STANDARD_IA' # 修改为低频存储 47 | ) 48 | -------------------------------------------------------------------------------- /demo/object_acl.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在CosConfig中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置对象 ACL 23 | response = client.put_object_acl( 24 | Bucket='examplebucket-1250000000', 25 | Key='exampleobject', 26 | ACL='public-read' 27 | ) 28 | 29 | # 查询对象 ACL 30 | response = client.get_object_acl( 31 | Bucket='examplebucket-1250000000', 32 | Key='exampleobject' 33 | ) 34 | -------------------------------------------------------------------------------- /demo/object_exists.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | response = client.object_exists( 23 | Bucket='examplebucket-1250000000', 24 | Key='exampleobject') 25 | print(response) -------------------------------------------------------------------------------- /demo/object_tagging.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置对象标签 23 | response = client.put_object_tagging( 24 | Bucket='examplebucket-1250000000', 25 | Key='exampleobject', 26 | Tagging={ 27 | 'TagSet': { 28 | 'Tag': [ 29 | { 30 | 'Key': "string", 31 | 'Value': 'string' 32 | } 33 | ] 34 | } 35 | } 36 | ) 37 | 38 | # 查询对象标签 39 | response = client.get_object_tagging( 40 | Bucket='examplebucket-1250000000', 41 | Key='exampleobject' 42 | ) 43 | print(response) 44 | 45 | # 删除对象标签 46 | response = client.delete_object_tagging( 47 | Bucket='examplebucket-1250000000', 48 | Key='exampleobject' 49 | ) 50 | 51 | -------------------------------------------------------------------------------- /demo/restore_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | response = client.restore_object( 23 | Bucket='examplebucket-1250000000', 24 | Key='exampleobject', 25 | RestoreRequest={ 26 | 'Days': 100, 27 | 'CASJobParameters': { 28 | 'Tier': 'Standard' 29 | } 30 | } 31 | ) -------------------------------------------------------------------------------- /demo/select_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | response = client.select_object_content( 23 | Bucket='examplebucket-1250000000', 24 | Key='exampleobject', 25 | Expression='Select * from COSObject', 26 | ExpressionType='SQL', 27 | InputSerialization={ 28 | 'CompressionType': 'NONE', 29 | 'JSON': { 30 | 'Type': 'LINES' 31 | } 32 | }, 33 | OutputSerialization={ 34 | 'CSV': { 35 | 'RecordDelimiter': '\n' 36 | } 37 | } 38 | ) 39 | 40 | # 获取封装在响应结果中的 EventStream 实例 41 | event_stream = response['Payload'] 42 | 43 | # 一次性获取全部检索结果 44 | # 注意, 因为 EventStream 对检索结果的获取是流式的, 所以当您再次调用 get_select_result() 方法时将返回空集 45 | result = event_stream.get_select_result() 46 | print(result) -------------------------------------------------------------------------------- /demo/server_bucket_encrypt.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 设置存储桶加密 23 | config_dict = { 24 | 'Rule': [ 25 | { 26 | 'ApplySideEncryptionConfiguration': { 27 | 'SSEAlgorithm': 'AES256' 28 | } 29 | } 30 | ] 31 | } 32 | response = client.put_bucket_encryption(Bucket='examplebucket-1250000000', ServerSideEncryptionConfiguration=config_dict) 33 | 34 | # 查询存储桶加密 35 | response = client.get_bucket_encryption(Bucket='examplebucket-1250000000') 36 | sse_algorithm = response['Rule'][0]['ApplyServerSideEncryptionByDefault']['SSEAlgorithm'] 37 | 38 | # 删除存储桶加密 39 | response = client.delete_bucket_encryption(Bucket='examplebucket-1250000000') -------------------------------------------------------------------------------- /demo/server_object_encrypt.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos.cos_comm import get_md5, to_bytes 5 | 6 | import sys 7 | import os 8 | import logging 9 | import base64 10 | 11 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 12 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 13 | 14 | # 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 15 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 16 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 17 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的region可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 18 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 19 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 20 | scheme = 'https' # 服务端加密必须使用 https 21 | 22 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) # 获取配置对象 23 | client = CosS3Client(config) 24 | 25 | # 上传 SSE-COS 加密对象,指定加密类型为 AES256即为 SSE-COS 加密 26 | response = client.put_object( 27 | Bucket='examplebucket-125000000', 28 | Key='sdk-sse-cos', 29 | Body='123', 30 | ServerSideEncryption='AES256' 31 | ) 32 | print(response['x-cos-server-side-encryption']) # 服务端返回'x-cos-server-side-encryption': 'AES256' 表示是 SSE-COS 对象 33 | 34 | # 下载 SSE-COS 加密对象,不需要携带加密头域,由服务端自动解密 35 | response = client.get_object( 36 | Bucket='examplebucket-125000000', 37 | Key='sdk-sse-cos' 38 | ) 39 | print(response['x-cos-server-side-encryption']) # 服务端返回'x-cos-server-side-encryption': 'AES256' 表示是 SSE-COS 对象 40 | 41 | 42 | # 上传 SSE-KMS 加密对象,指定加密类型为 cos/kms 即为 SSE-KMS 加密 43 | response = client.put_object( 44 | Bucket='examplebucket-125000000', 45 | Key='sdk-sse-kms', 46 | Body='123', 47 | ServerSideEncryption='cos/kms', # SSE-KMS 加密固定填写 cos/kms 48 | SSEKMSKeyId='kms-key-id', # 填写 KMS 的用户主密钥 CMK,如不填写则使用 COS 默认创建的 CMK 49 | SSEKMSContext=base64.standard_b64encode(to_bytes("{\"test\":\"test\"}")) # 加密上下文,值为 JSON 格式加密上下文键值对的 Base64 编码,可选 50 | ) 51 | print(response['x-cos-server-side-encryption']) # 服务端返回'x-cos-server-side-encryption': 'cos/kms' 表示是 SSE-KMS 对象 52 | 53 | # 下载 SSE-KMS 加密对象,不需要携带加密头域,由服务端自动解密 54 | response = client.get_object( 55 | Bucket='examplebucket-125000000', 56 | Key='sdk-sse-kms' 57 | ) 58 | print(response['x-cos-server-side-encryption']) # 服务端返回'x-cos-server-side-encryption': 'cos/kms' 表示是 SSE-KMS 对象 59 | 60 | # 高级接口上传 SSE-KMS 加密对象,指定加密类型为 cos/kms 即为 SSE-KMS 加密 61 | response = client.upload_file( 62 | Bucket='examplebucket-125000000', 63 | Key='sdk-sse-kms', 64 | LocalFilePath="sdk-sse-kms.local", 65 | ServerSideEncryption='cos/kms') # SSE-KMS 加密固定填写 cos/kms 66 | 67 | # 高级接口下载 SSE-KMS 加密对象,不需要携带加密头域,由服务端自动解密 68 | response = client.download_file( 69 | Bucket='examplebucket-125000000', 70 | Key='sdk-sse-kms', 71 | DestFilePath='sdk-sse-kms.local') 72 | 73 | # 上传、下载、拷贝、取回 SSE-C 加密对象 74 | 75 | bucket = 'examplebucket-125000000' 76 | file_name = 'sdk-sse-c' 77 | 78 | # 编码和哈希加密密钥 79 | ssec_secret = '00000000000000000000000000000001' # 原始密钥需要是32位 80 | ssec_key = base64.standard_b64encode(to_bytes(ssec_secret)) # 密钥必须 Base64编码 81 | ssec_key_md5 = get_md5(ssec_secret) 82 | 83 | # 上传 SSE-C 加密对象 84 | response = client.put_object( 85 | Bucket=bucket, Key=file_name, Body="00000", 86 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) 87 | print(response['x-cos-server-side-encryption-customer-algorithm']) # 服务端返回'x-cos-server-side-encryption-customer-algorithm': 'AES256' 表示是 SSE-C 对象 88 | 89 | # 下载 SSE-C 加密对象 90 | response = client.get_object( 91 | Bucket=bucket, Key=file_name, 92 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) 93 | print(response['x-cos-server-side-encryption-customer-algorithm']) # 服务端返回'x-cos-server-side-encryption-customer-algorithm': 'AES256' 表示是 SSE-C 对象 94 | 95 | # HEAD SSE-C 加密对象 96 | response = client.head_object( 97 | Bucket=bucket, Key=file_name, 98 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) 99 | print(response['x-cos-server-side-encryption-customer-algorithm']) # 服务端返回'x-cos-server-side-encryption-customer-algorithm': 'AES256' 表示是 SSE-C 对象 100 | 101 | # 高级接口上传 SSE-C 加密对象 102 | response = client.upload_file( 103 | Bucket=bucket, Key=file_name, LocalFilePath="sdk-sse-c.local", 104 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) 105 | 106 | # 高级接口下载 SSE-C 加密对象 107 | response = client.download_file( 108 | Bucket=bucket, Key=file_name, DestFilePath='sdk-sse-c.local', 109 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) 110 | 111 | # 拷贝 SSE-C 加密对象,源和目标的加密类型和密钥可以不一样。例子中的源对象是 SSE-C 类型,目标对象也是 SSE-C 类型。 112 | dest_ssec_secret = '00000000000000000000000000000002' # 密钥需要是32位 113 | dest_ssec_key = base64.standard_b64encode(to_bytes(dest_ssec_secret)) 114 | dest_ssec_key_md5 = get_md5(dest_ssec_secret) 115 | copy_source = {'Bucket': bucket, 'Key': file_name, 'Region': region} 116 | response = client.copy_object( 117 | Bucket=bucket, Key='sdk-sse-c-copy', CopySource=copy_source, 118 | SSECustomerAlgorithm='AES256', SSECustomerKey=dest_ssec_key, SSECustomerKeyMD5=dest_ssec_key_md5, 119 | CopySourceSSECustomerAlgorithm='AES256', CopySourceSSECustomerKey=ssec_key, CopySourceSSECustomerKeyMD5=ssec_key_md5 120 | ) 121 | 122 | # 高级接口拷贝 SSE-C 加密对象 123 | response = client.copy( 124 | Bucket=bucket, Key='sdk-sse-c-copy', CopySource=copy_source, MAXThread=2, 125 | SSECustomerAlgorithm='AES256', SSECustomerKey=dest_ssec_key, SSECustomerKeyMD5=dest_ssec_key_md5, 126 | CopySourceSSECustomerAlgorithm='AES256', CopySourceSSECustomerKey=ssec_key, CopySourceSSECustomerKeyMD5=ssec_key_md5) 127 | 128 | # 取回 SSE-C 加密对象 129 | response = client.restore_object( 130 | Bucket=bucket, Key=file_name, RestoreRequest={ 131 | 'Days': 1, 132 | 'CASJobParameters': { 133 | 'Tier': 'Expedited' 134 | } 135 | }, 136 | SSECustomerAlgorithm='AES256', SSECustomerKey=ssec_key, SSECustomerKeyMD5=ssec_key_md5) -------------------------------------------------------------------------------- /demo/traffic_limit.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | import sys 5 | import os 6 | import logging 7 | 8 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 9 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 10 | 11 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 12 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 13 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 14 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 15 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 16 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 17 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 18 | 19 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 20 | client = CosS3Client(config) 21 | 22 | # 上传时对单链接限速 23 | with open('test.bin', 'rb') as fp: 24 | response = client.put_object( 25 | Bucket='examplebucket-1250000000', # Bucket 由 BucketName-APPID 组成 26 | Key='exampleobject', 27 | Body=fp, 28 | TrafficLimit='819200' 29 | ) 30 | print(response['ETag']) 31 | 32 | 33 | # 下载时对单链接限速 34 | response = client.get_object( 35 | Bucket='examplebucket-1250000000', 36 | Key='exampleobject', 37 | TrafficLimit='819200' 38 | ) 39 | response['Body'].get_stream_to_file('exampleobject') 40 | -------------------------------------------------------------------------------- /demo/upload_object.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | from qcloud_cos import CosConfig 3 | from qcloud_cos import CosS3Client 4 | from qcloud_cos.cos_threadpool import SimpleThreadPool 5 | from qcloud_cos.cos_exception import CosClientError, CosServiceError 6 | 7 | import sys 8 | import os 9 | import logging 10 | 11 | # 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息 12 | logging.basicConfig(level=logging.INFO, stream=sys.stdout) 13 | 14 | # 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成 15 | secret_id = os.environ['COS_SECRET_ID'] # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 16 | secret_key = os.environ['COS_SECRET_KEY'] # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 17 | region = 'ap-beijing' # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket 18 | # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224 19 | token = None # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048 20 | scheme = 'https' # 指定使用 http/https 协议来访问 COS,默认为 https,可不填 21 | 22 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme) 23 | client = CosS3Client(config) 24 | 25 | '''上传对象(断点续传) 26 | ''' 27 | 28 | # 使用高级接口上传一次,不重试,此时没有使用断点续传的功能 29 | response = client.upload_file( 30 | Bucket='examplebucket-1250000000', 31 | Key='exampleobject', 32 | LocalFilePath='local.txt', 33 | EnableMD5=False, 34 | progress_callback=None 35 | ) 36 | 37 | # 使用高级接口断点续传,失败重试时不会上传已成功的分块(这里重试10次) 38 | for i in range(0, 10): 39 | try: 40 | response = client.upload_file( 41 | Bucket='examplebucket-1250000000', 42 | Key='exampleobject', 43 | LocalFilePath='local.txt') 44 | break 45 | except CosClientError or CosServiceError as e: 46 | print(e) 47 | 48 | 49 | '''批量上传(本地文件夹上传) 50 | ''' 51 | 52 | uploadDir = '/root/logs' 53 | bucket = 'examplebucket-125000000' 54 | g = os.walk(uploadDir) 55 | # 创建上传的线程池 56 | pool = SimpleThreadPool() 57 | for path, dir_list, file_list in g: 58 | for file_name in file_list: 59 | srcKey = os.path.join(path, file_name) 60 | cosObjectKey = srcKey.strip('/') 61 | # 判断 COS 上文件是否存在 62 | exists = False 63 | try: 64 | response = client.head_object(Bucket=bucket, Key=cosObjectKey) 65 | exists = True 66 | except CosServiceError as e: 67 | if e.get_status_code() == 404: 68 | exists = False 69 | else: 70 | print("Error happened, reupload it.") 71 | if not exists: 72 | print("File %s not exists in cos, upload it", srcKey) 73 | pool.add_task(client.upload_file, bucket, cosObjectKey, srcKey) 74 | 75 | pool.wait_completion() 76 | result = pool.get_result() 77 | if not result['success_all']: 78 | print("Not all files upload successed. you should retry") 79 | 80 | 81 | '''简单文件上传 82 | ''' 83 | 84 | # 文件流 简单上传 85 | file_name = 'test.txt' 86 | with open('test.txt', 'rb') as fp: 87 | response = client.put_object( 88 | Bucket='examplebucket-1250000000', # Bucket 由 BucketName-APPID 组成 89 | Body=fp, 90 | Key=file_name, 91 | StorageClass='STANDARD', 92 | ContentType='text/html; charset=utf-8' 93 | ) 94 | print(response['ETag']) 95 | 96 | # 字节流 简单上传 97 | response = client.put_object( 98 | Bucket='examplebucket-1250000000', 99 | Body=b'abcdefg', 100 | Key=file_name 101 | ) 102 | print(response['ETag']) 103 | 104 | # 本地路径 简单上传 105 | response = client.put_object_from_local_file( 106 | Bucket='examplebucket-1250000000', 107 | LocalFilePath='local.txt', 108 | Key=file_name 109 | ) 110 | print(response['ETag']) 111 | 112 | # 设置 HTTP 头部 简单上传 113 | response = client.put_object( 114 | Bucket='examplebucket-1250000000', 115 | Body=b'test', 116 | Key=file_name, 117 | ContentType='text/html; charset=utf-8' 118 | ) 119 | print(response['ETag']) 120 | 121 | # 设置自定义头部 简单上传 122 | response = client.put_object( 123 | Bucket='examplebucket-1250000000', 124 | Body=b'test', 125 | Key=file_name, 126 | Metadata={ 127 | 'x-cos-meta-key1': 'value1', 128 | 'x-cos-meta-key2': 'value2' 129 | } 130 | ) 131 | print(response['ETag']) 132 | 133 | # 上传时限速 134 | with open('test.bin', 'rb') as fp: 135 | response = client.put_object( 136 | Bucket='examplebucket-1250000000', 137 | Key='exampleobject', 138 | Body=fp, 139 | TrafficLimit='819200' 140 | ) 141 | print(response['ETag']) 142 | 143 | '''查询分块上传 144 | ''' 145 | 146 | response = client.list_multipart_uploads( 147 | Bucket='examplebucket-1250000000', 148 | Prefix='dir' 149 | ) 150 | 151 | '''初始化分块上传 152 | ''' 153 | 154 | response = client.create_multipart_upload( 155 | Bucket='examplebucket-1250000000', 156 | Key='exampleobject', 157 | StorageClass='STANDARD' 158 | ) 159 | 160 | '''上传分块 161 | ''' 162 | 163 | # 注意,上传分块的块数最多10000块 164 | response = client.upload_part( 165 | Bucket='examplebucket-1250000000', 166 | Key='exampleobject', 167 | Body=b'b'*1024*1024, 168 | PartNumber=1, 169 | UploadId='exampleUploadId' 170 | ) 171 | 172 | '''复制分块 173 | ''' 174 | 175 | response = client.upload_part_copy( 176 | Bucket='examplebucket-1250000000', 177 | Key='exampleobject', 178 | PartNumber=1, 179 | UploadId='exampleUploadId', 180 | CopySource={ 181 | 'Bucket': 'sourcebucket-1250000000', 182 | 'Key': 'exampleobject', 183 | 'Region': 'ap-guangzhou' 184 | } 185 | ) 186 | 187 | '''查询已上传分块 188 | ''' 189 | 190 | response = client.list_parts( 191 | Bucket='examplebucket-1250000000', 192 | Key='exampleobject', 193 | UploadId='exampleUploadId' 194 | ) 195 | 196 | '''完成分块上传 197 | ''' 198 | 199 | response = client.complete_multipart_upload( 200 | Bucket='examplebucket-1250000000', 201 | Key='exampleobject', 202 | UploadId='exampleUploadId', 203 | MultipartUpload={ 204 | 'Part': [ 205 | { 206 | 'ETag': 'string', 207 | 'PartNumber': 1 208 | }, 209 | { 210 | 'ETag': 'string', 211 | 'PartNumber': 2 212 | }, 213 | ] 214 | }, 215 | ) 216 | 217 | '''终止分块上传 218 | ''' 219 | 220 | response = client.abort_multipart_upload( 221 | Bucket='examplebucket-1250000000', 222 | Key='exampleobject', 223 | UploadId='exampleUploadId' 224 | ) 225 | -------------------------------------------------------------------------------- /qcloud_cos/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | python: 4 | - '2.7' 5 | - '3.5' 6 | - '3.6' 7 | install: 8 | - pip install requests 9 | - pip install six 10 | - pip install nose 11 | - pip install pycodestyle 12 | - pip install xmltodict 13 | - pip install crcmod 14 | notifications: 15 | email: 16 | recipients: 17 | - wjielai@tencent.com 18 | - fysntian@tencent.com 19 | script: 20 | - pycodestyle --max-line-length=200 qcloud_cos/. 21 | - nosetests -s -v ut/ 22 | deploy: 23 | provider: pypi 24 | distributions: sdist bdist_wheel 25 | user: dt3310321 26 | password: 27 | secure: JCBE84C22lHElRm7HmIf//UI123EuiFznEFPoVMPlRGb/XBrtYb+x1SRaO7Dn165CfVDpXtdNbJYfD9s2p3FUKzxSqkwl7FkkSl2g1jwKO97gKBPGxozBN+9pOJLTQUXBwON+erJSpMCHxrUjKKZBi56mUYXPP+A1X8sIHFMF4rLdPSuobjx0VGm2qFWhFeuLFPNOfF5ZKQDCnieptBLhrMXRcxyhZja/HsQh/JOjnMKZAmgJep2w2hI7ScYeTF0Ljk3RQbSN88HjZ7XP+U3bhiy5IE2u0WhJr6Q1OwxIuw8EIP+5mBNELT8Q5AMDnR85ehOVf67nl8j0nCiLzS55t1wuFHWExwW4kKF0dLpeV/fj3huFwQuAYItgZzCA/h3Fne6D3omjknd1uvWcUQzzXU1ixdeuq8XoDYxF8eox3GWQ/jbZY8lLXQ1BhaMK5E/MY8DJs1S+i6I1mJ34rCcnRYS1R3zZAJryaFxI6UsEAniXu4ESI+da7KD4y4TC0hY4RlcFyqQ0OVeeXoclQytRfgIT+EPZHt1mAr8qinmy5K2GoVcWwEj54AXp4LwiOosve6vqdeXjR/EeGy3zWjEfhn5B4z8UMLyGS/S1k3rSpV85KB4nLuzKGlyUkC2sjGr/xiG7CBC1UCbqx1CGLlCZ/HvEmKvuSrbJNbsgBNU/og= 28 | on: 29 | tags: true 30 | branch: master 31 | 32 | -------------------------------------------------------------------------------- /qcloud_cos/__init__.py: -------------------------------------------------------------------------------- 1 | from .cos_client import CosS3Client 2 | from .cos_client import CosConfig 3 | from .cos_exception import CosServiceError 4 | from .cos_exception import CosClientError 5 | from .cos_auth import CosS3Auth 6 | from .cos_comm import get_date 7 | from .meta_insight import MetaInsightClient 8 | from .ai_recognition import AIRecognitionClient 9 | 10 | import logging 11 | 12 | try: 13 | from logging import NullHandler 14 | except ImportError: 15 | class NullHandler(logging.Handler): 16 | def emit(self, record): 17 | pass 18 | 19 | logging.getLogger(__name__).addHandler(NullHandler()) 20 | -------------------------------------------------------------------------------- /qcloud_cos/cos_auth.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from six.moves.urllib.parse import quote, unquote, urlparse, urlencode 4 | import hmac 5 | import time 6 | import hashlib 7 | import logging 8 | from requests.auth import AuthBase 9 | from .cos_comm import to_unicode, to_bytes, to_str 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | def filter_headers(data): 15 | """只设置host content-type 还有x开头的头部. 16 | 17 | :param data(dict): 所有的头部信息. 18 | :return(dict): 计算进签名的头部. 19 | """ 20 | valid_headers = [ 21 | "cache-control", 22 | "content-disposition", 23 | "content-encoding", 24 | "content-type", 25 | "content-md5", 26 | "content-length", 27 | "expect", 28 | "expires", 29 | "host", 30 | "if-match", 31 | "if-modified-since", 32 | "if-none-match", 33 | "if-unmodified-since", 34 | "origin", 35 | "range", 36 | "transfer-encoding", 37 | "pic-operations", 38 | ] 39 | headers = {} 40 | for i in data: 41 | if str.lower(i) in valid_headers or str.lower(i).startswith("x-cos-") or str.lower(i).startswith("x-ci-"): 42 | headers[i] = data[i] 43 | return headers 44 | 45 | 46 | class CosS3Auth(AuthBase): 47 | 48 | def __init__(self, conf, key=None, params={}, expire=10000, sign_host=None): 49 | self._secret_id = conf._secret_id if conf._secret_id else \ 50 | (conf._credential_inst.secret_id if conf._credential_inst else None) 51 | self._secret_key = conf._secret_key if conf._secret_key else \ 52 | (conf._credential_inst.secret_key if conf._credential_inst else None) 53 | self._anonymous = conf._anonymous 54 | self._expire = expire 55 | self._params = params 56 | self._sign_params = conf._sign_params 57 | 58 | # 如果API指定了是否签名host,则以具体API为准,如果未指定则以配置为准 59 | if sign_host is not None: 60 | self._sign_host = bool(sign_host) 61 | else: 62 | self._sign_host = conf._sign_host 63 | 64 | if key: 65 | key = to_unicode(key) 66 | if key[0] == u'/': 67 | self._path = key 68 | else: 69 | self._path = u'/' + key 70 | else: 71 | self._path = u'/' 72 | 73 | def __call__(self, r): 74 | 75 | # 匿名请求直接返回 76 | if self._anonymous: 77 | r.headers['Authorization'] = "" 78 | logger.debug("anonymous reqeust") 79 | return r 80 | 81 | path = self._path 82 | uri_params = {} 83 | if self._sign_params: 84 | uri_params = self._params 85 | headers = filter_headers(r.headers) 86 | 87 | # 如果headers中不包含host头域,则从url中提取host,并且加入签名计算 88 | if self._sign_host: 89 | 90 | # 判断headers中是否包含host头域 91 | contain_host = False 92 | for i in headers: 93 | if str.lower(i) == "host": # 兼容host/Host/HOST等 94 | contain_host = True 95 | break 96 | 97 | # 从url中提取host 98 | if not contain_host: 99 | url_parsed = urlparse(r.url) 100 | if url_parsed.hostname is not None: 101 | headers["host"] = url_parsed.hostname 102 | 103 | # reserved keywords in headers urlencode are -_.~, notice that / should be encoded and space should not be encoded to plus sign(+) 104 | headers = dict([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in 105 | headers.items()]) # headers中的key转换为小写,value进行encode 106 | uri_params = dict([(quote(to_bytes(to_str(k)), '-_.~').lower(), quote(to_bytes(to_str(v)), '-_.~')) for k, v in 107 | uri_params.items()]) 108 | format_str = u"{method}\n{host}\n{params}\n{headers}\n".format( 109 | method=r.method.lower(), 110 | host=path, 111 | params='&'.join(map(lambda tupl: "%s=%s" % 112 | (tupl[0], tupl[1]), sorted(uri_params.items()))), 113 | headers='&'.join(map(lambda tupl: "%s=%s" % 114 | (tupl[0], tupl[1]), sorted(headers.items()))) 115 | ) 116 | logger.debug("format str: " + format_str) 117 | 118 | start_sign_time = int(time.time()) 119 | sign_time = "{bg_time};{ed_time}".format( 120 | bg_time=start_sign_time - 60, ed_time=start_sign_time + self._expire) 121 | sha1 = hashlib.sha1() 122 | sha1.update(to_bytes(format_str)) 123 | 124 | str_to_sign = "sha1\n{time}\n{sha1}\n".format( 125 | time=sign_time, sha1=sha1.hexdigest()) 126 | logger.debug('str_to_sign: ' + str(str_to_sign)) 127 | sign_key = hmac.new(to_bytes(self._secret_key), to_bytes( 128 | sign_time), hashlib.sha1).hexdigest() 129 | sign = hmac.new(to_bytes(sign_key), to_bytes( 130 | str_to_sign), hashlib.sha1).hexdigest() 131 | logger.debug('sign_key: ' + str(sign_key)) 132 | logger.debug('sign: ' + str(sign)) 133 | sign_tpl = "q-sign-algorithm=sha1&q-ak={ak}&q-sign-time={sign_time}&q-key-time={key_time}&q-header-list={headers}&q-url-param-list={params}&q-signature={sign}" 134 | 135 | r.headers['Authorization'] = sign_tpl.format( 136 | ak=self._secret_id, 137 | sign_time=sign_time, 138 | key_time=sign_time, 139 | params=';'.join(sorted(uri_params.keys())), 140 | headers=';'.join(sorted(headers.keys())), 141 | sign=sign 142 | ) 143 | logger.debug("sign_key" + str(sign_key)) 144 | logger.debug(r.headers['Authorization']) 145 | logger.debug("request headers: " + str(r.headers)) 146 | return r 147 | 148 | 149 | class CosRtmpAuth(AuthBase): 150 | 151 | def __init__(self, conf, bucket=None, channel=None, params={}, expire=3600, presign_expire=0): 152 | self._secret_id = conf._secret_id 153 | self._secret_key = conf._secret_key 154 | self._token = conf._token 155 | self._anonymous = conf._anonymous 156 | self._expire = expire 157 | self._presign_expire = presign_expire 158 | self._params = params 159 | if self._token: 160 | self._params['q-token'] = self._token 161 | self._path = u'/' + bucket + u'/' + channel 162 | 163 | def get_rtmp_sign(self): 164 | # get rtmp string 165 | canonicalized_param = '' 166 | for k, v in self._params.items(): 167 | canonicalized_param += '{key}={value}&'.format(key=k, value=v) 168 | if self._presign_expire >= 60: 169 | canonicalized_param += 'presign={value}'.format( 170 | value=self._presign_expire) 171 | canonicalized_param = canonicalized_param.rstrip('&') 172 | rtmp_str = u"{path}\n{params}\n".format( 173 | path=self._path, params=canonicalized_param) 174 | logger.debug("rtmp str: " + rtmp_str) 175 | 176 | sha1 = hashlib.sha1() 177 | sha1.update(to_bytes(rtmp_str)) 178 | # get time 179 | sign_time = int(time.time()) 180 | sign_time_str = "{start_time};{end_time}".format( 181 | start_time=sign_time - 60, end_time=sign_time + self._expire) 182 | str_to_sign = "sha1\n{time}\n{sha1}\n".format( 183 | time=sign_time_str, sha1=sha1.hexdigest()) 184 | logger.debug('str_to_sign: ' + str(str_to_sign)) 185 | # get sinature 186 | signature = hmac.new(to_bytes(self._secret_key), to_bytes( 187 | str_to_sign), hashlib.sha1).hexdigest() 188 | logger.debug('signature: ' + str(signature)) 189 | rtmp_sign = "q-sign-algorithm=sha1&q-ak={ak}&q-sign-time={sign_time}&q-key-time={key_time}&q-signature={sign}".format( 190 | ak=self._secret_id, sign_time=sign_time_str, key_time=sign_time_str, sign=signature) 191 | if canonicalized_param != '': 192 | return rtmp_sign + "&{params}".format(params=canonicalized_param) 193 | else: 194 | return rtmp_sign 195 | 196 | 197 | if __name__ == "__main__": 198 | pass 199 | -------------------------------------------------------------------------------- /qcloud_cos/cos_encryption_client.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | 3 | import logging 4 | from qcloud_cos import CosS3Client 5 | from qcloud_cos.crypto import RSAProvider 6 | from qcloud_cos.crypto import MetaHandle 7 | from qcloud_cos.crypto import DataDecryptAdapter 8 | from .cos_exception import CosClientError 9 | from .cos_comm import * 10 | from .cos_auth import CosS3Auth 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | 15 | class CosEncryptionClient(CosS3Client): 16 | """cos支持加密的客户端,封装相应请求""" 17 | 18 | def __init__(self, conf, provider, retry=1, session=None): 19 | """初始化client对象 20 | 21 | :param conf(CosConfig): 用户的配置. 22 | :param provider(BaseProvider): 客户端主密钥加密类 23 | :param retry(int): 失败重试的次数. 24 | :param session(object): http session. 25 | """ 26 | super(CosEncryptionClient, self).__init__(conf, retry, session) 27 | self.provider = provider 28 | 29 | def put_object(self, Bucket, Body, Key, EnableMD5=False, **kwargs): 30 | """单文件加密上传接口,适用于小文件,最大不得超过5GB 31 | 32 | :param Bucket(string): 存储桶名称. 33 | :param Body(file|string): 上传的文件内容,类型为文件流或字节流. 34 | :param Key(string): COS路径. 35 | :param EnableMD5(bool): 是否需要SDK计算Content-MD5,打开此开关会增加上传耗时. 36 | :kwargs(dict): 设置上传的headers. 37 | :return(dict): 上传成功返回的结果,包含ETag等信息. 38 | 39 | .. code-block:: python 40 | 41 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 42 | provider = RSAProvider() 43 | client = CosEncryptionClient(config, provider) 44 | # 上传本地文件到cos 45 | with open('test.txt', 'rb') as fp: 46 | response = client.put_object( 47 | Bucket='bucket', 48 | Body=fp, 49 | Key='test.txt' 50 | ) 51 | print (response['ETag']) 52 | """ 53 | encrypt_key, encrypt_start = self.provider.init_data_cipher() 54 | meta_handle = MetaHandle(encrypt_key, encrypt_start) 55 | kwargs = meta_handle.set_object_meta(kwargs) 56 | data = self.provider.make_data_encrypt_adapter(Body) 57 | response = super(CosEncryptionClient, self).put_object(Bucket, data, Key, EnableMD5, **kwargs) 58 | return response 59 | 60 | def get_object(self, Bucket, Key, **kwargs): 61 | """单文件加密下载接口 62 | 63 | :param Bucket(string): 存储桶名称. 64 | :param Key(string): COS路径. 65 | :param kwargs(dict): 设置下载的headers. 66 | :return(dict): 下载成功返回的结果,包含Body对应的StreamBody,可以获取文件流或下载文件到本地. 67 | 68 | .. code-block:: python 69 | 70 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 71 | provider = RSAProvider() 72 | client = CosEncryptionClient(config, provider) 73 | # 下载cos上的文件到本地 74 | response = client.get_object( 75 | Bucket='bucket', 76 | Key='test.txt' 77 | ) 78 | response['Body'].get_stream_to_file('local_file.txt') 79 | """ 80 | response = self.head_object(Bucket, Key, **kwargs) 81 | meta_handle = MetaHandle() 82 | encrypt_key, encrypt_start = meta_handle.get_object_meta(response) 83 | 84 | headers = mapped(kwargs) 85 | offset = 0 86 | real_start = 0 87 | if 'Range' in headers: 88 | read_range = headers['Range'] 89 | read_range = read_range.replace('bytes=', '').strip().split('-') 90 | if len(read_range) != 2: 91 | raise CosClientError('key:Range is wrong format, except first-last') 92 | 93 | real_start = self.provider.adjust_read_offset(int(read_range[0])) 94 | headers['Range'] = 'bytes=' + str(real_start) + '-' + read_range[1] 95 | offset = int(read_range[0]) - real_start 96 | final_headers = {} 97 | params = {} 98 | for key in headers: 99 | if key.startswith("response"): 100 | params[key] = headers[key] 101 | else: 102 | final_headers[key] = headers[key] 103 | headers = final_headers 104 | 105 | if 'versionId' in headers: 106 | params['versionId'] = headers['versionId'] 107 | del headers['versionId'] 108 | params = format_values(params) 109 | 110 | url = self._conf.uri(bucket=Bucket, path=Key) 111 | logger.info("get object, url=:{url} ,headers=:{headers}, params=:{params}".format( 112 | url=url, 113 | headers=headers, 114 | params=params)) 115 | rt = self.send_request( 116 | method='GET', 117 | url=url, 118 | bucket=Bucket, 119 | stream=True, 120 | auth=CosS3Auth(self._conf, Key, params=params), 121 | params=params, 122 | headers=headers) 123 | 124 | self.provider.init_data_cipter_by_user(encrypt_key, encrypt_start, real_start) 125 | response['Body'] = self.provider.make_data_decrypt_adapter(rt, offset) 126 | return response 127 | 128 | def create_multipart_upload(self, Bucket, Key, **kwargs): 129 | """创建分块上传,适用于大文件上传 130 | 131 | :param Bucket(string): 存储桶名称. 132 | :param Key(string): COS路径. 133 | :param kwargs(dict): 设置请求headers. 134 | :return(dict): 初始化分块上传返回的结果,包含UploadId等信息. 135 | 136 | .. code-block:: python 137 | 138 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 139 | provider = RSAProvider() 140 | client = CosEncryptionClient(config, provider) 141 | # 创建分块上传 142 | response = client.create_multipart_upload( 143 | Bucket='bucket', 144 | Key='test.txt' 145 | ) 146 | """ 147 | encrypt_key, encrypt_start = self.provider.init_data_cipher() 148 | meta_handle = MetaHandle(encrypt_key, encrypt_start) 149 | kwargs = meta_handle.set_object_meta(kwargs) 150 | response = super(CosEncryptionClient, self).create_multipart_upload(Bucket, Key, **kwargs) 151 | return response 152 | 153 | def upload_part(self, Bucket, Key, Body, PartNumber, UploadId, EnableMD5=False, **kwargs): 154 | """上传分块,单个大小不得超过5GB 155 | 156 | :param Bucket(string): 存储桶名称. 157 | :param Key(string): COS路径. 158 | :param Body(file|string): 上传分块的内容,可以为文件流或者字节流. 159 | :param PartNumber(int): 上传分块的编号. 160 | :param UploadId(string): 分块上传创建的UploadId. 161 | :param kwargs(dict): 设置请求headers. 162 | :param EnableMD5(bool): 是否需要SDK计算Content-MD5,打开此开关会增加上传耗时. 163 | :return(dict): 上传成功返回的结果,包含单个分块ETag等信息. 164 | 165 | .. code-block:: python 166 | 167 | config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象 168 | provider = RSAProvider() 169 | client = CosEncryptionClient(config, provider) 170 | # 分块上传 171 | with open('test.txt', 'rb') as fp: 172 | data = fp.read(1024*1024) 173 | response = client.upload_part( 174 | Bucket='bucket', 175 | Body=data, 176 | Key='test.txt' 177 | ) 178 | """ 179 | data = self.provider.make_data_encrypt_adapter(Body) 180 | response = super(CosEncryptionClient, self).upload_part(Bucket, Key, data, PartNumber, UploadId, 181 | EnableMD5=False, **kwargs) 182 | return response 183 | -------------------------------------------------------------------------------- /qcloud_cos/cos_exception.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | 3 | import xml.dom.minidom 4 | 5 | 6 | class CosException(Exception): 7 | def __init__(self, message): 8 | self._message = message 9 | 10 | def __str__(self): 11 | return str(self._message) 12 | 13 | 14 | def digest_xml(data): 15 | msg = dict() 16 | try: 17 | tree = xml.dom.minidom.parseString(data) 18 | root = tree.documentElement 19 | 20 | result = root.getElementsByTagName('Code') 21 | msg['code'] = result[0].childNodes[0].nodeValue 22 | 23 | result = root.getElementsByTagName('Message') 24 | msg['message'] = result[0].childNodes[0].nodeValue 25 | 26 | result = root.getElementsByTagName('Resource') 27 | msg['resource'] = result[0].childNodes[0].nodeValue 28 | 29 | result = root.getElementsByTagName('RequestId') 30 | msg['requestid'] = result[0].childNodes[0].nodeValue 31 | 32 | result = root.getElementsByTagName('TraceId') 33 | if result: 34 | msg['traceid'] = result[0].childNodes[0].nodeValue 35 | else: 36 | msg['traceid'] = 'Unknown' 37 | return msg 38 | except Exception as e: 39 | return "Response Error Msg Is INVALID" 40 | 41 | 42 | class CosClientError(CosException): 43 | """Client端错误,如timeout""" 44 | 45 | def __init__(self, message): 46 | CosException.__init__(self, message) 47 | 48 | 49 | class CosServiceError(CosException): 50 | """COS Server端错误,可以获取特定的错误信息""" 51 | 52 | def __init__(self, method, message, status_code): 53 | CosException.__init__(self, message) 54 | if isinstance(message, dict): 55 | self._origin_msg = '' 56 | self._digest_msg = message 57 | else: 58 | self._origin_msg = message 59 | self._digest_msg = digest_xml(message) 60 | self._status_code = status_code 61 | 62 | def __str__(self): 63 | return str(self._digest_msg) 64 | 65 | def get_origin_msg(self): 66 | """获取原始的XML格式错误信息""" 67 | return self._origin_msg 68 | 69 | def get_digest_msg(self): 70 | """获取经过处理的dict格式的错误信息""" 71 | return self._digest_msg 72 | 73 | def get_status_code(self): 74 | """获取http error code""" 75 | return self._status_code 76 | 77 | def get_error_code(self): 78 | """获取COS定义的错误码描述,服务器返回错误信息格式出错时,返回空 """ 79 | if isinstance(self._digest_msg, dict): 80 | return self._digest_msg['code'] 81 | return "Unknown" 82 | 83 | def get_error_msg(self): 84 | if isinstance(self._digest_msg, dict): 85 | return self._digest_msg['message'] 86 | return "Unknown" 87 | 88 | def get_resource_location(self): 89 | if isinstance(self._digest_msg, dict): 90 | return self._digest_msg['resource'] 91 | return "Unknown" 92 | 93 | def get_trace_id(self): 94 | if isinstance(self._digest_msg, dict): 95 | return self._digest_msg['traceid'] 96 | return "Unknown" 97 | 98 | def get_request_id(self): 99 | if isinstance(self._digest_msg, dict): 100 | return self._digest_msg['requestid'] 101 | return "Unknown" 102 | -------------------------------------------------------------------------------- /qcloud_cos/cos_threadpool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from threading import Thread 4 | from logging import getLogger 5 | from six.moves.queue import Queue 6 | from threading import Lock 7 | import gc 8 | 9 | logger = getLogger(__name__) 10 | 11 | 12 | class WorkerThread(Thread): 13 | def __init__(self, task_queue, *args, **kwargs): 14 | super(WorkerThread, self).__init__(*args, **kwargs) 15 | 16 | self._task_queue = task_queue 17 | self._succ_task_num = 0 18 | self._fail_task_num = 0 19 | self._ret = list() 20 | 21 | def run(self): 22 | while True: 23 | func, args, kwargs = self._task_queue.get() 24 | # 判断线程是否需要退出 25 | if func is None: 26 | return 27 | try: 28 | ret = func(*args, **kwargs) 29 | self._succ_task_num += 1 30 | self._ret.append(ret) 31 | 32 | except Exception as e: 33 | logger.error(str(e)) 34 | self._fail_task_num += 1 35 | if hasattr(e, '_message') and e._message: 36 | self._ret.append(e._message) 37 | elif hasattr(e, 'message') and e.message: 38 | self._ret.append(e.message) 39 | else: 40 | self._ret.append('meet some exception') 41 | finally: 42 | self._task_queue.task_done() 43 | 44 | def get_result(self): 45 | return self._succ_task_num, self._fail_task_num, self._ret 46 | 47 | 48 | class SimpleThreadPool: 49 | 50 | def __init__(self, num_threads=5, num_queue=0): 51 | self._num_threads = num_threads 52 | self._queue = Queue(num_queue) 53 | self._lock = Lock() 54 | self._active = False 55 | self._workers = list() 56 | self._finished = False 57 | 58 | def add_task(self, func, *args, **kwargs): 59 | if not self._active: 60 | with self._lock: 61 | if not self._active: 62 | self._workers = [] 63 | self._active = True 64 | 65 | for i in range(self._num_threads): 66 | w = WorkerThread(self._queue) 67 | self._workers.append(w) 68 | w.start() 69 | 70 | self._queue.put((func, args, kwargs)) 71 | 72 | def wait_completion(self): 73 | self._queue.join() 74 | self._finished = True 75 | # 已经结束的任务, 需要将线程都退出, 防止卡死 76 | for i in range(self._num_threads): 77 | self._queue.put((None, None, None)) 78 | 79 | self._active = False 80 | 81 | def get_result(self): 82 | assert self._finished 83 | detail = [worker.get_result() for worker in self._workers] 84 | succ_all = all([tp[1] == 0 for tp in detail]) 85 | return {'success_all': succ_all, 'detail': detail} 86 | 87 | 88 | if __name__ == '__main__': 89 | pass 90 | 91 | # pool = SimpleThreadPool(2) 92 | 93 | # def task_sleep(x): 94 | # from time import sleep 95 | # sleep(x) 96 | # return 'hello, sleep %d seconds' % x 97 | 98 | # def raise_exception(): 99 | # raise ValueError("Pa! Exception!") 100 | 101 | # for i in range(1000): 102 | # pool.add_task(task_sleep, 0.001) 103 | # print(i) 104 | # pool.add_task(task_sleep, 0) 105 | # pool.add_task(task_sleep, 0) 106 | # pool.add_task(raise_exception) 107 | # pool.add_task(raise_exception) 108 | 109 | # pool.wait_completion() 110 | # print(pool.get_result()) 111 | # [(1, 0, ['hello, sleep 5 seconds']), (2, 1, ['hello, sleep 2 seconds', 'hello, sleep 3 seconds', ValueError('Pa! Exception!',)])] 112 | -------------------------------------------------------------------------------- /qcloud_cos/resumable_downloader.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import json 4 | import os 5 | import sys 6 | import errno 7 | import threading 8 | import logging 9 | import uuid 10 | import hashlib 11 | import crcmod 12 | from .cos_comm import * 13 | from .streambody import StreamBody 14 | from .cos_threadpool import SimpleThreadPool 15 | 16 | logger = logging.getLogger(__name__) 17 | 18 | 19 | class ResumableDownLoader(object): 20 | def __init__(self, cos_client, bucket, key, dest_filename, object_info, part_size=20, max_thread=5, 21 | enable_crc=False, progress_callback=None, dump_record_dir=None, key_simplify_check=True, **kwargs): 22 | self.__cos_client = cos_client 23 | self.__bucket = bucket 24 | self.__key = key 25 | self.__dest_file_path = os.path.abspath(dest_filename) 26 | self.__object_info = object_info 27 | self.__max_thread = max_thread 28 | self.__enable_crc = enable_crc 29 | self.__progress_callback = progress_callback 30 | self.__headers = kwargs 31 | self.__key_simplify_check = key_simplify_check 32 | 33 | self.__max_part_count = 100 # 取决于服务端是否对并发有限制 34 | self.__min_part_size = 1024 * 1024 # 1M 35 | self.__part_size = self.__determine_part_size_internal(int(object_info['Content-Length']), part_size) 36 | self.__finished_parts = [] 37 | self.__lock = threading.Lock() 38 | self.__record = None # 记录当前的上下文 39 | if not dump_record_dir: 40 | self.__dump_record_dir = os.path.join(os.path.expanduser('~'), '.cos_download_tmp_file') 41 | else: 42 | self.__dump_record_dir = dump_record_dir 43 | 44 | record_filename = self.__get_record_filename(bucket, key, self.__dest_file_path) 45 | self.__record_filepath = os.path.join(self.__dump_record_dir, record_filename) 46 | self.__tmp_file = None 47 | 48 | if not os.path.exists(self.__dump_record_dir): 49 | # 多进程并发情况下makedirs会出现冲突, 需要进行异常捕获 50 | try: 51 | os.makedirs(self.__dump_record_dir) 52 | except OSError as e: 53 | if e.errno != errno.EEXIST: 54 | logger.error('os makedir error: dir: {0}, errno {1}'.format(self.__dump_record_dir), e.errno) 55 | raise 56 | pass 57 | logger.debug('resumale downloader init finish, bucket: {0}, key: {1}'.format(bucket, key)) 58 | 59 | def start(self): 60 | logger.debug('start resumable download, bucket: {0}, key: {1}'.format(self.__bucket, self.__key)) 61 | self.__load_record() # 从record文件中恢复读取上下文 62 | 63 | assert self.__tmp_file 64 | open(self.__tmp_file, 'a').close() 65 | 66 | # 已完成分块先设置下载进度 67 | if self.__progress_callback: 68 | for finished_part in self.__finished_parts: 69 | self.__progress_callback.report(finished_part.length) 70 | 71 | parts_need_to_download = self.__get_parts_need_to_download() 72 | logger.debug('parts_need_to_download: {0}'.format(parts_need_to_download)) 73 | pool = SimpleThreadPool(self.__max_thread) 74 | for part in parts_need_to_download: 75 | part_range = "bytes=" + str(part.start) + "-" + str(part.start + part.length - 1) 76 | headers = dict.copy(self.__headers) 77 | headers["Range"] = part_range 78 | pool.add_task(self.__download_part, part, headers) 79 | 80 | pool.wait_completion() 81 | result = pool.get_result() 82 | if not result['success_all']: 83 | raise CosClientError('some download_part fail after max_retry, please download_file again') 84 | 85 | if os.path.exists(self.__dest_file_path): 86 | os.remove(self.__dest_file_path) 87 | os.rename(self.__tmp_file, self.__dest_file_path) 88 | 89 | if self.__enable_crc: 90 | self.__check_crc() 91 | 92 | self.__del_record() 93 | logger.debug('download success, bucket: {0}, key: {1}'.format(self.__bucket, self.__key)) 94 | 95 | def __get_record_filename(self, bucket, key, dest_file_path): 96 | dest_file_path_md5 = hashlib.md5(dest_file_path.encode("utf-8")).hexdigest() 97 | key_md5 = hashlib.md5(key.encode("utf-8")).hexdigest() 98 | return '{0}_{1}.{2}'.format(bucket, key_md5, dest_file_path_md5) 99 | 100 | def __determine_part_size_internal(self, file_size, part_size): 101 | real_part_size = part_size * 1024 * 1024 # MB 102 | if real_part_size < self.__min_part_size: 103 | real_part_size = self.__min_part_size 104 | 105 | while real_part_size * self.__max_part_count < file_size: 106 | real_part_size = real_part_size * 2 107 | logger.debug('finish to determine part size, file_size: {0}, part_size: {1}'.format(file_size, real_part_size)) 108 | return real_part_size 109 | 110 | def __splite_to_parts(self): 111 | parts = [] 112 | file_size = int(self.__object_info['Content-Length']) 113 | num_parts = int((file_size + self.__part_size - 1) / self.__part_size) 114 | for i in range(num_parts): 115 | start = i * self.__part_size 116 | if i == num_parts - 1: 117 | length = file_size - start 118 | else: 119 | length = self.__part_size 120 | 121 | parts.append(PartInfo(i + 1, start, length)) 122 | return parts 123 | 124 | def __get_parts_need_to_download(self): 125 | all_set = set(self.__splite_to_parts()) 126 | logger.debug('all_set: {0}'.format(len(all_set))) 127 | finished_set = set(self.__finished_parts) 128 | logger.debug('finished_set: {0}'.format(len(finished_set))) 129 | return list(all_set - finished_set) 130 | 131 | def __download_part(self, part, headers): 132 | with open(self.__tmp_file, 'rb+') as f: 133 | f.seek(part.start, 0) 134 | range = None 135 | traffic_limit = None 136 | if 'Range' in headers: 137 | range = headers['Range'] 138 | 139 | if 'TrafficLimit' in headers: 140 | traffic_limit = headers['TrafficLimit'] 141 | logger.debug("part_id: {0}, part_range: {1}, traffic_limit:{2}".format(part.part_id, range, traffic_limit)) 142 | result = self.__cos_client.get_object(Bucket=self.__bucket, Key=self.__key, KeySimplifyCheck=self.__key_simplify_check, **headers) 143 | result["Body"].pget_stream_to_file(f, part.start, part.length) 144 | 145 | self.__finish_part(part) 146 | 147 | if self.__progress_callback: 148 | self.__progress_callback.report(part.length) 149 | 150 | def __finish_part(self, part): 151 | logger.debug('download part finished,bucket: {0}, key: {1}, part_id: {2}'. 152 | format(self.__bucket, self.__key, part.part_id)) 153 | with self.__lock: 154 | self.__finished_parts.append(part) 155 | self.__record['parts'].append({'part_id': part.part_id, 'start': part.start, 'length': part.length}) 156 | self.__dump_record(self.__record) 157 | 158 | def __dump_record(self, record): 159 | record_filepath = self.__record_filepath 160 | if os.path.exists(self.__record_filepath): 161 | record_filepath += '.tmp' 162 | with open(record_filepath, 'w') as f: 163 | json.dump(record, f) 164 | logger.debug( 165 | 'dump record to {0}, bucket: {1}, key: {2}'.format(record_filepath, self.__bucket, self.__key)) 166 | if record_filepath != self.__record_filepath: 167 | os.remove(self.__record_filepath) 168 | os.rename(record_filepath, self.__record_filepath) 169 | 170 | def __load_record(self): 171 | record = None 172 | 173 | if os.path.exists(self.__record_filepath): 174 | with open(self.__record_filepath, 'r') as f: 175 | record = json.load(f) 176 | ret = self.__check_record(record) 177 | # record记录是否跟head object的一致,不一致则删除 178 | if not ret: 179 | self.__del_record() 180 | record = None 181 | else: 182 | self.__part_size = record['part_size'] 183 | self.__tmp_file = record['tmp_filename'] 184 | if not os.path.exists(self.__tmp_file): 185 | record = None 186 | self.__tmp_file = None 187 | self.__del_record() 188 | else: 189 | self.__finished_parts = list( 190 | PartInfo(p['part_id'], p['start'], p['length']) for p in record['parts']) 191 | logger.debug('load record: finished parts nums: {0}'.format(len(self.__finished_parts))) 192 | self.__record = record 193 | 194 | if not record: 195 | self.__tmp_file = "{file_name}_{uuid}".format(file_name=self.__dest_file_path, uuid=uuid.uuid4().hex) 196 | record = {'bucket': self.__bucket, 'key': self.__key, 'tmp_filename': self.__tmp_file, 197 | 'mtime': self.__object_info['Last-Modified'], 'etag': self.__object_info['ETag'], 198 | 'file_size': self.__object_info['Content-Length'], 'part_size': self.__part_size, 'parts': []} 199 | self.__record = record 200 | self.__dump_record(record) 201 | 202 | def __check_record(self, record): 203 | return record['etag'] == self.__object_info['ETag'] and \ 204 | record['mtime'] == self.__object_info['Last-Modified'] and \ 205 | record['file_size'] == self.__object_info['Content-Length'] 206 | 207 | def __del_record(self): 208 | os.remove(self.__record_filepath) 209 | logger.debug('ResumableDownLoader delete record_file, path: {0}'.format(self.__record_filepath)) 210 | 211 | def __check_crc(self): 212 | logger.debug('start to check crc') 213 | c64 = crcmod.mkCrcFun(0x142F0E1EBA9EA3693, initCrc=0, xorOut=0xffffffffffffffff, rev=True) 214 | with open(self.__dest_file_path, 'rb') as f: 215 | local_crc64 = str(c64(f.read())) 216 | object_crc64 = self.__object_info['x-cos-hash-crc64ecma'] 217 | if local_crc64 is not None and object_crc64 is not None and local_crc64 != object_crc64: 218 | raise CosClientError('crc of client: {0} is mismatch with cos: {1}'.format(local_crc64, object_crc64)) 219 | 220 | 221 | class PartInfo(object): 222 | def __init__(self, part_id, start, length): 223 | self.part_id = part_id 224 | self.start = start 225 | self.length = length 226 | 227 | def __eq__(self, other): 228 | return self.__key() == other.__key() 229 | 230 | def __hash__(self): 231 | return hash(self.__key()) 232 | 233 | def __key(self): 234 | return self.part_id, self.start, self.length 235 | -------------------------------------------------------------------------------- /qcloud_cos/select_event_stream.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import os 3 | import uuid 4 | import struct 5 | import logging 6 | from .cos_comm import xml_to_dict 7 | from .cos_comm import to_unicode 8 | from .cos_exception import CosServiceError 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | 13 | class EventStream(): 14 | def __init__(self, rt): 15 | self._rt = rt 16 | self._raw = self._rt.raw 17 | self._finish = False 18 | 19 | def __iter__(self): 20 | return self 21 | 22 | def __next__(self): 23 | return self.next_event() 24 | 25 | next = __next__ 26 | 27 | def next_event(self): 28 | """获取下一个事件""" 29 | if self._finish: 30 | """要把剩下的内容读完丢弃或者自己关连接,否则不会自动关连接""" 31 | self._raw.read() 32 | raise StopIteration 33 | total_byte_length = struct.unpack('>I', bytes(self._raw.read(4)))[0] # message总长度 34 | header_byte_length = struct.unpack('>I', bytes(self._raw.read(4)))[0] # header总长度 35 | prelude_crc = struct.unpack('>I', bytes(self._raw.read(4)))[0] 36 | # 处理headers 37 | offset = 0 38 | msg_headers = {} 39 | while offset < header_byte_length: 40 | header_name_length = struct.unpack('>B', bytes(self._raw.read(1)))[0] 41 | header_name = to_unicode(self._raw.read(header_name_length)) 42 | header_value_type = struct.unpack('>B', bytes(self._raw.read(1)))[0] 43 | header_value_length = struct.unpack('>H', bytes(self._raw.read(2)))[0] 44 | header_value = to_unicode(self._raw.read(header_value_length)) 45 | msg_headers[header_name] = header_value 46 | offset += 4 + header_name_length + header_value_length 47 | # 处理payload(输出给用户的dict中也为bytes) 48 | payload_byte_length = total_byte_length - header_byte_length - 16 # payload总长度 49 | payload = self._raw.read(payload_byte_length) 50 | message_crc = struct.unpack('>I', bytes(self._raw.read(4)))[0] 51 | if ':message-type' in msg_headers and msg_headers[':message-type'] == 'event': 52 | if ':event-type' in msg_headers and msg_headers[':event-type'] == "Records": 53 | return {'Records': {'Payload': payload}} 54 | elif ':event-type' in msg_headers and msg_headers[':event-type'] == "Stats": 55 | return {'Stats': {'Details': xml_to_dict(payload)}} 56 | elif ':event-type' in msg_headers and msg_headers[':event-type'] == "Progress": 57 | return {'Progress': {'Details': xml_to_dict(payload)}} 58 | elif ':event-type' in msg_headers and msg_headers[':event-type'] == "Cont": 59 | return {'Cont': {}} 60 | elif ':event-type' in msg_headers and msg_headers[':event-type'] == "End": 61 | self._finish = True 62 | return {'End': {}} 63 | # 处理Error Message(抛出异常) 64 | if ':message-type' in msg_headers and msg_headers[':message-type'] == 'error': 65 | error_info = dict() 66 | error_info['code'] = msg_headers[':error-code'] 67 | error_info['message'] = msg_headers[':error-message'] 68 | error_info['resource'] = self._rt.request.url 69 | error_info['requestid'] = '' 70 | error_info['traceid'] = '' 71 | if 'x-cos-request-id' in self._rt.headers: 72 | error_info['requestid'] = self._rt.headers['x-cos-request-id'] 73 | if 'x-cos-trace-id' in self._rt.headers: 74 | error_info['traceid'] = self._rt.headers['x-cos-trace-id'] 75 | logger.error(error_info) 76 | e = CosServiceError('POST', error_info, self._rt.status_code) 77 | raise e 78 | 79 | def get_select_result(self): 80 | """获取查询结果""" 81 | data = b"" 82 | for event in self: 83 | if 'Records' in event: 84 | data += event['Records']['Payload'] 85 | return data 86 | 87 | def get_select_result_to_file(self, file_name): 88 | """保存查询结果到文件""" 89 | tmp_file_name = "{file_name}_{uuid}".format(file_name=file_name, uuid=uuid.uuid4().hex) 90 | with open(tmp_file_name, 'wb') as fp: 91 | for event in self: 92 | if 'Records' in event: 93 | data = event['Records']['Payload'] 94 | fp.write(data) 95 | if os.path.exists(file_name): 96 | os.remove(file_name) 97 | os.rename(tmp_file_name, file_name) 98 | -------------------------------------------------------------------------------- /qcloud_cos/streambody.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import os 3 | import uuid 4 | 5 | 6 | class StreamBody(object): 7 | def __init__(self, rt): 8 | self._rt = rt 9 | self._read_len = 0 10 | self._content_len = 0 11 | self._use_chunked = False 12 | self._use_encoding = False 13 | if 'Content-Length' in self._rt.headers: 14 | self._content_len = int(self._rt.headers['Content-Length']) 15 | elif 'Transfer-Encoding' in self._rt.headers and self._rt.headers['Transfer-Encoding'] == "chunked": 16 | self._use_chunked = True 17 | else: 18 | raise IOError("create StreamBody failed without Content-Length header or Transfer-Encoding header") 19 | 20 | if 'Content-Encoding' in self._rt.headers: 21 | self._use_encoding = True 22 | 23 | def __iter__(self): 24 | """提供一个默认的迭代器""" 25 | return self._rt.iter_content(1024) 26 | 27 | def __len__(self): 28 | return self._content_len 29 | 30 | def get_raw_stream(self): 31 | """提供原始流""" 32 | return self._rt.raw 33 | 34 | def get_stream(self, chunk_size=1024): 35 | """提供一个chunk可变的迭代器""" 36 | return self._rt.iter_content(chunk_size=chunk_size) 37 | 38 | def read(self, chunk_size=1024, auto_decompress=False): 39 | chunk = None 40 | if self._use_encoding and not auto_decompress: 41 | chunk = self._rt.raw.read(chunk_size) 42 | else: 43 | try: 44 | chunk = next(self._rt.iter_content(chunk_size)) 45 | except StopIteration: 46 | return '' 47 | return chunk 48 | 49 | def get_stream_to_file(self, file_name, disable_tmp_file=False, auto_decompress=False): 50 | """保存流到本地文件""" 51 | self._read_len = 0 52 | tmp_file_name = "{file_name}_{uuid}".format(file_name=file_name, uuid=uuid.uuid4().hex) 53 | if disable_tmp_file: 54 | tmp_file_name = file_name 55 | chunk_size = 1024 * 1024 56 | with open(tmp_file_name, 'wb') as fp: 57 | while True: 58 | chunk = self.read(chunk_size, auto_decompress) 59 | if not chunk: 60 | break 61 | self._read_len += len(chunk) 62 | fp.write(chunk) 63 | 64 | if not self._use_chunked and not ( 65 | self._use_encoding and auto_decompress) and self._read_len != self._content_len: 66 | if os.path.exists(tmp_file_name): 67 | os.remove(tmp_file_name) 68 | raise IOError("download failed with incomplete file") 69 | if file_name != tmp_file_name: 70 | if os.path.exists(file_name): 71 | os.remove(file_name) 72 | os.rename(tmp_file_name, file_name) 73 | 74 | def pget_stream_to_file(self, fdst, offset, expected_len, auto_decompress=False): 75 | """保存流到本地文件的offset偏移""" 76 | self._read_len = 0 77 | fdst.seek(offset, 0) 78 | chunk_size = 1024 * 1024 79 | while True: 80 | chunk = self.read(chunk_size, auto_decompress) 81 | if not chunk: 82 | break 83 | self._read_len += len(chunk) 84 | fdst.write(chunk) 85 | 86 | if not self._use_chunked and not (self._use_encoding and auto_decompress) and self._read_len != expected_len: 87 | raise IOError("download failed with incomplete file") 88 | -------------------------------------------------------------------------------- /qcloud_cos/version.py: -------------------------------------------------------------------------------- 1 | __version__ = '5.1.9.37' 2 | -------------------------------------------------------------------------------- /qcloud_cos/xml2dict.py: -------------------------------------------------------------------------------- 1 | # -*- coding=utf-8 2 | import xml.etree.ElementTree 3 | 4 | 5 | class Xml2Dict(dict): 6 | 7 | def __init__(self, parent_node): 8 | if parent_node.items(): 9 | self.updateDict(dict(parent_node.items())) 10 | if len(parent_node) == 0: 11 | self.updateDict({parent_node.tag: parent_node.text}) 12 | for element in parent_node: 13 | if len(element): 14 | aDict = Xml2Dict(element) 15 | self.updateDict({element.tag: aDict}) 16 | elif element.items(): 17 | elementattrib = element.items() 18 | if element.text: 19 | elementattrib.append((element.tag, element.text)) 20 | self.updateDict({element.tag: dict(elementattrib)}) 21 | else: 22 | self.updateDict({element.tag: element.text}) 23 | 24 | def updateDict(self, aDict): 25 | for key in aDict: 26 | if key in self: 27 | value = self.pop(key) 28 | if type(value) is not list: 29 | lst = list() 30 | lst.append(value) 31 | lst.append(aDict[key]) 32 | self.update({key: lst}) 33 | else: 34 | value.append(aDict[key]) 35 | self.update({key: value}) 36 | else: 37 | self.update({key: aDict[key]}) 38 | 39 | 40 | if __name__ == "__main__": 41 | pass 42 | # s = """ 43 | # 44 | # 10 45 | # 1test1 46 | # 2test2 47 | # 3test3 48 | # """ 49 | # root = xml.etree.ElementTree.fromstring(s) 50 | # xmldict = Xml2Dict(root) 51 | # print(xmldict) 52 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | xmltodict 2 | six 3 | crcmod 4 | pycryptodome -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from setuptools import setup, find_packages 4 | from platform import python_version_tuple 5 | import sys 6 | import io 7 | 8 | 9 | def requirements(): 10 | with open('requirements.txt', 'r') as fileobj: 11 | requirements = [] 12 | 13 | # certifi2021.10.8之后的版本不再支持python2和python3.6之前的版本 14 | if sys.version_info.major < 3 or \ 15 | (sys.version_info.major == 3 and sys.version_info.minor < 6): 16 | requirements.append('certifi<=2021.10.8') 17 | 18 | # requests2.27.1之后的版本不再支持python2和python3.7之前的版本 19 | if sys.version_info.major < 3 or \ 20 | (sys.version_info.major == 3 and sys.version_info.minor < 7): 21 | requirements.append('requests>=2.8,<=2.27.1') 22 | else: 23 | requirements.append('requests>=2.8') 24 | 25 | requirements.extend([line.strip() for line in fileobj]) 26 | return requirements 27 | 28 | 29 | def long_description(): 30 | with io.open('README.rst', 'r', encoding='utf8') as fileobj: 31 | return fileobj.read() 32 | 33 | 34 | setup( 35 | name='cos_python_sdk_v5', # comply with PEP 625 36 | version='1.9.37', 37 | url='https://www.qcloud.com/', 38 | license='MIT', 39 | author='tiedu, lewzylu, channingliu', 40 | author_email='dutie123@qq.com', 41 | description='cos-python-sdk-v5', 42 | long_description=long_description(), 43 | packages=find_packages(), 44 | install_requires=requirements() 45 | ) 46 | -------------------------------------------------------------------------------- /ut/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tencentyun/cos-python-sdk-v5/617a46a750d0c8fd2e2249d6e006866e6680b7dd/ut/__init__.py --------------------------------------------------------------------------------