Last active
September 11, 2022 11:16
-
-
Save dalmarcogd/14cdf85b79bfda6aa0db155badf1c1cb to your computer and use it in GitHub Desktop.
Upload file in python with base64 and json.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import base64 | |
| import binascii | |
| import uuid | |
| from django.core.exceptions import ValidationError | |
| from django.core.files.base import ContentFile | |
| from django.utils import six | |
| from django.utils.translation import ugettext_lazy as _ | |
| from rest_framework.fields import ( | |
| DateField, | |
| DateTimeField, | |
| DictField, | |
| FileField, | |
| FloatField, | |
| ImageField, | |
| IntegerField, | |
| ) | |
| from django.conf import settings | |
| class Base64FieldMixin(object): | |
| ALLOWED_TYPES = NotImplemented | |
| INVALID_FILE_MESSAGE = NotImplemented | |
| INVALID_TYPE_MESSAGE = NotImplemented | |
| EMPTY_VALUES = (None, '', [], (), {}) | |
| def __init__(self, *args, **kwargs): | |
| self.represent_in_base64 = kwargs.pop('represent_in_base64', False) | |
| super(Base64FieldMixin, self).__init__(*args, **kwargs) | |
| def to_internal_value(self, base64_data): | |
| # Check if this is a base64 string | |
| if base64_data in self.EMPTY_VALUES: | |
| return None | |
| if isinstance(base64_data, six.string_types): | |
| # Strip base64 header. | |
| if ';base64,' in base64_data: | |
| header, base64_data = base64_data.split(';base64,') | |
| # Try to decode the file. Return validation error if it fails. | |
| try: | |
| decoded_file = base64.b64decode(base64_data) | |
| except (TypeError, binascii.Error, ValueError): | |
| raise ValidationError(self.INVALID_FILE_MESSAGE) | |
| # Generate file name: | |
| # 12 characters are more than enough. | |
| file_name = str(uuid.uuid4())[:12] | |
| # Get the file name extension: | |
| file_extension = self.get_file_extension(file_name, decoded_file) | |
| if file_extension not in self.ALLOWED_TYPES: | |
| raise ValidationError(self.INVALID_TYPE_MESSAGE) | |
| complete_file_name = file_name + "." + file_extension | |
| data = ContentFile(decoded_file, name=complete_file_name) | |
| return super(Base64FieldMixin, self).to_internal_value(data) | |
| raise ValidationError(_('This is not an base64 string')) | |
| def get_file_extension(self, filename, decoded_file): | |
| raise NotImplemented | |
| def to_representation(self, file): | |
| if self.represent_in_base64: | |
| try: | |
| with open(file.path, 'rb') as f: | |
| return base64.b64encode(f.read()).decode() | |
| except Exception as e: | |
| print 'Fails to decode file: %s (%s)' % (e.message, type(e)) | |
| else: | |
| return super(Base64FieldMixin, self).to_representation(file) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import imghdr | |
| from django.utils.translation import ugettext_lazy as _ | |
| from rest_framework.fields import FileField | |
| from .base64_mixin_field import Base64FieldMixin | |
| class Base64FileField(Base64FieldMixin, FileField): | |
| """ | |
| A django-rest-framework field for handling file-uploads through raw post data. | |
| It uses base64 for en-/decoding the contents of the file. | |
| """ | |
| ALLOWED_TYPES = ( | |
| "jpeg", | |
| "jpg", | |
| "png", | |
| "gif", | |
| "txt", | |
| "csv" | |
| ) | |
| INVALID_FILE_MESSAGE = _("Please upload a valid file.") | |
| INVALID_TYPE_MESSAGE = _("The type of the file couldn't be determined.") | |
| def get_file_extension(self, filename, decoded_file): | |
| return imghdr.what(filename, decoded_file) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from rest_framework.fields import ImageField | |
| from django.core.exceptions import ValidationError | |
| from .base64_mixin_field import Base64FieldMixin | |
| from .image_base64_field import Base64ImageField | |
| class HybridImageField(Base64ImageField): | |
| """ | |
| A django-rest-framework field for handling image-uploads through | |
| raw post data, with a fallback to multipart form data. | |
| """ | |
| def to_internal_value(self, data): | |
| """ | |
| Try Base64Field first, and then try the ImageField | |
| ``to_internal_value``, MRO doesn't work here because | |
| Base64FieldMixin throws before ImageField can run. | |
| """ | |
| try: | |
| return Base64FieldMixin.to_internal_value(self, data) | |
| except ValidationError: | |
| return ImageField.to_internal_value(self, data) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import imghdr | |
| from rest_framework.fields import ImageField | |
| from django.utils.translation import ugettext_lazy as _ | |
| from .base64_mixin_field import Base64FieldMixin | |
| class Base64ImageField(Base64FieldMixin, ImageField): | |
| """ | |
| A django-rest-framework field for handling image-uploads through raw post data. | |
| It uses base64 for en-/decoding the contents of the file. | |
| """ | |
| ALLOWED_TYPES = ( | |
| "jpeg", | |
| "jpg", | |
| "png", | |
| "gif" | |
| ) | |
| INVALID_FILE_MESSAGE = _("Please upload a valid image.") | |
| INVALID_TYPE_MESSAGE = _("The type of the image couldn't be determined.") | |
| def get_file_extension(self, filename, decoded_file): | |
| extension = imghdr.what(filename, decoded_file) | |
| extension = "jpg" if extension == "jpeg" else extension | |
| return extension |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment