objects - upload to s3 python




Как я могу получить список только папок в amazon S3, используя python boto (6)

В принципе нет такой вещи, как папка в S3. Внутренне все хранится как ключ, и если в имени ключа есть символ косой черты, клиенты могут решить показать его как папку.

Имея это в виду, вы должны сначала получить все ключи, а затем использовать регулярное выражение для фильтрации путей, которые включают в себя косую черту. Решение, которое у вас есть сейчас, уже хорошее начало.

Я использую boto и python и amazon s3.

Если я использую

[key.name for key in list(self.bucket.list())]

то я получаю все ключи всех файлов.

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/new/abc.pdf
mybucket/files/pdf/2011/

что является лучшим способом

1. either get all folders from s3
2. or from that list just remove the file from the last and get the unique keys of folders

Я думаю делать так

set([re.sub("/[^/]*$","/",path) for path in mylist]

Как указано в одном из комментариев, предложенном j1m, возвращается префиксный объект. Если после имени / пути вы можете использовать имя переменной. Например:

import boto
import boto.s3

conn = boto.s3.connect_to_region('us-west-2')
bucket = conn.get_bucket(your_bucket)

folders = bucket.list("","/")
for folder in folders:
    print folder.name

Проблема здесь, как было сказано другими, заключается в том, что папка не обязательно имеет ключ, поэтому вам придется искать строки для символа / и определять их папки через них. Вот один из способов генерации рекурсивного словаря, имитирующего структуру папок.

Если вы хотите, чтобы все файлы и их URL были в папках

assets = {}
  for key in self.bucket.list(str(self.org) + '/'):
    path = key.name.split('/')

    identifier = assets
  for uri in path[1:-1]:
    try:
      identifier[uri]
    except:
      identifier[uri] = {}
    identifier = identifier[uri]

    if not key.name.endswith('/'):
      identifier[path[-1]] = key.generate_url(expires_in=0, query_auth=False)

return assets

Если вы просто хотите, чтобы пустые папки

folders = {}
  for key in self.bucket.list(str(self.org) + '/'):
    path = key.name.split('/')

    identifier = folders
  for uri in path[1:-1]:
    try:
      identifier[uri]
    except:
      identifier[uri] = {}
    identifier = identifier[uri]

    if key.name.endswith('/'):
      identifier[path[-1]] = {}

return folders

Затем это может быть рекурсивно зачитано позже.


Это будет неполным ответом, поскольку я не знаю python или boto, но я хочу прокомментировать базовую концепцию в вопросе.

Один из других плакатов был прав: в S3 нет понятия каталога. Есть только плоские пары ключ / значение. Многие приложения притворяются, что определенные разделители указывают записи каталога. Например, «/» или «\». Некоторые приложения заходят так далеко, как помещают фиктивный файл на место, так что, если «каталог» опустеет, вы все равно можете увидеть его в результатах списка.

Вам не всегда нужно тянуть все ваше ведро и делать фильтрацию локально. S3 имеет концепцию списка с разделителями, в котором вы конкретно определяете свой разделитель пути («/», «\», «|», «foobar» и т. Д.), А S3 вернет вам виртуальные результаты, аналогичные тому, что вы хотеть.

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html (Посмотрите на заголовок разделителя.)

Этот API предоставит вам один уровень каталогов. Итак, если бы у вас в вашем примере:

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/new/abc.pdf
mybucket/files/pdf/2011/

И вы перешли в СПИСОК с префиксом «» и разделителем «/», вы получите результаты:

mybucket/files/

Если вы перешли в СПИСОК с префиксом «mybucket / files /» и разделителем «/», вы получите результаты:

mybucket/files/pdf/

И если вы перешли в СПИСОК с префиксом «mybucket / files / pdf /» и разделителем «/», вы получите результаты:

mybucket/files/pdf/abc.pdf
mybucket/files/pdf/abc2.pdf
mybucket/files/pdf/abc3.pdf
mybucket/files/pdf/abc4.pdf
mybucket/files/pdf/new/
mybucket/files/pdf/2011/

Если бы вы хотели исключить сами файлы PDF из набора результатов, вы были бы сами по себе.

Теперь, как вы это делаете в python / boto, я понятия не имею. Надеюсь, есть способ пройти.


интерфейс boto позволяет вам перечислить содержимое ведра и предоставить префикс записи. Таким образом, у вас может быть запись для того, что будет каталогом в обычном файловом массиве:

import boto
AWS_ACCESS_KEY_ID = '...'
AWS_SECRET_ACCESS_KEY = '...'

conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.get_bucket()
bucket_entries = bucket.list(prefix='/path/to/your/directory')

for entry in bucket_entries:
    print entry

основываясь на ответе сета:

Чтобы получить каталоги верхнего уровня:

list(bucket.list("", "/"))

Чтобы получить подкаталоги files :

list(bucket.list("files/", "/")

и так далее.





boto