web-dev-qa-db-fra.com

Comment télécharger un fichier sur S3 sans créer de fichier local temporaire

Existe-t-il un moyen pratique de télécharger un fichier généré dynamiquement sur Amazon s3 directement sans créer un fichier local, puis de le télécharger sur le serveur s3? J'utilise python. Merci

22
susanne

Voici un exemple de téléchargement d'une image (à l'aide de la bibliothèque de demandes) et de son téléchargement sur s3, sans écrire dans un fichier local:

import boto
from boto.s3.key import Key
import requests

#setup the bucket
c = boto.connect_s3(your_s3_key, your_s3_key_secret)
b = c.get_bucket(bucket, validate=False)

#download the file
url = "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
r = requests.get(url)
if r.status_code == 200:
    #upload the file
    k = Key(b)
    k.key = "image1.png"
    k.content_type = r.headers['content-type']
    k.set_contents_from_string(r.content)
21
JimJty

La clé boto library's Key a plusieurs méthodes qui pourraient vous intéresser:

Pour un exemple d'utilisation de set_contents_from_string, voir la section Stockage de données de la documentation boto, collée ici pour plus de détails

>>> from boto.s3.key import Key
>>> k = Key(bucket)
>>> k.key = 'foobar'
>>> k.set_contents_from_string('This is a test of S3')
10
jterrace

Vous pouvez utiliser BytesIO depuis la bibliothèque standard Python.

from io import BytesIO
bytesIO = BytesIO()
bytesIO.write('whee')
bytesIO.seek(0)
s3_file.set_contents_from_file(bytesIO)
8
Roy Hyunjin Han

Je suppose que vous utilisez boto. boto 's Bucket.set_contents_from_file() acceptera un objet StringIO et tout code que vous avez écrit pour écrire des données dans un fichier devrait être facilement adaptable pour écrire dans un objet StringIO. Ou, si vous générez une chaîne, vous pouvez utiliser set_contents_from_string().

2
kindall

Vous pouvez essayer d'utiliser smart_open ( https://pypi.org/project/smart_open/ ). Je l'ai utilisé exactement pour cela: écrire des fichiers directement dans S3.

0
dd.
def upload_to_s3(url, **kwargs):
    '''
    :param url: url of image which have to upload or resize to upload
    :return: url of image stored on aws s3 bucket
    '''

    r = requests.get(url)
    if r.status_code == 200:
        # credentials stored in settings AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
        conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, Host=AWS_Host)

        # Connect to bucket and create key
        b = conn.get_bucket(AWS_Bucket_Name)
        k = b.new_key("{folder_name}/{filename}".format(**kwargs))

        k.set_contents_from_string(r.content, replace=True,
                                   headers={'Content-Type': 'application/%s' % (FILE_FORMAT)},
                                   policy='authenticated-read',
                                   reduced_redundancy=True)

        # TODO Change AWS_EXPIRY
        return k.generate_url(expires_in=AWS_EXPIRY, force_http=True)
0
Naveen Agarwal