
    jR                     &   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mZmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZmZmZ d dlmZ  ej        e          ZdZd	efd
Z G d de          Z G d d          Z G d de          Z e            Z dS )    N)CallableTupleUnion)parse)is_legal_addressis_legal_hostis_legal_port)GrpcHandler)ConnectionConfigExceptionConnectionNotExistExceptionExceptionsMessage)Configi  funcc                 B     t          j                     _         fd}|S )zD
    Decorator in order to achieve thread-safe singleton class.
    c                  V    j         5   | i |cd d d            S # 1 swxY w Y   d S N)__lock__)argskwargsr   s     b/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/pymilvus/orm/connections.py	lock_funczsynchronized.<locals>.lock_func)   s    ] 	) 	)4(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   "")	threadingLockr   )r   r   s   ` r   synchronizedr   #   s5     N$$DM) ) ) ) )     c                   D     e Zd ZdZd fdZd Ze fd            Z xZS )SingleInstanceMetaClassNreturnc                 :     t                      j        |i | d S r   )super__init__clsr   r   	__class__s      r   r!   z SingleInstanceMetaClass.__init__3   s%    $)&)))))r   c                     | j         r| j         S |                     |           | _          | j         j        |i | | j         S r   )instance__new__r!   )r#   r   r   s      r   __call__z SingleInstanceMetaClass.__call__6   sI    < 	 <{{3''t.v...|r   c                 >     t                      j        | g|R i |S r   )r    r'   r"   s      r   r'   zSingleInstanceMetaClass.__new__=   s)    uwws4T444V444r   r   N)	__name__
