aws是Amazon Web Service的简写,它包括众多服务,其中最有名的两个是EC2和S3。
S3是Simple Storage Service的简写,它是一种对象存储的实现。html
安装boto3和awscli:pip install boto3 awscli
配置aws:aws configure
python
根据提示输入access_key_id
, secret_access_key
和 region
。
其中access_key_id
, secret_access_key
的默认存储位置为:~/.aws/credentials
:web
[default] aws_access_key_id = YOUR_ACCESS_KEY aws_secret_access_key = YOUR_SECRET_KEY
region
的存储位置为~/.aws/config
:json
[default] region=us-east-1
以下代码,首先建立一个s3服务,而后查看所有Bucket,最后上传一个文件。api
import boto3 # Let's use Amazon S3 s3 = boto3.resource('s3') # Print out bucket names for bucket in s3.buckets.all(): print(bucket.name) # Upload a new file data = open('test.jpg', 'rb') s3.Bucket('my-bucket').put_object(Key='test.jpg', Body=data)
以下函数封装boto3的create_bucket(),若是建立Bucket成功,返回True,不然返回False。网络
import logging import boto3 from botocore.exceptions import ClientError def create_bucket(bucket_name): s3 = boto3.client('s3') try s3.create_bucket(Bucket=bucket_name) except ClientError as e: logging.error(e) return False return True
s3 = boto3.client('s3') response = s3.list_buckets() print('Existing buckets:') for bucket in response['Buckets']: print(f'{bucket["Name"]}')
s3提供了两种文件上传方式:upload_file()
和upload_fileobj()
。upload_file()
会把一个大文件拆分红若干个chunk并行上传,所以upload_file()
传输速率较快,它适用于上传内容已经肯定的文件。upload_fileobj()
可用于单线程上传一个二进制流。
upload_file()
例子:session
import logging import boto3 from botocore.exceptions import ClientError def upload_file(file_name, bucket, object_name=None): """Upload a file to an S3 bucket :param file_name: File to upload :param bucket: Bucket to upload to :param object_name: S3 object name. If not specified then file_name is used :return: True if file was uploaded, else False """ # If S3 object_name was not specified, use file_name if object_name is None: object_name = file_name # Upload the file s3_client = boto3.client('s3') try: response = s3_client.upload_file(file_name, bucket, object_name) except ClientError as e: logging.error(e) return False return True
upload_fileobj()
例子:多线程
s3 = boto3.client('s3') with open("FILE_NAME", "rb") as f: s3.upload_fileobj(f, "BUCKET_NAME", "OBJECT_NAME")
upload_fileobj()
的文件参数只能是rb模式打开的文件。并发
Client、Bucket、Object三个类型都提供了upload_file()
和upload_fileobj()
两个函数,每一个类型提供的同一函数功能都是等价的,并没有优劣之分,能够随意调用三个对象的上传文件函数。less
ExtraArgs提供了上传文件的其它参数,这些参数可用于控制上传文件的读写权限、meta信息等。S3Transfer是一个很是重要的对象,它定义了传输过程当中的许多参数,在
boto3.s3.transfer.S3Transfer.ALLOWED_UPLOAD_ARGS中,定义了ExtraArgs可用的参数列表。
s3.upload_file( 'FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME', ExtraArgs={'Metadata': {'mykey': 'myvalue'}} ) s3.upload_file( 'FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME', ExtraArgs={'ACL': 'public-read'} ) s3.upload_file( 'FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME', ExtraArgs={ 'GrantRead': 'uri="http://acs.amazonaws.com/groups/global/AllUsers"', 'GrantFullControl': 'id="01234567890abcdefg"', } )
一边上传一边打印上传进度能够经过实现Callback回调来实现。
s3.upload_file( 'FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME', Callback=ProgressPercentage('FILE_NAME') )
ProgressPercentage
import os import sys import threading class ProgressPercentage(object): def __init__(self, filename): self._filename = filename self._size = float(os.path.getsize(filename)) self._seen_so_far = 0 self._lock = threading.Lock() def __call__(self, bytes_amount): # To simplify, assume this is hooked up to a single filename with self._lock: self._seen_so_far += bytes_amount percentage = (self._seen_so_far / self._size) * 100 sys.stdout.write( "\r%s %s / %s (%.2f%%)" % ( self._filename, self._seen_so_far, self._size, percentage)) sys.stdout.flush()
下载文件和上传文件几乎是彻底对称的,Client、Bucket、Object三个对象提供了download_file()
、download_fileobj()
。download_file()
是并行的,download_file_obj()
是串行的,这两个函数一样提供了ExtraArgs和Callback参数。boto3.s3.transfer.S3Transfer.ALLOWED_DOWNLOAD_ARGS
描述了下载过程的ExtraArgs的可用参数。
import boto3 s3 = boto3.client('s3') s3.download_file('BUCKET_NAME', 'OBJECT_NAME', 'FILE_NAME') with open('FILE_NAME', 'wb') as f: s3.download_fileobj('BUCKET_NAME', 'OBJECT_NAME', f)
在上传文件、下载文件、复制文件过程当中,AWS SDK会自动管理重试等网络配置。默认的网络配置可适用于大多数状况,只有特殊情境下才须要修改传输配置。
传输配置封装在 boto3.s3.transfer.TransferConfig对象中,upload_file()等函数都有一个Config参数接受一个TransferConfig对象。
当使用upload_file()
上传一个大文件时,若是文件大小超过了multipart_threshold,那么会启动多线程上传。
import boto3 from boto3.s3.transfer import TransferConfig # Set the desired multipart threshold value (5GB) GB = 1024 ** 3 config = TransferConfig(multipart_threshold=5*GB) # Perform the transfer s3 = boto3.client('s3') s3.upload_file('FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME', Config=config)
对于upload_file()
和download_file()
默认启用多线程下载,为了减小网络占用或者增长网络占用,能够经过传输配置来控制。
# To consume less downstream bandwidth, decrease the maximum concurrency config = TransferConfig(max_concurrency=5) # Download an S3 object s3 = boto3.client('s3') s3.download_file('BUCKET_NAME', 'OBJECT_NAME', 'FILE_NAME', Config=config)
在boto3中,并发是经过多线程来实现的。若是不使用线程就无法实现并发,max_concurrency参数会被忽略掉。
# Disable thread use/transfer concurrency config = TransferConfig(use_threads=False) s3 = boto3.client('s3') s3.download_file('BUCKET_NAME', 'OBJECT_NAME', 'FILE_NAME', Config=config)
获取一个桶的静态服务配置
import boto3 # Retrieve the website configuration s3 = boto3.client('s3') result = s3.get_bucket_website('BUCKET_NAME')
设置一个桶的静态服务配置
# Define the website configuration website_configuration = { 'ErrorDocument': {'Key': 'error.html'}, 'IndexDocument': {'Suffix': 'index.html'}, } # Set the website configuration s3 = boto3.client('s3') s3.put_bucket_website('BUCKET_NAME', website_configuration)
删除一个桶的网站配置
# Delete the website configuration s3 = boto3.client('s3') s3.delete_bucket_website('BUCKET_NAME')
import boto3 # Retrieve a bucket's ACL s3 = boto3.client('s3') result = s3.get_bucket_acl(Bucket='my-bucket') print(result)
import logging import boto3 from botocore.exceptions import ClientError def create_presigned_url(bucket_name, object_name, expiration=3600): """Generate a presigned URL to share an S3 object :param bucket_name: string :param object_name: string :param expiration: Time in seconds for the presigned URL to remain valid :return: Presigned URL as string. If error, returns None. """ # Generate a presigned URL for the S3 object s3_client = boto3.client('s3') try: response = s3_client.generate_presigned_url('get_object', Params={'Bucket': bucket_name, 'Key': object_name}, ExpiresIn=expiration) except ClientError as e: logging.error(e) return None # The response contains the presigned URL return response
直接使用GET请求这个URL:
import requests # To install: pip install requests url = create_presigned_url('BUCKET_NAME', 'OBJECT_NAME') if url is not None: response = requests.get(url)
Presigned URLs
一节:https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-examples.htmlIAP:Identity&Access Policy
import boto3 # Retrieve the policy of the specified bucket s3 = boto3.client('s3') result = s3.get_bucket_policy('BUCKET_NAME') print(result['Policy'])
import json # Create a bucket policy bucket_name = 'BUCKET_NAME' bucket_policy = { 'Version': '2012-10-17', 'Statement': [{ 'Sid': 'AddPerm', 'Effect': 'Allow', 'Principal': '*', 'Action': ['s3:GetObject'], 'Resource': f'arn:aws:s3:::{bucket_name}/*' }] } # Convert the policy from JSON dict to string bucket_policy = json.dumps(bucket_policy) # Set the new policy s3 = boto3.client('s3') s3.put_bucket_policy(bucket_name, Policy=bucket_policy)
# Delete a bucket's policy s3 = boto3.client('s3') s3.delete_bucket_policy('BUCKET_NAME')
boto3根包提供了两类API:全局设置、重要入口类。
全局设置包括:
boto3.set_stream_logger(name='boto3', level=10, format_string=None)
设置日志级别boto3.setup_default_session(**kwargs)
设置默认session重要入口类包括:
boto3.resource(*args, **kwargs)
:最终会调用session包下的resource函数boto3.session.Session.resource()
boto3.client(*args, **kwargs)
:最终会调用session包下的resource函数boto3.session.Session.client()
boto3中的许多事物最终均可以看作一个集合,例如全部的Bucket构成一个集合,一个目录下的所有Object构成一个集合。collection包指的是boto3.resources.collection
。
collection包主要提供两个入口类:CollectionManager
和ResourceCollection
。这两个类几乎具备彻底同样的方法:
boto3.resource包下内容较多,它包括请求和回复的格式等类型。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/resources.html
boto3.session包只包含一个Session类,这个类是整个boto库的入口类。一个Session对象至关于一个包含了各类基础配置的对象(如aws_access_key_id、aws_secret_access_key等),利用此对象能够获取到Client、Resource等对象。
利用Session能够获取一些全局信息
get_available_regions(service_name, partition_name='aws', allow_non_regional=False)
:获取可用分区利用Session能够构建最重要的两个入口类:
resource(service_name, region_name=None, api_version=None, use_ssl=True, verify=None, endpoint_url=None, aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, config=None) client(service_name, region_name=None, api_version=None, use_ssl=True, verify=None, endpoint_url=None, aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None, config=None)
boto3.s3.transfer
包下包含两个类:TransferConfig和S3Transfer。TransferConfig对象可做为upload_file()
的Config参数的取值;S3Transfer对象实现了upload_file()
和download_file()
,实际上Client、Bucket、Object等类最终都会调用这两个函数,S3Transfer还提供了两个常量表示上传下载时可接受的参数:ALLOWED_DOWNLOAD_ARGS和ALLOWED_UPLOAD_ARGS。
class boto3.s3.transfer.TransferConfig(multipart_threshold=8388608, max_concurrency=10, multipart_chunksize=8388608, num_download_attempts=5, max_io_queue=100, io_chunksize=262144, use_threads=True) class boto3.s3.transfer.S3Transfer(client=None, config=None, osutil=None, manager=None) ALLOWED_DOWNLOAD_ARGS = ['VersionId', 'SSECustomerAlgorithm', 'SSECustomerKey', 'SSECustomerKeyMD5', 'RequestPayer'] ALLOWED_UPLOAD_ARGS = ['ACL', 'CacheControl', 'ContentDisposition', 'ContentEncoding', 'ContentLanguage', 'ContentType', 'Expires', 'GrantFullControl', 'GrantRead', 'GrantReadACP', 'GrantWriteACP', 'Metadata', 'RequestPayer', 'ServerSideEncryption', 'StorageClass', 'SSECustomerAlgorithm', 'SSECustomerKey', 'SSECustomerKeyMD5', 'SSEKMSKeyId', 'WebsiteRedirectLocation'] download_file(bucket, key, filename, extra_args=None, callback=None) upload_file(filename, bucket, key, callback=None, extra_args=None)[source]
boto3官网教程中的用户指南描述了boto3中的各个实体,是最终的文档。
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/index.html
boto3提供了两个级别的接口来访问AWS服务:High Level的Resource级别的接口,Low Level的Client接口。
Client级别的接口返回Dictionary来表示查询到的资源信息,Resource级别的接口对Client级别的接口进行了面向对象的封装,接口的返回值大部分都是Resource对象(若是返回值是某个Resource的信息的话),咱们能够对返回的对象再进行操做(好比删除,修改等)。
Resource对象是AWS服务的面向对象封装,它提供了比Client更抽象、更高级的封装。
每一个Resource对象都包含若干属性和方法,这些属性和方法能够分为如下几大类别: identifiers, attributes, actions, references, sub-resources, 和 collections。
Resource对象能够被分为两类:
服务对象和独立对象的区别在于:服务对象没有identifiers和attributes之类的属性和方法。
Collection对象和Django中的QuerySets很是像。
Client对象提供了最底层的AWS服务封装,这些服务操做和AWS服务定义是一一对应的。实际上,Client类型的代码是由JSON形式的服务说明文件直接生成的。
有些请求返回的对象太多,因此不能一次性所有返回,只能使用迭代的方式进行访问。
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/paginators.html
boto3会依次查找以下位置的配置,直到找到配置为止(也就是以下配置优先级递减):
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#configuration
content-range随机读取,至关于C语言中的fseek:https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16
https://boto3.amazonaws.com/v1/documentation/api/latest/index.html