Reputation: 161
I want to build an image download API by AWS Chalice on Lambda which the image is stored on AWS S3. However, the image downloaded through API can only be opened by running chalice on local, and could not open the file download from API deployed on AWS.
Since our s3 bucket is private and we want the download link to be available in long term (at least over a month). Hence, we throw our data through chalice api not s3 presigned url.
Here is my code
@app.route("/img/download", methods=["GET"])
def download_image_api():
def download_img():
bucket = "my-bucket-name"
key = "my-key-name"
filename = "imgae-file-name"
filepath = f"/tmp/{filename}"
# download imgae to lambda
s3 = boto3.client(
resource="s3",
region_name=config.AWS_REGION_NAME,
aws_access_key_id=config.ACCESS_ID,
aws_secret_access_key=config.SECRET_KEY
)
s3.download_file(bucket, key, filepath)
# build headers
file_size = os.path.getsize(filepath)
headers = {
'Content-Type': 'application/octet-stream',
'Content-Disposition': f'attachment; filename={filename}',
'Content-Length': str(file_size)
}
# build body
f = open(filepath, 'rb')
body = f.read()
return Response(body=body, headers=headers)
and the error message is
Upvotes: 0
Views: 55
Reputation: 161
In the end, we change our way to download the image. We generate a temporary presigned url from S3, and use directions to re-locate our image download URL.
@app.route("/img/download", methods=["GET"])
def download_image_api():
def download_img():
bucket = "my-bucket-name"
key = "my-key-name"
filename = "imgae-file-name"
filepath = f"/tmp/{filename}"
# get temporary presigned url
s3 = boto3.client(
resource="s3",
region_name=config.AWS_REGION_NAME,
aws_access_key_id=config.ACCESS_ID,
aws_secret_access_key=config.SECRET_KEY
)
presigned_utl = s3.generate_presigned_url(
'get_object',
Params={
'Bucket': bucket_name,
'Key': key
}
ExpiresIn=3600
)
# build headers
headers = {
"Location": presigned_url
}
return Response(
body=json.dumps(dict()),
headers=headers,
status_code=302
)
Hence, users can still download image directly from API.
Upvotes: 0