o
    ưi9                     @   s"  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j)f  dee' deee'ef  defddZ*e%					d(de'dee'ef dee' dee' deee(ej)f  dee' deee'ef  deeeeeef f fddZ+e,dZ-ddddddd d d!d"	Z.d#e'de'fd$d%Z/dee'ef dee'e'f fd&d'Z0dS ))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              
      s   t  }zUt }	d|d< |du rtj| |d\}
}}
}
ttf| ||||||d|}t }t|j	|}|	
d|I dH }t|rJ|I dH }n|}|du rWtd| |W S  tyo } z
tj| ||||dd}~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   Zoriginal_exceptionZ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ctxZfunc_with_contextZinit_responseresponsee r4   G/home/app/Keep/.python/lib/python3.10/site-packages/litellm/ocr/main.pyr      sV   E	
r   c                 K   s  t  }z|d}	|dd}
|dddu }t|ts%tdt| |d}|d	kr7t|}|d}|d
vrCtd| dtj	| |||d\} }}}|rT|}|rX|}t
j| t|d}|du rmtd| td|  d|  tdi |}|j| d}i }|D ]}||v r||||< q|j|i | d}td|  |	j| ||
|d|d tj| |||pt|	||||||t|d}|W S  ty } z
tj| ||||dd}~w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: )r7   r   )r   r>   litellm_paramsr   )r   r   r>   r   Zlogging_objr   r   r   r   headersZprovider_configr?   r   r4   )r   popget
isinstancedictr)   r8   %convert_file_document_to_url_documentr!   r"   r   Zget_provider_ocr_configZLlmProvidersr
   debugr   Zget_supported_ocr_paramsZmap_ocr_paramsZupdate_environment_variablesbase_llm_http_handlerr#   r   r*   r+   )r   r   r   r   r   r   r   r,   r-   r6   r7   Z	_is_asyncZdoc_typeZdynamic_api_keyZdynamic_api_baseZocr_provider_configr?   Zsupported_paramsr=   paramr>   r2   r3   r4   r4   r5   r#      s   I





	r#   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                 C   s<   t j| d  }t|}|r|S t| \}}|p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_MAPrB   	mimetypes
guess_type)rI   extmimeZguessedr/   r4   r4   r5   get_mime_typee  s   
rU   c           	   	   C   s  |  d}|du rtdd}d}t|ttfrMt|}tj|s)td| t	|}tj
|}t|d}| }W d   n1 sGw   Y  n<t|trU|}n4t|ts_t|drt|drpt|dd}|rpt	|}| }t|tr~|d	}n
td
t| d|stdd| v r| d }t|std| t|d	}d| d| }|drtd| dt| d| d d|dS td| dt| d| d d|dS )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>"}
    r9   Nz|document with type='file' must include a 'file' field containing a file path (str), pathlib.Path, file-like object, or bytesrK   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=)r;   )r8   r;   z>OCR file input: Converted file to document_url data URI (mime=r:   )r8   r:   )rB   r)   rC   strr   rL   rM   isfileFileNotFoundErrorrU   basenameopenrW   bytesr   hasattrgetattrencoder8   _MIME_PATTERNmatchbase64	b64encodedecode
startswithr
   rF   len)	r   Z
file_inputrY   	file_namerI   fZ
file_bytesZbase64_dataZdata_urir4   r4   r5   rE   s  sx   









rE   )NNNNN)1__doc__r   rf   r$   rQ   rL   re	functoolsr   ior   pathlibr   typingr   r   r   r   r	   Zhttpxr!   Zlitellm._loggingr
   Zlitellm.constantsr   Z*litellm.litellm_core_utils.litellm_loggingr   ZLiteLLMLoggingObjZ(litellm.llms.base_llm.ocr.transformationr   r   Z*litellm.llms.custom_httpx.llm_http_handlerr   Zlitellm.types.routerr   Zlitellm.utilsr   r   rG   r[   floatTimeoutr   r#   compilerd   rP   rU   rE   r4   r4   r4   r5   <module>   s    
	t
	 
B&