
    ?h2%                       d Z ddlmZmZ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mZmZmZ ddlm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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 	 ddl4m5Z5 ddl6Z6e G d d             Z8 G d de9e1      Z:e G d d             Z;e G d d             Z<e G d d             Z=eeee9e=f      e9f   Z>e G d d             Z? G d de      Z@y# e7$ r Y yw xY w)z
GraphQL `Get` command.
    )	dataclassFieldfields)Enum)dumps)AnyDictListLiteralOptionalSequenceTupleUnion)util)
Connection)ConsistencyLevel)AdditionalPropertiesException)WhereNearText
NearVectorGraphQL
NearObjectFilterAsk	NearImage	NearVideo	NearAudioNearThermal	NearDepthNearIMU	MediaTypeSort)UUID)image_encoder_b64_capitalize_first_letterget_valid_uuidfile_encoder_b64BaseEnum)	_Warnings)search_get_pb2Nc                   :    e Zd ZU eed<   eee      ed<   defdZy)BM25query
propertiesreturnc                     dt        j                  | j                         }| j                  <t	        | j                        dkD  r$dj                  | j                        }|d| dz  }d|z   dz   S )Nquery: r   ",", properties: [""]zbm25:{})r   _sanitize_strr-   r.   lenjoinselfretpropss      N/home/chris/cleankitchens-env/lib/python3.12/site-packages/weaviate/gql/get.py__str__zBM25.__str__4   sm    **4::678??&3t+?!+CJJt/E%eWB//C#~##    N)__name__
__module____qualname__str__annotations__r   r
   r>    r?   r=   r,   r,   /   s"    Jc##$ $r?   r,   c                       e Zd ZdZdZy)HybridFusionrankedFusionrelativeScoreFusionN)r@   rA   rB   RANKEDRELATIVE_SCORErE   r?   r=   rG   rG   <   s    F*Nr?   rG   c                   p    e Zd ZU eed<   ee   ed<   eee      ed<   eee      ed<   ee   ed<   defdZ	y)	Hybridr-   alphavectorr.   fusion_typer/   c                    dt        j                  | j                         }| j                  |d| j                   z  }| j                  |d| j                   z  }| j
                  <t        | j
                        dkD  r$dj                  | j
                        }|d| dz  }| j                  It        | j                  t              r|d| j                  j                   z  }n|d| j                   z  }d	|z   d
z   S )Nr1   z
, vector: z	, alpha: r   r2   r3   r4   z, fusionType: zhybrid:{r5   )r   r6   r-   rO   rN   r.   r7   r8   rP   
isinstancer   valuer9   s      r=   r>   zHybrid.__str__I   s    **4::678;;"Z}--C::!Ytzzl++C??&3t+?!+CJJt/E%eWB//C'$**D1(8(8(>(>'?@@(8(8'9::C#%%r?   N)
r@   rA   rB   rC   rD   r   floatr
   rG   r>   rE   r?   r=   rM   rM   A   sF    JE?T%[!!c##,''& &r?   rM   c                   >    e Zd ZU ee   ed<   eed<   eed<   defdZy)GroupBypathgroupsobjects_per_groupr/   c                 x    dj                  | j                        }d| d| j                   d| j                   dS )Nr2   zgroupBy:{path:["z"], groups:z, objectsPerGroup:r5   )r8   rW   rX   rY   r:   r<   s     r=   r>   zGroupBy.__str__a   s=    

499%"5'T[[MASTXTjTjSkkmnnr?   N)r@   rA   rB   r
   rC   rD   intr>   rE   r?   r=   rV   rV   [   s$    
s)OKo or?   rV   c                   H    e Zd ZU eed<   eed<   eeed f      ed<   defdZy)LinkTolink_onlinked_classr.   r/   c                     dj                  d | j                  D              }| j                  dz   | j                  z   dz   |z   dz   S )N c              3   2   K   | ]  }t        |        y wNrC   .0xs     r=   	<genexpr>z!LinkTo.__str__.<locals>.<genexpr>m   s     9AQ9   z{... on {}})r8   r.   r_   r`   r[   s     r=   r>   zLinkTo.__str__l   sC    999||j(4+<+<<sBUJTQQr?   N)r@   rA   rB   rC   rD   r   r   r>   rE   r?   r=   r^   r^   f   s/    LsH}-..R Rr?   r^   c                       e Zd ZU dZeed<   dZeed<   dZeed<   dZeed<   dZ	eed<   dZ
eed<   dZeed<   dZeed	<   d
efdZy)AdditionalPropertiesFuuidrO   creationTimeUnixlastUpdateTimeUnixdistance	certaintyscoreexplainScorer/   c                 N   g }t        | j                        }|D ]d  }t        |j                  t              st        | |j                        }|s7|j                  }|j                  dk(  rd}|j                  |       f t        |      dkD  rddj                  |      z   dz   S y)Nro   idr   z _additional{rb   }  )
r   	__class__
issubclasstypeboolgetattrnameappendr7   r8   )r:   additional_props
cls_fieldsfieldenabledr   s         r=   r>   zAdditionalProperties.__str__   s    &((.t~~(>
 	2E%**d+ 'ejj 9 ::DzzV+#$++D1	2  1$"SXX.>%??$FFr?   N)r@   rA   rB   ro   r}   rD   rO   rp   rq   rr   rs   rt   ru   rC   r>   rE   r?   r=   rn   rn   t   s`    D$FD"d"$$HdItE4L$ r?   rn   c                   <    e Zd ZdZdedee   def fdZde	dd fdZ
d	edd fd
Zdedd fdZdedd fdZedefd       Zdedd fdZdedd fdZdedd fdZd@dededd fdZd@dededd fdZd@dededd fdZd@dededd fdZd@dededd fdZd@dededd fdZde	dd fdZde	dd fdZdedd fdZdee ee!eee e   ef   f   e"eef   e#f   dd fdZ$dee%ef   dd fd Z&dAd"edee e      dd fd#Z'	 	 	 	 dBd"ed$ee(   d%ee e(      dee e      d&ee)   dd fd'Z*de e   d(e	d)e	dd fd*Z+	 	 	 dCd+ee   d,ee   d-ee e      dd fd.Z,d/edd fd0Z-d1e.dd fd2Z/d@d3edefd4Z0def fd5Z1d6d7de!eef   fd8Z2dd9de!fd:Z3de4ee5ef      dd;fd<Z6defd=Z7d>e8dd!fd?Z9 xZ:S )D
GetBuilderz:
    GetBuilder class used to create GraphQL queries.
    