__module____qualname__r&   r!   r(   r   r'   __classcell__)r$   s   @r   r   r   0   sv        H* * * * * *   5 5 5 5 \5 5 5 5 5r   r   c                   8    e Zd ZdedededdfdZd Zdefd	ZdS )
ReconnectHandlerconnsconnection_namer   r   Nc                 n    || _         || _        || _        d| _        t	          j                    | _        d S )NF)r2   r1   _kwargsis_idle_stater   r   reconnect_lock)selfr1   r2   r   s       r   r!   zReconnectHandler.__init__C   s6    .
"'n..r   c                 t   d}t                               d| d           t          j        |           | j        st                               d           d S | j        5  t                               d           d| _        	 t                               d           | j                            | j	                   n*# t          $ r t                               d           Y nw xY wd}|s	 t                               d	            | j        j        | j	        fi | j         d
}nL# t          $ r?}t                               d| d| d           t          j        |           Y d }~nd }~ww xY w|n# d}|s	 t                               d	            | j        j        | j	        fi | j         d
}nL# t          $ r?}t                               d| d| d           t          j        |           Y d }~nd }~ww xY w|w xY wt                               d           d d d            d S # 1 swxY w Y   d S )N   z%state is idle, schedule reconnect in z secondsz"idle state changed, skip reconnectzreconnect on idle stateFz#try disconnecting old connection...zdisconnect failed: {e}ztry reconnecting...Tzreconnect failed: z, try again after reconnected)loggerdebugtimesleepr5   r6   infor1   
disconnectr2   	Exceptionwarningconnectr4   )r7   check_after_secondsr:   es       r   check_state_and_reconnect_laterz0ReconnectHandler.check_state_and_reconnect_laterJ   s   Z=PZZZ[[[
&'''! 	LL=>>>F  	' 	'KK1222!&D8BCCC
%%d&:;;;; 9 9 97888889 $% 	88%:;;;*
*4+?PP4<PPP&*$ 8 8 8cccFYccc   
#677777777	8 & 	8 $% 	88%:;;;*
*4+?PP4<PPP&*$ 8 8 8cccFYccc   
#677777777	8 & 	8 	8 	8 	8 	8 KK&&&)	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   "H-9B<;E4<$C# E4"C##E4&H-+9D%$H-%
E./5E)$H-)E..H-4H:9F43H4
G=	>5G8	3H8G=	=HH--H14H1statec                 2   t                               d|            | j        5  |j        d         dk    rd| _        	 d d d            d S d| _        t          j        | j                                                   d d d            d S # 1 swxY w Y   d S )Nzstate change to:    idleFT)target)	r;   r<   r6   valuer5   r   ThreadrF   start)r7   rG   s     r   reconnect_on_idlez"ReconnectHandler.reconnect_on_idleg   s   000111  	R 	R{1~''%*"	R 	R 	R 	R 	R 	R 	R 	R "&DD$HIIIOOQQQ	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	Rs   B3BBB)r+   r,   r-   objectstrr!   rF   rO    r   r   r0   r0   B   su        /f /s /F /t / / / /' ' ':Rv R R R R R Rr   r0   c                   &   e Zd ZdZddZdedeeef         fdZdedee	j
        ffd	Zd
 Z	 	 	 	 ddededededee	j
        ff
dZdefdZdefdZej        ddddfdedededededdfdZdefdZdefdZdedefdZej        fdedefdZdS )ConnectionszRClass for managing all connections of milvus.  Used as a singleton in this module.r   Nc                 <   i | _         i | _        d| _        t          j        dk    r?|                     t          j                  \  }}||f| _        |j        |j        nd|d}ndt          j         dt          j         d} | j	        di t          j
        |i dS )al  Constructs a default milvus alias config

            default config will be read from env: MILVUS_URI and MILVUS_CONN_ALIAS
            with default value: default="localhost:19530"

         Read default connection config from environment variable: MILVUS_URI.
            Format is:
                [scheme://][<user>@<password>]host[:<port>]

                scheme is one of: http, https, or <empty>

        Examples:
            localhost
            localhost:19530
            test_user@localhost:19530
            http://test_userlocalhost:19530
            https://test_user:password@localhost:19530

        N )useraddress:rR   )_alias_connected_alias_env_urir   
MILVUS_URI$_Connections__parse_address_from_uriusernameDEFAULT_HOSTDEFAULT_PORTadd_connectionMILVUS_CONN_ALIAS)r7   rX   
parsed_uridefault_conn_configs       r   r!   zConnections.__init__t   s    (  """"&"?"?@Q"R"RGZ$j1DM 0:/B/N
++TV"# # $1IIF4GII# #
 	NNv79LMNNNNNr   hostportc                    t          |          st          t          j                  t	          |          st          t          j                  dt          |          cxk    rdk     sn d| d}t          |          d S )Nmessager   i  zport number z% out of range, valid range [0, 65535))r   r   r   HostTyper	   PortTypeint)r7   rf   rg   msgs       r   __verify_host_portzConnections.__verify_host_port   s    T"" 	P+4E4NOOOOT"" 	P+4E4NOOOOCII%%%%%%%%LLLLC+C8888 &%r   uric           	      z   d}	 t          j        |          }nQ# t          $ rD}t          |                    |           dt          |          j         d| d          d d }~ww xY wt          |j                  dk    r%t          |                    |                     d |j	        |j	        nt          j        }|j        dk    rdnt          j        }|j        |j        n|}| d	| }|                     ||           t!          |          s#t          |                    |                    ||fS )
NzPIllegal uri: [{}], expected form 'http[s]://[user:password@]example.com[:12345]'z: <z, >ri   r   https443rY   )r   urlparserA   r   formattyper+   lennetlochostnamer   r`   schemera   rg   _Connections__verify_host_portr   )	r7   rp   illegal_uri_msgrd   rE   rf   default_portrg   addrs	            r   __parse_address_from_uriz$Connections.__parse_address_from_uri   sp   ^ 		,,JJ 	 	 	+*11#66SS477;KSSqSSS  	
 z !!Q&&+7M7Mc7R7R4TUUU[__&0&9&Ez""6K^ * 1W < <uu&BU",/"=z<d+++%% 	Q+O4J4J34O4OPPPPZs    
A'?A""A'c           
         |                                 D ]\  }}|                     |                    dd          |                    dd          |                    dd          |                    dd                    \  }}|| j        v rA| j        |                             d          |k    rt          t          j        |z            ||                    dd          d}||j        d
k    rd|d<   || j        |<   d	S )a#  Configures a milvus connection.

        Addresses priority in kwargs: address, uri, host and port

        :param kwargs:
            * *address* (``str``) -- Optional. The actual address of Milvus instance.
                Example address: "localhost:19530"

            * *uri* (``str``) -- Optional. The uri of Milvus instance.
                Example uri: "http://localhost:19530", "tcp:localhost:19530", "https://ok.s3.south.com:19530".

            * *host* (``str``) -- Optional. The host of Milvus instance.
                Default at "localhost", PyMilvus will fill in the default host
                if only port is provided.

            * *port* (``str/int``) -- Optional. The port of Milvus instance.
                Default at 19530, PyMilvus will fill in the default port if only host is provided.

        Example::

            connections.add_connection(
                default={"host": "localhost", "port": "19530"},
                dev1={"host": "localhost", "port": "19531"},
                dev2={"uri": "http://random.com/random"},
                dev3={"uri": "http://localhost:19530"},
                dev4={"uri": "tcp://localhost:19530"},
                dev5={"address": "localhost:19530"},
                prod={"uri": "http://random.random.random.com:19530"},
            )
        rX   rV   rp   rf   rg   ri   rW   )rX   rW   Nrs   Tsecure)	items_Connections__get_full_addressgetr[   rZ   r   r   ConnDiffConfr{   )r7   r   aliasconfigr   rd   alias_configs          r   rb   zConnections.add_connection   s"   > $\\^^ 	. 	.ME6#66

9b))

5"%%

62&&

62&&	   D* ---$+e2D2H2H2S2SW[2[2[/8I8VY^8^____  

62.. L
 %**;w*F*F)-X&!-DK'	. 	.r   rV   rX   c                    |dk    r't          |          st          d| d          |d fS |dk    rJt          |t                    r|                    d          r|d fS |                     |          \  }}||fS |dk    r|nt          j        }|dk    r|nt          j        }| 	                    ||           | d| }t          |          st          d| d| d	          |d fS )
NrV   zIllegal address: z%, should be in form 'localhost:19530'ri   zunix:rY   zIllegal host: z
 or port: z+, should be in form of '111.1.1.1', '19530')
r   r   
isinstancerQ   
startswithr^   r   r`   ra   r|   )	r7   rX   rp   rf   rg   parsed_host_portr   s	            r   __get_full_addresszConnections.__get_full_address   sA    b==#G,, /^^^^    D= "99#s## !w(?(? !Dy ";;C@@OGVF?"

(;

(;u---!!%!!%% 	+jjjjjj    Tzr   r   c                     t          |t                    s*t          t          j        t          |          z            || j        v r.| j                            |                                           dS dS )zDisconnects connection from the registry.

        :param alias: The name of milvus connection
        :type alias: str
        ri   N)	r   rQ   r   r   	AliasTyperw   r[   popcloser7   r   s     r   r@   zConnections.disconnect  sz     %%% 	_+4E4ORVW\R]R]4]^^^^D)))!%%e,,2244444 *)r   c                     t          |t                    s*t          t          j        t          |          z            |                     |           | j                            |d           dS )z|Removes connection from the registry.

        :param alias: The name of milvus connection
        :type alias: str
        ri   N)	r   rQ   r   r   r   rw   r@   rZ   r   r   s     r   remove_connectionzConnections.remove_connection  si     %%% 	_+4E4ORVW\R]R]4]^^^^t$$$$$r   defaultrW   passworddb_nametokenc           	          |                     d          rt          j        |d                   j                                        dvr|d                             d          st          d|d          d          t          j        |d                   j	        }|
                                st          d| d          d	d
lm} t                              d|d          d           |                    |d                   }	|	t          d          |	|d<   t!          j        |          |d<   |d<   |d<   |d<    fd}
dt$          dt&          fd}t)          t*                    s*t          t,          j        t1                    z            |                    dd          |                    dd          |                    dd          |                    dd          f}t+          |          pdt+          |          pdt+          |          pd}}} ||          r  j        | \  }}||d<                                  rA j                                      d          |k    rt          t,          j        z            |Y|j        p|}|j        p|}|j         !                    d          }tE          |          dk    r|d         n|}|j        dk    rd|d<    |
d#i |||||d  dS  j#        O j#        \  }}||d<   |j        |j        nd}|j        |j        nd}|j        dk    rd|d<    |
d#i ||||d! dS  j        v rBtI           j                 %                                          }||d<    |
d#i |||d"| dS t          t,          j&        z            )$a  
        Constructs a milvus connection and register it under given alias.

        :param alias: The name of milvus connection
        :type  alias: str

        :param kwargs:
            * *address* (``str``) -- Optional. The actual address of Milvus instance.
                Example address: "localhost:19530"
            * *uri* (``str``) -- Optional. The uri of Milvus instance.
                Example uri: "http://localhost:19530", "tcp:localhost:19530", "https://ok.s3.south.com:19530".
            * *host* (``str``) -- Optional. The host of Milvus instance.
                Default at "localhost", PyMilvus will fill in the default host
                if only port is provided.
            * *port* (``str/int``) -- Optional. The port of Milvus instance.
                Default at 19530, PyMilvus will fill in the default port if only host is provided.
            * *secure* (``bool``) --
                Optional. Default is false. If set to true, tls will be enabled.
            * *user* (``str``) --
                Optional. Use which user to connect to Milvus instance. If user and password
                are provided, we will add related header in every RPC call.
            * *password* (``str``) --
                Optional and required when user is provided. The password corresponding to
                the user.
            * *token* (``str``) --
                Optional. Serving as the key for identification and authentication purposes.
                Whenever a token is furnished, we shall supplement the corresponding header
                to each RPC call.
            * *keep_alive* (``bool``) --
                Optional. Default is false. If set to true, client will keep an alive connection.
            * *db_name* (``str``) --
                Optional. default database name of this connection
            * *client_key_path* (``str``) --
                Optional. If use tls two-way authentication, need to write the client.key path.
            * *client_pem_path* (``str``) --
                Optional. If use tls two-way authentication, need to write the client.pem path.
            * *ca_pem_path* (``str``) --
                Optional. If use tls two-way authentication, need to write the ca.pem path.
            * *server_pem_path* (``str``) --
                Optional. If use tls one-way authentication, need to write the server.pem path.
            * *server_name* (``str``) --
                Optional. If use tls, need to write the common name.

        :raises NotImplementedError: If handler in connection parameters is not GRPC.
        :raises ParamError: If pool in connection parameters is not supported.
        :raises Exception: If server specified in parameters is not ready, we cannot connect to
                           server.

        :example:
            >>> from pymilvus import connections
            >>> connections.connect("test", host="localhost", port="19530")
        rp   )unixhttprs   tcpz.dbzuri: zU is illegal, needs start with [unix, http, https, tcp] or a local file endswith [.db]ri   zOpen local milvus failed, dir: z is not existsr   )server_manager_instancezPass in the local path z, and run it using milvus-liteNzOpen local milvus failedrW   r   r   r   c                     t          d	i | }|                     d          }t          |t          t          f          r|nt
          j        }|                    |           |                     dd          r)|                    t                    j
                   |                     d           |                     dd            |                     dd           |j        <   t          j        |           j        <   d S )
Ntimeout)r   
keep_aliveFr   r   r   rV   rR   )r
   r   r   rm   floatr   MILVUS_CONN_TIMEOUT_wait_for_channel_readyregister_state_change_callbackr0   rO   r   r[   copydeepcopyrZ   )r   ghtr   r   kwargs_copyr7   s       r   connect_milvusz+Connections.connect.<locals>.connect_milvus  s   &&v&&B

9%%A%a#u66VaaF<VG&&w&777zz,.. 11$T5+>>P   JJz"""JJw%%%JJy"%%%+-D!%(!%v!6!6DKr   r   r   c                 4    t          d | D                       S )Nc              3   "   K   | ]
}|d k    V  dS )rV   NrR   ).0cs     r   	<genexpr>z;Connections.connect.<locals>.with_config.<locals>.<genexpr>  s&      //1qBw//////r   )any)r   s    r   with_configz(Connections.connect.<locals>.with_config  s    ////////r   rX   rV   rf   rg   /rI   rs   Tr   )rW   r   r   r   )rW   r   r   )r   r   rR   )'r   r   ru   r{   lowerendswithr   pathlibPathparentis_dirmilvus_lite.server_managerr   r;   r?   start_and_get_urir   r   r   boolr   rQ   r   r   rw   r   r   has_connectionrZ   r   r_   r   pathsplitrx   r\   dictr   ConnLackConf)r7   r   rW   r   r   r   r   parent_pathr   	local_urir   r   r   r   rd   groupconnect_aliasr   s   ``               @r   rC   zConnections.connect+  s   | ::e 	&u!>!>!E!K!K!M!M V
 "
 "
 %=))%00 / IF5M  I  I  I    ",ve}55<K%%'' /YkYYY    KJJJJJKK_&-___```/AA&-PPI /8RSSSS%F5M mF++"F"*J!(I$G	7 	7 	7 	7 	7 	7 	7$	0 	0$ 	0 	0 	0 	0 %%% 	_+4E4ORVW\R]R]4]^^^^ JJy"%%JJub!!JJvr""JJvr""	
 !$D		RX1D"c%jjFVTVh ;v 	6t6?D* $F9""5)) `dk%.@.D.DY.O.OSW.W.W/8I8VY^8^____ %!*2d%.:("--c22&)%jj1nn%((' $//'+F8$N``V`$X_`````F =$#}D* $F9*4*=*I:&&rD.8.A.Mz**SUH  G++#'x NSSVS$7SSSSSF DK U!3!9!9!;!;<<M$(M&!NYY]YXwYYYRXYYYF (0A0NQV0VWWWWr   c                 *      fd j         D             S )a#  List names of all connections.

        :return list:
            Names of all connections.

        :example:
            >>> from pymilvus import connections
            >>> connections.connect("test", host="localhost", port="19530")
            >>> connections.list_connections()
        c                 J    g | ]}|j                             |d           f S r   )r[   r   )r   kr7   s     r   
<listcomp>z0Connections.list_connections.<locals>.<listcomp>  s1    MMMAD)--a667MMMr   )rZ   )r7   s   `r   list_connectionszConnections.list_connections  s"     NMMMMMMMr   c                     t          |t                    s*t          t          j        t          |          z            | j                            |i           S )aC  
        Retrieves connection configure by alias.

        :param alias: The name of milvus connection
        :type  alias: str

        :return dict:
            The connection configure which of the name is alias.
            If alias does not exist, return empty dict.

        :example:
            >>> from pymilvus import connections
            >>> connections.connect("test", host="localhost", port="19530")
            >>> connections.list_connections()
            >>> connections.get_connection_addr('test')
            {'host': 'localhost', 'port': '19530'}
        ri   )r   rQ   r   r   r   rw   rZ   r   r   s     r   get_connection_addrzConnections.get_connection_addr  sQ    $ %%% 	_+4E4ORVW\R]R]4]^^^^{ub)))r   c                     t          |t                    s*t          t          j        t          |          z            || j        v S )a  Check if connection named alias exists.

        :param alias: The name of milvus connection
        :type  alias: str

        :return bool:
            if the connection of name alias exists.

        :example:
            >>> from pymilvus import connections
            >>> connections.connect("test", host="localhost", port="19530")
            >>> connections.list_connections()
            >>> connections.get_connection_addr('test')
            {'host': 'localhost', 'port': '19530'}
        ri   )r   rQ   r   r   r   rw   r[   r   s     r   r   zConnections.has_connection  sI      %%% 	_+4E4ORVW\R]R]4]^^^^---r   c                     t          |t                    s*t          t          j        t          |          z            | j                            |d          }|t          t          j	                  |S )z!Retrieves a GrpcHandler by alias.ri   N)
r   rQ   r   r   r   rw   r[   r   r   ConnectFirst)r7   r   conns      r   _fetch_handlerzConnections._fetch_handler  sp    %%% 	_+4E4ORVW\R]R]4]^^^^$((55<-6G6TUUUUr   r*   )rV   rV   rV   rV   )r+   r,   r-   __doc__r!   rQ   r   rm   r|   r   ParseResultr^   rb   r   r@   r   r   rc   rC   listr   r   r   r   r
   r   rR   r   r   rT   rT   q   s7       \\&O &O &O &OP9s 9%S/ 9 9 9 9 C  S%:K4L        42. 2. 2.l    	
  u 	!   @
5 
5 
5 
5 
5
%s 
% 
% 
% 
% - pX pXpX pX 	pX
 pX pX 
pX pX pX pXdN$ N N N N* * * * *..C .D . . . .( +1*B 	 	C 	{ 	 	 	 	 	 	r   rT   )	metaclass)!r   loggingr   r   r=   typingr   r   r   urllibr   pymilvus.client.checkr   r   r	   pymilvus.client.grpc_handlerr
   pymilvus.exceptionsr   r   r   pymilvus.settingsr   	getLoggerr+   r;   VIRTUAL_PORTr   rw   r   r0   rT   connectionsrR   r   r   <module>r      s           ) ) ) ) ) ) ) ) ) )       P P P P P P P P P P 4 4 4 4 4 4         
 % $ $ $ $ $		8	$	$
x 
 
 
 
5 5 5 5 5d 5 5 5$,R ,R ,R ,R ,R ,R ,R ,R^m m m m m3 m m m mb kmmr   