0
votes

I have this lambda function which creates a signed URL for the Object in bucket and return a URL to API gateway .

here is my lambda function code

import uuid
import boto3


def lambda_handler(event, context):
    s3 = boto3.client('s3')

    upload_key = uuid.uuid4().hex

    bucket = 'test-bucket-athena'


    # Generate the presigned URL for upload
    presigned_upload_url = s3.generate_presigned_url(
        ClientMethod='put_object',
        Params={
            'Bucket': bucket,
            'Key': upload_key,
            'Expires': 3600
        }
    )

    # return the result
    return {
        "upload_url": presigned_upload_url
        #"download_url": presigned_download_url
    }

When i run this code i get below error

[ERROR] ParamValidationError: Parameter validation failed: Unknown parameter in input: "Expires", must be one of: Bucket, IfMatch, IfModifiedSince, IfNoneMatch, IfUnmodifiedSince, Key, Range, ResponseCacheControl, ResponseContentDisposition, ResponseContentEncoding, ResponseContentLanguage, ResponseContentType, ResponseExpires, VersionId, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, RequestPayer, PartNumber, ExpectedBucketOwner Traceback (most recent call last):   File "/var/task/lambda_function.py", line 14, in lambda_handler     presigned_download_url = s3.generate_presigned_url(   File "/var/runtime/botocore/signers.py", line 586, in generate_presigned_url     request_dict = serializer.serialize_to_request(   File "/var/runtime/botocore/validate.py", line 293, in serialize_to_request     raise ParamValidationError(report=report.generate_report())

I thought the S3 url that i have provide is not in correct format but i tested all combination and nothing seems to be working

I have tried below formats

bucket = 'test-bucket-athena'
bucket = 'test-bucket-athena/'
bucket = 's3://test-bucket-athena/'
bucket = 's3://test-bucket-athena'
bucket = 's3:///test-bucket-athena'

Please suggest what silly mistake i am doing here

1
you're code works for me using my own bucket in this format bucket = 'test-bucket-athena'; somehow it thinks Expires doesn't belong in your parameters, but not sure why - Jonathan Leon
which boto3 version are you using? - Jonathan Leon
hi @JonathanLeon i am using 1.17.88 boto3 version - SUDARSHAN
i'm on '1.16.30' and the method looks to be the same with your version. generate_presigned_url(ClientMethod, Params=None, ExpiresIn=3600, HttpMethod=None) although this uses ExpiresIn and not Expires. maybe take it out of params and make same level as Params and ClientMethod???? - Jonathan Leon
When i removed 'ExpiresIn': 3600 or Expires i am able to get the url in response - SUDARSHAN

1 Answers

0
votes

The bucketname should be in the format 'bucketname', just as you have on the first line:

bucket = 'test-bucket-athena'

But, I think you missed the error in the error message:

[ERROR] ParamValidationError: Parameter validation failed: Unknown parameter in input: "Expires", must be one of:

You have Expires in the Params section and its should actually be at the same level as Params.

presigned_upload_url = s3.generate_presigned_url(
        ClientMethod='put_object',
        Params={
            'Bucket': bucket,
            'Key': upload_key
        }, 
        ExpiresIn=3600
    )