class_namer.   
connectionc                    t         |   |       t        |t              st	        dt        |             |g }t        |t              r|g}t        |t              st	        dt        |             g | _        |D ]H  }t        |t              st        |t              st	        d      | j                  j                  |       J t        |      | _        dt               i| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        y)a  
        Initialize a GetBuilder class instance.

        Parameters
        ----------
        class_name : str
            Class name of the objects to interact with.
        properties : str or list of str
            Properties of the objects to interact with.
        connection : weaviate.connect.Connection
            Connection object to an active and running Weaviate instance.

        Raises
        ------
        TypeError
            If argument/s is/are of wrong type.
        z'class name must be of type str but was Nz<properties must be of type str, list of str or None but was z8All the `properties` must be of type `str` or Reference!__one_levelF)super__init__rR   rC   	TypeErrorr|   list_propertiesr^   r   r%   _class_nameset_additional_additional_dataclass_where_limit_offset_after_near_clause_contains_filter_sort_bm25_hybrid	_group_by_alias_tenant_autocut_consistency_level)r:   r   r.   r   proprz   s        r=   r   zGetBuilder.__init__   s\   & 	$*c*Ed:FVEWXYYJj#&$J*d+QRVWaRbQcd  :< 	*DdC(D&1I Z[[##D)	*
 !9 D"/!7 FJ"'+%)&*%)  	 !&%)
%)
)-,0%)&*'+15r?   autocutr/   c                 X    t        |t              st        d      || _        d| _        | S )z7Cuts off irrelevant results based on "jumps" in scores.zautocut must be of type intT)rR   r\   r   r   r   )r:   r   s     r=   with_autocutzGetBuilder.with_autocut   s,    '3'9:: $r?   tenantc                 X    t        |t              st        d      || _        d| _        | S )zSets a tenant for the query.ztenant must be of type strT)rR   rC   r   r   r   )r:   r   s     r=   with_tenantzGetBuilder.with_tenant   s,    &#&899 $r?   
after_uuidc                     t        |t        j                        st        d      dt	        |       d| _        d| _        | S )zCan be used to extract all elements by giving the last ID from the previous "page".

        Requires limit to be set but cannot be combined with any other filters or search. Part of the Cursor API.
        z2after_uuid must be of type UUID (str or uuid.UUID)zafter: ""T)rR   r#   __args__r   r&   r   r   )r:   r   s     r=   
with_afterzGetBuilder.with_after   sA    
 *dmm4PQQ 
!; <A> $r?   contentc                 4    t        |      | _        d| _        | S )a  
        Set `where` filter.

        Parameters
        ----------
        content : dict
            The content of the `where` filter to set. See examples below.

        Examples
        --------
        The `content` prototype is like this:

        >>> content = {
        ...     'operator': '<operator>',
        ...     'operands': [
        ...         {
        ...             'path': [path],
        ...             'operator': '<operator>'
        ...             '<valueType>': <value>
        ...         },
        ...         {
        ...             'path': [<matchPath>],
        ...             'operator': '<operator>',
        ...             '<valueType>': <value>
        ...         }
        ...     ]
        ... }

        This is a complete `where` filter but it does not have to be like this all the time.

        Single operand:

        >>> content = {
        ...     'path': ["wordCount"],    # Path to the property that should be used
        ...     'operator': 'GreaterThan',  # operator
        ...     'valueInt': 1000       # value (which is always = to the type of the path property)
        ... }

        Or

        >>> content = {
        ...     'path': ["id"],
        ...     'operator': 'Equal',
        ...     'valueString': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf"
        ... }

        Multiple operands:

        >>> content = {
        ...     'operator': 'And',
        ...     'operands': [
        ...         {
        ...             'path': ["wordCount"],
        ...             'operator': 'GreaterThan',
        ...             'valueInt': 1000
        ...         },
        ...         {
        ...             'path': ["wordCount"],
        ...             'operator': 'LessThan',
        ...             'valueInt': 1500
        ...         }
        ...     ]
        ... }

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.
        T)r   r   r   r:   r   s     r=   
