's3.Bucket' object has no attribute 'put': AttributeError

13,905

As per the official docs here, instead of

s3.Bucket(BUCKET_NAME).put(Key= filename, Body=data, ACL='public-read')

you should use put_object() function as

s3.Bucket(BUCKET_NAME).put_object(Key= filename, Body=data, ACL='public-read')
Share:
13,905

Related videos on Youtube

Seeker90
Author by

Seeker90

Updated on June 04, 2022

Comments

  • Seeker90
    Seeker90 about 2 years

    I am trying to download a file from an URL and upload the file in an S3 bucket. My code is as follows-

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import print_function
    import xml.etree.ElementTree as etree
    from datetime import datetime as dt
    import os
    import urllib
    import requests
    import boto3
    from botocore.client import Config
    
    from urllib.parse import urlparse
    
    
    def lambda_handler(event, context):
        """ Route the incoming request based on type (LaunchRequest, IntentRequest,
        etc.) The JSON body of the request is provided in the event parameter.
        """
    
        print('event.session.application.applicationId=' + event['session'
              ]['application']['applicationId'])
    
        # if (event['session']['application']['applicationId'] !=
        #         "amzn1.echo-sdk-ams.app.[unique-value-here]"):
        #     raise ValueError("Invalid Application ID")
    
        if event['session']['new']:
            on_session_started({'requestId': event['request']['requestId'
                               ]}, event['session'])
    
        if event['request']['type'] == 'LaunchRequest':
            return on_launch(event['request'], event['session'])
        elif event['request']['type'] == 'IntentRequest':
            return on_intent(event['request'], event['session'])
        elif event['request']['type'] == 'SessionEndedRequest':
            return on_session_ended(event['request'], event['session'])
    
    
    def on_session_started(session_started_request, session):
        """ Called when the session starts """
    
        print('on_session_started requestId='
              + session_started_request['requestId'] + ', sessionId='
              + session['sessionId'])
    
    
    def on_launch(launch_request, session):
        """ Called when the user launches the skill without specifying what they
        want
        """
    
        print('on_launch requestId=' + launch_request['requestId']
              + ', sessionId=' + session['sessionId'])
    
        # Dispatch to your skill's launch
    
        return get_welcome_response()
    
    
    def on_intent(intent_request, session):
        """ Called when the user specifies an intent for this skill """
    
        print('on_intent requestId=' + intent_request['requestId']
              + ', sessionId=' + session['sessionId'])
    
        intent = intent_request['intent']
        intent_name = intent_request['intent']['name']
    
        # Dispatch to your skill's intent handlers
    
        if intent_name == 'DownloadFiles':
            return get_file(intent, session)
        elif intent_name == 'AMAZON.HelpIntent':
            return get_welcome_response()
        else:
            raise ValueError('Invalid intent')
    
    
    def on_session_ended(session_ended_request, session):
        """ Called when the user ends the session.Is not called when the skill returns should_end_session=true """
    
        print('on_session_ended requestId='
              + session_ended_request['requestId'] + ', sessionId='
              + session['sessionId'])
    
    
        # add cleanup logic here
    
    # --------------- Functions that control the skill's behavior ------------------
    
    def get_welcome_response():
        """ If we wanted to initialize the session to have some attributes we could add those here """
    
        session_attributes = {}
        card_title = 'Welcome'
        speech_output = \
            "Welcome to file download Application. Please ask me to download files by saying, Ask downloader for download"
    
        # If the user either does not reply to the welcome message or says something
        # that is not understood, they will be prompted again with this text.
    
        reprompt_text = \
            "Please ask me to download files by saying, Ask downloader for download"
        should_end_session = False
        return build_response(session_attributes,
                              build_speechlet_response(card_title,
                              speech_output, reprompt_text,
                              should_end_session))
    
    
    def get_file(intent, session):
        """ Grabs the files from the path that have to be downloaded """
    
        card_title = intent['name']
        session_attributes = {}
        should_end_session = True
        username = '*'
        password = '*'
    
        ACCESS_KEY_ID = '*'
        ACCESS_SECRET_KEY = '*+9'
        BUCKET_NAME = 'lambda-file-upload'
    
        url = 'https://drive.google.com/drive/xyz'
        filename = os.path.basename(urlparse(url).path)
    
        # urllib.urlretrieve(url, "code.zip")
    
        r = requests.get(url, auth=(username, password))
    
        if r.status_code == 200:
            with open("/tmp/" + filename, 'wb') as out:
                for bits in r.iter_content():
                    out.write(bits)
    
        data = open("/tmp/" + filename, 'rb')
        # 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= filename, Body=data, ACL='public-read')
        speech_output = "The file" + filename + "has been downloaded"
        reprompt_text = ""
        return build_response(session_attributes,
                              build_speechlet_response(card_title,
                              speech_output, reprompt_text,
                              should_end_session))
    
    
    # --------------- Helpers that build all of the responses ----------------------
    
    def build_speechlet_response(
        title,
        output,
        reprompt_text,
        should_end_session,
        ):
        return {
            'outputSpeech': {'type': 'PlainText', 'text': output},
            'card': {'type': 'Simple', 'title': 'SessionSpeechlet - ' \
                     + title, 'content': 'SessionSpeechlet - ' + output},
            'reprompt': {'outputSpeech': {'type': 'PlainText',
                         'text': reprompt_text}},
            'shouldEndSession': should_end_session,
            }
    
    
    def build_response(session_attributes, speechlet_response):
        return {'version': '1.0', 'sessionAttributes': session_attributes,
                'response': speechlet_response}
    

    I am getting the following error: -

    's3.Bucket' object has no attribute 'put': AttributeError
    

    I am trying to create an Alexa Skill which will download file from an URL. Hence I created a lambda function.I am new to AWS lambda and S3. I would really appreciate some help.