Как я могу получить доступ к файлам s3 в Python с помощью URL-адресов?

Я хочу написать Python script, который будет читать и записывать файлы с s3, используя их url, например: 's3:/mybucket/file. Он должен запускаться локально и в облаке без каких-либо изменений кода. Есть ли способ сделать это?

Изменить: здесь есть несколько хороших предложений, но то, что я действительно хочу, позволяет мне это сделать:

 myfile = open("s3://mybucket/file", "r")

а затем использовать этот файловый объект, как любой другой объект. Это было бы здорово. Я мог бы написать что-то вроде этого для себя, если его не существует. Я мог бы создать этот слой абстракции на simples3 или boto.

Ответы

Ответ 1

Для открытия он должен быть таким же простым, как:

import urllib
opener = urllib.URLopener()
myurl = "https://s3.amazonaws.com/skyl/fake.xyz"
myfile = opener.open(myurl)

Это будет работать с s3, если файл является общедоступным.

Чтобы записать файл с помощью boto, это выглядит примерно так:

from boto.s3.connection import S3Connection
conn = S3Connection(AWS_KEY, AWS_SECRET)
bucket = conn.get_bucket(BUCKET)
destination = bucket.new_key()
destination.name = filename
destination.set_contents_from_file(myfile)
destination.make_public()

lemme знает, работает ли это для вас:)

Ответ 2

Вот как они это делают в awscli :

def find_bucket_key(s3_path):
    """
    This is a helper function that given an s3 path such that the path is of
    the form: bucket/key
    It will return the bucket and the key represented by the s3 path
    """
    s3_components = s3_path.split('/')
    bucket = s3_components[0]
    s3_key = ""
    if len(s3_components) > 1:
        s3_key = '/'.join(s3_components[1:])
    return bucket, s3_key


def split_s3_bucket_key(s3_path):
    """Split s3 path into bucket and key prefix.
    This will also handle the s3:// prefix.
    :return: Tuple of ('bucketname', 'keyname')
    """
    if s3_path.startswith('s3://'):
        s3_path = s3_path[5:]
    return find_bucket_key(s3_path)

Который вы могли бы просто использовать с таким кодом

from awscli.customizations.s3.utils import split_s3_bucket_key
import boto3
client = boto3.client('s3')
bucket_name, key_name = split_s3_bucket_key(
    's3://example-bucket-name/path/to/example.txt')
response = client.get_object(Bucket=bucket_name, Key=key_name)

Это не относится к цели взаимодействия с ключом s3 как к файлу, подобному объекту, но является шагом в этом направлении.

Ответ 3

Я не видел ничего, что могло бы работать напрямую с URL-адресами S3, но вы могли бы использовать библиотеку доступа S3 (simples3 выглядит прилично) и некоторые простые манипуляции с строкой:

>>> url = "s3:/bucket/path/"
>>> _, path = url.split(":", 1)
>>> path = path.lstrip("/")
>>> bucket, path = path.split("/", 1)
>>> print bucket
'bucket'
>>> print path
'path/'

Ответ 4

Вы можете использовать Boto Python API для доступа к S3 с помощью python. Это хорошая библиотека. После того, как вы выполните установку Boto, следующая программа-образец будет работать для вас

>>> k = Key(b)
>>> k.key = 'yourfile'
>>> k.set_contents_from_filename('yourfile.txt')

Здесь вы можете найти дополнительную информацию http://boto.cloudhackers.com/s3_tut.html#storing-data

Ответ 5

http://s3tools.org/s3cmd работает очень хорошо и поддерживает форму s3://структуры URL, которую вы хотите. Он работает в Linux и Windows. Если вам нужен собственный API для вызова из программы python, то http://code.google.com/p/boto/ - лучший выбор.

Ответ 6

Попробуйте s3fs

Первый пример в документации:

>>> import s3fs
>>> fs = s3fs.S3FileSystem(anon=True)
>>> fs.ls('my-bucket')
['my-file.txt']
>>> with fs.open('my-bucket/my-file.txt', 'rb') as f:
...     print(f.read())
b'Hello, world'