with_wherezGetBuilder.with_where   s    N Gn $r?   c                 J    | j                   r| j                   S | j                  S rd   )r   r   )r:   s    r=   r   zGetBuilder.name:  s    "kkt{{?t/?/??r?   c                 b    | j                   t        d      t        |      | _         d| _        | S )a  
        Set `nearText` filter. This filter can be used with text modules (text2vec).
        E.g.: text2vec-contextionary, text2vec-transformers.
        NOTE: The 'autocorrect' field is enabled only with the `text-spellcheck` Weaviate module.

        Parameters
        ----------
        content : dict
            The content of the `nearText` filter to set. See examples below.

        Examples
        --------
        Content full prototype:

        >>> content = {
        ...     'concepts': <list of str or str>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'moveAwayFrom': { # Optional
        ...         'concepts': <list of str or str>,
        ...         'force': <float>
        ...     },
        ...     'moveTo': { # Optional
        ...         'concepts': <list of str or str>,
        ...         'force': <float>
        ...     },
        ...     'autocorrect': <bool>, # Optional
        ... }

        Full content:

        >>> content = {
        ...     'concepts': ["fashion"],
        ...     'certainty': 0.7, # or 'distance'
        ...     'moveAwayFrom': {
        ...         'concepts': ["finance"],
        ...         'force': 0.45
        ...     },
        ...     'moveTo': {
        ...         'concepts': ["haute couture"],
        ...         'force': 0.85
        ...     },
        ...     'autocorrect': True
        ... }

        Partial content:

        >>> content = {
        ...     'concepts': ["fashion"],
        ...     'certainty': 0.7, # or 'distance'
        ...     'moveTo': {
        ...         'concepts': ["haute couture"],
        ...         'force': 0.85
        ...     }
        ... }

        Minimal content:

        >>> content = {
        ...     'concepts': "fashion"
        ... }

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        QCannot use multiple 'near' filters, or a 'near' filter along with a 'ask' filter!T)r   AttributeErrorr   r   r   s     r=   with_near_textzGetBuilder.with_near_text>  s?    V ( (  %W- $r?   c                 b    | j                   t        d      t        |      | _         d| _        | S )a  
        Set `nearVector` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearVector` filter to set. See examples below.

        Examples
        --------
        Content full prototype:

        >>> content = {
        ...     'vector' : <list of float>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        NOTE: Supported types for 'vector' are `list`, 'numpy.ndarray`, `torch.Tensor`
                and `tf.Tensor`.

        Full content:

        >>> content = {
        ...     'vector' : [.1, .2, .3, .5],
        ...     'certainty': 0.75, # or 'distance'
        ... }

        Minimal content:

        >>> content = {
        ...     'vector' : [.1, .2, .3, .5]
        ... }

        Or

        >>> content = {
        ...     'vector' : torch.tensor([.1, .2, .3, .5])
        ... }

        Or

        >>> content = {
        ...     'vector' : torch.tensor([[.1, .2, .3, .5]]) # it is going to be squeezed.
        ... }

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)r   r   r   r   r   s     r=   with_near_vectorzGetBuilder.with_near_vector  s?    v ( (  'w/ $r?   c                     | j                   j                  dk\  }| j                  t        d      t	        ||      | _        d| _        | S )a  
        Set `nearObject` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearObject` filter to set. See examples below.

        Examples
        --------
        Content prototype:

        >>> {
        ...     'id': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }
        >>> # alternatively
        >>> {
        ...     'beacon': "weaviate://localhost/ClassName/e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf"
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        z1.14r   T)_connectionserver_versionr   r   r   r   )r:   r   is_server_version_14s      r=   with_near_objectzGetBuilder.with_near_object  sY    L  $//>>&H( (  'w0DE $r?   encodec                     | j                   t        d      |rt        |d         |d<   t        |      | _         d| _        | S )a  
        Set `nearImage` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearImage` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["image"]` to base64 and convert to string. If True, the
            `content["image"]` can be an image path or a file opened in binary read mode. If False,
            the `content["image"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'image': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'image': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'image': "my_image_path.png",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Image', 'description')\
        ...     .with_near_image(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_image_file = open("my_image_path.png", "br")
        >>> content = {
        ...     'image': my_image_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Image', 'description')\
        ...     .with_near_image(content, encode=True) # <- encode MUST be set to True
        >>> my_image_file.close()

        With `encoded` False:

        >>> from weaviate.util import image_encoder_b64, image_decoder_b64
        >>> encoded_image = image_encoder_b64("my_image_path.png")
        >>> content = {
        ...     'image': encoded_image,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Image', 'description')\
        ...     .with_near_image(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import image_encoder_b64, image_decoder_b64
        >>> with open("my_image_path.png", "br") as my_image_file:
        ...     encoded_image = image_encoder_b64(my_image_file)
        >>> content = {
        ...     'image': encoded_image,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Image', 'description')\
        ...     .with_near_image(content, encode=False) # <- encode MUST be set to False

        Encode Image yourself:

        >>> import base64
        >>> with open("my_image_path.png", "br") as my_image_file:
        ...     encoded_image = base64.b64encode(my_image_file.read()).decode("utf-8")
        >>> content = {
        ...     'image': encoded_image,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Image', 'description')\
        ...     .with_near_image(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   imageT)r   r   r$   r   r   r:   r   r   s      r=   with_near_imagezGetBuilder.with_near_image  sV    B ( (  01ABGG%g. $r?   c                    t         j                  | _        | j                  t	        d      |r9t        || j                  j                           || j                  j                  <   t        |      | _        d| _        | S )a  
        Set `nearAudio` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearAudio` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["audio"]` to base64 and convert to string. If True, the
            `content["audio"]` can be an audio path or a file opened in binary read mode. If False,
            the `content["audio"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'audio': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'audio': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'audio': "my_audio_path.wav",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Audio', 'description')\
        ...     .with_near_audio(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_audio_file = open("my_audio_path.wav", "br")
        >>> content = {
        ...     'audio': my_audio_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Audio', 'description')\
        ...     .with_near_audio(content, encode=True) # <- encode MUST be set to True
        >>> my_audio_file.close()

        With `encoded` False:

        >>> from weaviate.util import file_encoder_b64
        >>> encoded_audio = file_encoder_b64("my_audio_path.wav")
        >>> content = {
        ...     'audio': encoded_audio,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Audio', 'description')\
        ...     .with_near_audio(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import file_encoder_b64
        >>> with open("my_audio_path.wav", "br") as my_audio_file:
        ...     encoded_audio = file_encoder_b64(my_audio_file)
        >>> content = {
        ...     'audio': encoded_audio,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Audio', 'description')\
        ...     .with_near_audio(content, encode=False) # <- encode MUST be set to False

        Encode Audio yourself:

        >>> import base64
        >>> with open("my_audio_path.wav", "br") as my_audio_file:
        ...     encoded_audio = base64.b64encode(my_audio_file.read()).decode("utf-8")
        >>> content = {
        ...     'audio': encoded_audio,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Audio', 'description')\
        ...     .with_near_audio(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)	r!   AUDIO_media_typer   r   r'   rS   r   r   r   s      r=   with_near_audiozGetBuilder.with_near_audios  z    B %??( (  .>wtGWGWG]G]?^._GD$$**+%g. $r?   c                    t         j                  | _        | j                  t	        d      |r9t        || j                  j                           || j                  j                  <   t        |      | _        d| _        | S )a  
        Set `nearVideo` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearVideo` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["video"]` to base64 and convert to string. If True, the
            `content["video"]` can be an video path or a file opened in binary read mode. If False,
            the `content["video"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'video': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'video': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'video': "my_video_path.avi",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Video', 'description')\
        ...     .with_near_video(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_video_file = open("my_video_path.avi", "br")
        >>> content = {
        ...     'video': my_video_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Video', 'description')\
        ...     .with_near_video(content, encode=True) # <- encode MUST be set to True
        >>> my_video_file.close()

        With `encoded` False:

        >>> from weaviate.util import file_encoder_b64
        >>> encoded_video = file_encoder_b64("my_video_path.avi")
        >>> content = {
        ...     'video': encoded_video,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Video', 'description')\
        ...     .with_near_video(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import file_encoder_b64, video_decoder_b64
        >>> with open("my_video_path.avi", "br") as my_video_file:
        ...     encoded_video = file_encoder_b64(my_video_file)
        >>> content = {
        ...     'video': encoded_video,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Video', 'description')\
        ...     .with_near_video(content, encode=False) # <- encode MUST be set to False

        Encode Video yourself:

        >>> import base64
        >>> with open("my_video_path.avi", "br") as my_video_file:
        ...     encoded_video = base64.b64encode(my_video_file.read()).decode("utf-8")
        >>> content = {
        ...     'video': encoded_video,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Video', 'description')\
        ...     .with_near_video(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)	r!   VIDEOr   r   r   r'   rS   r   r   r   s      r=   with_near_videozGetBuilder.with_near_video  r   r?   c                    t         j                  | _        | j                  t	        d      |r9t        || j                  j                           || j                  j                  <   t        |      | _        d| _        | S )a  
        Set `nearDepth` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearDepth` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["depth"]` to base64 and convert to string. If True, the
            `content["depth"]` can be an depth path or a file opened in binary read mode. If False,
            the `content["depth"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'depth': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'depth': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'depth': "my_depth_path.png",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Depth', 'description')\
        ...     .with_near_depth(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_depth_file = open("my_depth_path.png", "br")
        >>> content = {
        ...     'depth': my_depth_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Depth', 'description')\
        ...     .with_near_depth(content, encode=True) # <- encode MUST be set to True
        >>> my_depth_file.close()

        With `encoded` False:

        >>> from weaviate.util import file_encoder_b64
        >>> encoded_depth = file_encoder_b64("my_depth_path.png")
        >>> content = {
        ...     'depth': encoded_depth,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Depth', 'description')\
        ...     .with_near_depth(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import file_encoder_b64
        >>> with open("my_depth_path.png", "br") as my_depth_file:
        ...     encoded_depth = file_encoder_b64(my_depth_file)
        >>> content = {
        ...     'depth': encoded_depth,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Depth', 'description')\
        ...     .with_near_depth(content, encode=False) # <- encode MUST be set to False

        Encode Depth yourself:

        >>> import base64
        >>> with open("my_depth_path.png", "br") as my_depth_file:
        ...     encoded_depth = base64.b64encode(my_depth_file.read()).decode("utf-8")
        >>> content = {
        ...     'depth': encoded_depth,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Depth', 'description')\
        ...     .with_near_depth(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)	r!   DEPTHr   r   r   r'   rS   r   r   r   s      r=   with_near_depthzGetBuilder.with_near_depthM  r   r?   c                    t         j                  | _        | j                  t	        d      |r9t        || j                  j                           || j                  j                  <   t        |      | _        d| _        | S )a  
        Set `nearThermal` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearThermal` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["thermal"]` to base64 and convert to string. If True, the
            `content["thermal"]` can be an thermal path or a file opened in binary read mode. If False,
            the `content["thermal"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'thermal': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'thermal': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'thermal': "my_thermal_path.png",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Thermal', 'description')\
        ...     .with_near_thermal(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_thermal_file = open("my_thermal_path.png", "br")
        >>> content = {
        ...     'thermal': my_thermal_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Thermal', 'description')\
        ...     .with_near_thermal(content, encode=True) # <- encode MUST be set to True
        >>> my_thermal_file.close()

        With `encoded` False:

        >>> from weaviate.util import file_encoder_b64
        >>> encoded_thermal = file_encoder_b64("my_thermal_path.png")
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Thermal', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import file_encoder_b64
        >>> with open("my_thermal_path.png", "br") as my_thermal_file:
        ...     encoded_thermal = file_encoder_b64(my_thermal_file)
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Thermal', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        Encode Thermal yourself:

        >>> import base64
        >>> with open("my_thermal_path.png", "br") as my_thermal_file:
        ...     encoded_thermal = base64.b64encode(my_thermal_file.read()).decode("utf-8")
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('Thermal', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)	r!   THERMALr   r   r   r'   rS   r   r   r   s      r=   with_near_thermalzGetBuilder.with_near_thermal  s|    B %,,( (  .>wtGWGWG]G]?^._GD$$**+'0 $r?   c                    t         j                  | _        | j                  t	        d      |r9t        || j                  j                           || j                  j                  <   t        |      | _        d| _        | S )a  
        Set `nearIMU` filter.

        Parameters
        ----------
        content : dict
            The content of the `nearIMU` filter to set. See examples below.
        encode : bool, optional
            Whether to encode the `content["thermal"]` to base64 and convert to string. If True, the
            `content["thermal"]` can be an thermal path or a file opened in binary read mode. If False,
            the `content["thermal"]` MUST be a base64 encoded string (NOT bytes, i.e. NOT binary
            string that looks like this: b'BASE64ENCODED' but simple 'BASE64ENCODED').
            By default True.

        Examples
        --------
        Content prototype:

        >>> content = {
        ...     'thermal': <str or binary read file>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ... }

        >>> {
        ...     'thermal': "e5dc4a4c-ef0f-3aed-89a3-a73435c6bbcf",
        ...     'certainty': 0.7 # or 'distance'
        ... }

        With `encoded` True:

        >>> content = {
        ...     'thermal': "my_thermal_path.png",
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('IMU', 'description')\
        ...     .with_near_thermal(content, encode=True) # <- encode MUST be set to True

        OR

        >>> my_thermal_file = open("my_thermal_path.png", "br")
        >>> content = {
        ...     'thermal': my_thermal_file,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('IMU', 'description')\
        ...     .with_near_thermal(content, encode=True) # <- encode MUST be set to True
        >>> my_thermal_file.close()

        With `encoded` False:

        >>> from weaviate.util import file_encoder_b64
        >>> encoded_thermal = file_encoder_b64("my_thermal_path.png")
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('IMU', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        OR

        >>> from weaviate.util import file_encoder_b64
        >>> with open("my_thermal_path.png", "br") as my_thermal_file:
        ...     encoded_thermal = file_encoder_b64(my_thermal_file)
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('IMU', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        Encode IMU yourself:

        >>> import base64
        >>> with open("my_thermal_path.png", "br") as my_thermal_file:
        ...     encoded_thermal = base64.b64encode(my_thermal_file.read()).decode("utf-8")
        >>> content = {
        ...     'thermal': encoded_thermal,
        ...     'certainty': 0.7 # or 'distance' instead
        ... }
        >>> query = client.query.get('IMU', 'description')\
        ...     .with_near_thermal(content, encode=False) # <- encode MUST be set to False

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        AttributeError
            If another 'near' filter was already set.
        r   T)	r!   IMUr   r   r   r'   rS   r    r   r   s      r=   with_near_imuzGetBuilder.with_near_imu'  sz    B %==( (  .>wtGWGWG]G]?^._GD$$**+#G, $r?   limitc                 B    |dk  rt        d      || _        d| _        | S )a^  
        The limit of objects returned.

        Parameters
        ----------
        limit : int
            The max number of objects returned.

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        ValueError
            If 'limit' is non-positive.
           z)limit cannot be non-positive (limit >=1).T)
ValueErrorr   r   )r:   r   s     r=   
with_limitzGetBuilder.with_limit  s+    ( 19HII $r?   offsetc                 J    |dk  rt        d      d| d| _        d| _        | S )a  
        The offset of objects returned, i.e. the starting index of the returned objects should be
        used in conjunction with the `with_limit` method.

        Parameters
        ----------
        offset : int
            The offset used for the returned objects.

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        ValueError
            If 'offset' is non-positive.
        r   z+offset cannot be non-positive (offset >=0).zoffset: rb   T)r   r   r   )r:   r   s     r=   with_offsetzGetBuilder.with_offset  s4    * A:JKK!&+ $r?   c                 b    | j                   t        d      t        |      | _         d| _        | S )as  
        Ask a question for which weaviate will retrieve the answer from your data.
        This filter can be used only with QnA module: qna-transformers.
        NOTE: The 'autocorrect' field is enabled only with the `text-spellcheck` Weaviate module.

        Parameters
        ----------
        content : dict
            The content of the `ask` filter to set. See examples below.

        Examples
        --------
        Content full prototype:

        >>> content = {
        ...     'question' : <str>,
        ...     # certainty ONLY with `cosine` distance specified in the schema
        ...     'certainty': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'distance': <float>, # Optional, either 'certainty' OR 'distance'
        ...     'properties': <list of str or str> # Optional
        ...     'autocorrect': <bool>, # Optional
        ... }

        Full content:

        >>> content = {
        ...     'question' : "What is the NLP?",
        ...     'certainty': 0.7, # or 'distance'
        ...     'properties': ['body'] # search the answer in these properties only.
        ...     'autocorrect': True
        ... }

        Minimal content:

        >>> content = {
        ...     'question' : "What is the NLP?"
        ... }

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.
        r   T)r   r   r   r   r   s     r=   with_askzGetBuilder.with_ask  s>    Z ( (   L $r?   c                 
   t        |t              rnt        | j                        dkD  st        | j                  d         dkD  r2t	        t        | j                        t        | j                              || _        | S | j                  2t	        t        | j                        t        | j                              t        |t
              r | j                  d   j                  |       | S t        |t              rB|D ];  }t        |t
              st        d      | j                  d   j                  |       = | S t        |t              r| j                  |       | S t        |t              st        dt        |             |j                         D ]  \  }}t        |t
              st        d      t               | j                  |<   t        |t
              r| j                  |   j                  |       gt        |t              st        dt        |       d      t        |      dk(  rt!        d	      |D ];  }t        |t
              st        d
      | j                  |   j                  |       =  | S )a  
        Add additional properties (i.e. properties from `_additional` clause). See Examples below.
        If the the 'properties' is of data type `str` or `list` of `str` then the method is
        idempotent, if it is of type `dict` or `tuple` then the exiting property is going to be
        replaced. To set the setting of one of the additional property use the `tuple` data type
        where `properties` look like this (clause: dict, settings: dict) where the 'settings' are
        the properties inside the '(...)' of the clause. See Examples for more information.

        Parameters
        ----------
        properties : str, list of str, dict[str, str], dict[str, list of str] or tuple[dict, dict]
            The additional properties to include in the query. Can be property name as `str`,
            a list of property names, a dictionary (clause without settings) where the value is a
            `str` or list of `str`, or a `tuple` of 2 elements:
                (clause: Dict[str, str or list[str]], settings: Dict[str, Any])
            where the 'clause' is the property and all its sub-properties and the 'settings' is the
            setting of the property, i.e. everything that is inside the `(...)` right after the
            property name. See Examples below.

        Examples
        --------

        >>> # single additional property with this GraphQL query
        >>> '''
        ... {
        ...     Get {
        ...         Article {
        ...             title
        ...             author
        ...             _additional {
        ...                 id
        ...             }
        ...         }
        ...     }
        ... }
        ... '''
        >>> client.query\
        ...     .get('Article', ['title', 'author'])\
        ...     .with_additional('id']) # argument as `str`

        >>> # multiple additional property with this GraphQL query
        >>> '''
        ... {
        ...     Get {
        ...         Article {
        ...             title
        ...             author
        ...             _additional {
        ...                 id
        ...                 certainty
        ...             }
        ...         }
        ...     }
        ... }
        ... '''
        >>> client.query\
        ...     .get('Article', ['title', 'author'])\
        ...     .with_additional(['id', 'certainty']) # argument as `List[str]`

        >>> # additional properties as clause with this GraphQL query
        >>> '''
        ... {
        ...     Get {
        ...         Article {
        ...             title
        ...             author
        ...             _additional {
        ...                 classification {
        ...                     basedOn
        ...                     classifiedFields
        ...                     completed
        ...                     id
        ...                     scope
        ...                 }
        ...             }
        ...         }
        ...     }
        ... }
        ... '''
        >>> client.query\
        ...     .get('Article', ['title', 'author'])\
        ...     .with_additional(
        ...         {
        ...             'classification' : ['basedOn', 'classifiedFields', 'completed', 'id']
        ...         }
        ...     ) # argument as `dict[str, List[str]]`
        >>> # or with this GraphQL query
        >>> '''
        ... {
        ...     Get {
        ...         Article {
        ...             title
        ...             author
        ...             _additional {
        ...                 classification {
        ...                     completed
        ...                 }
        ...             }
        ...         }
        ...     }
        ... }
        ... '''
        >>> client.query\
        ...     .get('Article', ['title', 'author'])\
        ...     .with_additional(
        ...         {
        ...             'classification' : 'completed'
        ...         }
        ...     ) # argument as `Dict[str, str]`

        Consider the following GraphQL clause:

        >>> '''
        ... {
        ...     Get {
        ...         Article {
        ...             title
        ...             author
        ...             _additional {
        ...                 token (
        ...                     properties: ["content"]
        ...                     limit: 10
        ...                     certainty: 0.8
        ...                 ) {
        ...                     certainty
        ...                     endPosition
        ...                     entity
        ...                     property
        ...                     startPosition
        ...                     word
        ...                 }
        ...             }
        ...         }
        ...     }
        ... }
        ... '''

        Then the python translation of this is the following:

        >>> clause = {
        ...     'token': [ # if only one, can be passes as `str`
        ...         'certainty',
        ...         'endPosition',
        ...         'entity',
        ...         'property',
        ...         'startPosition',
        ...         'word',
        ...     ]
        ... }
        >>> settings = {
        ...     'properties': ["content"],  # is required
        ...     'limit': 10,                # optional, int
        ...     'certainty': 0.8            # optional, float
        ... }
        >>> client.query\
        ...     .get('Article', ['title', 'author'])\
        ...     .with_additional(
        ...         (clause, settings)
        ...     ) # argument as `Tuple[Dict[str, List[str]], Dict[str, Any]]`

        If the desired clause does not match any example above, then the clause can always be
        converted to string before passing it to the `.with_additional()` method.

        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.

        Raises
        ------
        TypeError
            If one of the property is not of a correct data type.
        r   r   r   zGIf type of 'properties' is `list` then all items must be of type `str`!zZThe 'properties' argument must be either of type `str`, `list`, `dict` or `tuple`! Given: zFIf type of 'properties' is `dict` then all keys must be of type `str`!znIf type of 'properties' is `dict` then all the values must be either of type `str` or `list` of `str`! Given: !zlIf type of 'properties' is `dict` and a value is of type `list` then at least one element should be present!zeIf type of 'properties' is `dict` and a value is of type `list` then all items must be of type `str`!)rR   rn   r7   r   r   rC   r   addr   r   tuple_tuple_to_dictdictr|   itemsr   r   )r:   r.   r   keyvaluesrS   s         r=   with_additionalzGetBuilder.with_additional  s|   f j"674##$q(C0@0@0O,PST,T3(()3t/I/I+J  *4D&K''3/D$$%s4+E+E'F  j#&]+//
