
    AHj:                        d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlmZmZmZmZmZ ddlZddlZddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlm Z  ddl!m"Z" ddl#m$Z$m%Z%  e        Z&e%	 	 	 	 	 d$de'dee'ef   dee'   dee'   deee(ejR                  f      dee'   deee'ef      defd       Z*e%	 	 	 	 	 d$de'dee'ef   dee'   dee'   deee(ejR                  f      dee'   deee'ef      deeeeeef   f   fd       Z+ ejX                  d      Z-dddddddddd 	Z.d!e'de'fd"Z/dee'ef   dee'e'f   fd#Z0y)%z 
Main OCR function for LiteLLM.
    N)partial)IOBase)Path)Any	CoroutineDictOptionalUnion)verbose_logger)request_timeout)Logging)BaseOCRConfigOCRResponse)BaseLLMHTTPHandler)GenericLiteLLMParams)ProviderConfigManagerclientmodeldocumentapi_keyapi_basetimeoutcustom_llm_providerextra_headersreturnc                   K   t               }	 t        j                         }	d|d<   |t        j                  | |      \  }
}}
}
t        t        f| ||||||d|}t        j                         }t        |j                  |      }|	j                  d|       d{   }t        j                  |      r| d{   }n|}|t        d|       |S 7 87 # t        $ r}t        j                  | ||||      d}~ww xY ww)ar  
    Async OCR function.

    Args:
        model: Model name (e.g., "mistral/mistral-ocr-latest")
        document: Document to process in Mistral format:
            {"type": "document_url", "document_url": "https://..."} for PDFs/docs,
            {"type": "image_url", "image_url": "https://..."} for images, or
            {"type": "file", "file": <path/bytes/file-obj>} for local files
        api_key: Optional API key
        api_base: Optional API base URL
        timeout: Optional timeout
        custom_llm_provider: Optional custom LLM provider
        extra_headers: Optional extra headers
        **kwargs: Additional parameters (e.g., include_image_base64, pages, image_limit)

    Returns:
        OCRResponse in Mistral OCR format with pages, model, usage_info, etc.

    Example:
        ```python
        import litellm

        # OCR with PDF
        response = await litellm.aocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "document_url",
                "document_url": "https://arxiv.org/pdf/2201.04234"
            },
            include_image_base64=True
        )

        # OCR with image
        response = await litellm.aocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "image_url",
                "image_url": "https://example.com/image.png"
            }
        )

        # OCR with base64 encoded PDF
        response = await litellm.aocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "document_url",
                "document_url": f"data:application/pdf;base64,{base64_pdf}"
            }
        )

        # OCR with local file
        response = await litellm.aocr(
            model="mistral/mistral-ocr-latest",
            document={"type": "file", "file": "/path/to/document.pdf"}
        )
        ```
    TaocrN)r   r   )r   r   r   r   r   r   r   z2Got an unexpected None response from the OCR API: r   r   original_exceptioncompletion_kwargsextra_kwargs)localsasyncioget_event_looplitellmget_llm_providerr   ocrcontextvarscopy_contextrunrun_in_executoriscoroutine
