[英]Boto3 + Django + S3 decoded base64 Image Upload not working
[英]Upload a base64 string(Image Data) to S3 server in Python using Boto3 and get URL in return
我正在嘗試使用 Python 將基本 64 字符串上傳到 S3 存儲桶中。 我用谷歌搜索並得到了一些答案,但沒有一個對我有用。 有些答案使用 boto 而不是 boto3,因此它們對我沒用。 我也試過這個鏈接: Boto3: upload file from base64 to S3但它對我不起作用,因為Object
方法對 s3 是未知的。
以下是我到目前為止的代碼:
import boto3
s3 = boto3.client('s3')
filename = photo.personId + '.png'
bucket_name = 'photos-collection'
dataToPutInS3 = base64.b64decode(photo.url[23:])
將此變量dataToPutInS3
數據上傳到 s3 存儲桶並從中獲取 url 的正確方法是什么。
您沒有提到如何獲得 base64。 為了重現,我的代碼片段使用requests
庫從 Internet 獲取圖像,然后使用base64
庫將其轉換為 base64。
這里的技巧是確保您要上傳的 base64 字符串不包含data:image/jpeg;base64
前綴。 而且,正如評論中提到的@dmigo,您應該使用boto3.resource而不是 boto3.client。
from botocore.vendored import requests
import base64
import boto3
s3 = boto3.resource('s3')
bucket_name = 'BukcetName'
#where the file will be uploaded, if you want to upload the file to folder use 'Folder Name/FileName.jpeg'
file_name_with_extention = 'FileName.jpeg'
url_to_download = 'URL'
#make sure there is no data:image/jpeg;base64 in the string that returns
def get_as_base64(url):
return base64.b64encode(requests.get(url).content)
def lambda_handler(event, context):
image_base64 = get_as_base64(url_to_download)
obj = s3.Object(bucket_name,file_name_with_extention)
obj.put(Body=base64.b64decode(image_base64))
#get bucket location
location = boto3.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint']
#get object url
object_url = "https://%s.s3-%s.amazonaws.com/%s" % (bucket_name,location, file_name_with_extention)
print(object_url)
更多關於S3.Object.put 。
您可以將 base64 轉換為 IO 字節並使用upload_fileobj
上傳到 S3 存儲桶。
import base64
import six
import uuid
import imghdr
import io
def get_file_extension(file_name, decoded_file):
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
def decode_base64_file(data):
"""
Fuction to convert base 64 to readable IO bytes and auto-generate file name with extension
:param data: base64 file input
:return: tuple containing IO bytes file and filename
"""
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
TypeError('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension,)
return io.BytesIO(decoded_file), complete_file_name
def upload_base64_file(base64_file):
bucket_name = 'your_bucket_name'
file, file_name = decode_base64_file(base64_file)
client = boto3.client('s3', aws_access_key_id='aws_access_key_id',
aws_secret_access_key='aws_secret_access_key')
client.upload_fileobj(
file,
bucket_name,
file_name,
ExtraArgs={'ACL': 'public-read'}
)
return f"https://{bucket_name}.s3.amazonaws.com/{file_name}"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.