o
    Zh0&                     @   s   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	m
Z
mZmZmZ d dlmZ d dl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mZmZ ee Z!G dd dZ"G dd deeZ#G dd de$Z%dS )    N)datetime)mktime)AnyDictListLiteralOptional)	urlencode)format_date_time)
Embeddings)secret_from_env)ndarray)	BaseModel
ConfigDictField	SecretStrc                   @   s*   e Zd ZdZdedededdfddZdS )	UrlzURL class for parsing the URL.hostpathschemareturnNc                 C   s   || _ || _|| _d S N)r   r   r   )selfr   r   r    r   ^/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/embeddings/sparkllm.py__init__%   s   zUrl.__init____name__
__module____qualname____doc__strr   r   r   r   r   r   "   s    r   c                   @   s|  e Zd ZU dZededdZeed< 	 ededdd	dZ	e
e ed
< 	 ededdd	dZe
e ed< 	 edd	Zeed< 	 edd	Zed ed< 	 eddZdee dede
eee   fddZdee de
eee   fddZdede
ee  fddZe	 d-d!ed"edededef
d#d$Zed!edefd%d&Zd'ededeeef fd(d)Zed*ede
e fd+d,Z dS ).SparkLLMTextEmbeddingsu  SparkLLM embedding model integration.

    Setup:
        To use, you should have the environment variable "SPARK_APP_ID","SPARK_API_KEY"
        and "SPARK_API_SECRET" set your APP_ID, API_KEY and API_SECRET or pass it
        as a name parameter to the constructor.

        .. code-block:: bash

            export SPARK_APP_ID="your-api-id"
            export SPARK_API_KEY="your-api-key"
            export SPARK_API_SECRET="your-api-secret"

    Key init args — completion params:
        api_key: Optional[str]
            Automatically inferred from env var `SPARK_API_KEY` if not provided.
        app_id: Optional[str]
            Automatically inferred from env var `SPARK_APP_ID` if not provided.
        api_secret: Optional[str]
            Automatically inferred from env var `SPARK_API_SECRET` if not provided.
        base_url: Optional[str]
            Base URL path for API requests.

    See full list of supported init args and their descriptions in the params section.

    Instantiate:

        .. code-block:: python

            from langchain_community.embeddings import SparkLLMTextEmbeddings

            embed = SparkLLMTextEmbeddings(
                api_key="...",
                app_id="...",
                api_secret="...",
                # other
            )

    Embed single text:
        .. code-block:: python

            input_text = "The meaning of life is 42"
            embed.embed_query(input_text)

        .. code-block:: python

            [-0.4912109375, 0.60595703125, 0.658203125, 0.3037109375, 0.6591796875, 0.60302734375, ...]

    Embed multiple text:
        .. code-block:: python

            input_texts = ["This is a test query1.", "This is a test query2."]
            embed.embed_documents(input_texts)

        .. code-block:: python

            [
                [-0.1962890625, 0.94677734375, 0.7998046875, -0.1971435546875, 0.445556640625, 0.54638671875, ...],
                [  -0.44970703125, 0.06585693359375, 0.7421875, -0.474609375, 0.62353515625, 1.0478515625, ...],
            ]
    app_idZSPARK_APP_ID)aliasdefault_factoryspark_app_idapi_keyZSPARK_API_KEYN)defaultspark_api_key
api_secretZSPARK_API_SECRETspark_api_secretz#https://emb-cn-huabei-1.xf-yun.com/base_urlpara)r-   querydomainT)Zpopulate_by_nametextsr   r   c                 C   s   d}d}d}| j r| j  }| jr| j }| jr| j }| j|d||d}g }|D ]1}d|ddgi}	| ||	}
tj||
ddid	j}| 	|}|d
urW|
|  q+|
d
 q+|S )aD  Internal method to call Spark Embedding API and return embeddings.

        Args:
            texts: A list of texts to embed.
            host: Base URL path for API requests

        Returns:
            A list of list of floats representing the embeddings,
            or list with value None if an error occurs.
         POST)request_urlmethodr'   r*   messagesuser)contentZrolezcontent-typezapplication/json)jsonheadersN)r&   Zget_secret_valuer)   r+   _assemble_ws_auth_url	_get_bodyrequestsposttext_parser_messageappendtolist)r   r0   r   r#   r'   r*   urlZembed_resultr>   Zquery_contextr7   responseZres_arrr   r   r   _embed   s:   