ValueError	Exceptionexception_type)r   r   r   r   r   r   r   kwargs
local_varsloop_funcctxfunc_with_contextinit_responseresponsees                    H/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm/ocr/main.pyr   r      s;    J J,
%%'v &+2+C+Ch,(A"Aq 

 3'

 

 &&(#CGGT2"2249JKK}-**H$HDXJO   L +  
$$ 3 (
 	

sM   DBC CC ;C<C DC C 	D"C<<DDc                    t               }	 |j                  d      }	|j                  dd      }
|j                  dd      du }t        |t              st        dt        |             |j                  d      }|d	k(  rt        |      }|j                  d      }|d
vrt        d| d      t        j                  | |||      \  } }}}|r|}|r|}t        j                  | t        j                  |            }|t        d|       t        j                  d|  d|        t        di |}|j!                  |       }i }|D ]  }||v s|j                  |      ||<    |j#                  |i |       }t        j                  d|        |	j%                  || ||
|d|       t&        j)                  | |||xs t*        |	||||||t	        |            }|S # t,        $ r}t        j.                  | ||||      d}~ww xY w)a  
    Synchronous OCR function.

    Args:
        model: Model name (e.g., "mistral/mistral-ocr-latest")
        document: Document to process in Mistral format:
            {"type": "document_url", "document_url": "https://..."} for PDFs/docs,
            {"type": "image_url", "image_url": "https://..."} for images, or
            {"type": "file", "file": <path/bytes/file-obj>} for local files
        api_key: Optional API key
        api_base: Optional API base URL
        timeout: Optional timeout
        custom_llm_provider: Optional custom LLM provider
        extra_headers: Optional extra headers
        **kwargs: Additional parameters (e.g., include_image_base64, pages, image_limit)

    Returns:
        OCRResponse in Mistral OCR format with pages, model, usage_info, etc.

    Example:
        ```python
        import litellm

        # OCR with PDF
        response = litellm.ocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "document_url",
                "document_url": "https://arxiv.org/pdf/2201.04234"
            },
            include_image_base64=True
        )

        # OCR with image
        response = litellm.ocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "image_url",
                "image_url": "https://example.com/image.png"
            }
        )

        # OCR with base64 encoded PDF
        response = litellm.ocr(
            model="mistral/mistral-ocr-latest",
            document={
                "type": "document_url",
                "document_url": f"data:application/pdf;base64,{base64_pdf}"
            }
        )

        # OCR with local file
        response = litellm.ocr(
            model="mistral/mistral-ocr-latest",
            document={"type": "file", "file": "/path/to/document.pdf"}
        )

        # Access pages
        for page in response.pages:
            print(f"Page {page.index}: {page.markdown}")
        ```
    litellm_logging_objlitellm_call_idNr   FTz<document must be a dict with 'type' and URL/file field, got typefile)document_url	image_urlzInvalid document type: z0. Must be 'document_url', 'image_url', or 'file')r   r   r   r   )r   providerz#OCR is not supported for provider: zOCR call - model: z, provider: )r   )non_default_paramsoptional_paramsr   z#OCR optional_params after mapping: )r=   r   )r0   r   rD   litellm_paramsr   )r   r   rD   r   logging_objr   r   r   r   headersprovider_configrE   r    )r"   popget
isinstancedictr-   r>   %convert_file_document_to_url_documentr%   r&   r   get_provider_ocr_configLlmProvidersr   debugr   get_supported_ocr_paramsmap_ocr_paramsupdate_from_kwargsbase_llm_http_handlerr'   r   r.   r/   )r   r   r   r   r   r   r   r0   r1   r<   r=   	_is_asyncdoc_typedynamic_api_keydynamic_api_baseocr_provider_configrE   supported_paramsrC   paramrD   r8   r9   s                          r:   r'   r'      s   R Jr
17<Q1R)/4Et)LJJvu-5	 (D)NtT\~N^_  <<' v<XFH||F+H88)( 4A A  $$ 3	
	
 %G'H
 "99))*=>
 	 &56I5JK  	 |4G3HI	

 .77 /GGeGT% 	>E,2JJu,="5)	>
 .<<1 = 
 	B?BSTU 	..+#2$ !4 	/ 		
 ),,+.+ 3!// - 
  
$$ 3 (
 	

s   EG" BG" "	H
+HH
z^[\w.+-]+/[\w.+-]+$zapplication/pdfz	image/pngz
image/jpegz	image/gifz
image/webpz
image/tiffz	image/bmp)	z.pdfz.pngz.jpgz.jpegz.gifz.webpz.tiffz.tifz.bmp	file_pathc                     t         j                  j                  |       d   j                         }t        j                  |      }|r|S t        j                  |       \  }}|xs dS )z
    Determine MIME type from file path extension.

    Falls back to mimetypes.guess_type, then to 'application/octet-stream'.
       application/octet-stream)ospathsplitextlower_MIME_TYPE_MAPrK   	mimetypes