;Kj$'" :!$,#a    /33D9: Kj%(
+K*d+##'
#3"46  &++- 	1KCc3'\  %(EDS!&#&  %))&1fd+88<V~QH  6{a 6    1!%-#7    %))%01'	14 r?   c                     | j                   t        |      | _         d| _        | S | j                   j                  |       | S )a  
        Sort objects based on specific field/s. Multiple sort fields can be used, the objects are
        going to be sorted according to order of the sort configs passed. This method can be called
        multiple times and it does not overwrite the last entry but appends it to the previous
        ones, see examples below.

        Parameters
        ----------
        content : Union[list, dict]
            The content of the Sort filter. Can be a single Sort configuration or a list of
            configurations.

        Examples
        --------
        The `content` should have this form:

        >>> content = {
        ...     'path': ['name']       # Path to the property that should be used
        ...     'order': 'asc'         # Sort order, possible values: asc, desc
        ... }
        >>> client.query.get('Author', ['name', 'address'])\
        ...     .with_sort(content)

        Or a list of sort configurations:

        >>> content = [
        ...     {
        ...         'path': ['name']        # Path to the property that should be used
        ...         'order': 'asc'          # Sort order, possible values: asc, desc
        ...     },
        ...         'path': ['address']     # Path to the property that should be used
        ...         'order': 'desc'         # Sort order, possible values: asc, desc
        ...     }
        ... ]

        If we have a list we can add it in 2 ways.
        Pass the list:

        >>> client.query.get('Author', ['name', 'address'])\
        ...     .with_sort(content)

        Or one configuration at a time:

        >>> client.query.get('Author', ['name', 'address'])\
        ...     .with_sort(content[0])
        ...     .with_sort(content[1])

        It is possible to call this method multiple times with lists only too.


        Returns
        -------
        weaviate.gql.get.GetBuilder
            The updated GetBuilder.
        )r   T)r   r"   r   r   r   s     r=   	with_sortzGetBuilder.with_sort  sC    r ::g.DJ$(D!  JJNN7N+r?   Nr-   c                 6    t        ||      | _        d| _        | S )a?  Add BM25 query to search the inverted index for keywords.

        Parameters
        ----------
        query: str
            The query to search for.
        properties: Optional[List[str]]
            Which properties should be searched. If 'None' or empty all properties will be searched. By default, None
        T)r,   r   r   )r:   r-   r.   s      r=   	with_bm25zGetBuilder.with_bm254  s     %,
 $r?   rN   rO   rP   c                 <    t        |||||      | _        d| _        | S )a  Get objects using bm25 and vector, then combine the results using a reciprocal ranking algorithm.

        Parameters
        ----------
        query: str
            The query to search for.
        alpha: Optional[float]
            Factor determining how BM25 and vector search are weighted. If 'None' the weaviate default of 0.75 is used.
            By default, None
            alpha = 0 -> bm25, alpha=1 -> vector search
        vector: Optional[List[float]]
            Vector that is searched for. If 'None', weaviate will use the configured text-to-vector module to create a
            vector from the "query" field.
            By default, None
        properties: Optional[List[str]]:
            Which properties should be searched by BM25. Does not have any effect for vector search. If None or empty
            all properties are searched.
        fusion_type: Optional[HybridFusionType]:
            Which fusion type should be used to merge keyword and vector search.
        T)rM   r   r   )r:   r-   rN   rO   r.   rP   s         r=   with_hybridzGetBuilder.with_hybridC  s%    8 eUFJL $r?   rX   rY   c                 8    t        |||      | _        d| _        | S )a  Retrieve groups of objects from Weaviate.

        Note that the return values must be set using .with_additional() to see the output.

        Parameters
        ----------
        properties: List[str]
            Properties to group by
        groups: int
            Maximum number of groups
        objects_per_group: int
            Maximum number of objects per group

        T)rV   r   r   )r:   r.   rX   rY   s       r=   with_group_byzGetBuilder.with_group_byc  s"    " !V5FG $r?   single_promptgrouped_taskgrouped_propertiesc                    ||t        d      |t        |t              r|t        |t              st        d      | j                  j                  dk  r)t        j                  | j                  j                         dg}d}|-|j                  d       |dt        j                  |       dz  }||t        |      d	kD  r|j                  d
       g }|'|j                  dt        j                  |              |4t        |      d	kD  r&dj                  |      }|j                  d| d       |ddj                  |       dz  }| j                  d   j                  d| ddj                  |       d       | S )a  Generate responses using the OpenAI generative search.

        At least one of the two parameters must be set.

        Parameters
        ----------
        grouped_task: Optional[str]
            The task to generate a grouped response.
        grouped_properties: Optional[List[str]]:
            The properties whose contents are added to the prompts. If None or empty,
            all text properties contents are added.
        single_prompt: Optional[str]
            The prompt to generate a single response.
        zNEither parameter grouped_result_task or single_result_prompt must be not None.z&prompts and tasks must be of type str.z1.17.3errorry   singleResultzsingleResult:{prompt:r5   r   groupedResultztask:r2   zproperties:["r4   zgroupedResult:{,r   z	generate(z){rb   )r   rR   rC   r   r   r)   weaviate_too_old_for_openair   r   r6   r7   r8   r   r   )r:   r   r   r   resultstask_and_promptargsr<   s           r=   with_generatezGetBuilder.with_generatex  s   (  \%9`  %j.L$Zc-JDEE**X511$2B2B2Q2QR%Y$NN>*!78J8J=8Y7ZZ\]]O#*s3E/F/JNN?+D'eD$6$6|$D#EFG!-#6H2IA2M

#56mE7"56!1#((4.1ADDO'++i7HCHHU\L]K^^`,abr?   aliasc                     || _         | S )zGives an alias for the query. Needs to be used if 'multi_get' requests the same 'class_name' twice.

        Parameters
        ----------
        alias: str
            The alias for the query.
        )r   )r:   r   s     r=   
