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.
@@ -189,8 +191,7 @@ def param_serialize(
189191 :param _request_auth: set to override the auth_settings for an a single
190192 request; this effectively ignores the authentication
191193 in the spec for a single request.
192- :return: tuple of form (path, http_method, query_params, header_params,
193- body, post_params, files)
194+ :return: tuple of (method, url, header_params, body, post_params)
194195 """
195196
196197 config = self .configuration
@@ -562,21 +563,14 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
562563 elif isinstance (v , bytes ):
563564 filedata = v
564565
565- # Validate file size
566- if len (filedata ) < 4 :
567- raise ValueError (f"File data too small ({ len (filedata )} bytes) - minimum 4 bytes required" )
568- if len (filedata ) > 2 * 1024 * 1024 : # 2MB limit (matches Okta's background image limit)
569- raise ValueError (f"File data too large ({ len (filedata )} bytes) - maximum 2MB allowed" )
570-
571566 # Detect file type from magic bytes
572- # Note: This is client-side validation only. Okta API performs
573- # comprehensive server-side image validation as the security boundary.
574- if filedata .startswith (b'\x89 PNG\r \n \x1a \n ' ): # Full PNG signature
567+ # Note: This is client-side detection for correct Content-Type
568+ # assignment. Okta API performs server-side image validation
569+ # as the security boundary.
570+ if filedata .startswith (b'\x89 PNG\r \n \x1a \n ' ):
575571 filename = f"{ k } .png"
576572 mimetype = "image/png"
577- elif filedata .startswith (b'\xFF \xD8 \xFF \xE0 ' ) or \
578- filedata .startswith (b'\xFF \xD8 \xFF \xE1 ' ) or \
579- filedata .startswith (b'\xFF \xD8 \xFF \xDB ' ): # JPEG variants
573+ elif filedata .startswith (b'\xFF \xD8 ' ): # All JPEG variants start with SOI marker
580574 filename = f"{ k } .jpg"
581575 mimetype = "image/jpeg"
582576 elif filedata .startswith (b'GIF87a' ) or filedata .startswith (b'GIF89a' ):
@@ -586,6 +580,7 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
586580 # For unknown types, attempt PIL validation if available
587581 pil_validated = False
588582 try :
583+ from PIL import Image # Lazy import — Pillow is optional
589584 img = Image .open (io .BytesIO (filedata ))
590585 img .verify () # Verify it's actually a valid image
591586 format_to_ext = {'PNG' : 'png' , 'JPEG' : 'jpg' , 'GIF' : 'gif' }
@@ -594,17 +589,24 @@ def files_parameters(self, files: Dict[str, Union[str, bytes]]):
594589 mimetype = f"image/{ ext if ext != 'jpg' else 'jpeg' } "
595590 pil_validated = True
596591 except ImportError :
597- # PIL not available - continue to fallback
598- pass
592+ logger .warning (
593+ "Could not detect file type from magic bytes and "
594+ "Pillow is not installed for advanced detection. "
595+ "Install it with: pip install pillow"
596+ )
599597 except Exception :
600- # PIL validation failed - file may not be a valid image
601- pass
598+ logger .warning (
599+ "File type detection failed — the file may not "
600+ "be a valid image. Okta accepts PNG, JPEG, and "
601+ "GIF formats only."
602+ )
602603
603604 if not pil_validated :
604- # Fallback: Default to PNG with warning
605- # Server-side validation will reject if not a valid image
606- filename = f"{ k } .png"
607- mimetype = "image/png"
605+ # Fallback: default to application/octet-stream for
606+ # unrecognized types; server-side validation will
607+ # reject if the file is not a valid image.
608+ filename = f"{ k } .bin"
609+ mimetype = "application/octet-stream"
608610 else :
609611 raise ValueError ("Unsupported file value" )
610612 params .append (tuple ([k , tuple ([filename , filedata , mimetype ])]))
0 commit comments