web-dev-qa-db-fra.com

Comment puis-je accéder aux fichiers s3 dans Python en utilisant des URL?

Je veux écrire un script Python qui va lire et écrire des fichiers depuis s3 en utilisant leurs URL, par exemple: 's3:/mybucket/file'. Il devrait s'exécuter localement et dans le cloud sans y a-t-il un moyen de le faire?

Edit: Il y a quelques bonnes suggestions ici mais ce que je veux vraiment, c'est quelque chose qui me permet de faire ceci:

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

puis utilisez cet objet fichier comme tout autre objet fichier. Ce serait vraiment cool. Je pourrais juste écrire quelque chose comme ça pour moi si ça n'existe pas. Je pourrais construire cette couche d'abstraction sur simples3 ou boto.

26
Nate Reed

Pour l'ouverture, cela devrait être aussi simple que:

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

Cela fonctionnera avec s3 si le fichier est public.

Pour écrire un fichier en utilisant boto, cela va quelque chose comme ceci:

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()

laissez-moi savoir si cela fonctionne pour vous :)

12
Skylar Saveland

Voici comment ils le font dans 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)

Que vous pourriez simplement utiliser avec un code comme celui-ci

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)

Cela ne répond pas à l'objectif d'interagir avec une clé s3 comme un fichier comme un objet mais c'est un pas dans cette direction.

6
gene_wood

Je n'ai pas vu quelque chose qui fonctionnerait directement avec les URL S3, mais vous pouvez utiliser un bibliothèque d'accès S ( simples semble décent) et une manipulation de chaîne simple:

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

http://s3tools.org/s3cmd fonctionne plutôt bien et prend en charge la forme s3: // de la structure URL que vous souhaitez. Il fait des affaires sur Linux et Windows. Si vous avez besoin d'une API native pour appeler à partir d'un programme python alors http://code.google.com/p/boto/ est un meilleur choix.

1
Joe Drumgoole

Vous pouvez utiliser Boto Python API pour accéder à S3 par python. C'est une bonne bibliothèque. Après avoir fait l'installation de Boto, l'exemple de programme suivant fonctionnera pour vous

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

Vous pouvez trouver plus d'informations ici http://boto.cloudhackers.com/s3_tut.html#storing-data

1
Anto Binish Kaspar

Essayez s3fs

Premier exemple sur les documents:

>>> 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'
0
Guilherme Freitas