with_aliaszGetBuilder.with_alias  s     r?   consistency_levelc                 >    d|j                    d| _        d| _        | S )z*Set the consistency level for the request.zconsistencyLevel: rb   T)rS   r   r   )r:   r   s     r=   with_consistency_levelz!GetBuilder.with_consistency_level  s*     %77H7N7N6Oq"Q $r?   wrap_getc                    |rd}nd}| j                   || j                   dz   z  }|| j                  z  }| j                  r|dz  }| j                  |t	        | j                        z  }| j
                  |d| j
                   dz  }| j                  || j                  z  }| j                  |t	        | j                        z  }| j                  |t	        | j                        z  }| j                  |t	        | j                        z  }| j                  |t	        | j                        z  }| j                  |t	        | j                        z  }| j                  || j                  z  }| j                  || j                  z  }| j                  |d| j                   dz  }| j                  |d	| j                   z  }|d
z  }| j!                         }|s| j"                  st%        d      dj'                  d | j"                  D              | j!                         z   }|d|z   dz   z  }|r|dz  }|S )a+  
        Build query filter as a string.

        Parameters
        ----------
        wrap_get: bool
            A boolean to decide wether {Get{...}} is placed around the query. Useful for multi_get.

        Returns
        -------
        str
            The GraphQL query as a string.
        z{Get{ry   : (zlimit: rb   z	tenant: "r   z	autocut: )zeNo 'properties' or 'additional properties' specified to be returned. At least one should be included.c              3   2   K   | ]  }t        |        y wrd   re   rf   s     r=   ri   z#GetBuilder.build.<locals>.<genexpr>  s     ?c!f?rj   rk   r5   rl   )r   r   r   r   rC   r   r   r   r   r   r   r   r   r   r   r   _additional_to_strr   r   r8   )r:   r  r-   r   r.   s        r=   buildzGetBuilder.build  s1    EE;;"T[[4''E!!!  SLE{{&T[[)){{&74;;-q11||'%  ,T..//zz%TZZ(zz%TZZ(||'T\\**~~)T^^,,{{&$&&2000||'9T\\N!44}}(9T]]O44SLE224 D$4$4 3 
 XX?d.>.>??$BYBYB[[
z!C''TMEr?   c                 T
   | j                   j                  duxr | j                  du xs6 t        | j                  t              xs t        | j                  t
              xr t        | j                        dk(  xr t        | j                  d         dk(  xs d| j                  d   v xr\ | j                  du xrL | j                  du xr< | j                  du xr, | j                  du xr t        d | j                  D              }|rd}| j                   j                         }t        |      dkD  rd|ff}	 | j                   j                  j                  j!                  t#        j$                  | j&                  | j(                  | j                  t        | j                  t              rwt#        j                  | j                  j*                  d	   | j                  j*                  j-                  d
d      | j                  j*                  j-                  dd            nd| j                  t        | j                  t
              rwt#        j
                  | j                  j*                  d   | j                  j*                  j-                  d
d      | j                  j*                  j-                  dd            nd| j/                  | j                        | j0                  t#        j2                  | j0                  j4                  | j0                  j6                  | j0                  j8                  | j0                  j:                  | j0                  j<                  | j0                  j>                  | j0                  j@                        nd| jB                  ?t#        jD                  | jB                  jF                  | jB                  jH                        nd| jJ                  it#        jL                  | jJ                  jF                  | jJ                  jH                  | jJ                  jN                  | jJ                  j6                        nd      |      \  }}g }|jP                  D ]\  }| jS                  |jF                        }| jU                  |jV                        }	t        |	      dkD  r|	|d<   |jY                  |       ^ dd| j&                  |iii}
|
S t`        |          S # tZ        j\                  $ r}d|j_                         gi}
Y d}~|
S d}~ww xY w)a[  
        Builds and runs the query.

        Returns
        -------
        dict
            The response of the query.

        Raises
        ------
        requests.ConnectionError
            If the network connection to weaviate fails.
        weaviate.UnexpectedStatusCodeException
            If weaviate reports a none OK status.
        Nr   r   r   rw   c              3   P   K   | ]  }t        |t              rd |vxr d|v   yw)z...r   N)rR   rC   )rg   r   s     r=   ri   z GetBuilder.do.<locals>.<genexpr>#  s4      dC( T!?m4&??s   $&rE   authorizationrO   rs   rr   )rO   rs   rr   )rw   rs   rr   )ro   rO   creation_time_unixlast_update_time_unixrr   explain_scorert   )r.   r-   )r.   r-   rN   rO   )
collectionr   near_vectornear_objectr.   metadatabm25_searchhybrid_search)r  r   dataGeterrors)2r   	grpc_stubr   rR   r   r   r7   r   r   r   r   r   allr   get_current_bearer_tokenSearch	with_callr*   SearchRequestr   r   r   get_convert_references_to_grpcr   MetadataRequestro   rO   rp   rq   rr   ru   rt   r   r,   r.   r-   r   rM   rN   r   "_convert_references_to_grpc_result_extract_additional_propertiesr  r   grpcRpcErrordetailsr   do)r:   grpc_enabledr  access_tokenres_objectsresultobj
additionalr   erz   s               r=   r(  zGetBuilder.do  s   " &&d2 !!T) =d//<=d//<	 D$$%* D$$]349dTTEUEUVcEd=d $ 

d" t# t#   ,,  	* RTH++DDFL< 1$,l;=?4))33::DD"00#'#3#3"kk  ,,8&t'8'8*E %3$=$=#'#4#4#<#<X#F&*&7&7&?&?&C&CKQU&V%)%6%6%>%>%B%B:t%T% "  ,,8&t'8'8*E %3$=$=#0088>&*&7&7&?&?&C&CKQU&V%)%6%6%>%>%B%B:t%T% "#'#C#CDDTDT#U  55A "0!?!?!%!;!;!@!@#'#=#=#D#D/3/I/I/Z/Z262L2L2_2_%)%?%?%H%H*.*D*D*Q*Q"&"<"<"B"B" "  ::1 %3$7$7'+zz'<'<DJJDTDT% "  <<3 '5&;&;'+||'>'>"&,,"4"4"&,,"4"4#'<<#6#6	' "W,Z &] E /Qb !kk (FAA&BSBSTC!%!D!DV__!UJ:*-7M*NN3'( UT%5%5w$?@Z N7:<	 == 4#aiik]3N4s   =N)S6 6T'	T""T'r<   zsearch_get_pb2.MetadataResultc                    i }| j                   |S | j                   j                  r|j                  |d<   | j                   j                  r@t	        |j                        dkD  r#|j                  D cg c]  }t        |       c}nd |d<   | j                   j                  r|j                  r|j                  nd |d<   | j                   j                  r|j                  r|j                  nd |d<   | j                   j                  r&|j                  rt        |j                        nd |d<   | j                   j                  r&|j                  rt        |j                         nd |d<   | j                   j"                  r|j$                  r|j"                  nd |d<   | j                   j&                  r|j(                  r|j*                  nd |d	<   |S c c}w )
Nrw   r   rO   rr   rs   rp   rq   rt   ru   )r   ro   rw   rO   r7   rT   rr   distance_presentrs   certainty_presentrp   creation_time_unix_presentrC   r  rq   last_update_time_unix_presentr  rt   score_presentru   explain_score_presentr  )r:   r<   r   nums       r=   r$  z)GetBuilder._extract_additional_propertiess  s    ,.%%-##%%**%*XXT"%%,,8;ELL8IA8Mu||4s4SW X& %%..=B=S=S5>>Y]Z(%%//?D?V?VEOO\`[)%%66161Q1QE,,-W[ /0 %%88494W4WE//0]a 12 %%++7<7J7JPTW%%%22','B'B## ^,  ) 5s   2Gzsearch_get_pb2.PropertiesResultc                     i }|j                   j                         D ]
  \  }}|||<    |j                  D ]8  }|j                  D cg c]  }| j	                  |       c}||j
                  <   : |S c c}w rd   )non_ref_propertiesr   	ref_propsr.   r#  	prop_name)r:   r.   r.  r   non_ref_propref_propr   s          r=   r#  z-GetBuilder._convert_references_to_grpc_result  s     "$","?"?"E"E"G 	(D,'F4L	( #,, 	HJRJ]J]*BF77=*F8%%&	
 	*s   A3z search_get_pb2.PropertiesRequestc                 D   t        j                  |D cg c]  }t        |t              s| c}|D cg c]W  }t        |t              rEt        j
                  |j                  |j                  | j                  |j                              Y c}      S c c}w c c}w )N)target_collectionreference_propertyr.   )r;  ref_properties)
r*   PropertiesRequestrR   rC   r^   RefPropertiesRequestr`   r_   r!  r.   )r:   r.   r   s      r=   r!  z&GetBuilder._convert_references_to_grpc  s     //1;Uz$PS?TU ' dF+ 33&*&7&7'+||#??P
 	
Us   BBAB
c                 d   | j                   t        | j                         S d}d}t        | j                  d         D ]  }d}||dz   z  } t        | j                  j	                         d       D ]2  \  }}|dk(  rd}||dz   z  }t        |      D ]
  }||dz   z  } |d	z  }4 |du ry
