Learning Python Network Programming

(Sean Pound) #1

APIs in Action


We have now included a header in our HTTP request, x-amz-acl, which specifies a
permission set to be applied to the object. We've also added a new argument to our
function signature so that we can specify the permission set on the command line.
We have used the so-called canned ACLs (canned Access Control Lists), which
have been provided by S3, and are documented at http://docs.aws.amazon.com/
AmazonS3/latest/dev/acl-overview.html#canned-acl.


The ACL that we're interested in is called public-read. This will allow anyone to
download the file without needing any kind of authentication. We can now re-run
our upload, but this time it will apply this ACL to it:


$ python3.4 s3_client.py mybucket.example.com test.jpg ~/test.jpg
public-read


Uploaded test.jpg OK


Now, visiting the file's S3 URL in a browser will give us the option to download
the file.


Displaying an uploaded file in a web browser


If you have uploaded an image, then you may be wondering why the browser had
asked us to save it instead of just displaying it. The reason is that we haven't set the
file's Content-Type.


If you remember from the last chapter, the Content-Type header in an HTTP
response tells the client, which in this case is our browser, the type of file that is in
the body. By default, S3 applies the content type of binary/octet-stream. Because
of this Content-Type, the browser can't tell that it's downloading an image, so it just
presents it as a file that can be saved. We can fix this by supplying a Content-Type
header in the upload request. S3 will store the type that we specify, and it will use it
as the Content-Type in the subsequent download responses.


Add the code block shown here to the import at the beginning of s3_client.py:


import mimetypes

Then change upload_file() to this:


def upload_file(bucket, s3_name, local_path, acl='private'):
data = open(local_path, 'rb').read()
url = 'http://{}.{}/{}'.format(bucket, endpoint, s3_name)
headers = {'x-amz-acl': acl}
mimetype = mimetypes.guess_type(local_path)[0]
if mimetype:
headers['Content-Type'] = mimetype
Free download pdf