Boto3: Unable to seek in file download

Created on 20 Aug 2017  路  3Comments  路  Source: boto/boto3

Perhaps I am missing something, but it does not seem that I can seek a file I am trying to download from s3 and request a specific byte offset of that file. If this is possible please point me in the right direction.

obj = boto3.resource('s3').Object(bucket, path)
stream = obj.get()['Body']._raw_stream
print stream.seekable()
>> False

Invoking the seek() method on the stream throws the unsupported error.

The stop gap solution is to call the iterator, and iterate through the file, but this is not a good solution if the files are large. I believe S3 API supports byte offset requests -- as seeking seems to be supported in other languages.

Perhaps there is a different way to do this and I am approaching it incorrectly as this seems to be a core functionality?

This presents a number of issues if I wish to pull a chunk of bytes from a large file in s3.

closing-soon question

Most helpful comment

You can do the same thing in boto3 it is just a different parameter. Something like this should work:

import boto3

obj = boto3.resource('s3').Object('mybucketfoo', 'foo')
stream = obj.get(Range='bytes=1-3')['Body']
print(stream.read())

Let us know if that helps.

All 3 comments

I was able to achieve a solution using boto v2.45 and v2.48
This allow for seeking functionality using the explicit Range header in the API request.

conn = S3Connection(a,b)
bucket = conn.get_bucket(bucket)
key = bucket.get_key(key_path)
byte_block = key.get_contents_as_string(headers={'Range': 'bytes=22000-23000'})

You can do the same thing in boto3 it is just a different parameter. Something like this should work:

import boto3

obj = boto3.resource('s3').Object('mybucketfoo', 'foo')
stream = obj.get(Range='bytes=1-3')['Body']
print(stream.read())

Let us know if that helps.

@kyleknap Thanks for the help. Tested and works. Thanks again

Was this page helpful?
0 / 5 - 0 ratings