2323import datetime
2424import io
2525import json
26+ import logging
2627import mimetypes
2728import os
2829import re
2930import tempfile
3031from enum import Enum
31- from PIL import Image
3232from typing import Tuple , Optional , List , Dict , Union
3333from urllib .parse import quote
3434
4949
5050RequestSerialized = Tuple [str , str , Dict [str , str ], Optional [str ], List [str ]]
5151
52+ logger = logging .getLogger ("okta-sdk-python" )
53+
5254
5355class ApiClient :
5456 """Generic API client for OpenAPI client library builds.
@@ -205,8 +207,7 @@ def param_serialize(
205207 :param _request_auth: set to override the auth_settings for an a single
206208 request; this effectively ignores the authentication
207209 in the spec for a single request.
208- :return: tuple of form (path, http_method, query_params, header_params,
209- body, post_params, files)
210+ :return: tuple of (method, url, header_params, body, post_params)
210211 """
211212
212213 config = self .configuration
@@ -578,21 +579,14 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
578579 elif isinstance (v , bytes ):
579580 filedata = v
580581
581- # Validate file size
582- if len (filedata ) < 4 :
583- raise ValueError (f"File data too small ({ len (filedata )} bytes) - minimum 4 bytes required" )
584- if len (filedata ) > 2 * 1024 * 1024 : # 2MB limit (matches Okta's background image limit)
585- raise ValueError (f"File data too large ({ len (filedata )} bytes) - maximum 2MB allowed" )
586-
587582 # Detect file type from magic bytes
588- # Note: This is client-side validation only. Okta API performs
589- # comprehensive server-side image validation as the security boundary.
590- if filedata .startswith (b'\x89 PNG\r \n \x1a \n ' ): # Full PNG signature
583+ # Note: This is client-side detection for correct Content-Type
584+ # assignment. Okta API performs server-side image validation
585+ # as the security boundary.
586+ if filedata .startswith (b'\x89 PNG\r \n \x1a \n ' ):
591587 filename = f"{ k } .png"
592588 mimetype = "image/png"
593- elif filedata .startswith (b'\xFF \xD8 \xFF \xE0 ' ) or \
594- filedata .startswith (b'\xFF \xD8 \xFF \xE1 ' ) or \
595- filedata .startswith (b'\xFF \xD8 \xFF \xDB ' ): # JPEG variants
589+ elif filedata .startswith (b'\xFF \xD8 ' ): # All JPEG variants start with SOI marker
596590 filename = f"{ k } .jpg"
597591 mimetype = "image/jpeg"
598592 elif filedata .startswith (b'GIF87a' ) or filedata .startswith (b'GIF89a' ):
@@ -602,6 +596,7 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
602596 # For unknown types, attempt PIL validation if available
603597 pil_validated = False
604598 try :
599+ from PIL import Image # Lazy import — Pillow is optional
605600 img = Image .open (io .BytesIO (filedata ))
606601 img .verify () # Verify it's actually a valid image
607602 format_to_ext = {'PNG' : 'png' , 'JPEG' : 'jpg' , 'GIF' : 'gif' }
@@ -610,17 +605,24 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
610605 mimetype = f"image/{ ext if ext != 'jpg' else 'jpeg' } "
611606 pil_validated = True
612607 except ImportError :
613- # PIL not available - continue to fallback
614- pass
608+ logger .warning (
609+ "Could not detect file type from magic bytes and "
610+ "Pillow is not installed for advanced detection. "
611+ "Install it with: pip install pillow"
612+ )
615613 except Exception :
616- # PIL validation failed - file may not be a valid image
617- pass
614+ logger .warning (
615+ "File type detection failed — the file may not "
616+ "be a valid image. Okta accepts PNG, JPEG, and "
617+ "GIF formats only."
618+ )
618619
619620 if not pil_validated :
620- # Fallback: Default to PNG with warning
621- # Server-side validation will reject if not a valid image
622- filename = f"{ k } .png"
623- mimetype = "image/png"
621+ # Fallback: default to application/octet-stream for
622+ # unrecognized types; server-side validation will
623+ # reject if the file is not a valid image.
624+ filename = f"{ k } .bin"
625+ mimetype = "application/octet-stream"
624626 else :
625627 raise ValueError ("Unsupported file value" )
626628 params .append (tuple ([k , tuple ([filename , filedata , mimetype ])]))
0 commit comments