zSparkLLMTextEmbeddings._embedc                 C   s   |  || jS )zPublic method to get embeddings for a list of documents.

        Args:
            texts: The list of texts to embed.

        Returns:
            A list of embeddings, one for each text, or None if an error occurs.
        rD   r,   )r   r0   r   r   r   embed_documents   s   	z&SparkLLMTextEmbeddings.embed_documentsr>   c                 C   s$   |  |g| j}|dur|d S dS )zPublic method to get embedding for a single query text.

        Args:
            text: The text to embed.

        Returns:
            Embeddings for the text, or None if an error occurs.
        Nr   rE   )r   r>   resultr   r   r   embed_query   s   	z"SparkLLMTextEmbeddings.embed_queryGETr1   r3   r4   c                 C   s   t | }|j}|j}t }tt| }d	||||}	t
j|d|	dtjd }
t|
jdd}d|dd|f }t|djdd}|||d}| d	 t| S )
Nz host: {}
date: {}
{} {} HTTP/1.1utf-8)	digestmod)encodingz:api_key="%s", algorithm="%s", headers="%s", signature="%s"zhmac-sha256zhost date request-line)r   dateauthorization?)r"   
_parse_urlr   r   r   nowr
   r   	timetupleformathmacnewencodehashlibsha256digestbase64	b64encodedecoder	   )r3   r4   r'   r*   ur   r   rQ   rM   Zsignature_originZsignature_shaZsignature_sha_strZauthorization_originrN   valuesr   r   r   r:      s2   

z,SparkLLMTextEmbeddings._assemble_ws_auth_urlc                 C   sp   |  d}| |d d  }| d |d  }| d}|dkr$td|  ||d  }|d | }t|||}|S )Nz://   /r   zinvalid request url:)indexAssembleHeaderExceptionr   )r3   Zstidxr   r   Zedidxr   r]   r   r   r   rP      s   

z!SparkLLMTextEmbeddings._parse_urlappidc              	   C   sF   |dddd| j ddididd	tt|d
 iid}|S )NZ39769795890r_   )r#   uidstatusZembrL   utf8)r/   featurer5   r>   rJ   )headerZ	parameterpayload)r/   rZ   r[   r8   dumpsrV   r\   )r   rc   r>   bodyr   r   r   r;      s   
z SparkLLMTextEmbeddings._get_bodymessagec                 C   s   t | }|d d }|dkrtd| d|  d S |d d d }t|}ttj}|	d	}tj
||d
}t|dkrI|d d }|S |}|S )Nrh   coder   zRequest error: z, ri   rg   r>   <)dtypei 
  )r8   loadsloggerwarningrZ   	b64decodenpro   Zfloat32ZnewbyteorderZ
frombufferlen)rl   datarm   Z	text_baseZ	text_datadtr>   arrayr   r   r   r?      s   


z&SparkLLMTextEmbeddings._parser_message)rI   r1   r1   )!r   r   r   r    r   r   r&   r   __annotations__r)   r   r+   r,   r!   r/   r   r   Zmodel_configr   floatrD   rF   rH   staticmethodr:   r   rP   dictr   r   r;   r   r?   r   r   r   r   r"   ,   s^   
 >
&"(r"   c                   @   s"   e Zd ZdZdeddfddZdS )rb   z3Exception raised for errors in the header assembly.msgr   Nc                 C   s
   || _ d S r   )rl   )r   r}   r   r   r   r     s   
z AssembleHeaderException.__init__r   r   r   r   r   rb     s    rb   )&rZ   rW   rT   r8   loggingr   timer   typingr   r   r   r   r   urllib.parser	   Zwsgiref.handlersr
   numpyrt   r<   Zlangchain_core.embeddingsr   Zlangchain_core.utilsr   r   Zpydanticr   r   r   r   	getLoggerr   rq   r   r"   	Exceptionrb   r   r   r   r   <module>   s*    

 e