File size: 1,813 Bytes
4072732
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# app/image.py

import re
from io import BytesIO
import base64
from typing import Union

from .typing import ImageType

try:
    from PIL import Image
except ImportError:
    Image = None  # Handle absence of PIL

from .errors import MissingRequirementsError

ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'}

def is_allowed_extension(filename: str) -> bool:
    """
    Checks if the given filename has an allowed extension.
    """
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def is_data_uri_an_image(data_uri: str) -> bool:
    """
    Checks if the given data URI represents an image.
    """
    if not re.match(r'data:image/(\w+);base64,', data_uri):
        raise ValueError("Invalid data URI image.")
    image_format = re.match(r'data:image/(\w+);base64,', data_uri).group(1).lower()
    if image_format not in ALLOWED_EXTENSIONS and image_format != "svg+xml":
        raise ValueError("Invalid image format (from MIME type).")
    return True

def extract_data_uri(data_uri: str) -> bytes:
    """
    Extracts the binary data from the given data URI.
    """
    data = data_uri.split(",")[1]
    return base64.b64decode(data)

def to_data_uri(image: str) -> str:
    """
    Validates and returns the data URI for an image.
    """
    is_data_uri_an_image(image)
    return image

def to_image(image: str) -> ImageType:
    """
    Converts a base64-encoded image to bytes.
    """
    if Image is None:
        raise MissingRequirementsError('Install "pillow" package for image processing.')
    is_data_uri_an_image(image)
    return extract_data_uri(image)

class MissingRequirementsError(Exception):
    pass

class ImageResponse:
    def __init__(self, url: str, alt: str):
        self.url = url
        self.alt = alt