o
    bi#                     @   s   d dl Z d dlZd dlmZ d dlZd dlmZmZ d dlZd dl	Z	d dl
mZ eeZdd Zdd Zd	d
 ZedkrEdZee dS dS )    N)	natsorted)TONGYI_API_KEY	OCR_MODEL)OpenAIc              
   C   s
  t d t dt|  t d| d| ddd|id|igdg}t d	 zt }t d
t tjjt	t|dd}t | }t d| |j
dkrZt d|j
|j W dS t d|j
 t|drt|jdrt|jjdkrd|jjd v rd|jjd jv rt|jjd jd dkr|jjd jd d d }t|jdd}t|jdd}	t d||	t| t dt|dkr|dd d n| |||	fW S t d t d| W dS  ty }
 zt jd t|
d!d" t d#t  W Y d}
~
dS d}
~
ww )$uM  
    调用通义千问OCR接口识别图片中的表格内容

    Args:
        system_prompt (str): 系统提示词
        ocr_result (str): OCR识别结果的描述
        image_url (str): 图片URL地址

    Returns:
        tuple: (识别结果内容, 输入token数, 输出token数) 或 (None, 0, 0) 当调用失败时
    u!   开始调用通义千问OCR接口#   OCR系统提示词长度: %d 字符   图片URL: %ssystemZrolecontentuserimagetextu-   构建完成多模态消息，准备调用APIu.   发送OCR请求到通义千问API，模型: %s皙?)api_keymodelmessagestemperatureu-   通义千问API调用完成，耗时: %.2f秒   uC   通义千问OCR接口调用失败，状态码: %d, 错误信息: %s)Nr   r   u   API响应状态码: %doutputchoicesr   messager
   input_tokensoutput_tokensuQ   OCR识别成功，输入token: %d, 输出token: %d, 响应内容长度: %d 字符u   OCR识别结果前100字符: %sd   N...u0   API响应格式异常，无法提取有效内容u   完整响应对象: %su.   调用通义千问OCR接口时发生异常: %sTexc_info   异常堆栈信息: %s)loggerinfodebuglentimer   	dashscopeZMultiModalConversationcallr   status_codeerrorr   hasattrr   r   r   getattrusage	Exceptionstr	traceback
format_exc)system_prompt
ocr_result	image_urlr   
start_timeresponseapi_call_timer
   r   r   e r5   7/home/project/hydrological_data_analyse/src/call_llm.pycall_tongyi_ocr   sv   





(
r7   c              
   c   sB   t d t dt|  t d| t dt| d| dddd	|id
d|dgdg}zttdd}t }t dt |jj	j
t|dddidd}t | }t d| g }d}	d}
t d |D ]R}|jr|jd jjdur|jd jj}|| t dt|dkr|dd d n| |V  qi|jrt|jdd}	t|jdd}
t|jdd}t d|	|
| qid|}t d |	|
t| t d!t|d"kr|dd" d n| |	|
fV  W d   W dS 1 sw   Y  W dS  ty  } zt jd#t|dd$ t d%t  d&V  W Y d}~dS d}~ww )'u4  
    调用通义千问OCR接口识别图片中的表格内容（流式版本）

    优化点：
    1. 分离内容流式返回和token统计功能
    2. 简化yield逻辑，专注于内容流
    3. 使用上下文管理器确保资源清理
    4. 添加更详细的错误处理

    Args:
        system_prompt (str): 系统提示词
        ocr_result (str): OCR识别结果的描述
        image_url (str): 图片URL地址

    Yields:
        str: 内容片段（流式返回）
        tuple: (输入token数, 输出token数) 在流结束时返回
    u3   开始调用通义千问OCR接口（流式模式）r   r   u    OCR结果描述长度: %d 字符r   r	   r   r0   url)typer0   r   )r9   r   z1https://dashscope.aliyuncs.com/compatible-mode/v1)r   base_urlu4   发送OCR流式请求到通义千问API，模型: %sTZinclude_usager   )r   r   streamZstream_optionsr   u3   通义千问流式API连接建立，耗时: %.2f秒r   u   开始处理流式响应Nu   收到内容片段: %s2   r   Zprompt_tokensZcompletion_tokenstotal_tokensuA   收到用量统计，输入token: %d, 输出token: %d, 总计: %d uZ   OCR流式识别完成，总输入token: %d, 总输出token: %d, 总内容长度: %d 字符u   OCR识别完整结果: %sr   u4   调用通义千问OCR流式接口时发生异常: %sr   r   )r   r   )r   r   r    r!   r   r   r"   r   ZchatZcompletionscreater   deltar
   appendr)   r(   joinr*   r&   r+   r,   r-   )r.   r/   r0   r   clientr1   r;   r3   content_partsr   r   chunkr
   r=   Zfull_contentr4   r5   r5   r6   call_tongyi_ocr_streamb   s|   


(

(&1rF   c              	   C   s   d}t t| D ]e}|dvrq	t }td| dd | ds%q	|ddd	 }d
| }t|d|}t	tj
| | dddd}|| W d    n1 sWw   Y  tdt | dd td q	d S )Nu  
    你是一个专业的OCR工具，识别图片里表格的内容：
    1. 检测出图片里完整的表格，如果表格不完整，则直接忽略
    2. 表格数据前31行表示一年中每一天的数据，竖向记录，一列表示一个月，识别时也要竖向识别，按月份返回数据。切记这是真实数据，只有一月、三月、五月、七月、八月、十月、十二月，有31天。二月只有28或者29天，其余月份只有30天
    3. 第32行记录的是平均数，若均值不存在，则对应值记录为None

    数据返回格式为:{"1月": {"data": [0.1, 0.2], "avg": 0.3}, "2月": {...}}，每个月份数据的长度，要与这个月的天数相符。如果某个月份存在数据缺失，则用null进行填充
    )z102.jpgz103.jpgu   处理图片: r>   )end)z.pngz.jpgz.jpeg.   r   zGhttps://questions-1309102452.cos.ap-nanjing.myqcloud.com/images/ruiwen/u   识别图中的表格z_processed.jsonwzutf-8)encodingu   ，耗时: z.2fu    秒   )r   oslistdirr"   printlowerendswithrsplitr7   openpathrB   writesleep)
image_pathr.   filenamer1   Zfile_prefixr0   resfr5   r5   r6   llm_ocr   s"   
 r[   __main__z*D:\project\hydrological_data_analyse/input)rM   r#   Znatsortr   r"   varr   r   loggingr,   Zopenair   	getLogger__name__r   r7   rF   r[   rW   r5   r5   r5   r6   <module>   s     
Tg