Repository navigation
Expand file tree
/
Copy pathapi_utils.py
More file actions
76 lines (67 loc) · 2.75 KB
/
Copy pathapi_utils.py
File metadata and controls
76 lines (67 loc) · 2.75 KB
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
68
69
70
71
72
73
74
75
76
import logging
import os
from io import BytesIO
import requests
from PIL import Image
LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO")
logger = logging.getLogger(__name__)
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
def decode_request(request) -> Image.Image | None:
"""
Decodes an incoming request to extract an image.
Args:
request: The incoming request object. Expected to have a "content" key
which can be a URL string or a file-like object from an upload.
Returns:
An PIL.Image.Image object if successful, None otherwise.
"""
file_content = request.get("content")
if file_content is None:
logger.warning("Request content is missing.")
return None
if isinstance(file_content, str) and "http" in file_content:
# Handle URL input
url = file_content.replace("localhost:3210", "backend:3210") # HACK
try:
response = requests.get(url, stream=True)
response.raise_for_status() # Raise an exception for bad status codes
image = Image.open(BytesIO(response.content))
logger.debug("Successfully processed URL input.")
return image
except requests.exceptions.RequestException as e:
logger.error(f"Failed to fetch image from URL {url}: {e}")
return None
except IOError as e:
logger.error(f"Failed to open image from URL {url} content: {e}")
return None
elif hasattr(file_content, "file") and not isinstance(file_content, str):
try:
# We've narrowed the type, so file_content.file is now more safely accessed
# The linter knows if we reach here, it's not a str.
file_bytes = file_content.file.read()
image = Image.open(BytesIO(file_bytes))
logger.debug("Successfully processed file input.")
return image
except (
AttributeError
): # Keep this for robustness in case file_content.file isn't callable
logger.error(
"Failed to access 'file' attribute or 'read' method from file_content."
)
return None
except IOError as e:
logger.error(f"Failed to open image from file content: {e}")
return None
finally:
# Ensure the file handle is closed if it's an upload object
if hasattr(file_content.file, "close"):
file_content.file.close()
else:
# Catch-all for unexpected types
logger.warning(
f"Unexpected content type or format for request: {type(file_content)}. "
"Expected a URL string or a file upload object."
)
return None