|dz   S )z
        Convert `self._additional` attribute to a `str`.

        Returns
        -------
        str
            The converted self._additional.
        z _additional {Fr   Trb   c                     | d   S Nr   rE   	key_values    r=   <lambda>z/GetBuilder._additional_to_str.<locals>.<lambda>  s    R[\]R^ r?   r   z {rx   ry   r5   )r   rC   sortedr   r   )r:   str_to_return
has_values	one_levelr   r   rS   s          r=   r	  zGetBuilder._additional_to_str  s     %%1t1122(
 0 0 ?@ 	-IJY_,M	- "$"2"2"8"8":@^_ 	"KCm#JS4Z'M -,-T!M	" s""r?   tuple_valuec                 "   t        |      dk7  rt        d      |\  }}t        |t              rt        |t              st	        d      t        |      dk7  rt        dt        |             t        |      dk(  rt        dt        |             t        |j                               d   \  }}t        |t              st	        d      |d	z   }	 t        |j                         d
       D ]7  \  }}t        |t              st	        d      ||dz   t        |      z   dz   z  }9 	 |dz  }t               | j                  |<   t        |t              r| j                  |   j                  |       yt        |t
              st	        dt        |       d      t        |      dk(  rt        d      |D ];  }t        |t              st	        d      | j                  |   j                  |       = y# t        $ r t	        d      dw xY w)a  
        Convert the tuple data type argument to a dictionary.

        Parameters
        ----------
        tuple_value : tuple
            The tuple value as (clause: <dict>, settings: <dict>).

        Raises
        ------
        ValueError
            If 'tuple_value' does not have exactly 2 elements.
        TypeError
            If the configuration of the 'tuple_value' is not correct.
           zcIf type of 'properties' is `tuple` then it should have length 2: (clause: <dict>, settings: <dict>)zWIf type of 'properties' is `tuple` then it should have this data type: (<dict>, <dict>)r   zfIf type of 'properties' is `tuple` then the 'clause' (first element) should have only one key. Given: r   zmIf type of 'properties' is `tuple` then the 'settings' (second element) should have at least one key. Given: zTIf type of 'properties' is `tuple` then first element's key should be of type `str`!r  c                     | d   S rH  rE   rI  s    r=   rK  z+GetBuilder._tuple_to_dict.<locals>.<lambda>  s    YWX\ r?   rL  zlIf type of 'properties' is `tuple` then the second elements (<dict>) should have all the keys of type `str`!r  rb   Nr  z|If type of 'properties' is `tuple` then first element's dict values must be either of type `str` or `list` of `str`! Given: r   zIf type of 'properties' is `tuple` and first element's dict value is of type `list` then at least one element should be present!zzIf type of 'properties' is `tuple` and first element's dict value is of type  `list` then all items must be of type `str`!)r7   r   rR   r   r   r   r   rC   rM  r   r   r   r   r|   )	r:   rQ  clausesettings
