英文:
Python zappa task for uploading files to S3 bucket
问题
我尝试将上传照片的功能移到Zappa任务中。
views.py
def perform_create(self, serializer):
photos = dict((self.request.data).lists())['photos']
for photo in photos:
byte = base64.b64encode(photo.read())
upload_photos(byte.decode('utf-8'), photo.name)
tasks.py
@task
def upload_photos(photo, name):
byte_data = photo.encode(encoding='utf-8')
b = base64.b64decode(byte_data)
img = Image.open(io.BytesIO(b))
width = img.width
height = img.height
with open(name, 'rb') as file:
picture = File(file)
Images.objects.create(photo=picture, width=width, height=height)
os.remove(name)
在本地一切正常,照片上传到S3存储桶。但是当我部署到AWS上时,我在img.save()上遇到了错误:
oserror: [Errno 30] Read-only file system: 'file-name.jpg'
据我所知,问题出在临时将文件保存在内存中。也许我需要指定临时路径?有什么办法可以修复吗?
英文:
I've tried to move upload photos functional to zappa task.
views.py
def perform_create(self, serializer):
photos = dict((self.request.data).lists())['photos']
for photo in photos:
byte = base64.b64encode(photo.read())
upload_photos(byte.decode('utf-8'), photo.name)
tasks.py
@task
def upload_photos(photo, name):
byte_data = photo.encode(encoding='utf-8')
b = base64.b64decode(byte_data)
img = Image.open(io.BytesIO(b))
width = img.width
height = img.height
with open(name, 'rb') as file:
picture = File(file)
Images.objects.create(photo=picture, width=width, height=height)
os.remove(name)
Locally everything works fine, photos uploaded to S3 bucket. But when I deployed zappa to AWS I've got the error on img.save():
oserror: [Errno 30] Read-only file system: 'file-name.jpg'
As I understand, the problem with temporarily saving file in memory. Maybe I have to specify tmp path?
Any ideas how can I fix it?
答案1
得分: 0
这是我的解决方案,它在使用zappa+S3和本地环境时都能完美运行。您也可以在序列化器的创建方法中使用这个逻辑:
views.py
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
def perform_create(self, serializer):
photos = dict((self.request.data).lists())['photos']
for photo in photos:
path = default_storage.save(f'tmp/{photo.name}', ContentFile(photo.read()))
return s3_upload_photo(path, photo.name)
tasks.py
@task()
def s3_upload_photo(path, file_name):
path_object = Path(path)
with default_storage.open('tmp/' + file_name, 'rb') as file:
photo = File(file, name=path_object.name)
width, height = get_image_dimensions(photo)
instance = ModelName.objects.create(photo=photo, width=width, height=height)
default_storage.delete(path)
return instance
英文:
Here is my solutions, it perfectly works with zappa+S3 and locally. You can use this logic in serializer create method also:
views.py
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
def perform_create(self, serializer):
photos = dict((self.request.data).lists())['photos']
for photo in photos:
path = default_storage.save(f'tmp/{photo.name}', ContentFile(photo.read()))
return s3_upload_photo(path, photo.name)
tasks.py
@task()
def s3_upload_photo(path, file_name):
path_object = Path(path)
with default_storage.open('tmp/' + file_name, 'rb') as file:
photo = File(file, name=path_object.name)
width, height = get_image_dimensions(photo)
instance = ModelName.objects.create(photo=photo, width=width, height=height)
default_storage.delete(path)
return instance
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论