2015-03-31 58 views
83

我正在尝试使用新的boto3客户端为AWS执行“hello world”。如何使用boto3将S3对象保存到文件中

我使用的用例很简单:从S3获取对象并将其保存到文件中。

在博托2.X我会做这样的:

import boto 
key = boto.connect_s3().get_bucket('foo').get_key('foo') 
key.get_contents_to_filename('/tmp/foo') 

在博托3。我无法找到一个干净的方式做同样的事情,所以我手动遍历“流”对象:

import boto3 
key = boto3.resource('s3').Object('fooo', 'docker/my-image.tar.gz').get() 
with open('/tmp/my-image.tar.gz', 'w') as f: 
    chunk = key['Body'].read(1024*8) 
    while chunk: 
     f.write(chunk) 
     chunk = key['Body'].read(1024*8) 

import boto3 
key = boto3.resource('s3').Object('fooo', 'docker/my-image.tar.gz').get() 
with open('/tmp/my-image.tar.gz', 'w') as f: 
    for chunk in iter(lambda: key['Body'].read(4096), b''): 
     f.write(chunk) 

,它工作正常。我想知道是否有任何“本地”boto3功能,将执行相同的任务?

回答

139

最近有一个自定义进入Boto3,这有助于此(除其他外)。这是目前公开的低级别S3客户端上,并可以这样使用:

s3_client = boto3.client('s3') 
open('hello.txt').write('Hello, world!') 

# Upload the file to S3 
s3_client.upload_file('hello.txt', 'MyBucket', 'hello-remote.txt') 

# Download the file from S3 
s3_client.download_file('MyBucket', 'hello-remote.txt', 'hello2.txt') 
print(open('hello2.txt').read()) 

这些功能会自动处理读/写文件,以及并行做多上传大文件。

+1

@Daniel:感谢您的答复。如果我想在boto3上传使用分段上传的文件,你能回复答案吗? – 2015-11-02 07:16:27

+1

@RahulKumarPatle'upload_file'方法会自动使用分段上传来处理大文件。 – Daniel 2015-11-03 16:26:09

+0

@Daniel - 关于multipart_upload,我创建了一个[SO问题](http://stackoverflow.com/questions/34303775/complete-a-multipart-upload-with-boto3)。 'upload_file'方法似乎不会自动使用分段上传来处理超过'multipart_threshold'配置的文件大小;至少,我还没有能够以这种方式工作。我很想做错!任何帮助是极大的赞赏。 – blehman 2015-12-16 16:47:33

43

boto3现在拥有比客户端更好的接口:

resource = boto3.resource('s3') 
my_bucket = resource.Bucket('MyBucket') 
my_bucket.download_file(key, local_filename) 

这本身不是大大高于接受答案的client(更好虽然文档说它一个更好的工作重试上传和下载失败),但考虑到资源通常更符合人体工程学原理(例如,s3 bucketobject资源比客户端方法更好),这确实允许您保留在资源层而不必下拉。

Resources通常可以以与客户端相同的方式创建,它们采用全部或大部分相同的参数,并将其转发给其内部客户端。

+1

我正在顺利使用。谢谢。 – arsho 2017-03-11 11:56:17

+1

很好的例子,如果你有一个BytesIO对象,那么为了保存一个对象,你需要添加一个关于如何保存对象的相关方法:my_bucket.upload_file()或者my_bucket.upload_fileobj())。 – SMX 2017-05-19 16:06:39

31

对于那些你想模拟像boto2方法set_contents_from_string谁,你可以尝试

import boto3 
from cStringIO import StringIO 

s3c = boto3.client('s3') 
contents = 'My string to save to S3 object' 
target_bucket = 'hello-world.by.vor' 
target_file = 'data/hello.txt' 
fake_handle = StringIO(contents) 

# notice if you do fake_handle.read() it reads like a file handle 
s3c.put_object(Bucket=target_bucket, Key=target_file, Body=fake_handle.read()) 
+12

这就是答案。下面是一个问题:“如何使用boto3将字符串保存到S3对象?” – jkdev 2016-10-31 02:49:08

+0

for python3我不得不使用 import io; fake_handl e = io.StringIO(内容) – Felix 2017-05-12 03:26:38

5
# Preface: File is json with contents: {'name': 'Android', 'status': 'ERROR'} 

import boto3 
import io 

s3 = boto3.resource(
    's3', 
    aws_access_key_id='my_access_id', 
    aws_secret_access_key='my_secret_key' 
) 

obj = s3.Object('my-bucket', 'key-to-file.json') 
data = io.BytesIO() 
obj.download_fileobj(data) 

# object is now a bytes string, Converting it to a dict: 
new_dict = json.loads(data.getvalue().decode("utf-8")) 

print(new_dict['status']) 
# Should print "Error" 
+8

切勿将AWS_ACCESS_KEY_ID或您的AWS_SECRET_ACCESS_KEY放入您的代码中。这些应该用awscli'aws configure'命令来定义,它们会被'botocore'自动找到。 – 2017-03-16 23:36:55

+0

有效的点。应该包括那真的。 – SixDays 2017-04-04 10:00:33

相关问题