clause_keyr   clause_with_settingsr   rS   s	            r=   r   zGetBuilder._tuple_to_dict  sd   " {q 5 
 '&$'z(D/I#  v;!--0[M;  x=A114XA 
 "&,,.1!4
F*c* 
  *C/	$X^^%5;YZ H
U!#s+#B  %d
U5\(AC(GG$H 	#14-.fc"1266v>&$'CCG<.PQS  v;!F   	>EeS)D  1266u=	>+  	: 	s   AG8 8H)Trd   )NNNN)NNN);r@   rA   rB   __doc__rC   r   
PROPERTIESr   r   r\   r   r   r#   r   r   r   propertyr   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r
   r	   r   rn   r   r   r   r   rT   rG   r   r   r   r   r   r  r
  r(  r$  r#  r   r^   r!  r	  r   r   __classcell__)rz   s   @r=   r   r      s   :63 :6HZ4H :6V` :6xC L # , 
T 
l 
I$ I< IV @c @ @Rd R| RhB B BH/ / /bjt jT j\ jXkt kT k\ kZkt kT k\ kZkt kT k\ kZk kt k| kZkT k4 k< kZ  6# , 84 4 4lq#tCtCy#~!667tTz9JL``
q
 
qf>tTz!2 >| >@s c0C | $ "&(,*..2  e%	
 T#Y' l+ 
@s)-0EH	. (,&*26	3}3 sm3 %T#Y/	3
 
3j 
8H \ ?d ?c ?Bm D m ^ 4 	c3h B;	
"5#56
	+
 #C #@T>% T>D T>r?   r   )ArY  dataclassesr   r   r   enumr   jsonr   typingr   r	   r
   r   r   r   r   r   weaviater   weaviate.connectr   weaviate.data.replicationr   weaviate.exceptionsr   weaviate.gql.filterr   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   weaviate.typesr#   weaviate.utilr$   r%   r&   r'   r(   weaviate.warningsr)   weaviate.proto.v1r*   r%  ImportErrorr,   rC   rG   rM   rV   r^   rZ  rn   r   rE   r?   r=   <module>rk     s8   1 0   M M M  ' 6 =    "    (	0
 	$ 	$ 	$+3 +
 & & &2 o o o R R R 8E#v+./45
   6V> V>K  		s   
C> >DD