question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

listing the top level contents of a s3 bucket with Prefix and Delimiter

See original GitHub issue

Apologies for what sounds like a very basic question. In this example from the s3 docs is there a way to list the continents? I was hoping this might work, but it doesn’t seem to:

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('edsu-test-bucket')

for o in bucket.objects.filter(Delimiter='/'):
    print(o.key)

However, the equivalent code using boto2 does seem to work the way I expect:

import boto

s3 = boto.connect_s3()
bucket = s3.get_bucket('edsu-test-bucket')

for o in bucket.list(delimiter='/'):
    print(o.name)

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:13
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

44reactions
amatthiescommented, Jun 28, 2015

@edsu I ran into this as well. The “directories” to list aren’t really objects (but substrings of object keys), so I do not expect them to show up in an objects collection. As a quick workaround, I list them via client.list_objects.

For non-public buckets (or buckets that you can explicitly access):

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('edsu-test-bucket')
result = bucket.meta.client.list_objects(Bucket=bucket.name,
                                         Delimiter='/')
for o in result.get('CommonPrefixes'):
    print(o.get('Prefix'))

Would print:

Europe/ North America/

This doesn’t support anonymous calls, though. When I run this, I get an AccessDenied error.

For anonymous calls I haven’t found a way to use a s3 resource at all (so far). But I can call list_objects on a low-level client:

import boto3
import botocore

client = boto3.client('s3',  # region_name='us-east-1',
                      config=botocore.client.Config(signature_version=botocore.UNSIGNED))
result = client.list_objects(Bucket='edsu-test-bucket',
                             Prefix='North America/',
                             Delimiter='/'
                             )
for o in result.get('CommonPrefixes'):
    print(o.get('Prefix'))                   

Not very beautiful, but it prints what I wanted

North America/Canada/ North America/USA/

30reactions
kyleknapcommented, Jun 29, 2015

@amatthies is on the right track here. The reason that it is not included in the list of objects returned is that the values that you are expecting when you use the delimiter are prefixes (e.g. Europe/, North America) and prefixes do not map into the object resource interface. If you want to know the prefixes of the objects in a bucket you will have to use list_objects. However, I would suggest to use the pagination interface for this because this will allow you to iterate through all objects in the bucket without having to provide pagination tokens:

import boto3
client = boto3.client('s3')
paginator = client.get_paginator('list_objects')
for result in paginator.paginate(Bucket='edsu-test-bucket', Delimiter='/'):
    for prefix in result.get('CommonPrefixes'):
        print(prefix.get('Prefix'))

As to your question as how to use anonymous clients for resources try the following. You will have to hook into the event system to disable signing:

import boto3

from botocore.handlers import disable_signing

resource = boto3.resource('s3')

resource.meta.client.meta.events.register(
    'choose-signer.s3.*', disable_signing)

I realize that this not documented anywhere. Documenting the event system and things you can do with it is on our list of thing that we want to do.

Based on the conversation, I see the following action items:

  1. Improve documentation to use client when you are trying to get prefixes.
  2. Document the event system and things you can do with the event system
  3. Possibly adding a way to disable signing upon instantiation of the resource.

Let me know what you all think or if there is anything else that should be added to this list.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Organizing objects using prefixes - AWS Documentation
You can use prefixes to organize the data that you store in Amazon S3 buckets. A prefix is a string of characters at...
Read more >
Retrieving subfolders names in S3 bucket from boto3
A reminder about boto3 : boto3.resource is a nice high level API. ... a simple way to list contents of a subfolder in...
Read more >
List files and folders of AWS S3 bucket using prefix & delimiter
It is used to get all the objects of the specified bucket. The arguments prefix and delimiter for this method is used for...
Read more >
Quickest Ways to List Files in S3 Bucket - Binary Guy
As you can see it is easy to list files from one folder by using the “Prefix” parameter. List files in S3 using...
Read more >
Difference between prefixes and nested folders in Amazon S3
A key prefix is a string of characters that can be the complete path in front of the object name (including the bucket...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found