guess_type)r]   extmimeguessedr3   s        r:   get_mime_typerk   f  s^     ''

9
%a
(
.
.
0Cc"D%%i0JGQ000    c           	      x   | j                  d      }|t        d      d}d}t        |t        t        f      rt        |      }t
        j                  j                  |      st        d|       t        |      }t
        j                  j                  |      }t        |d      5 }|j                         }ddd       nt        |t              r|}nt        |t              st        |d      rXt        |d      rt!        |dd      }|rt        |      }|j                         }t        |t              r*|j#                  d	      }nt        d
t%        |       d      st        d      d| v r| d   }t&        j)                  |      st        d|       t+        j,                  |      j/                  d	      }d| d| }|j1                  d      r-t3        j4                  d| dt7        |       d| d       d|dS t3        j4                  d| dt7        |       d| d       d|dS # 1 sw Y   xY w)a  
    Convert a file-type document dict to a document_url-type document dict
    with an inline base64 data URI.

    Accepts document dicts like:
        {"type": "file", "file": "/path/to/document.pdf"}        # file path string
        {"type": "file", "file": Path("/path/to/doc.pdf")}       # pathlib.Path
        {"type": "file", "file": <binary file-like object>}      # file-like object (BinaryIO)
        {"type": "file", "file": b"raw bytes"}                   # raw bytes

    Returns:
        {"type": "document_url", "document_url": "data:<mime>;base64,<data>"}
        or {"type": "image_url", "image_url": "data:<mime>;base64,<data>"}
    r?   Nz|document with type='file' must include a 'file' field containing a file path (str), pathlib.Path, file-like object, or bytesr`   zFile not found: rbreadnamezutf-8zUnsupported file input type: zG. Expected str (file path), pathlib.Path, bytes, or a file-like object.z"File is empty or could not be read	mime_typezInvalid MIME type: zdata:z;base64,zimage/z;OCR file input: Converted file to image_url data URI (mime=z, size=z bytes, name=)rA   )r>   rA   z>OCR file input: Converted file to document_url data URI (mime=r@   )r>   r@   )rK   r-   rL   strr   ra   rb   isfileFileNotFoundErrorrk   basenameopenro   bytesr   hasattrgetattrencoder>   _MIME_PATTERNmatchbase64	b64encodedecode
startswithr   rQ   len)	r   
file_inputrq   	file_namer]   f
file_bytesbase64_datadata_uris	            r:   rN   rN   t  sO    f%JJ
 	
 0I#I*sDk*
O	ww~~i(#&6yk$BCC!),	GG$$Y/	)T" 	"aJ	" 	"	J	&
	J	'7:v+F:v&
FD9I))4	__&
j#&#**73J+D,<+= >T T
 	

 =>>h[)	y).yk:;;"":.55g>Kyk+7HH%Kws:&7}YKqR	
 $(;;Kws:&7}YKqR	
 'AAS	" 	"s   'H00H9)NNNNN)1__doc__r#   r~   r(   rf   ra   re	functoolsr   ior   pathlibr   typingr   r   r   r	   r
   httpxr%   litellm._loggingr   litellm.constantsr   *litellm.litellm_core_utils.litellm_loggingr   LiteLLMLoggingObj(litellm.llms.base_llm.ocr.transformationr   r   *litellm.llms.custom_httpx.llm_http_handlerr   litellm.types.routerr   litellm.utilsr   r   rU   rs   floatTimeoutr   r'   compiler|   re   rk   rN   rI   rl   r:   <module>r      s=       	 	    8 8   + - S O I 5 7 +,   ""59)-.2q
q
38nq
 c]q
 sm	q

 eE5==012q
 "#q
 DcN+q
 q
 q
h  ""59)-.2{
{
38n{
 c]{
 sm	{

 eE5==012{
 "#{
 DcN+{
 ;	#sK"7889{
 {
D 

12 
1S 1S 1IBDcN IBtCQTH~ IBrl   