boto3用法

aws是Amazon Web Service的簡寫,它包括衆多服務,其中最有名的兩個是EC2和S3。
S3是Simple Storage Service的簡寫,它是一種對象存儲的實現。html

安裝和配置

安裝boto3和awscli:pip install boto3 awscli
配置aws:aws configurepython

根據提示輸入access_key_id, secret_access_keyregion
其中access_key_id, secret_access_key的默認存儲位置爲:~/.aws/credentialsweb

[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)

Code Examples

使用Bucket

建立bucket

以下函數封裝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

列出bucket

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

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對象。

修改multipart閾值

當使用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)

將一個Bucket做爲一個靜態服務

獲取一個桶的靜態服務配置

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')

獲取一個Bucket的權限列表

import boto3

# Retrieve a bucket's ACL
s3 = boto3.client('s3')
result = s3.get_bucket_acl(Bucket='my-bucket')
print(result)

presigned URL

分享一個Object

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)

其它技巧

桶策略

IAP: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根包

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()

collection包

boto3中的許多事物最終均可以看作一個集合,例如全部的Bucket構成一個集合,一個目錄下的所有Object構成一個集合。collection包指的是boto3.resources.collection
collection包主要提供兩個入口類:CollectionManagerResourceCollection。這兩個類幾乎具備徹底同樣的方法:

  • all():獲取所有對象的迭代器
  • filter():過濾對象
  • limit(count):只讀取count個對象
  • page_size(count)和pages()用於分頁

resource包

boto3.resource包下內容較多,它包括請求和回覆的格式等類型。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/resources.html

session包

boto3.session包只包含一個Session類,這個類是整個boto庫的入口類。一個Session對象至關於一個包含了各類基礎配置的對象(如aws_access_key_id、aws_secret_access_key等),利用此對象能夠獲取到Client、Resource等對象。
利用Session能夠獲取一些全局信息

  • get_available_partitions():獲取可用分區列表
  • get_available_regions():獲取可用region列表
  • available_profiles:獲取可用的配置文件目錄
  • get_available_regions(service_name, partition_name='aws', allow_non_regional=False):獲取可用分區
  • get_available_resources():獲取可用資源列表,也就是能夠用sess.resource(service_name)函數獲取的服務列表
  • get_awailable_services():獲取可用服務列表,也就是能夠用sess.client(service_name)函數獲取的服務列表
  • get_credentials():和此session有關的祕鑰,使用botocore.credential.Credential對象存儲。

利用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

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

Resource對象是AWS服務的面向對象封裝,它提供了比Client更抽象、更高級的封裝。
每一個Resource對象都包含若干屬性和方法,這些屬性和方法能夠分爲如下幾大類別: identifiers, attributes, actions, references, sub-resources, 和 collections。
Resource對象能夠被分爲兩類:

  • 服務對象(Service Resource):例如 sqs, s3, ec2
  • 獨立對象(Indivisual Resource):例如sqs.Queue 、 s3.Bucket

服務對象和獨立對象的區別在於:服務對象沒有identifiers和attributes之類的屬性和方法。

Collection

Collection對象和Django中的QuerySets很是像。

Client

Client對象提供了最底層的AWS服務封裝,這些服務操做和AWS服務定義是一一對應的。實際上,Client類型的代碼是由JSON形式的服務說明文件直接生成的。

Paginator分頁

有些請求返回的對象太多,因此不能一次性所有返回,只能使用迭代的方式進行訪問。
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/paginators.html

Configuration

boto3會依次查找以下位置的配置,直到找到配置爲止(也就是以下配置優先級遞減):

  • boto.client()方法中的參數
  • 建立session時傳遞的參數
  • 環境變量
  • Shared credential file (~/.aws/credentials)
  • AWS config file (~/.aws/config)
  • Assume Role provider
  • Boto2 config file (/etc/boto.cfg and ~/.boto)
  • Instance metadata service on an Amazon EC2 instance that has an IAM role configured.

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

S3 API

相關文章
相關標籤/搜索