web-dev-qa-db-fra.com

Fonction Lambda AWS Python - Télécharger un fichier vers S3

J'ai une fonction AWS Lambda écrite en Python 2.7 dans laquelle je souhaite:

1) Prenez un fichier .xls à partir d’une adresse HTTP.

2) Stockez-le dans un endroit temporaire.

3) Stockez le fichier dans un compartiment S3.

Mon code est le suivant:

from __future__ import print_function
import urllib
import datetime 
import boto3
from botocore.client import Config

def lambda_handler(event, context):

    """Make a variable containing the date format based on YYYYYMMDD"""
    cur_dt = datetime.datetime.today().strftime('%Y%m%d')

    """Make a variable containing the url and current date based on the variable
    cur_dt"""
    dls = "http://11.11.111.111/XL/" + cur_dt + ".xlsx"
    urllib.urlretrieve(dls, cur_dt + "test.xls")

    ACCESS_KEY_ID = 'Abcdefg'
    ACCESS_SECRET_KEY = 'hijklmnop+6dKeiAByFluK1R7rngF'
    BUCKET_NAME = 'my-bicket'
    FILE_NAME = cur_dt + "test.xls";

    data = open('/tmp/' + FILE_NAME, 'wb')

    # S3 Connect
    s3 = boto3.resource(
        's3',
        aws_access_key_id=ACCESS_KEY_ID,
        aws_secret_access_key=ACCESS_SECRET_KEY,
        config=Config(signature_version='s3v4')
    )

    # Uploaded File
    s3.Bucket(BUCKET_NAME).put(Key=FILE_NAME, Body=data, ACL='public-read')

Cependant, lorsque j'exécute cette fonction, le message d'erreur suivant s'affiche:

'IOError: [Errno 30] Système de fichiers en lecture seule'

J'ai passé des heures à essayer de résoudre ce problème, mais je suis tombé sur la tête. Toute aide serait appréciée.

4
pol_guy

'IOError: [Errno 30] Système de fichiers en lecture seule'

Vous semblez manquer de certains droits d'accès en écriture. Si votre lambda a une autre stratégie, essayez d’attacher cette stratégie à votre rôle: 

arn: aws: iam :: aws: policy/AWSLambdaFullAccess

Il a également un accès complet sur S3, au cas où vous ne pourriez pas écrire dans votre compartiment. Si cela résout votre problème, vous supprimerez ensuite certains droits. 

4
Sébastien Coste

change data = open('/tmp/' + FILE_NAME, 'wb') change le wb pour "r" 

de plus, je suppose que votre utilisateur IAM a un accès complet à S3, n'est-ce pas?

ou peut-être que le problème réside dans la demande de cette URL ... essayez que cur_dt commence par "/tmp/"__.urllib.urlretrieve(dls, "/tmp/" + cur_dt + "test.xls")

1
UXDart

J'ai téléchargé l'image sur s3 Bucket. Dans "Lambda Test Event", j'ai créé un événement de test json contenant le fichier BASE64 de l'image à télécharger sur s3 Bucket et le nom de l'image . Lambda Test JSON Event fallows ======>

            { 
                "ImageName": "Your Image Name",
                "img64":"BASE64 of Your Image"
            }

Voici le code pour télécharger une image ou n’importe quel fichier sur s3 ======>

import boto3
import base64
def lambda_handler(event, context):
    s3 = boto3.resource(u's3')
    bucket = s3.Bucket(u'YOUR-BUCKET-NAME')
    path_test = '/tmp/output'         # temp path in lambda.
    key = event['ImageName']          # assign filename to 'key' variable
    data = event['img64']             # assign base64 of an image to data variable 
    data1 = data
    img = base64.b64decode(data1)     # decode the encoded image data (base64)
    with open(path_test, 'wb') as data:
        #data.write(data1)
        data.write(img)
        bucket.upload_file(path_test, key)   # Upload image directly inside bucket
        #bucket.upload_file(path_test, 'FOLDERNAME-IN-YOUR-BUCKET /{}'.format(key))    # Upload image inside folder of your s3 bucket.
    print('res---------------->',path_test)
    print('key---------------->',key)

    return {
            'status': 'True',
       'statusCode': 200,
       'body': 'Image Uploaded'
      }
0
Suraj Kulkarni