diff --git a/.github/workflows/merge.yaml b/.github/workflows/build-and-publish-docs.yaml similarity index 74% rename from .github/workflows/merge.yaml rename to .github/workflows/build-and-publish-docs.yaml index a2100b49..4d75c53d 100644 --- a/.github/workflows/merge.yaml +++ b/.github/workflows/build-and-publish-docs.yaml @@ -1,10 +1,11 @@ -name: 'CI (main)' +name: "Build and publish documentation to sdk-docs" on: - push: - branches: - - main workflow_dispatch: {} + workflow_call: + secrets: + SSH_DEPLOY_KEY: + required: true jobs: build-and-deploy-documentation: @@ -29,4 +30,4 @@ jobs: user-email: clients@pinecone.io target-branch: main target-directory: python - commit-message: 'Python: automated documentation build - pinecone-python-client merge SHA: ${{ github.sha }}' + commit-message: "Python: automated documentation build - pinecone-python-client merge SHA: ${{ github.sha }}" diff --git a/.github/workflows/testing-dependency.yaml b/.github/workflows/testing-dependency.yaml index 5ba30106..68676919 100644 --- a/.github/workflows/testing-dependency.yaml +++ b/.github/workflows/testing-dependency.yaml @@ -56,12 +56,11 @@ jobs: # - 4.1.0 - 4.3.3 protobuf_version: - - 3.20.3 + - 4.25.3 + protoc-gen-openapiv2: + - 0.0.1 googleapis_common_protos_version: - - 1.53.0 - 1.62.0 - grpc_gateway_protoc_gen_openapiv2_version: - - 0.1.0 steps: - uses: actions/checkout@v4 - uses: ./.github/actions/test-dependency-grpc @@ -92,12 +91,11 @@ jobs: - 3.1.3 - 4.3.3 protobuf_version: - - 3.20.3 + - 4.25.3 + protoc-gen-openapiv2: + - 0.0.1 googleapis_common_protos_version: - - 1.53.0 - 1.62.0 - grpc_gateway_protoc_gen_openapiv2_version: - - 0.1.0 steps: - uses: actions/checkout@v4 - uses: ./.github/actions/test-dependency-grpc @@ -158,3 +156,19 @@ jobs: index_name: '${{ needs.dependency-matrix-setup.outputs.index_name }}' PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}' urllib3_version: '${{ matrix.urllib3_version }}' + + deps-cleanup: + name: Deps cleanup + runs-on: ubuntu-latest + needs: + - dependency-matrix-setup + - dependency-matrix-grpc + - dependency-matrix-grpc-312 + - dependency-matrix-rest + - dependency-matrix-rest-312 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/delete-index + with: + index_name: '${{ needs.dependency-matrix-setup.outputs.index_name }}' + PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}' \ No newline at end of file diff --git a/.github/workflows/testing-integration.yaml b/.github/workflows/testing-integration.yaml index ee07e42f..3334becf 100644 --- a/.github/workflows/testing-integration.yaml +++ b/.github/workflows/testing-integration.yaml @@ -3,6 +3,54 @@ name: "Integration Tests" workflow_call: {} jobs: + # setup-index: + # name: Setup proxyconfig test index + # runs-on: ubuntu-latest + # outputs: + # index_name: ${{ steps.create-index.outputs.index_name }} + # steps: + # - uses: actions/checkout@v4 + # - name: Create index + # id: create-index + # uses: ./.github/actions/create-index + # with: + # PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }} + # NAME_PREFIX: 'proxyconfig-' + # REGION: 'us-west-2' + # CLOUD: 'aws' + # DIMENSION: 1536 + # METRIC: 'cosine' + + # proxy-config: + # name: Proxy config tests + # needs: [setup-index] + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/setup-python@v5 + # with: + # python-version: 3.9 + # - name: Setup Poetry + # uses: ./.github/actions/setup-poetry + # - name: 'Run integration tests (proxy config)' + # run: | + # poetry run pytest tests/integration/proxy_config -s -v + # env: + # PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}' + # PINECONE_INDEX_NAME: ${{ needs.setup-index.outputs.index_name }} + # - name: Upload logs + # if: always() + # uses: actions/upload-artifact@v4 + # with: + # name: proxy_config_test_logs + # path: tests/integration/proxy_config/logs + # - name: Cleanup index + # if: always() + # uses: ./.github/actions/delete-index + # with: + # PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }} + # INDEX_NAME: ${{ needs.setup-index.outputs.index_name }} + data-plane-serverless: name: Data plane serverless integration tests runs-on: ubuntu-latest @@ -27,7 +75,6 @@ jobs: spec: '${{ matrix.spec }}' PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}' freshness_timeout_seconds: 600 - # data-plane-pod: # name: Data plane pod integration tests # runs-on: ubuntu-latest diff --git a/.github/workflows/testing-unit.yaml b/.github/workflows/testing-unit.yaml index 3574b1c2..19842b24 100644 --- a/.github/workflows/testing-unit.yaml +++ b/.github/workflows/testing-unit.yaml @@ -7,6 +7,7 @@ jobs: name: Unit tests runs-on: ubuntu-latest strategy: + fail-fast: false matrix: python-version: - 3.8 @@ -28,8 +29,11 @@ jobs: with: include_grpc: '${{ matrix.use_grpc }}' include_types: true - - name: Run unit tests + - name: Run unit tests (REST) run: poetry run pytest --cov=pinecone --timeout=120 tests/unit + - name: Run unit tests (GRPC) + if: ${{ matrix.use_grpc == true }} + run: poetry run pytest --cov=pinecone/grpc --timeout=120 tests/unit_grpc - name: mypy check env: INCLUDE_GRPC: '${{ matrix.use_grpc }}' diff --git a/.gitignore b/.gitignore index 3f605053..4200d51d 100644 --- a/.gitignore +++ b/.gitignore @@ -154,3 +154,5 @@ dmypy.json # Datasets *.hdf5 *~ + +tests/integration/proxy_config/logs \ No newline at end of file diff --git a/README.md b/README.md index 728f898b..4e93a6d5 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,10 @@ pip3 install "pinecone-client[grpc]"==3.0.0 ```shell # Install the latest version -poetry add pinecone +poetry add pinecone-client # Install the latest version, with grpc extras -poetry add pinecone --extras grpc +poetry add pinecone-client --extras grpc # Install a specific version poetry add pinecone-client==3.0.0 @@ -71,14 +71,14 @@ from pinecone import Pinecone pc = Pinecone() # This reads the PINECONE_API_KEY env var ``` -#### Using a configuration object +#### Using configuration keyword params If you prefer to pass configuration in code, for example if you have a complex application that needs to interact with multiple different Pinecone projects, the constructor accepts a keyword argument for `api_key`. If you pass configuration in this way, you can have full control over what name to use for the environment variable, sidestepping any issues that would result from two different client instances both needing to read the same `PINECONE_API_KEY` variable that the client implicitly checks for. -Configuration passed with keyword arguments takes precedent over environment variables. +Configuration passed with keyword arguments takes precedence over environment variables. ```python import os @@ -87,6 +87,81 @@ from pinecone import Pinecone pc = Pinecone(api_key=os.environ.get('CUSTOM_VAR')) ``` +### Proxy configuration + +If your network setup requires you to interact with Pinecone via a proxy, you will need +to pass additional configuration using optional keyword parameters. These optional parameters are forwarded to `urllib3`, which is the underlying library currently used by the Pinecone client to make HTTP requests. You may find it helpful to refer to the [urllib3 documentation on working with proxies](https://urllib3.readthedocs.io/en/stable/advanced-usage.html#http-and-https-proxies) while troubleshooting these settings. + +Here is a basic example: + +```python +from pinecone import Pinecone + +pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com' +) + +pc.list_indexes() +``` + +If your proxy requires authentication, you can pass those values in a header dictionary using the `proxy_headers` parameter. + +```python +from pinecone import Pinecone +import urllib3 import make_headers + +pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password') +) + +pc.list_indexes() +``` + +### Using proxies with self-signed certificates + +By default the Pinecone Python client will perform SSL certificate verification +using the CA bundle maintained by Mozilla in the [certifi](https://pypi.org/project/certifi/) package. + +If your proxy server is using a self-signed certificate, you will need to pass the path to the certificate in PEM format using the `ssl_ca_certs` parameter. + +```python +from pinecone import Pinecone +import urllib3 import make_headers + +pc = Pinecone( + api_key="YOUR_API_KEY", + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password'), + ssl_ca_certs='path/to/cert-bundle.pem' +) + +pc.list_indexes() +``` + +### Disabling SSL verification + +If you would like to disable SSL verification, you can pass the `ssl_verify` +parameter with a value of `False`. We do not recommend going to production with SSL verification disabled. + +```python +from pinecone import Pinecone +import urllib3 import make_headers + +pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password'), + ssl_ca_certs='path/to/cert-bundle.pem', + ssl_verify=False +) + +pc.list_indexes() + +``` + ### Working with GRPC (for improved performance) If you've followed instructions above to install with optional `grpc` extras, you can unlock some performance improvements by working with an alternative version of the client imported from the `pinecone.grpc` subpackage. @@ -110,9 +185,8 @@ index.query(vector=[...], top_key=10) ### Create a serverless index -> [!WARNING] -> Serverless indexes are in **public preview** and are available only on AWS in the -> `us-west-2` region. Check the [current limitations](https://docs.pinecone.io/docs/limits#serverless-index-limitations) and test thoroughly before using it in production. +The following example creates a serverless index in the `us-west-2` +region of AWS. For more information on serverless and regional availability, see [Understanding indexes](https://docs.pinecone.io/guides/indexes/understanding-indexes#serverless-indexes). ```python from pinecone import Pinecone, ServerlessSpec @@ -341,9 +415,9 @@ update_response = index.update( ## List vectors -The `list` and `list_paginated` methods can be used to list vector ids matching a particular id prefix. +The `list` and `list_paginated` methods can be used to list vector ids matching a particular id prefix. With clever assignment of vector ids, this can be used to help model hierarchical relationships between -different vectors such as when there are embeddings for multiple chunks or fragments related to the +different vectors such as when there are embeddings for multiple chunks or fragments related to the same document. The `list` method returns a generator that handles pagination on your behalf. diff --git a/pinecone/__version__ b/pinecone/__version__ index a0cd9f0c..99eba4de 100644 --- a/pinecone/__version__ +++ b/pinecone/__version__ @@ -1 +1 @@ -3.1.0 \ No newline at end of file +4.1.0 \ No newline at end of file diff --git a/pinecone/config/config.py b/pinecone/config/config.py index 9f622429..5b5f111c 100644 --- a/pinecone/config/config.py +++ b/pinecone/config/config.py @@ -5,12 +5,17 @@ from pinecone.config.openapi import OpenApiConfigFactory from pinecone.core.client.configuration import Configuration as OpenApiConfiguration from pinecone.utils import normalize_host +from pinecone.utils.constants import SOURCE_TAG class Config(NamedTuple): api_key: str = "" host: str = "" - openapi_config: Optional[OpenApiConfiguration] = None + proxy_url: Optional[str] = None + proxy_headers: Optional[Dict[str, str]] = None + ssl_ca_certs: Optional[str] = None + ssl_verify: Optional[bool] = None additional_headers: Optional[Dict[str, str]] = {} + source_tag: Optional[str] = None class ConfigBuilder: """ @@ -33,23 +38,45 @@ class ConfigBuilder: def build( api_key: Optional[str] = None, host: Optional[str] = None, - openapi_config: Optional[OpenApiConfiguration] = None, + proxy_url: Optional[str] = None, + proxy_headers: Optional[Dict[str, str]] = None, + ssl_ca_certs: Optional[str] = None, + ssl_verify: Optional[bool] = None, additional_headers: Optional[Dict[str, str]] = {}, **kwargs, ) -> Config: api_key = api_key or kwargs.pop("api_key", None) or os.getenv("PINECONE_API_KEY") host = host or kwargs.pop("host", None) host = normalize_host(host) + source_tag = kwargs.pop(SOURCE_TAG, None) if not api_key: raise PineconeConfigurationError("You haven't specified an Api-Key.") if not host: raise PineconeConfigurationError("You haven't specified a host.") - openapi_config = ( - openapi_config - or kwargs.pop("openapi_config", None) - or OpenApiConfigFactory.build(api_key=api_key, host=host) - ) + return Config(api_key, host, proxy_url, proxy_headers, ssl_ca_certs, ssl_verify, additional_headers, source_tag) + + @staticmethod + def build_openapi_config( + config: Config, openapi_config: Optional[OpenApiConfiguration] = None, **kwargs + ) -> OpenApiConfiguration: + if openapi_config: + openapi_config = OpenApiConfigFactory.copy(openapi_config=openapi_config, api_key=config.api_key, host=config.host) + elif openapi_config is None: + openapi_config = OpenApiConfigFactory.build(api_key=config.api_key, host=config.host) - return Config(api_key, host, openapi_config, additional_headers) \ No newline at end of file + # Check if value passed before overriding any values present + # in the openapi_config. This means if the user has passed + # an openapi_config object and a kwarg for the same setting, + # the kwarg will take precedence. + if (config.proxy_url): + openapi_config.proxy = config.proxy_url + if (config.proxy_headers): + openapi_config.proxy_headers = config.proxy_headers + if (config.ssl_ca_certs): + openapi_config.ssl_ca_cert = config.ssl_ca_certs + if (config.ssl_verify != None): + openapi_config.verify_ssl = config.ssl_verify + + return openapi_config \ No newline at end of file diff --git a/pinecone/config/openapi.py b/pinecone/config/openapi.py index 6c6c3c05..c8ba117a 100644 --- a/pinecone/config/openapi.py +++ b/pinecone/config/openapi.py @@ -3,6 +3,7 @@ import certifi import socket +import copy from urllib3.connection import HTTPConnection @@ -17,11 +18,34 @@ class OpenApiConfigFactory: @classmethod def build(cls, api_key: str, host: Optional[str] = None, **kwargs): openapi_config = OpenApiConfiguration() + openapi_config.api_key = {"ApiKeyAuth": api_key} openapi_config.host = host openapi_config.ssl_ca_cert = certifi.where() openapi_config.socket_options = cls._get_socket_options() - openapi_config.api_key = {"ApiKeyAuth": api_key} return openapi_config + + @classmethod + def copy(cls, openapi_config: OpenApiConfiguration, api_key: str, host: str) -> OpenApiConfiguration: + ''' + Copy a user-supplied openapi configuration and update it with the user's api key and host. + If they have not specified other socket configuration, we will use the default values. + We expect these objects are being passed mainly a vehicle for proxy configuration, so + we don't modify those settings. + ''' + copied = copy.deepcopy(openapi_config) + + copied.api_key = {"ApiKeyAuth": api_key} + copied.host = host + + # Set sensible defaults if the user hasn't set them + if not copied.socket_options: + copied.socket_options = cls._get_socket_options() + + # We specifically do not modify the user's ssl_ca_cert or proxy settings, as + # they may have set them intentionally. This is the main reason somebody would + # pass an openapi_config in the first place. + + return copied @classmethod def _get_socket_options( diff --git a/pinecone/control/langchain_import_warnings.py b/pinecone/control/langchain_import_warnings.py new file mode 100644 index 00000000..fb4a00ca --- /dev/null +++ b/pinecone/control/langchain_import_warnings.py @@ -0,0 +1,9 @@ +from pinecone.utils import docslinks + +KB_ARTICLE = docslinks['LANGCHAIN_IMPORT_KB_ARTICLE'] +GITHUB_REPO = docslinks['GITHUB_REPO'] + +def _build_langchain_attribute_error_message(method_name: str): + return f"""{method_name} is not a top-level attribute of the Pinecone class provided by pinecone's official python package developed at {GITHUB_REPO}. You may have a name collision with an export from another dependency in your project that wraps Pinecone functionality and exports a similarly named class. Please refer to the following knowledge base article for more information: {KB_ARTICLE} +""" + diff --git a/pinecone/control/pinecone.py b/pinecone/control/pinecone.py index 00a37ac8..2de6cd4e 100644 --- a/pinecone/control/pinecone.py +++ b/pinecone/control/pinecone.py @@ -1,13 +1,13 @@ import time +import warnings from typing import Optional, Dict, Any, Union, List, cast, NamedTuple from .index_host_store import IndexHostStore -from pinecone.config import PineconeConfig, Config +from pinecone.config import PineconeConfig, Config, ConfigBuilder from pinecone.core.client.api.manage_indexes_api import ManageIndexesApi -from pinecone.core.client.api_client import ApiClient -from pinecone.utils import get_user_agent, normalize_host +from pinecone.utils import normalize_host, setup_openapi_client from pinecone.core.client.models import ( CreateCollectionRequest, CreateIndexRequest, @@ -16,6 +16,7 @@ ConfigureIndexRequestSpecPod ) from pinecone.models import ServerlessSpec, PodSpec, IndexList, CollectionList +from .langchain_import_warnings import _build_langchain_attribute_error_message from pinecone.data import Index @@ -25,6 +26,10 @@ def __init__( self, api_key: Optional[str] = None, host: Optional[str] = None, + proxy_url: Optional[str] = None, + proxy_headers: Optional[Dict[str, str]] = None, + ssl_ca_certs: Optional[str] = None, + ssl_verify: Optional[bool] = None, config: Optional[Config] = None, additional_headers: Optional[Dict[str, str]] = {}, pool_threads: Optional[int] = 1, @@ -39,6 +44,14 @@ def __init__( :type api_key: str, optional :param host: The control plane host to connect to. :type host: str, optional + :param proxy_url: The URL of the proxy to use for the connection. Default: `None` + :type proxy_url: str, optional + :param proxy_headers: Additional headers to pass to the proxy. Use this if your proxy setup requires authentication. Default: `{}` + :type proxy_headers: Dict[str, str], optional + :param ssl_ca_certs: The path to the SSL CA certificate bundle to use for the connection. This path should point to a file in PEM format. Default: `None` + :type ssl_ca_certs: str, optional + :param ssl_verify: SSL verification is performed by default, but can be disabled using the boolean flag. Default: `True` + :type ssl_verify: bool, optional :param config: A `pinecone.config.Config` object. If passed, the `api_key` and `host` parameters will be ignored. :type config: pinecone.config.Config, optional :param additional_headers: Additional headers to pass to the API. Default: `{}` @@ -84,26 +97,113 @@ def __init__( request parameters to print out an equivalent curl command that you can run yourself or share with Pinecone support. **Be very careful with this option, as it will print out your API key** which forms part of a required authentication header. Default: `false` + + ### Proxy configuration + + If your network setup requires you to interact with Pinecone via a proxy, you will need + to pass additional configuration using optional keyword parameters. These optional parameters + are forwarded to `urllib3`, which is the underlying library currently used by the Pinecone client to + make HTTP requests. You may find it helpful to refer to the + [urllib3 documentation on working with proxies](https://urllib3.readthedocs.io/en/stable/advanced-usage.html#http-and-https-proxies) + while troubleshooting these settings. + + Here is a basic example: + + ```python + from pinecone import Pinecone + + pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com' + ) + + pc.list_indexes() + ``` + + If your proxy requires authentication, you can pass those values in a header dictionary using the `proxy_headers` parameter. + + ```python + from pinecone import Pinecone + import urllib3 import make_headers + + pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password') + ) + + pc.list_indexes() + ``` + + ### Using proxies with self-signed certificates + + By default the Pinecone Python client will perform SSL certificate verification + using the CA bundle maintained by Mozilla in the [certifi](https://pypi.org/project/certifi/) package. + If your proxy server is using a self-signed certificate, you will need to pass the path to the certificate + in PEM format using the `ssl_ca_certs` parameter. + + ```python + from pinecone import Pinecone + import urllib3 import make_headers + + pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password'), + ssl_ca_certs='path/to/cert-bundle.pem' + ) + + pc.list_indexes() + ``` + + ### Disabling SSL verification + + If you would like to disable SSL verification, you can pass the `ssl_verify` + parameter with a value of `False`. We do not recommend going to production with SSL verification disabled. + + ```python + from pinecone import Pinecone + import urllib3 import make_headers + + pc = Pinecone( + api_key='YOUR_API_KEY', + proxy_url='https://your-proxy.com', + proxy_headers=make_headers(proxy_basic_auth='username:password'), + ssl_ca_certs='path/to/cert-bundle.pem', + ssl_verify=False + ) + + pc.list_indexes() + + ``` """ - if config or kwargs.get("config"): - configKwarg = config or kwargs.get("config") - if not isinstance(configKwarg, Config): + if config: + if not isinstance(config, Config): raise TypeError("config must be of type pinecone.config.Config") else: - self.config = configKwarg + self.config = config else: - self.config = PineconeConfig.build(api_key=api_key, host=host, additional_headers=additional_headers, **kwargs) + self.config = PineconeConfig.build( + api_key=api_key, + host=host, + additional_headers=additional_headers, + proxy_url=proxy_url, + proxy_headers=proxy_headers, + ssl_ca_certs=ssl_ca_certs, + ssl_verify=ssl_verify, + **kwargs + ) + if kwargs.get("openapi_config", None): + warnings.warn("Passing openapi_config is deprecated and will be removed in a future release. Please pass settings such as proxy_url, proxy_headers, ssl_ca_certs, and ssl_verify directly to the Pinecone constructor as keyword arguments. See the README at https://github.com/pinecone-io/pinecone-python-client for examples.", DeprecationWarning) + + self.openapi_config = ConfigBuilder.build_openapi_config(self.config, **kwargs) self.pool_threads = pool_threads + if index_api: self.index_api = index_api else: - api_client = ApiClient(configuration=self.config.openapi_config, pool_threads=self.pool_threads) - api_client.user_agent = get_user_agent() - extra_headers = self.config.additional_headers or {} - for key, value in extra_headers.items(): - api_client.set_default_header(key, value) - self.index_api = ManageIndexesApi(api_client) + self.index_api = setup_openapi_client(ManageIndexesApi, self.config, self.openapi_config, pool_threads) self.index_host_store = IndexHostStore() """ @private """ @@ -446,6 +546,13 @@ def _get_status(self, name: str): response = api_instance.describe_index(name) return response["status"] + @staticmethod + def from_texts(*args, **kwargs): + raise AttributeError(_build_langchain_attribute_error_message("from_texts")) + + @staticmethod + def from_documents(*args, **kwargs): + raise AttributeError(_build_langchain_attribute_error_message("from_documents")) def Index(self, name: str = '', host: str = '', **kwargs): """ @@ -521,12 +628,21 @@ def Index(self, name: str = '', host: str = '', **kwargs): raise ValueError("Either name or host must be specified") pt = kwargs.pop('pool_threads', None) or self.pool_threads + api_key = self.config.api_key + openapi_config = self.openapi_config if host != '': # Use host url if it is provided - return Index(api_key=self.config.api_key, host=normalize_host(host), pool_threads=pt, **kwargs) - - if name != '': + index_host=normalize_host(host) + else: # Otherwise, get host url from describe_index using the index name index_host = self.index_host_store.get_host(self.index_api, self.config, name) - return Index(api_key=self.config.api_key, host=index_host, pool_threads=pt, **kwargs) + + return Index( + host=index_host, + api_key=api_key, + pool_threads=pt, + openapi_config=openapi_config, + source_tag=self.config.source_tag, + **kwargs + ) \ No newline at end of file diff --git a/pinecone/core/grpc/protos/vector_service_pb2.py b/pinecone/core/grpc/protos/vector_service_pb2.py index 6982eab5..01997dfa 100644 --- a/pinecone/core/grpc/protos/vector_service_pb2.py +++ b/pinecone/core/grpc/protos/vector_service_pb2.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vector_service.proto +# Protobuf Python Version: 4.25.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection +from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -17,1630 +18,190 @@ from protoc_gen_openapiv2.options import annotations_pb2 as protoc__gen__openapiv2_dot_options_dot_annotations__pb2 -DESCRIPTOR = _descriptor.FileDescriptor( - name='vector_service.proto', - package='', - syntax='proto3', - serialized_options=b'\n\021io.pinecone.protoP\001Z+github.com/pinecone-io/go-pinecone/pinecone\222A\311\002\022K\n\014Pinecone API\";\n\017Pinecone.io Ops\022\023https://pinecone.io\032\023support@pinecone.io\032\014{index_host}*\001\0022\020application/json:\020application/jsonZx\nv\n\nApiKeyAuth\022h\010\002\022YAn API Key is required to call Pinecone APIs. Get yours at https://www.pinecone.io/start/\032\007Api-Key \002b\020\n\016\n\nApiKeyAuth\022\000r9\n\031More Pinecone.io API docs\022\034https://www.pinecone.io/docs', - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x14vector_service.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"~\n\x0cSparseValues\x12\x35\n\x07indices\x18\x01 \x03(\rB$\x92\x41\x1eJ\x16[1, 312, 822, 14, 980]x\xe8\x07\x80\x01\x01\xe0\x41\x02\x12\x37\n\x06values\x18\x02 \x03(\x02\x42\'\x92\x41!J\x19[0.1, 0.2, 0.3, 0.4, 0.5]x\xe8\x07\x80\x01\x01\xe0\x41\x02\"\xfd\x01\n\x06Vector\x12,\n\x02id\x18\x01 \x01(\tB \x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe0\x41\x02\x12G\n\x06values\x18\x02 \x03(\x02\x42\x37\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\xe0\x41\x02\x12$\n\rsparse_values\x18\x04 \x01(\x0b\x32\r.SparseValues\x12V\n\x08metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\"\x93\x02\n\x0cScoredVector\x12,\n\x02id\x18\x01 \x01(\tB \x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe0\x41\x02\x12\x18\n\x05score\x18\x02 \x01(\x02\x42\t\x92\x41\x06J\x04\x30.08\x12=\n\x06values\x18\x03 \x03(\x02\x42-\x92\x41*J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12V\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\"\x89\x01\n\x0cRequestUnion\x12 \n\x06upsert\x18\x01 \x01(\x0b\x32\x0e.UpsertRequestH\x00\x12 \n\x06\x64\x65lete\x18\x02 \x01(\x0b\x32\x0e.DeleteRequestH\x00\x12 \n\x06update\x18\x03 \x01(\x0b\x32\x0e.UpdateRequestH\x00\x42\x13\n\x11RequestUnionInner\"d\n\rUpsertRequest\x12&\n\x07vectors\x18\x01 \x03(\x0b\x32\x07.VectorB\x0c\x92\x41\x06x\xe8\x07\x80\x01\x01\xe0\x41\x02\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"1\n\x0eUpsertResponse\x12\x1f\n\x0eupserted_count\x18\x01 \x01(\rB\x07\x92\x41\x04J\x02\x31\x30\"\xb6\x01\n\rDeleteRequest\x12(\n\x03ids\x18\x01 \x03(\tB\x1b\x92\x41\x18J\x10[\"id-0\", \"id-1\"]x\xe8\x07\x80\x01\x01\x12%\n\ndelete_all\x18\x02 \x01(\x08\x42\x11\x92\x41\x0e:\x05\x66\x61lseJ\x05\x66\x61lse\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\'\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"\x10\n\x0e\x44\x65leteResponse\"h\n\x0c\x46\x65tchRequest\x12+\n\x03ids\x18\x01 \x03(\tB\x1e\x92\x41\x18J\x10[\"id-0\", \"id-1\"]x\xe8\x07\x80\x01\x01\xe0\x41\x02\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\xe1\x01\n\rFetchResponse\x12,\n\x07vectors\x18\x01 \x03(\x0b\x32\x1b.FetchResponse.VectorsEntry\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\x32\n\x05usage\x18\x03 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 5}H\x00\x88\x01\x01\x1a\x37\n\x0cVectorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x05value\x18\x02 \x01(\x0b\x32\x07.Vector:\x02\x38\x01\x42\x08\n\x06_usage\"\xf8\x01\n\x0bListRequest\x12,\n\x06prefix\x18\x01 \x01(\tB\x17\x92\x41\x14J\x0c\"document1#\"x\xe8\x07\x80\x01\x01H\x00\x88\x01\x01\x12 \n\x05limit\x18\x02 \x01(\rB\x0c\x92\x41\t:\x03\x31\x30\x30J\x02\x31\x32H\x01\x88\x01\x01\x12\x42\n\x10pagination_token\x18\x03 \x01(\tB#\x92\x41 J\x1e\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"H\x02\x88\x01\x01\x12+\n\tnamespace\x18\x04 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"B\t\n\x07_prefixB\x08\n\x06_limitB\x13\n\x11_pagination_token\"?\n\nPagination\x12\x31\n\x04next\x18\x01 \x01(\tB#\x92\x41 J\x1e\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"\",\n\x08ListItem\x12 \n\x02id\x18\x01 \x01(\tB\x14\x92\x41\x11J\x0f\"document1#abb\"\"\x83\x02\n\x0cListResponse\x12S\n\x07vectors\x18\x01 \x03(\x0b\x32\t.ListItemB7\x92\x41\x34J2[{\"id\": \"document1#abb\"}, {\"id\": \"document1#abc\"}]\x12$\n\npagination\x18\x02 \x01(\x0b\x32\x0b.PaginationH\x00\x88\x01\x01\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\x32\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 1}H\x01\x88\x01\x01\x42\r\n\x0b_paginationB\x08\n\x06_usage\"\xd0\x02\n\x0bQueryVector\x12G\n\x06values\x18\x01 \x03(\x02\x42\x37\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\xe0\x41\x02\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12(\n\x05top_k\x18\x02 \x01(\rB\x19\x92\x41\x16J\x02\x31\x30Y\x00\x00\x00\x00\x00\x88\xc3@i\x00\x00\x00\x00\x00\x00\xf0?\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12{\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructBR\x92\x41OJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}\"\xfa\x03\n\x0cQueryRequest\x12+\n\tnamespace\x18\x01 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12+\n\x05top_k\x18\x02 \x01(\rB\x1c\x92\x41\x16J\x02\x31\x30Y\x00\x00\x00\x00\x00\x88\xc3@i\x00\x00\x00\x00\x00\x00\xf0?\xe0\x41\x02\x12{\n\x06\x66ilter\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructBR\x92\x41OJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}\x12(\n\x0einclude_values\x18\x04 \x01(\x08\x42\x10\x92\x41\r:\x05\x66\x61lseJ\x04true\x12*\n\x10include_metadata\x18\x05 \x01(\x08\x42\x10\x92\x41\r:\x05\x66\x61lseJ\x04true\x12)\n\x07queries\x18\x06 \x03(\x0b\x32\x0c.QueryVectorB\n\x18\x01\x92\x41\x05x\n\x80\x01\x01\x12\x44\n\x06vector\x18\x07 \x03(\x02\x42\x34\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\x12$\n\rsparse_vector\x18\t \x01(\x0b\x32\r.SparseValues\x12&\n\x02id\x18\x08 \x01(\tB\x1a\x92\x41\x17J\x12\"example-vector-1\"x\x80\x04\"a\n\x12SingleQueryResults\x12\x1e\n\x07matches\x18\x01 \x03(\x0b\x32\r.ScoredVector\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\xaa\x01\n\rQueryResponse\x12(\n\x07results\x18\x01 \x03(\x0b\x32\x13.SingleQueryResultsB\x02\x18\x01\x12\x1e\n\x07matches\x18\x02 \x03(\x0b\x32\r.ScoredVector\x12\x11\n\tnamespace\x18\x03 \x01(\t\x12\x32\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 5}H\x00\x88\x01\x01\x42\x08\n\x06_usage\"7\n\x05Usage\x12\x1f\n\nread_units\x18\x01 \x01(\rB\x06\x92\x41\x03J\x01\x35H\x00\x88\x01\x01\x42\r\n\x0b_read_units\"\xb2\x02\n\rUpdateRequest\x12,\n\x02id\x18\x01 \x01(\tB \x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe0\x41\x02\x12\x44\n\x06values\x18\x02 \x03(\x02\x42\x34\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12Z\n\x0cset_metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\x12+\n\tnamespace\x18\x04 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\x10\n\x0eUpdateResponse\"D\n\x19\x44\x65scribeIndexStatsRequest\x12\'\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\"4\n\x10NamespaceSummary\x12 \n\x0cvector_count\x18\x01 \x01(\rB\n\x92\x41\x07J\x05\x35\x30\x30\x30\x30\"\x9a\x03\n\x1a\x44\x65scribeIndexStatsResponse\x12?\n\nnamespaces\x18\x01 \x03(\x0b\x32+.DescribeIndexStatsResponse.NamespacesEntry\x12\x1c\n\tdimension\x18\x02 \x01(\rB\t\x92\x41\x06J\x04\x31\x30\x32\x34\x12 \n\x0eindex_fullness\x18\x03 \x01(\x02\x42\x08\x92\x41\x05J\x03\x30.4\x12&\n\x12total_vector_count\x18\x04 \x01(\rB\n\x92\x41\x07J\x05\x38\x30\x30\x30\x30\x1a\x44\n\x0fNamespacesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.NamespaceSummary:\x02\x38\x01:\x8c\x01\x92\x41\x88\x01\x32\x85\x01{\"namespaces\": {\"\": {\"vectorCount\": 50000}, \"example-namespace-2\": {\"vectorCount\": 30000}}, \"dimension\": 1024, \"index_fullness\": 0.4}2\x95\x06\n\rVectorService\x12\x63\n\x06Upsert\x12\x0e.UpsertRequest\x1a\x0f.UpsertResponse\"8\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/upsert:\x01*\x92\x41\x1b\n\x11Vector Operations*\x06upsert\x12v\n\x06\x44\x65lete\x12\x0e.DeleteRequest\x1a\x0f.DeleteResponse\"K\x82\xd3\xe4\x93\x02\'\"\x0f/vectors/delete:\x01*Z\x11*\x0f/vectors/delete\x92\x41\x1b\n\x11Vector Operations*\x06\x64\x65lete\x12[\n\x05\x46\x65tch\x12\r.FetchRequest\x1a\x0e.FetchResponse\"3\x82\xd3\xe4\x93\x02\x10\x12\x0e/vectors/fetch\x92\x41\x1a\n\x11Vector Operations*\x05\x66\x65tch\x12V\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"1\x82\xd3\xe4\x93\x02\x0f\x12\r/vectors/list\x92\x41\x19\n\x11Vector Operations*\x04list\x12V\n\x05Query\x12\r.QueryRequest\x1a\x0e.QueryResponse\".\x82\xd3\xe4\x93\x02\x0b\"\x06/query:\x01*\x92\x41\x1a\n\x11Vector Operations*\x05query\x12\x63\n\x06Update\x12\x0e.UpdateRequest\x1a\x0f.UpdateResponse\"8\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/update:\x01*\x92\x41\x1b\n\x11Vector Operations*\x06update\x12\xb4\x01\n\x12\x44\x65scribeIndexStats\x12\x1a.DescribeIndexStatsRequest\x1a\x1b.DescribeIndexStatsResponse\"e\x82\xd3\xe4\x93\x02\x33\"\x15/describe_index_stats:\x01*Z\x17\x12\x15/describe_index_stats\x92\x41)\n\x11Vector Operations*\x14\x64\x65scribe_index_statsB\x8f\x03\n\x11io.pinecone.protoP\x01Z+github.com/pinecone-io/go-pinecone/pinecone\x92\x41\xc9\x02\x12K\n\x0cPinecone API\";\n\x0fPinecone.io Ops\x12\x13https://pinecone.io\x1a\x13support@pinecone.io\x1a\x0c{index_host}*\x01\x02\x32\x10\x61pplication/json:\x10\x61pplication/jsonZx\nv\n\nApiKeyAuth\x12h\x08\x02\x12YAn API Key is required to call Pinecone APIs. Get yours at https://www.pinecone.io/start/\x1a\x07\x41pi-Key \x02\x62\x10\n\x0e\n\nApiKeyAuth\x12\x00r9\n\x19More Pinecone.io API docs\x12\x1chttps://www.pinecone.io/docsb\x06proto3' - , - dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_api_dot_field__behavior__pb2.DESCRIPTOR,protoc__gen__openapiv2_dot_options_dot_annotations__pb2.DESCRIPTOR,]) - - - - -_SPARSEVALUES = _descriptor.Descriptor( - name='SparseValues', - full_name='SparseValues', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='indices', full_name='SparseValues.indices', index=0, - number=1, type=13, cpp_type=3, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\036J\026[1, 312, 822, 14, 980]x\350\007\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='values', full_name='SparseValues.values', index=1, - number=2, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A!J\031[0.1, 0.2, 0.3, 0.4, 0.5]x\350\007\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=165, - serialized_end=291, -) - - -_VECTOR = _descriptor.Descriptor( - name='Vector', - full_name='Vector', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='Vector.id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='values', full_name='Vector.values', index=1, - number=2, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sparse_values', full_name='Vector.sparse_values', index=2, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='metadata', full_name='Vector.metadata', index=3, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=294, - serialized_end=547, -) - - -_SCOREDVECTOR = _descriptor.Descriptor( - name='ScoredVector', - full_name='ScoredVector', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='ScoredVector.id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='score', full_name='ScoredVector.score', index=1, - number=2, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\006J\0040.08', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='values', full_name='ScoredVector.values', index=2, - number=3, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A*J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sparse_values', full_name='ScoredVector.sparse_values', index=3, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='metadata', full_name='ScoredVector.metadata', index=4, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=550, - serialized_end=825, -) - - -_REQUESTUNION = _descriptor.Descriptor( - name='RequestUnion', - full_name='RequestUnion', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='upsert', full_name='RequestUnion.upsert', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='delete', full_name='RequestUnion.delete', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='update', full_name='RequestUnion.update', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='RequestUnionInner', full_name='RequestUnion.RequestUnionInner', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=828, - serialized_end=965, -) - - -_UPSERTREQUEST = _descriptor.Descriptor( - name='UpsertRequest', - full_name='UpsertRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='vectors', full_name='UpsertRequest.vectors', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\006x\350\007\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='UpsertRequest.namespace', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=967, - serialized_end=1067, -) - - -_UPSERTRESPONSE = _descriptor.Descriptor( - name='UpsertResponse', - full_name='UpsertResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='upserted_count', full_name='UpsertResponse.upserted_count', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\004J\00210', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1069, - serialized_end=1118, -) - - -_DELETEREQUEST = _descriptor.Descriptor( - name='DeleteRequest', - full_name='DeleteRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ids', full_name='DeleteRequest.ids', index=0, - number=1, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\030J\020[\"id-0\", \"id-1\"]x\350\007\200\001\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='delete_all', full_name='DeleteRequest.delete_all', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\016:\005falseJ\005false', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='DeleteRequest.namespace', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='filter', full_name='DeleteRequest.filter', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1121, - serialized_end=1303, -) - - -_DELETERESPONSE = _descriptor.Descriptor( - name='DeleteResponse', - full_name='DeleteResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1305, - serialized_end=1321, -) - - -_FETCHREQUEST = _descriptor.Descriptor( - name='FetchRequest', - full_name='FetchRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ids', full_name='FetchRequest.ids', index=0, - number=1, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\030J\020[\"id-0\", \"id-1\"]x\350\007\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='FetchRequest.namespace', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1323, - serialized_end=1427, -) - - -_FETCHRESPONSE_VECTORSENTRY = _descriptor.Descriptor( - name='VectorsEntry', - full_name='FetchResponse.VectorsEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='FetchResponse.VectorsEntry.key', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='FetchResponse.VectorsEntry.value', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=b'8\001', - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1590, - serialized_end=1645, -) - -_FETCHRESPONSE = _descriptor.Descriptor( - name='FetchResponse', - full_name='FetchResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='vectors', full_name='FetchResponse.vectors', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='FetchResponse.namespace', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='usage', full_name='FetchResponse.usage', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\023J\021{\"read_units\": 5}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_FETCHRESPONSE_VECTORSENTRY, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='_usage', full_name='FetchResponse._usage', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=1430, - serialized_end=1655, -) - - -_LISTREQUEST = _descriptor.Descriptor( - name='ListRequest', - full_name='ListRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='prefix', full_name='ListRequest.prefix', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\024J\014\"document1#\"x\350\007\200\001\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='limit', full_name='ListRequest.limit', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\t:\003100J\00212', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='pagination_token', full_name='ListRequest.pagination_token', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A J\036\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='ListRequest.namespace', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='_prefix', full_name='ListRequest._prefix', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - _descriptor.OneofDescriptor( - name='_limit', full_name='ListRequest._limit', - index=1, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - _descriptor.OneofDescriptor( - name='_pagination_token', full_name='ListRequest._pagination_token', - index=2, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=1658, - serialized_end=1906, -) - - -_PAGINATION = _descriptor.Descriptor( - name='Pagination', - full_name='Pagination', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='next', full_name='Pagination.next', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A J\036\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1908, - serialized_end=1971, -) - - -_LISTITEM = _descriptor.Descriptor( - name='ListItem', - full_name='ListItem', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='ListItem.id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\021J\017\"document1#abb\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=1973, - serialized_end=2017, -) - - -_LISTRESPONSE = _descriptor.Descriptor( - name='ListResponse', - full_name='ListResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='vectors', full_name='ListResponse.vectors', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A4J2[{\"id\": \"document1#abb\"}, {\"id\": \"document1#abc\"}]', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='pagination', full_name='ListResponse.pagination', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='ListResponse.namespace', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='usage', full_name='ListResponse.usage', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\023J\021{\"read_units\": 1}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='_pagination', full_name='ListResponse._pagination', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - _descriptor.OneofDescriptor( - name='_usage', full_name='ListResponse._usage', - index=1, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=2020, - serialized_end=2279, -) - - -_QUERYVECTOR = _descriptor.Descriptor( - name='QueryVector', - full_name='QueryVector', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='values', full_name='QueryVector.values', index=0, - number=1, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sparse_values', full_name='QueryVector.sparse_values', index=1, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='top_k', full_name='QueryVector.top_k', index=2, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\026J\00210Y\000\000\000\000\000\210\303@i\000\000\000\000\000\000\360?', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='QueryVector.namespace', index=3, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='filter', full_name='QueryVector.filter', index=4, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222AOJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2282, - serialized_end=2618, -) - - -_QUERYREQUEST = _descriptor.Descriptor( - name='QueryRequest', - full_name='QueryRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='namespace', full_name='QueryRequest.namespace', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='top_k', full_name='QueryRequest.top_k', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\026J\00210Y\000\000\000\000\000\210\303@i\000\000\000\000\000\000\360?\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='filter', full_name='QueryRequest.filter', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222AOJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='include_values', full_name='QueryRequest.include_values', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\r:\005falseJ\004true', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='include_metadata', full_name='QueryRequest.include_metadata', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\r:\005falseJ\004true', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='queries', full_name='QueryRequest.queries', index=5, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001\222A\005x\n\200\001\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='vector', full_name='QueryRequest.vector', index=6, - number=7, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sparse_vector', full_name='QueryRequest.sparse_vector', index=7, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='id', full_name='QueryRequest.id', index=8, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\027J\022\"example-vector-1\"x\200\004', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=2621, - serialized_end=3127, -) - - -_SINGLEQUERYRESULTS = _descriptor.Descriptor( - name='SingleQueryResults', - full_name='SingleQueryResults', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='matches', full_name='SingleQueryResults.matches', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='SingleQueryResults.namespace', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3129, - serialized_end=3226, -) - - -_QUERYRESPONSE = _descriptor.Descriptor( - name='QueryResponse', - full_name='QueryResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='results', full_name='QueryResponse.results', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='matches', full_name='QueryResponse.matches', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='QueryResponse.namespace', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='usage', full_name='QueryResponse.usage', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\023J\021{\"read_units\": 5}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='_usage', full_name='QueryResponse._usage', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=3229, - serialized_end=3399, -) - - -_USAGE = _descriptor.Descriptor( - name='Usage', - full_name='Usage', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='read_units', full_name='Usage.read_units', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\003J\0015', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='_read_units', full_name='Usage._read_units', - index=0, containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[]), - ], - serialized_start=3401, - serialized_end=3456, -) - - -_UPDATEREQUEST = _descriptor.Descriptor( - name='UpdateRequest', - full_name='UpdateRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='UpdateRequest.id', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\340A\002', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='values', full_name='UpdateRequest.values', index=1, - number=2, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='sparse_values', full_name='UpdateRequest.sparse_values', index=2, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='set_metadata', full_name='UpdateRequest.set_metadata', index=3, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='namespace', full_name='UpdateRequest.namespace', index=4, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\025J\023\"example-namespace\"', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3459, - serialized_end=3765, -) - - -_UPDATERESPONSE = _descriptor.Descriptor( - name='UpdateResponse', - full_name='UpdateResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3767, - serialized_end=3783, -) - - -_DESCRIBEINDEXSTATSREQUEST = _descriptor.Descriptor( - name='DescribeIndexStatsRequest', - full_name='DescribeIndexStatsRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='filter', full_name='DescribeIndexStatsRequest.filter', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3785, - serialized_end=3853, -) - - -_NAMESPACESUMMARY = _descriptor.Descriptor( - name='NamespaceSummary', - full_name='NamespaceSummary', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='vector_count', full_name='NamespaceSummary.vector_count', index=0, - number=1, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\007J\00550000', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3855, - serialized_end=3907, -) - - -_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY = _descriptor.Descriptor( - name='NamespacesEntry', - full_name='DescribeIndexStatsResponse.NamespacesEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='DescribeIndexStatsResponse.NamespacesEntry.key', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='DescribeIndexStatsResponse.NamespacesEntry.value', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=b'8\001', - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=4109, - serialized_end=4177, -) - -_DESCRIBEINDEXSTATSRESPONSE = _descriptor.Descriptor( - name='DescribeIndexStatsResponse', - full_name='DescribeIndexStatsResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='namespaces', full_name='DescribeIndexStatsResponse.namespaces', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='dimension', full_name='DescribeIndexStatsResponse.dimension', index=1, - number=2, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\006J\0041024', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='index_fullness', full_name='DescribeIndexStatsResponse.index_fullness', index=2, - number=3, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\005J\0030.4', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='total_vector_count', full_name='DescribeIndexStatsResponse.total_vector_count', index=3, - number=4, type=13, cpp_type=3, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\222A\007J\00580000', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY, ], - enum_types=[ - ], - serialized_options=b'\222A\210\0012\205\001{\"namespaces\": {\"\": {\"vectorCount\": 50000}, \"example-namespace-2\": {\"vectorCount\": 30000}}, \"dimension\": 1024, \"index_fullness\": 0.4}', - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=3910, - serialized_end=4320, -) - -_VECTOR.fields_by_name['sparse_values'].message_type = _SPARSEVALUES -_VECTOR.fields_by_name['metadata'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_SCOREDVECTOR.fields_by_name['sparse_values'].message_type = _SPARSEVALUES -_SCOREDVECTOR.fields_by_name['metadata'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_REQUESTUNION.fields_by_name['upsert'].message_type = _UPSERTREQUEST -_REQUESTUNION.fields_by_name['delete'].message_type = _DELETEREQUEST -_REQUESTUNION.fields_by_name['update'].message_type = _UPDATEREQUEST -_REQUESTUNION.oneofs_by_name['RequestUnionInner'].fields.append( - _REQUESTUNION.fields_by_name['upsert']) -_REQUESTUNION.fields_by_name['upsert'].containing_oneof = _REQUESTUNION.oneofs_by_name['RequestUnionInner'] -_REQUESTUNION.oneofs_by_name['RequestUnionInner'].fields.append( - _REQUESTUNION.fields_by_name['delete']) -_REQUESTUNION.fields_by_name['delete'].containing_oneof = _REQUESTUNION.oneofs_by_name['RequestUnionInner'] -_REQUESTUNION.oneofs_by_name['RequestUnionInner'].fields.append( - _REQUESTUNION.fields_by_name['update']) -_REQUESTUNION.fields_by_name['update'].containing_oneof = _REQUESTUNION.oneofs_by_name['RequestUnionInner'] -_UPSERTREQUEST.fields_by_name['vectors'].message_type = _VECTOR -_DELETEREQUEST.fields_by_name['filter'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_FETCHRESPONSE_VECTORSENTRY.fields_by_name['value'].message_type = _VECTOR -_FETCHRESPONSE_VECTORSENTRY.containing_type = _FETCHRESPONSE -_FETCHRESPONSE.fields_by_name['vectors'].message_type = _FETCHRESPONSE_VECTORSENTRY -_FETCHRESPONSE.fields_by_name['usage'].message_type = _USAGE -_FETCHRESPONSE.oneofs_by_name['_usage'].fields.append( - _FETCHRESPONSE.fields_by_name['usage']) -_FETCHRESPONSE.fields_by_name['usage'].containing_oneof = _FETCHRESPONSE.oneofs_by_name['_usage'] -_LISTREQUEST.oneofs_by_name['_prefix'].fields.append( - _LISTREQUEST.fields_by_name['prefix']) -_LISTREQUEST.fields_by_name['prefix'].containing_oneof = _LISTREQUEST.oneofs_by_name['_prefix'] -_LISTREQUEST.oneofs_by_name['_limit'].fields.append( - _LISTREQUEST.fields_by_name['limit']) -_LISTREQUEST.fields_by_name['limit'].containing_oneof = _LISTREQUEST.oneofs_by_name['_limit'] -_LISTREQUEST.oneofs_by_name['_pagination_token'].fields.append( - _LISTREQUEST.fields_by_name['pagination_token']) -_LISTREQUEST.fields_by_name['pagination_token'].containing_oneof = _LISTREQUEST.oneofs_by_name['_pagination_token'] -_LISTRESPONSE.fields_by_name['vectors'].message_type = _LISTITEM -_LISTRESPONSE.fields_by_name['pagination'].message_type = _PAGINATION -_LISTRESPONSE.fields_by_name['usage'].message_type = _USAGE -_LISTRESPONSE.oneofs_by_name['_pagination'].fields.append( - _LISTRESPONSE.fields_by_name['pagination']) -_LISTRESPONSE.fields_by_name['pagination'].containing_oneof = _LISTRESPONSE.oneofs_by_name['_pagination'] -_LISTRESPONSE.oneofs_by_name['_usage'].fields.append( - _LISTRESPONSE.fields_by_name['usage']) -_LISTRESPONSE.fields_by_name['usage'].containing_oneof = _LISTRESPONSE.oneofs_by_name['_usage'] -_QUERYVECTOR.fields_by_name['sparse_values'].message_type = _SPARSEVALUES -_QUERYVECTOR.fields_by_name['filter'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_QUERYREQUEST.fields_by_name['filter'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_QUERYREQUEST.fields_by_name['queries'].message_type = _QUERYVECTOR -_QUERYREQUEST.fields_by_name['sparse_vector'].message_type = _SPARSEVALUES -_SINGLEQUERYRESULTS.fields_by_name['matches'].message_type = _SCOREDVECTOR -_QUERYRESPONSE.fields_by_name['results'].message_type = _SINGLEQUERYRESULTS -_QUERYRESPONSE.fields_by_name['matches'].message_type = _SCOREDVECTOR -_QUERYRESPONSE.fields_by_name['usage'].message_type = _USAGE -_QUERYRESPONSE.oneofs_by_name['_usage'].fields.append( - _QUERYRESPONSE.fields_by_name['usage']) -_QUERYRESPONSE.fields_by_name['usage'].containing_oneof = _QUERYRESPONSE.oneofs_by_name['_usage'] -_USAGE.oneofs_by_name['_read_units'].fields.append( - _USAGE.fields_by_name['read_units']) -_USAGE.fields_by_name['read_units'].containing_oneof = _USAGE.oneofs_by_name['_read_units'] -_UPDATEREQUEST.fields_by_name['sparse_values'].message_type = _SPARSEVALUES -_UPDATEREQUEST.fields_by_name['set_metadata'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_DESCRIBEINDEXSTATSREQUEST.fields_by_name['filter'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT -_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY.fields_by_name['value'].message_type = _NAMESPACESUMMARY -_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY.containing_type = _DESCRIBEINDEXSTATSRESPONSE -_DESCRIBEINDEXSTATSRESPONSE.fields_by_name['namespaces'].message_type = _DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY -DESCRIPTOR.message_types_by_name['SparseValues'] = _SPARSEVALUES -DESCRIPTOR.message_types_by_name['Vector'] = _VECTOR -DESCRIPTOR.message_types_by_name['ScoredVector'] = _SCOREDVECTOR -DESCRIPTOR.message_types_by_name['RequestUnion'] = _REQUESTUNION -DESCRIPTOR.message_types_by_name['UpsertRequest'] = _UPSERTREQUEST -DESCRIPTOR.message_types_by_name['UpsertResponse'] = _UPSERTRESPONSE -DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST -DESCRIPTOR.message_types_by_name['DeleteResponse'] = _DELETERESPONSE -DESCRIPTOR.message_types_by_name['FetchRequest'] = _FETCHREQUEST -DESCRIPTOR.message_types_by_name['FetchResponse'] = _FETCHRESPONSE -DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST -DESCRIPTOR.message_types_by_name['Pagination'] = _PAGINATION -DESCRIPTOR.message_types_by_name['ListItem'] = _LISTITEM -DESCRIPTOR.message_types_by_name['ListResponse'] = _LISTRESPONSE -DESCRIPTOR.message_types_by_name['QueryVector'] = _QUERYVECTOR -DESCRIPTOR.message_types_by_name['QueryRequest'] = _QUERYREQUEST -DESCRIPTOR.message_types_by_name['SingleQueryResults'] = _SINGLEQUERYRESULTS -DESCRIPTOR.message_types_by_name['QueryResponse'] = _QUERYRESPONSE -DESCRIPTOR.message_types_by_name['Usage'] = _USAGE -DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST -DESCRIPTOR.message_types_by_name['UpdateResponse'] = _UPDATERESPONSE -DESCRIPTOR.message_types_by_name['DescribeIndexStatsRequest'] = _DESCRIBEINDEXSTATSREQUEST -DESCRIPTOR.message_types_by_name['NamespaceSummary'] = _NAMESPACESUMMARY -DESCRIPTOR.message_types_by_name['DescribeIndexStatsResponse'] = _DESCRIBEINDEXSTATSRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -SparseValues = _reflection.GeneratedProtocolMessageType('SparseValues', (_message.Message,), { - 'DESCRIPTOR' : _SPARSEVALUES, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:SparseValues) - }) -_sym_db.RegisterMessage(SparseValues) - -Vector = _reflection.GeneratedProtocolMessageType('Vector', (_message.Message,), { - 'DESCRIPTOR' : _VECTOR, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:Vector) - }) -_sym_db.RegisterMessage(Vector) - -ScoredVector = _reflection.GeneratedProtocolMessageType('ScoredVector', (_message.Message,), { - 'DESCRIPTOR' : _SCOREDVECTOR, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:ScoredVector) - }) -_sym_db.RegisterMessage(ScoredVector) - -RequestUnion = _reflection.GeneratedProtocolMessageType('RequestUnion', (_message.Message,), { - 'DESCRIPTOR' : _REQUESTUNION, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:RequestUnion) - }) -_sym_db.RegisterMessage(RequestUnion) - -UpsertRequest = _reflection.GeneratedProtocolMessageType('UpsertRequest', (_message.Message,), { - 'DESCRIPTOR' : _UPSERTREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:UpsertRequest) - }) -_sym_db.RegisterMessage(UpsertRequest) - -UpsertResponse = _reflection.GeneratedProtocolMessageType('UpsertResponse', (_message.Message,), { - 'DESCRIPTOR' : _UPSERTRESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:UpsertResponse) - }) -_sym_db.RegisterMessage(UpsertResponse) - -DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_message.Message,), { - 'DESCRIPTOR' : _DELETEREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:DeleteRequest) - }) -_sym_db.RegisterMessage(DeleteRequest) - -DeleteResponse = _reflection.GeneratedProtocolMessageType('DeleteResponse', (_message.Message,), { - 'DESCRIPTOR' : _DELETERESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:DeleteResponse) - }) -_sym_db.RegisterMessage(DeleteResponse) - -FetchRequest = _reflection.GeneratedProtocolMessageType('FetchRequest', (_message.Message,), { - 'DESCRIPTOR' : _FETCHREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:FetchRequest) - }) -_sym_db.RegisterMessage(FetchRequest) - -FetchResponse = _reflection.GeneratedProtocolMessageType('FetchResponse', (_message.Message,), { - - 'VectorsEntry' : _reflection.GeneratedProtocolMessageType('VectorsEntry', (_message.Message,), { - 'DESCRIPTOR' : _FETCHRESPONSE_VECTORSENTRY, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:FetchResponse.VectorsEntry) - }) - , - 'DESCRIPTOR' : _FETCHRESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:FetchResponse) - }) -_sym_db.RegisterMessage(FetchResponse) -_sym_db.RegisterMessage(FetchResponse.VectorsEntry) - -ListRequest = _reflection.GeneratedProtocolMessageType('ListRequest', (_message.Message,), { - 'DESCRIPTOR' : _LISTREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:ListRequest) - }) -_sym_db.RegisterMessage(ListRequest) - -Pagination = _reflection.GeneratedProtocolMessageType('Pagination', (_message.Message,), { - 'DESCRIPTOR' : _PAGINATION, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:Pagination) - }) -_sym_db.RegisterMessage(Pagination) - -ListItem = _reflection.GeneratedProtocolMessageType('ListItem', (_message.Message,), { - 'DESCRIPTOR' : _LISTITEM, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:ListItem) - }) -_sym_db.RegisterMessage(ListItem) - -ListResponse = _reflection.GeneratedProtocolMessageType('ListResponse', (_message.Message,), { - 'DESCRIPTOR' : _LISTRESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:ListResponse) - }) -_sym_db.RegisterMessage(ListResponse) - -QueryVector = _reflection.GeneratedProtocolMessageType('QueryVector', (_message.Message,), { - 'DESCRIPTOR' : _QUERYVECTOR, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:QueryVector) - }) -_sym_db.RegisterMessage(QueryVector) - -QueryRequest = _reflection.GeneratedProtocolMessageType('QueryRequest', (_message.Message,), { - 'DESCRIPTOR' : _QUERYREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:QueryRequest) - }) -_sym_db.RegisterMessage(QueryRequest) - -SingleQueryResults = _reflection.GeneratedProtocolMessageType('SingleQueryResults', (_message.Message,), { - 'DESCRIPTOR' : _SINGLEQUERYRESULTS, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:SingleQueryResults) - }) -_sym_db.RegisterMessage(SingleQueryResults) - -QueryResponse = _reflection.GeneratedProtocolMessageType('QueryResponse', (_message.Message,), { - 'DESCRIPTOR' : _QUERYRESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:QueryResponse) - }) -_sym_db.RegisterMessage(QueryResponse) - -Usage = _reflection.GeneratedProtocolMessageType('Usage', (_message.Message,), { - 'DESCRIPTOR' : _USAGE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:Usage) - }) -_sym_db.RegisterMessage(Usage) - -UpdateRequest = _reflection.GeneratedProtocolMessageType('UpdateRequest', (_message.Message,), { - 'DESCRIPTOR' : _UPDATEREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:UpdateRequest) - }) -_sym_db.RegisterMessage(UpdateRequest) - -UpdateResponse = _reflection.GeneratedProtocolMessageType('UpdateResponse', (_message.Message,), { - 'DESCRIPTOR' : _UPDATERESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:UpdateResponse) - }) -_sym_db.RegisterMessage(UpdateResponse) - -DescribeIndexStatsRequest = _reflection.GeneratedProtocolMessageType('DescribeIndexStatsRequest', (_message.Message,), { - 'DESCRIPTOR' : _DESCRIBEINDEXSTATSREQUEST, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:DescribeIndexStatsRequest) - }) -_sym_db.RegisterMessage(DescribeIndexStatsRequest) - -NamespaceSummary = _reflection.GeneratedProtocolMessageType('NamespaceSummary', (_message.Message,), { - 'DESCRIPTOR' : _NAMESPACESUMMARY, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:NamespaceSummary) - }) -_sym_db.RegisterMessage(NamespaceSummary) - -DescribeIndexStatsResponse = _reflection.GeneratedProtocolMessageType('DescribeIndexStatsResponse', (_message.Message,), { - - 'NamespacesEntry' : _reflection.GeneratedProtocolMessageType('NamespacesEntry', (_message.Message,), { - 'DESCRIPTOR' : _DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:DescribeIndexStatsResponse.NamespacesEntry) - }) - , - 'DESCRIPTOR' : _DESCRIBEINDEXSTATSRESPONSE, - '__module__' : 'vector_service_pb2' - # @@protoc_insertion_point(class_scope:DescribeIndexStatsResponse) - }) -_sym_db.RegisterMessage(DescribeIndexStatsResponse) -_sym_db.RegisterMessage(DescribeIndexStatsResponse.NamespacesEntry) - - -DESCRIPTOR._options = None -_SPARSEVALUES.fields_by_name['indices']._options = None -_SPARSEVALUES.fields_by_name['values']._options = None -_VECTOR.fields_by_name['id']._options = None -_VECTOR.fields_by_name['values']._options = None -_VECTOR.fields_by_name['metadata']._options = None -_SCOREDVECTOR.fields_by_name['id']._options = None -_SCOREDVECTOR.fields_by_name['score']._options = None -_SCOREDVECTOR.fields_by_name['values']._options = None -_SCOREDVECTOR.fields_by_name['metadata']._options = None -_UPSERTREQUEST.fields_by_name['vectors']._options = None -_UPSERTREQUEST.fields_by_name['namespace']._options = None -_UPSERTRESPONSE.fields_by_name['upserted_count']._options = None -_DELETEREQUEST.fields_by_name['ids']._options = None -_DELETEREQUEST.fields_by_name['delete_all']._options = None -_DELETEREQUEST.fields_by_name['namespace']._options = None -_FETCHREQUEST.fields_by_name['ids']._options = None -_FETCHREQUEST.fields_by_name['namespace']._options = None -_FETCHRESPONSE_VECTORSENTRY._options = None -_FETCHRESPONSE.fields_by_name['namespace']._options = None -_FETCHRESPONSE.fields_by_name['usage']._options = None -_LISTREQUEST.fields_by_name['prefix']._options = None -_LISTREQUEST.fields_by_name['limit']._options = None -_LISTREQUEST.fields_by_name['pagination_token']._options = None -_LISTREQUEST.fields_by_name['namespace']._options = None -_PAGINATION.fields_by_name['next']._options = None -_LISTITEM.fields_by_name['id']._options = None -_LISTRESPONSE.fields_by_name['vectors']._options = None -_LISTRESPONSE.fields_by_name['namespace']._options = None -_LISTRESPONSE.fields_by_name['usage']._options = None -_QUERYVECTOR.fields_by_name['values']._options = None -_QUERYVECTOR.fields_by_name['top_k']._options = None -_QUERYVECTOR.fields_by_name['namespace']._options = None -_QUERYVECTOR.fields_by_name['filter']._options = None -_QUERYREQUEST.fields_by_name['namespace']._options = None -_QUERYREQUEST.fields_by_name['top_k']._options = None -_QUERYREQUEST.fields_by_name['filter']._options = None -_QUERYREQUEST.fields_by_name['include_values']._options = None -_QUERYREQUEST.fields_by_name['include_metadata']._options = None -_QUERYREQUEST.fields_by_name['queries']._options = None -_QUERYREQUEST.fields_by_name['vector']._options = None -_QUERYREQUEST.fields_by_name['id']._options = None -_SINGLEQUERYRESULTS.fields_by_name['namespace']._options = None -_QUERYRESPONSE.fields_by_name['results']._options = None -_QUERYRESPONSE.fields_by_name['usage']._options = None -_USAGE.fields_by_name['read_units']._options = None -_UPDATEREQUEST.fields_by_name['id']._options = None -_UPDATEREQUEST.fields_by_name['values']._options = None -_UPDATEREQUEST.fields_by_name['set_metadata']._options = None -_UPDATEREQUEST.fields_by_name['namespace']._options = None -_NAMESPACESUMMARY.fields_by_name['vector_count']._options = None -_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY._options = None -_DESCRIBEINDEXSTATSRESPONSE.fields_by_name['dimension']._options = None -_DESCRIBEINDEXSTATSRESPONSE.fields_by_name['index_fullness']._options = None -_DESCRIBEINDEXSTATSRESPONSE.fields_by_name['total_vector_count']._options = None -_DESCRIBEINDEXSTATSRESPONSE._options = None - -_VECTORSERVICE = _descriptor.ServiceDescriptor( - name='VectorService', - full_name='VectorService', - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=4323, - serialized_end=5112, - methods=[ - _descriptor.MethodDescriptor( - name='Upsert', - full_name='VectorService.Upsert', - index=0, - containing_service=None, - input_type=_UPSERTREQUEST, - output_type=_UPSERTRESPONSE, - serialized_options=b'\202\323\344\223\002\024\"\017/vectors/upsert:\001*\222A\033\n\021Vector Operations*\006upsert', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='Delete', - full_name='VectorService.Delete', - index=1, - containing_service=None, - input_type=_DELETEREQUEST, - output_type=_DELETERESPONSE, - serialized_options=b'\202\323\344\223\002\'\"\017/vectors/delete:\001*Z\021*\017/vectors/delete\222A\033\n\021Vector Operations*\006delete', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='Fetch', - full_name='VectorService.Fetch', - index=2, - containing_service=None, - input_type=_FETCHREQUEST, - output_type=_FETCHRESPONSE, - serialized_options=b'\202\323\344\223\002\020\022\016/vectors/fetch\222A\032\n\021Vector Operations*\005fetch', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='List', - full_name='VectorService.List', - index=3, - containing_service=None, - input_type=_LISTREQUEST, - output_type=_LISTRESPONSE, - serialized_options=b'\202\323\344\223\002\017\022\r/vectors/list\222A\031\n\021Vector Operations*\004list', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='Query', - full_name='VectorService.Query', - index=4, - containing_service=None, - input_type=_QUERYREQUEST, - output_type=_QUERYRESPONSE, - serialized_options=b'\202\323\344\223\002\013\"\006/query:\001*\222A\032\n\021Vector Operations*\005query', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='Update', - full_name='VectorService.Update', - index=5, - containing_service=None, - input_type=_UPDATEREQUEST, - output_type=_UPDATERESPONSE, - serialized_options=b'\202\323\344\223\002\024\"\017/vectors/update:\001*\222A\033\n\021Vector Operations*\006update', - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name='DescribeIndexStats', - full_name='VectorService.DescribeIndexStats', - index=6, - containing_service=None, - input_type=_DESCRIBEINDEXSTATSREQUEST, - output_type=_DESCRIBEINDEXSTATSRESPONSE, - serialized_options=b'\202\323\344\223\0023\"\025/describe_index_stats:\001*Z\027\022\025/describe_index_stats\222A)\n\021Vector Operations*\024describe_index_stats', - create_key=_descriptor._internal_create_key, - ), -]) -_sym_db.RegisterServiceDescriptor(_VECTORSERVICE) - -DESCRIPTOR.services_by_name['VectorService'] = _VECTORSERVICE - +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14vector_service.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\x80\x01\n\x0cSparseValues\x12\x36\n\x07indices\x18\x01 \x03(\rB%\x92\x41\x1eJ\x16[1, 312, 822, 14, 980]x\xe8\x07\x80\x01\x01\xe2\x41\x01\x02\x12\x38\n\x06values\x18\x02 \x03(\x02\x42(\x92\x41!J\x19[0.1, 0.2, 0.3, 0.4, 0.5]x\xe8\x07\x80\x01\x01\xe2\x41\x01\x02\"\xff\x01\n\x06Vector\x12-\n\x02id\x18\x01 \x01(\tB!\x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe2\x41\x01\x02\x12H\n\x06values\x18\x02 \x03(\x02\x42\x38\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\xe2\x41\x01\x02\x12$\n\rsparse_values\x18\x04 \x01(\x0b\x32\r.SparseValues\x12V\n\x08metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\"\x94\x02\n\x0cScoredVector\x12-\n\x02id\x18\x01 \x01(\tB!\x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe2\x41\x01\x02\x12\x18\n\x05score\x18\x02 \x01(\x02\x42\t\x92\x41\x06J\x04\x30.08\x12=\n\x06values\x18\x03 \x03(\x02\x42-\x92\x41*J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12V\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\"\x89\x01\n\x0cRequestUnion\x12 \n\x06upsert\x18\x01 \x01(\x0b\x32\x0e.UpsertRequestH\x00\x12 \n\x06\x64\x65lete\x18\x02 \x01(\x0b\x32\x0e.DeleteRequestH\x00\x12 \n\x06update\x18\x03 \x01(\x0b\x32\x0e.UpdateRequestH\x00\x42\x13\n\x11RequestUnionInner\"e\n\rUpsertRequest\x12\'\n\x07vectors\x18\x01 \x03(\x0b\x32\x07.VectorB\r\x92\x41\x06x\xe8\x07\x80\x01\x01\xe2\x41\x01\x02\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"1\n\x0eUpsertResponse\x12\x1f\n\x0eupserted_count\x18\x01 \x01(\rB\x07\x92\x41\x04J\x02\x31\x30\"\xb6\x01\n\rDeleteRequest\x12(\n\x03ids\x18\x01 \x03(\tB\x1b\x92\x41\x18J\x10[\"id-0\", \"id-1\"]x\xe8\x07\x80\x01\x01\x12%\n\ndelete_all\x18\x02 \x01(\x08\x42\x11\x92\x41\x0e:\x05\x66\x61lseJ\x05\x66\x61lse\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\'\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"\x10\n\x0e\x44\x65leteResponse\"i\n\x0c\x46\x65tchRequest\x12,\n\x03ids\x18\x01 \x03(\tB\x1f\x92\x41\x18J\x10[\"id-0\", \"id-1\"]x\xe8\x07\x80\x01\x01\xe2\x41\x01\x02\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\xe1\x01\n\rFetchResponse\x12,\n\x07vectors\x18\x01 \x03(\x0b\x32\x1b.FetchResponse.VectorsEntry\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\x32\n\x05usage\x18\x03 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 5}H\x00\x88\x01\x01\x1a\x37\n\x0cVectorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x16\n\x05value\x18\x02 \x01(\x0b\x32\x07.Vector:\x02\x38\x01\x42\x08\n\x06_usage\"\xf8\x01\n\x0bListRequest\x12,\n\x06prefix\x18\x01 \x01(\tB\x17\x92\x41\x14J\x0c\"document1#\"x\xe8\x07\x80\x01\x01H\x00\x88\x01\x01\x12 \n\x05limit\x18\x02 \x01(\rB\x0c\x92\x41\t:\x03\x31\x30\x30J\x02\x31\x32H\x01\x88\x01\x01\x12\x42\n\x10pagination_token\x18\x03 \x01(\tB#\x92\x41 J\x1e\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"H\x02\x88\x01\x01\x12+\n\tnamespace\x18\x04 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"B\t\n\x07_prefixB\x08\n\x06_limitB\x13\n\x11_pagination_token\"?\n\nPagination\x12\x31\n\x04next\x18\x01 \x01(\tB#\x92\x41 J\x1e\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"\",\n\x08ListItem\x12 \n\x02id\x18\x01 \x01(\tB\x14\x92\x41\x11J\x0f\"document1#abb\"\"\x83\x02\n\x0cListResponse\x12S\n\x07vectors\x18\x01 \x03(\x0b\x32\t.ListItemB7\x92\x41\x34J2[{\"id\": \"document1#abb\"}, {\"id\": \"document1#abc\"}]\x12$\n\npagination\x18\x02 \x01(\x0b\x32\x0b.PaginationH\x00\x88\x01\x01\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12\x32\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 1}H\x01\x88\x01\x01\x42\r\n\x0b_paginationB\x08\n\x06_usage\"\xd1\x02\n\x0bQueryVector\x12H\n\x06values\x18\x01 \x03(\x02\x42\x38\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\xe2\x41\x01\x02\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12(\n\x05top_k\x18\x02 \x01(\rB\x19\x92\x41\x16J\x02\x31\x30Y\x00\x00\x00\x00\x00\x88\xc3@i\x00\x00\x00\x00\x00\x00\xf0?\x12+\n\tnamespace\x18\x03 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12{\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructBR\x92\x41OJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}\"\xfb\x03\n\x0cQueryRequest\x12+\n\tnamespace\x18\x01 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\x12,\n\x05top_k\x18\x02 \x01(\rB\x1d\x92\x41\x16J\x02\x31\x30Y\x00\x00\x00\x00\x00\x88\xc3@i\x00\x00\x00\x00\x00\x00\xf0?\xe2\x41\x01\x02\x12{\n\x06\x66ilter\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructBR\x92\x41OJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}\x12(\n\x0einclude_values\x18\x04 \x01(\x08\x42\x10\x92\x41\r:\x05\x66\x61lseJ\x04true\x12*\n\x10include_metadata\x18\x05 \x01(\x08\x42\x10\x92\x41\r:\x05\x66\x61lseJ\x04true\x12)\n\x07queries\x18\x06 \x03(\x0b\x32\x0c.QueryVectorB\n\x18\x01\x92\x41\x05x\n\x80\x01\x01\x12\x44\n\x06vector\x18\x07 \x03(\x02\x42\x34\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\x12$\n\rsparse_vector\x18\t \x01(\x0b\x32\r.SparseValues\x12&\n\x02id\x18\x08 \x01(\tB\x1a\x92\x41\x17J\x12\"example-vector-1\"x\x80\x04\"a\n\x12SingleQueryResults\x12\x1e\n\x07matches\x18\x01 \x03(\x0b\x32\r.ScoredVector\x12+\n\tnamespace\x18\x02 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\xaa\x01\n\rQueryResponse\x12(\n\x07results\x18\x01 \x03(\x0b\x32\x13.SingleQueryResultsB\x02\x18\x01\x12\x1e\n\x07matches\x18\x02 \x03(\x0b\x32\r.ScoredVector\x12\x11\n\tnamespace\x18\x03 \x01(\t\x12\x32\n\x05usage\x18\x04 \x01(\x0b\x32\x06.UsageB\x16\x92\x41\x13J\x11{\"read_units\": 5}H\x00\x88\x01\x01\x42\x08\n\x06_usage\"7\n\x05Usage\x12\x1f\n\nread_units\x18\x01 \x01(\rB\x06\x92\x41\x03J\x01\x35H\x00\x88\x01\x01\x42\r\n\x0b_read_units\"\xb3\x02\n\rUpdateRequest\x12-\n\x02id\x18\x01 \x01(\tB!\x92\x41\x1aJ\x12\"example-vector-1\"x\x80\x04\x80\x01\x01\xe2\x41\x01\x02\x12\x44\n\x06values\x18\x02 \x03(\x02\x42\x34\x92\x41\x31J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\xa0\x9c\x01\x80\x01\x01\x12$\n\rsparse_values\x18\x05 \x01(\x0b\x32\r.SparseValues\x12Z\n\x0cset_metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB+\x92\x41(J&{\"genre\": \"documentary\", \"year\": 2019}\x12+\n\tnamespace\x18\x04 \x01(\tB\x18\x92\x41\x15J\x13\"example-namespace\"\"\x10\n\x0eUpdateResponse\"D\n\x19\x44\x65scribeIndexStatsRequest\x12\'\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\"4\n\x10NamespaceSummary\x12 \n\x0cvector_count\x18\x01 \x01(\rB\n\x92\x41\x07J\x05\x35\x30\x30\x30\x30\"\x9a\x03\n\x1a\x44\x65scribeIndexStatsResponse\x12?\n\nnamespaces\x18\x01 \x03(\x0b\x32+.DescribeIndexStatsResponse.NamespacesEntry\x12\x1c\n\tdimension\x18\x02 \x01(\rB\t\x92\x41\x06J\x04\x31\x30\x32\x34\x12 \n\x0eindex_fullness\x18\x03 \x01(\x02\x42\x08\x92\x41\x05J\x03\x30.4\x12&\n\x12total_vector_count\x18\x04 \x01(\rB\n\x92\x41\x07J\x05\x38\x30\x30\x30\x30\x1a\x44\n\x0fNamespacesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.NamespaceSummary:\x02\x38\x01:\x8c\x01\x92\x41\x88\x01\x32\x85\x01{\"namespaces\": {\"\": {\"vectorCount\": 50000}, \"example-namespace-2\": {\"vectorCount\": 30000}}, \"dimension\": 1024, \"index_fullness\": 0.4}2\x95\x06\n\rVectorService\x12\x63\n\x06Upsert\x12\x0e.UpsertRequest\x1a\x0f.UpsertResponse\"8\x92\x41\x1b\n\x11Vector Operations*\x06upsert\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/upsert:\x01*\x12v\n\x06\x44\x65lete\x12\x0e.DeleteRequest\x1a\x0f.DeleteResponse\"K\x92\x41\x1b\n\x11Vector Operations*\x06\x64\x65lete\x82\xd3\xe4\x93\x02\'\"\x0f/vectors/delete:\x01*Z\x11*\x0f/vectors/delete\x12[\n\x05\x46\x65tch\x12\r.FetchRequest\x1a\x0e.FetchResponse\"3\x92\x41\x1a\n\x11Vector Operations*\x05\x66\x65tch\x82\xd3\xe4\x93\x02\x10\x12\x0e/vectors/fetch\x12V\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"1\x92\x41\x19\n\x11Vector Operations*\x04list\x82\xd3\xe4\x93\x02\x0f\x12\r/vectors/list\x12V\n\x05Query\x12\r.QueryRequest\x1a\x0e.QueryResponse\".\x92\x41\x1a\n\x11Vector Operations*\x05query\x82\xd3\xe4\x93\x02\x0b\"\x06/query:\x01*\x12\x63\n\x06Update\x12\x0e.UpdateRequest\x1a\x0f.UpdateResponse\"8\x92\x41\x1b\n\x11Vector Operations*\x06update\x82\xd3\xe4\x93\x02\x14\"\x0f/vectors/update:\x01*\x12\xb4\x01\n\x12\x44\x65scribeIndexStats\x12\x1a.DescribeIndexStatsRequest\x1a\x1b.DescribeIndexStatsResponse\"e\x92\x41)\n\x11Vector Operations*\x14\x64\x65scribe_index_stats\x82\xd3\xe4\x93\x02\x33\"\x15/describe_index_stats:\x01*Z\x17\x12\x15/describe_index_statsB\x8f\x03\n\x11io.pinecone.protoP\x01Z+github.com/pinecone-io/go-pinecone/pinecone\x92\x41\xc9\x02\x12K\n\x0cPinecone API\";\n\x0fPinecone.io Ops\x12\x13https://pinecone.io\x1a\x13support@pinecone.io\x1a\x0c{index_host}*\x01\x02\x32\x10\x61pplication/json:\x10\x61pplication/jsonZx\nv\n\nApiKeyAuth\x12h\x08\x02\x12YAn API Key is required to call Pinecone APIs. Get yours at https://www.pinecone.io/start/\x1a\x07\x41pi-Key \x02\x62\x10\n\x0e\n\nApiKeyAuth\x12\x00r9\n\x19More Pinecone.io API docs\x12\x1chttps://www.pinecone.io/docsb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vector_service_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\021io.pinecone.protoP\001Z+github.com/pinecone-io/go-pinecone/pinecone\222A\311\002\022K\n\014Pinecone API\";\n\017Pinecone.io Ops\022\023https://pinecone.io\032\023support@pinecone.io\032\014{index_host}*\001\0022\020application/json:\020application/jsonZx\nv\n\nApiKeyAuth\022h\010\002\022YAn API Key is required to call Pinecone APIs. Get yours at https://www.pinecone.io/start/\032\007Api-Key \002b\020\n\016\n\nApiKeyAuth\022\000r9\n\031More Pinecone.io API docs\022\034https://www.pinecone.io/docs' + _globals['_SPARSEVALUES'].fields_by_name['indices']._options = None + _globals['_SPARSEVALUES'].fields_by_name['indices']._serialized_options = b'\222A\036J\026[1, 312, 822, 14, 980]x\350\007\200\001\001\342A\001\002' + _globals['_SPARSEVALUES'].fields_by_name['values']._options = None + _globals['_SPARSEVALUES'].fields_by_name['values']._serialized_options = b'\222A!J\031[0.1, 0.2, 0.3, 0.4, 0.5]x\350\007\200\001\001\342A\001\002' + _globals['_VECTOR'].fields_by_name['id']._options = None + _globals['_VECTOR'].fields_by_name['id']._serialized_options = b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\342A\001\002' + _globals['_VECTOR'].fields_by_name['values']._options = None + _globals['_VECTOR'].fields_by_name['values']._serialized_options = b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001\342A\001\002' + _globals['_VECTOR'].fields_by_name['metadata']._options = None + _globals['_VECTOR'].fields_by_name['metadata']._serialized_options = b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}' + _globals['_SCOREDVECTOR'].fields_by_name['id']._options = None + _globals['_SCOREDVECTOR'].fields_by_name['id']._serialized_options = b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\342A\001\002' + _globals['_SCOREDVECTOR'].fields_by_name['score']._options = None + _globals['_SCOREDVECTOR'].fields_by_name['score']._serialized_options = b'\222A\006J\0040.08' + _globals['_SCOREDVECTOR'].fields_by_name['values']._options = None + _globals['_SCOREDVECTOR'].fields_by_name['values']._serialized_options = b'\222A*J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]' + _globals['_SCOREDVECTOR'].fields_by_name['metadata']._options = None + _globals['_SCOREDVECTOR'].fields_by_name['metadata']._serialized_options = b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}' + _globals['_UPSERTREQUEST'].fields_by_name['vectors']._options = None + _globals['_UPSERTREQUEST'].fields_by_name['vectors']._serialized_options = b'\222A\006x\350\007\200\001\001\342A\001\002' + _globals['_UPSERTREQUEST'].fields_by_name['namespace']._options = None + _globals['_UPSERTREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_UPSERTRESPONSE'].fields_by_name['upserted_count']._options = None + _globals['_UPSERTRESPONSE'].fields_by_name['upserted_count']._serialized_options = b'\222A\004J\00210' + _globals['_DELETEREQUEST'].fields_by_name['ids']._options = None + _globals['_DELETEREQUEST'].fields_by_name['ids']._serialized_options = b'\222A\030J\020[\"id-0\", \"id-1\"]x\350\007\200\001\001' + _globals['_DELETEREQUEST'].fields_by_name['delete_all']._options = None + _globals['_DELETEREQUEST'].fields_by_name['delete_all']._serialized_options = b'\222A\016:\005falseJ\005false' + _globals['_DELETEREQUEST'].fields_by_name['namespace']._options = None + _globals['_DELETEREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_FETCHREQUEST'].fields_by_name['ids']._options = None + _globals['_FETCHREQUEST'].fields_by_name['ids']._serialized_options = b'\222A\030J\020[\"id-0\", \"id-1\"]x\350\007\200\001\001\342A\001\002' + _globals['_FETCHREQUEST'].fields_by_name['namespace']._options = None + _globals['_FETCHREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_FETCHRESPONSE_VECTORSENTRY']._options = None + _globals['_FETCHRESPONSE_VECTORSENTRY']._serialized_options = b'8\001' + _globals['_FETCHRESPONSE'].fields_by_name['namespace']._options = None + _globals['_FETCHRESPONSE'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_FETCHRESPONSE'].fields_by_name['usage']._options = None + _globals['_FETCHRESPONSE'].fields_by_name['usage']._serialized_options = b'\222A\023J\021{\"read_units\": 5}' + _globals['_LISTREQUEST'].fields_by_name['prefix']._options = None + _globals['_LISTREQUEST'].fields_by_name['prefix']._serialized_options = b'\222A\024J\014\"document1#\"x\350\007\200\001\001' + _globals['_LISTREQUEST'].fields_by_name['limit']._options = None + _globals['_LISTREQUEST'].fields_by_name['limit']._serialized_options = b'\222A\t:\003100J\00212' + _globals['_LISTREQUEST'].fields_by_name['pagination_token']._options = None + _globals['_LISTREQUEST'].fields_by_name['pagination_token']._serialized_options = b'\222A J\036\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"' + _globals['_LISTREQUEST'].fields_by_name['namespace']._options = None + _globals['_LISTREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_PAGINATION'].fields_by_name['next']._options = None + _globals['_PAGINATION'].fields_by_name['next']._serialized_options = b'\222A J\036\"Tm90aGluZyB0byBzZWUgaGVyZQo=\"' + _globals['_LISTITEM'].fields_by_name['id']._options = None + _globals['_LISTITEM'].fields_by_name['id']._serialized_options = b'\222A\021J\017\"document1#abb\"' + _globals['_LISTRESPONSE'].fields_by_name['vectors']._options = None + _globals['_LISTRESPONSE'].fields_by_name['vectors']._serialized_options = b'\222A4J2[{\"id\": \"document1#abb\"}, {\"id\": \"document1#abc\"}]' + _globals['_LISTRESPONSE'].fields_by_name['namespace']._options = None + _globals['_LISTRESPONSE'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_LISTRESPONSE'].fields_by_name['usage']._options = None + _globals['_LISTRESPONSE'].fields_by_name['usage']._serialized_options = b'\222A\023J\021{\"read_units\": 1}' + _globals['_QUERYVECTOR'].fields_by_name['values']._options = None + _globals['_QUERYVECTOR'].fields_by_name['values']._serialized_options = b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001\342A\001\002' + _globals['_QUERYVECTOR'].fields_by_name['top_k']._options = None + _globals['_QUERYVECTOR'].fields_by_name['top_k']._serialized_options = b'\222A\026J\00210Y\000\000\000\000\000\210\303@i\000\000\000\000\000\000\360?' + _globals['_QUERYVECTOR'].fields_by_name['namespace']._options = None + _globals['_QUERYVECTOR'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_QUERYVECTOR'].fields_by_name['filter']._options = None + _globals['_QUERYVECTOR'].fields_by_name['filter']._serialized_options = b'\222AOJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}' + _globals['_QUERYREQUEST'].fields_by_name['namespace']._options = None + _globals['_QUERYREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_QUERYREQUEST'].fields_by_name['top_k']._options = None + _globals['_QUERYREQUEST'].fields_by_name['top_k']._serialized_options = b'\222A\026J\00210Y\000\000\000\000\000\210\303@i\000\000\000\000\000\000\360?\342A\001\002' + _globals['_QUERYREQUEST'].fields_by_name['filter']._options = None + _globals['_QUERYREQUEST'].fields_by_name['filter']._serialized_options = b'\222AOJM{\"genre\": {\"$in\": [\"comedy\", \"documentary\", \"drama\"]}, \"year\": {\"$eq\": 2019}}' + _globals['_QUERYREQUEST'].fields_by_name['include_values']._options = None + _globals['_QUERYREQUEST'].fields_by_name['include_values']._serialized_options = b'\222A\r:\005falseJ\004true' + _globals['_QUERYREQUEST'].fields_by_name['include_metadata']._options = None + _globals['_QUERYREQUEST'].fields_by_name['include_metadata']._serialized_options = b'\222A\r:\005falseJ\004true' + _globals['_QUERYREQUEST'].fields_by_name['queries']._options = None + _globals['_QUERYREQUEST'].fields_by_name['queries']._serialized_options = b'\030\001\222A\005x\n\200\001\001' + _globals['_QUERYREQUEST'].fields_by_name['vector']._options = None + _globals['_QUERYREQUEST'].fields_by_name['vector']._serialized_options = b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001' + _globals['_QUERYREQUEST'].fields_by_name['id']._options = None + _globals['_QUERYREQUEST'].fields_by_name['id']._serialized_options = b'\222A\027J\022\"example-vector-1\"x\200\004' + _globals['_SINGLEQUERYRESULTS'].fields_by_name['namespace']._options = None + _globals['_SINGLEQUERYRESULTS'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_QUERYRESPONSE'].fields_by_name['results']._options = None + _globals['_QUERYRESPONSE'].fields_by_name['results']._serialized_options = b'\030\001' + _globals['_QUERYRESPONSE'].fields_by_name['usage']._options = None + _globals['_QUERYRESPONSE'].fields_by_name['usage']._serialized_options = b'\222A\023J\021{\"read_units\": 5}' + _globals['_USAGE'].fields_by_name['read_units']._options = None + _globals['_USAGE'].fields_by_name['read_units']._serialized_options = b'\222A\003J\0015' + _globals['_UPDATEREQUEST'].fields_by_name['id']._options = None + _globals['_UPDATEREQUEST'].fields_by_name['id']._serialized_options = b'\222A\032J\022\"example-vector-1\"x\200\004\200\001\001\342A\001\002' + _globals['_UPDATEREQUEST'].fields_by_name['values']._options = None + _globals['_UPDATEREQUEST'].fields_by_name['values']._serialized_options = b'\222A1J([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]x\240\234\001\200\001\001' + _globals['_UPDATEREQUEST'].fields_by_name['set_metadata']._options = None + _globals['_UPDATEREQUEST'].fields_by_name['set_metadata']._serialized_options = b'\222A(J&{\"genre\": \"documentary\", \"year\": 2019}' + _globals['_UPDATEREQUEST'].fields_by_name['namespace']._options = None + _globals['_UPDATEREQUEST'].fields_by_name['namespace']._serialized_options = b'\222A\025J\023\"example-namespace\"' + _globals['_NAMESPACESUMMARY'].fields_by_name['vector_count']._options = None + _globals['_NAMESPACESUMMARY'].fields_by_name['vector_count']._serialized_options = b'\222A\007J\00550000' + _globals['_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY']._options = None + _globals['_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY']._serialized_options = b'8\001' + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['dimension']._options = None + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['dimension']._serialized_options = b'\222A\006J\0041024' + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['index_fullness']._options = None + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['index_fullness']._serialized_options = b'\222A\005J\0030.4' + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['total_vector_count']._options = None + _globals['_DESCRIBEINDEXSTATSRESPONSE'].fields_by_name['total_vector_count']._serialized_options = b'\222A\007J\00580000' + _globals['_DESCRIBEINDEXSTATSRESPONSE']._options = None + _globals['_DESCRIBEINDEXSTATSRESPONSE']._serialized_options = b'\222A\210\0012\205\001{\"namespaces\": {\"\": {\"vectorCount\": 50000}, \"example-namespace-2\": {\"vectorCount\": 30000}}, \"dimension\": 1024, \"index_fullness\": 0.4}' + _globals['_VECTORSERVICE'].methods_by_name['Upsert']._options = None + _globals['_VECTORSERVICE'].methods_by_name['Upsert']._serialized_options = b'\222A\033\n\021Vector Operations*\006upsert\202\323\344\223\002\024\"\017/vectors/upsert:\001*' + _globals['_VECTORSERVICE'].methods_by_name['Delete']._options = None + _globals['_VECTORSERVICE'].methods_by_name['Delete']._serialized_options = b'\222A\033\n\021Vector Operations*\006delete\202\323\344\223\002\'\"\017/vectors/delete:\001*Z\021*\017/vectors/delete' + _globals['_VECTORSERVICE'].methods_by_name['Fetch']._options = None + _globals['_VECTORSERVICE'].methods_by_name['Fetch']._serialized_options = b'\222A\032\n\021Vector Operations*\005fetch\202\323\344\223\002\020\022\016/vectors/fetch' + _globals['_VECTORSERVICE'].methods_by_name['List']._options = None + _globals['_VECTORSERVICE'].methods_by_name['List']._serialized_options = b'\222A\031\n\021Vector Operations*\004list\202\323\344\223\002\017\022\r/vectors/list' + _globals['_VECTORSERVICE'].methods_by_name['Query']._options = None + _globals['_VECTORSERVICE'].methods_by_name['Query']._serialized_options = b'\222A\032\n\021Vector Operations*\005query\202\323\344\223\002\013\"\006/query:\001*' + _globals['_VECTORSERVICE'].methods_by_name['Update']._options = None + _globals['_VECTORSERVICE'].methods_by_name['Update']._serialized_options = b'\222A\033\n\021Vector Operations*\006update\202\323\344\223\002\024\"\017/vectors/update:\001*' + _globals['_VECTORSERVICE'].methods_by_name['DescribeIndexStats']._options = None + _globals['_VECTORSERVICE'].methods_by_name['DescribeIndexStats']._serialized_options = b'\222A)\n\021Vector Operations*\024describe_index_stats\202\323\344\223\0023\"\025/describe_index_stats:\001*Z\027\022\025/describe_index_stats' + _globals['_SPARSEVALUES']._serialized_start=166 + _globals['_SPARSEVALUES']._serialized_end=294 + _globals['_VECTOR']._serialized_start=297 + _globals['_VECTOR']._serialized_end=552 + _globals['_SCOREDVECTOR']._serialized_start=555 + _globals['_SCOREDVECTOR']._serialized_end=831 + _globals['_REQUESTUNION']._serialized_start=834 + _globals['_REQUESTUNION']._serialized_end=971 + _globals['_UPSERTREQUEST']._serialized_start=973 + _globals['_UPSERTREQUEST']._serialized_end=1074 + _globals['_UPSERTRESPONSE']._serialized_start=1076 + _globals['_UPSERTRESPONSE']._serialized_end=1125 + _globals['_DELETEREQUEST']._serialized_start=1128 + _globals['_DELETEREQUEST']._serialized_end=1310 + _globals['_DELETERESPONSE']._serialized_start=1312 + _globals['_DELETERESPONSE']._serialized_end=1328 + _globals['_FETCHREQUEST']._serialized_start=1330 + _globals['_FETCHREQUEST']._serialized_end=1435 + _globals['_FETCHRESPONSE']._serialized_start=1438 + _globals['_FETCHRESPONSE']._serialized_end=1663 + _globals['_FETCHRESPONSE_VECTORSENTRY']._serialized_start=1598 + _globals['_FETCHRESPONSE_VECTORSENTRY']._serialized_end=1653 + _globals['_LISTREQUEST']._serialized_start=1666 + _globals['_LISTREQUEST']._serialized_end=1914 + _globals['_PAGINATION']._serialized_start=1916 + _globals['_PAGINATION']._serialized_end=1979 + _globals['_LISTITEM']._serialized_start=1981 + _globals['_LISTITEM']._serialized_end=2025 + _globals['_LISTRESPONSE']._serialized_start=2028 + _globals['_LISTRESPONSE']._serialized_end=2287 + _globals['_QUERYVECTOR']._serialized_start=2290 + _globals['_QUERYVECTOR']._serialized_end=2627 + _globals['_QUERYREQUEST']._serialized_start=2630 + _globals['_QUERYREQUEST']._serialized_end=3137 + _globals['_SINGLEQUERYRESULTS']._serialized_start=3139 + _globals['_SINGLEQUERYRESULTS']._serialized_end=3236 + _globals['_QUERYRESPONSE']._serialized_start=3239 + _globals['_QUERYRESPONSE']._serialized_end=3409 + _globals['_USAGE']._serialized_start=3411 + _globals['_USAGE']._serialized_end=3466 + _globals['_UPDATEREQUEST']._serialized_start=3469 + _globals['_UPDATEREQUEST']._serialized_end=3776 + _globals['_UPDATERESPONSE']._serialized_start=3778 + _globals['_UPDATERESPONSE']._serialized_end=3794 + _globals['_DESCRIBEINDEXSTATSREQUEST']._serialized_start=3796 + _globals['_DESCRIBEINDEXSTATSREQUEST']._serialized_end=3864 + _globals['_NAMESPACESUMMARY']._serialized_start=3866 + _globals['_NAMESPACESUMMARY']._serialized_end=3918 + _globals['_DESCRIBEINDEXSTATSRESPONSE']._serialized_start=3921 + _globals['_DESCRIBEINDEXSTATSRESPONSE']._serialized_end=4331 + _globals['_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY']._serialized_start=4120 + _globals['_DESCRIBEINDEXSTATSRESPONSE_NAMESPACESENTRY']._serialized_end=4188 + _globals['_VECTORSERVICE']._serialized_start=4334 + _globals['_VECTORSERVICE']._serialized_end=5123 # @@protoc_insertion_point(module_scope) diff --git a/pinecone/core/grpc/protos/vector_service_pb2.pyi b/pinecone/core/grpc/protos/vector_service_pb2.pyi index 3ffa7f4c..2b09c253 100644 --- a/pinecone/core/grpc/protos/vector_service_pb2.pyi +++ b/pinecone/core/grpc/protos/vector_service_pb2.pyi @@ -1,504 +1,739 @@ """ @generated by mypy-protobuf. Do not edit manually! isort:skip_file +Generated file - DO NOT EDIT +This file is generated from the pinecone-io/apis repo. +Any changes made directly here WILL be overwritten. """ -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, - FileDescriptor as google___protobuf___descriptor___FileDescriptor, -) -from google.protobuf.internal.containers import ( - MessageMap as google___protobuf___internal___containers___MessageMap, - RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, - RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, -) +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import google.protobuf.struct_pb2 +import typing -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor -from google.protobuf.struct_pb2 import ( - Struct as google___protobuf___struct_pb2___Struct, -) +@typing.final +class SparseValues(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor -from typing import ( - Iterable as typing___Iterable, - Mapping as typing___Mapping, - Optional as typing___Optional, - Text as typing___Text, - overload as typing___overload, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -DESCRIPTOR: google___protobuf___descriptor___FileDescriptor = ... - -class SparseValues(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - indices: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] = ... - values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... - - def __init__(self, + INDICES_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + @property + def indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ... + def __init__( + self, *, - indices : typing___Optional[typing___Iterable[builtin___int]] = None, - values : typing___Optional[typing___Iterable[builtin___float]] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"indices",b"indices",u"values",b"values"]) -> None: ... -type___SparseValues = SparseValues - -class Vector(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - id: typing___Text = ... - values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... - + indices: collections.abc.Iterable[builtins.int] | None = ..., + values: collections.abc.Iterable[builtins.float] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["indices", b"indices", "values", b"values"]) -> None: ... + +global___SparseValues = SparseValues + +@typing.final +class Vector(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + SPARSE_VALUES_FIELD_NUMBER: builtins.int + METADATA_FIELD_NUMBER: builtins.int + id: builtins.str + """This is the vector's unique id.""" @property - def sparse_values(self) -> type___SparseValues: ... + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """This is the vector data included in the request.""" @property - def metadata(self) -> google___protobuf___struct_pb2___Struct: ... + def sparse_values(self) -> global___SparseValues: ... + @property + def metadata(self) -> google.protobuf.struct_pb2.Struct: + """This is the metadata included in the request.""" - def __init__(self, + def __init__( + self, *, - id : typing___Optional[typing___Text] = None, - values : typing___Optional[typing___Iterable[builtin___float]] = None, - sparse_values : typing___Optional[type___SparseValues] = None, - metadata : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"metadata",b"metadata",u"sparse_values",b"sparse_values"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"id",b"id",u"metadata",b"metadata",u"sparse_values",b"sparse_values",u"values",b"values"]) -> None: ... -type___Vector = Vector - -class ScoredVector(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - id: typing___Text = ... - score: builtin___float = ... - values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... + id: builtins.str = ..., + values: collections.abc.Iterable[builtins.float] | None = ..., + sparse_values: global___SparseValues | None = ..., + metadata: google.protobuf.struct_pb2.Struct | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["metadata", b"metadata", "sparse_values", b"sparse_values"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "metadata", b"metadata", "sparse_values", b"sparse_values", "values", b"values"]) -> None: ... + +global___Vector = Vector + +@typing.final +class ScoredVector(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + SCORE_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + SPARSE_VALUES_FIELD_NUMBER: builtins.int + METADATA_FIELD_NUMBER: builtins.int + id: builtins.str + """This is the vector's unique id.""" + score: builtins.float + """This is a measure of similarity between this vector and the query vector. The higher the score, the more they are similar.""" + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """This is the vector data, if it is requested.""" @property - def sparse_values(self) -> type___SparseValues: ... + def sparse_values(self) -> global___SparseValues: + """This is the sparse data, if it is requested.""" @property - def metadata(self) -> google___protobuf___struct_pb2___Struct: ... + def metadata(self) -> google.protobuf.struct_pb2.Struct: + """This is the metadata, if it is requested.""" - def __init__(self, + def __init__( + self, *, - id : typing___Optional[typing___Text] = None, - score : typing___Optional[builtin___float] = None, - values : typing___Optional[typing___Iterable[builtin___float]] = None, - sparse_values : typing___Optional[type___SparseValues] = None, - metadata : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"metadata",b"metadata",u"sparse_values",b"sparse_values"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"id",b"id",u"metadata",b"metadata",u"score",b"score",u"sparse_values",b"sparse_values",u"values",b"values"]) -> None: ... -type___ScoredVector = ScoredVector - -class RequestUnion(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - + id: builtins.str = ..., + score: builtins.float = ..., + values: collections.abc.Iterable[builtins.float] | None = ..., + sparse_values: global___SparseValues | None = ..., + metadata: google.protobuf.struct_pb2.Struct | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["metadata", b"metadata", "sparse_values", b"sparse_values"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "metadata", b"metadata", "score", b"score", "sparse_values", b"sparse_values", "values", b"values"]) -> None: ... + +global___ScoredVector = ScoredVector + +@typing.final +class RequestUnion(google.protobuf.message.Message): + """This is a container to hold mutating vector requests. This is not actually used + in any public APIs. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UPSERT_FIELD_NUMBER: builtins.int + DELETE_FIELD_NUMBER: builtins.int + UPDATE_FIELD_NUMBER: builtins.int @property - def upsert(self) -> type___UpsertRequest: ... - + def upsert(self) -> global___UpsertRequest: ... @property - def delete(self) -> type___DeleteRequest: ... - + def delete(self) -> global___DeleteRequest: ... @property - def update(self) -> type___UpdateRequest: ... + def update(self) -> global___UpdateRequest: ... + def __init__( + self, + *, + upsert: global___UpsertRequest | None = ..., + delete: global___DeleteRequest | None = ..., + update: global___UpdateRequest | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["RequestUnionInner", b"RequestUnionInner", "delete", b"delete", "update", b"update", "upsert", b"upsert"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["RequestUnionInner", b"RequestUnionInner", "delete", b"delete", "update", b"update", "upsert", b"upsert"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["RequestUnionInner", b"RequestUnionInner"]) -> typing.Literal["upsert", "delete", "update"] | None: ... + +global___RequestUnion = RequestUnion + +@typing.final +class UpsertRequest(google.protobuf.message.Message): + """The request for the `upsert` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VECTORS_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + namespace: builtins.str + """This is the namespace name where you upsert vectors.""" + @property + def vectors(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Vector]: + """An array containing the vectors to upsert. Recommended batch limit is 100 vectors.""" - def __init__(self, + def __init__( + self, *, - upsert : typing___Optional[type___UpsertRequest] = None, - delete : typing___Optional[type___DeleteRequest] = None, - update : typing___Optional[type___UpdateRequest] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"RequestUnionInner",b"RequestUnionInner",u"delete",b"delete",u"update",b"update",u"upsert",b"upsert"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"RequestUnionInner",b"RequestUnionInner",u"delete",b"delete",u"update",b"update",u"upsert",b"upsert"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"RequestUnionInner",b"RequestUnionInner"]) -> typing_extensions___Literal["upsert","delete","update"]: ... -type___RequestUnion = RequestUnion + vectors: collections.abc.Iterable[global___Vector] | None = ..., + namespace: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["namespace", b"namespace", "vectors", b"vectors"]) -> None: ... -class UpsertRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - namespace: typing___Text = ... +global___UpsertRequest = UpsertRequest +@typing.final +class UpsertResponse(google.protobuf.message.Message): + """The response for the `upsert` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + UPSERTED_COUNT_FIELD_NUMBER: builtins.int + upserted_count: builtins.int + """The number of vectors upserted.""" + def __init__( + self, + *, + upserted_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["upserted_count", b"upserted_count"]) -> None: ... + +global___UpsertResponse = UpsertResponse + +@typing.final +class DeleteRequest(google.protobuf.message.Message): + """The request for the `Delete` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + IDS_FIELD_NUMBER: builtins.int + DELETE_ALL_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + FILTER_FIELD_NUMBER: builtins.int + delete_all: builtins.bool + """This indicates that all vectors in the index namespace should be deleted.""" + namespace: builtins.str + """The namespace to delete vectors from, if applicable.""" @property - def vectors(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___Vector]: ... + def ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Vectors to delete.""" - def __init__(self, + @property + def filter(self) -> google.protobuf.struct_pb2.Struct: + """If specified, the metadata filter here will be used to select the vectors to delete. This is mutually exclusive + with specifying ids to delete in the ids param or using delete_all=True. + See https://www.pinecone.io/docs/metadata-filtering/. + """ + + def __init__( + self, *, - vectors : typing___Optional[typing___Iterable[type___Vector]] = None, - namespace : typing___Optional[typing___Text] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"namespace",b"namespace",u"vectors",b"vectors"]) -> None: ... -type___UpsertRequest = UpsertRequest + ids: collections.abc.Iterable[builtins.str] | None = ..., + delete_all: builtins.bool = ..., + namespace: builtins.str = ..., + filter: google.protobuf.struct_pb2.Struct | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["filter", b"filter"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["delete_all", b"delete_all", "filter", b"filter", "ids", b"ids", "namespace", b"namespace"]) -> None: ... -class UpsertResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - upserted_count: builtin___int = ... +global___DeleteRequest = DeleteRequest - def __init__(self, - *, - upserted_count : typing___Optional[builtin___int] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"upserted_count",b"upserted_count"]) -> None: ... -type___UpsertResponse = UpsertResponse +@typing.final +class DeleteResponse(google.protobuf.message.Message): + """The response for the `Delete` operation.""" -class DeleteRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - ids: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... - delete_all: builtin___bool = ... - namespace: typing___Text = ... + DESCRIPTOR: google.protobuf.descriptor.Descriptor - @property - def filter(self) -> google___protobuf___struct_pb2___Struct: ... + def __init__( + self, + ) -> None: ... - def __init__(self, - *, - ids : typing___Optional[typing___Iterable[typing___Text]] = None, - delete_all : typing___Optional[builtin___bool] = None, - namespace : typing___Optional[typing___Text] = None, - filter : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"filter",b"filter"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"delete_all",b"delete_all",u"filter",b"filter",u"ids",b"ids",u"namespace",b"namespace"]) -> None: ... -type___DeleteRequest = DeleteRequest +global___DeleteResponse = DeleteResponse -class DeleteResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... +@typing.final +class FetchRequest(google.protobuf.message.Message): + """The request for the `fetch` operation.""" - def __init__(self, - ) -> None: ... -type___DeleteResponse = DeleteResponse + DESCRIPTOR: google.protobuf.descriptor.Descriptor -class FetchRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - ids: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] = ... - namespace: typing___Text = ... + IDS_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + namespace: builtins.str + @property + def ids(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """The vector IDs to fetch. Does not accept values containing spaces.""" - def __init__(self, + def __init__( + self, *, - ids : typing___Optional[typing___Iterable[typing___Text]] = None, - namespace : typing___Optional[typing___Text] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"ids",b"ids",u"namespace",b"namespace"]) -> None: ... -type___FetchRequest = FetchRequest + ids: collections.abc.Iterable[builtins.str] | None = ..., + namespace: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ids", b"ids", "namespace", b"namespace"]) -> None: ... -class FetchResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - class VectorsEntry(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - key: typing___Text = ... +global___FetchRequest = FetchRequest - @property - def value(self) -> type___Vector: ... +@typing.final +class FetchResponse(google.protobuf.message.Message): + """The response for the `fetch` operation.""" - def __init__(self, - *, - key : typing___Optional[typing___Text] = None, - value : typing___Optional[type___Vector] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... - type___VectorsEntry = VectorsEntry + DESCRIPTOR: google.protobuf.descriptor.Descriptor - namespace: typing___Text = ... + @typing.final + class VectorsEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___Vector: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___Vector | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + VECTORS_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + USAGE_FIELD_NUMBER: builtins.int + namespace: builtins.str + """The namespace of the vectors.""" @property - def vectors(self) -> google___protobuf___internal___containers___MessageMap[typing___Text, type___Vector]: ... + def vectors(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Vector]: + """The fetched vectors, in the form of a map between the fetched ids and the fetched vectors""" @property - def usage(self) -> type___Usage: ... + def usage(self) -> global___Usage: + """ The usage for this operation.""" - def __init__(self, + def __init__( + self, *, - vectors : typing___Optional[typing___Mapping[typing___Text, type___Vector]] = None, - namespace : typing___Optional[typing___Text] = None, - usage : typing___Optional[type___Usage] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"_usage",b"_usage",u"usage",b"usage"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"_usage",b"_usage",u"namespace",b"namespace",u"usage",b"usage",u"vectors",b"vectors"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_usage",b"_usage"]) -> typing_extensions___Literal["usage"]: ... -type___FetchResponse = FetchResponse - -class ListRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - prefix: typing___Text = ... - limit: builtin___int = ... - pagination_token: typing___Text = ... - namespace: typing___Text = ... - - def __init__(self, + vectors: collections.abc.Mapping[builtins.str, global___Vector] | None = ..., + namespace: builtins.str = ..., + usage: global___Usage | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_usage", b"_usage", "usage", b"usage"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_usage", b"_usage", "namespace", b"namespace", "usage", b"usage", "vectors", b"vectors"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_usage", b"_usage"]) -> typing.Literal["usage"] | None: ... + +global___FetchResponse = FetchResponse + +@typing.final +class ListRequest(google.protobuf.message.Message): + """The request for the `list` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PREFIX_FIELD_NUMBER: builtins.int + LIMIT_FIELD_NUMBER: builtins.int + PAGINATION_TOKEN_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + prefix: builtins.str + """The vector IDs to fetch. Does not accept values containing spaces.""" + limit: builtins.int + """Max number of IDs to return per page.""" + pagination_token: builtins.str + """Pagination token to continue a previous listing operation.""" + namespace: builtins.str + def __init__( + self, *, - prefix : typing___Optional[typing___Text] = None, - limit : typing___Optional[builtin___int] = None, - pagination_token : typing___Optional[typing___Text] = None, - namespace : typing___Optional[typing___Text] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"_limit",b"_limit",u"_pagination_token",b"_pagination_token",u"_prefix",b"_prefix",u"limit",b"limit",u"pagination_token",b"pagination_token",u"prefix",b"prefix"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"_limit",b"_limit",u"_pagination_token",b"_pagination_token",u"_prefix",b"_prefix",u"limit",b"limit",u"namespace",b"namespace",u"pagination_token",b"pagination_token",u"prefix",b"prefix"]) -> None: ... - @typing___overload - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_limit",b"_limit"]) -> typing_extensions___Literal["limit"]: ... - @typing___overload - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_pagination_token",b"_pagination_token"]) -> typing_extensions___Literal["pagination_token"]: ... - @typing___overload - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_prefix",b"_prefix"]) -> typing_extensions___Literal["prefix"]: ... -type___ListRequest = ListRequest - -class Pagination(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - next: typing___Text = ... - - def __init__(self, + prefix: builtins.str | None = ..., + limit: builtins.int | None = ..., + pagination_token: builtins.str | None = ..., + namespace: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_limit", b"_limit", "_pagination_token", b"_pagination_token", "_prefix", b"_prefix", "limit", b"limit", "pagination_token", b"pagination_token", "prefix", b"prefix"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_limit", b"_limit", "_pagination_token", b"_pagination_token", "_prefix", b"_prefix", "limit", b"limit", "namespace", b"namespace", "pagination_token", b"pagination_token", "prefix", b"prefix"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_limit", b"_limit"]) -> typing.Literal["limit"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_pagination_token", b"_pagination_token"]) -> typing.Literal["pagination_token"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_prefix", b"_prefix"]) -> typing.Literal["prefix"] | None: ... + +global___ListRequest = ListRequest + +@typing.final +class Pagination(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NEXT_FIELD_NUMBER: builtins.int + next: builtins.str + def __init__( + self, *, - next : typing___Optional[typing___Text] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"next",b"next"]) -> None: ... -type___Pagination = Pagination + next: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["next", b"next"]) -> None: ... -class ListItem(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - id: typing___Text = ... +global___Pagination = Pagination - def __init__(self, +@typing.final +class ListItem(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + id: builtins.str + def __init__( + self, *, - id : typing___Optional[typing___Text] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"id",b"id"]) -> None: ... -type___ListItem = ListItem + id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["id", b"id"]) -> None: ... + +global___ListItem = ListItem -class ListResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - namespace: typing___Text = ... +@typing.final +class ListResponse(google.protobuf.message.Message): + """The response for the `List` operation.""" + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VECTORS_FIELD_NUMBER: builtins.int + PAGINATION_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + USAGE_FIELD_NUMBER: builtins.int + namespace: builtins.str + """The namespace of the vectors.""" @property - def vectors(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___ListItem]: ... + def vectors(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ListItem]: + """A list of ids""" @property - def pagination(self) -> type___Pagination: ... + def pagination(self) -> global___Pagination: + """Pagination token to continue past this listing""" @property - def usage(self) -> type___Usage: ... + def usage(self) -> global___Usage: + """ The usage for this operation.""" - def __init__(self, + def __init__( + self, *, - vectors : typing___Optional[typing___Iterable[type___ListItem]] = None, - pagination : typing___Optional[type___Pagination] = None, - namespace : typing___Optional[typing___Text] = None, - usage : typing___Optional[type___Usage] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"_pagination",b"_pagination",u"_usage",b"_usage",u"pagination",b"pagination",u"usage",b"usage"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"_pagination",b"_pagination",u"_usage",b"_usage",u"namespace",b"namespace",u"pagination",b"pagination",u"usage",b"usage",u"vectors",b"vectors"]) -> None: ... - @typing___overload - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_pagination",b"_pagination"]) -> typing_extensions___Literal["pagination"]: ... - @typing___overload - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_usage",b"_usage"]) -> typing_extensions___Literal["usage"]: ... -type___ListResponse = ListResponse - -class QueryVector(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... - top_k: builtin___int = ... - namespace: typing___Text = ... + vectors: collections.abc.Iterable[global___ListItem] | None = ..., + pagination: global___Pagination | None = ..., + namespace: builtins.str = ..., + usage: global___Usage | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_pagination", b"_pagination", "_usage", b"_usage", "pagination", b"pagination", "usage", b"usage"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_pagination", b"_pagination", "_usage", b"_usage", "namespace", b"namespace", "pagination", b"pagination", "usage", b"usage", "vectors", b"vectors"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_pagination", b"_pagination"]) -> typing.Literal["pagination"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_usage", b"_usage"]) -> typing.Literal["usage"] | None: ... + +global___ListResponse = ListResponse + +@typing.final +class QueryVector(google.protobuf.message.Message): + """A single query vector within a `QueryRequest`.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUES_FIELD_NUMBER: builtins.int + SPARSE_VALUES_FIELD_NUMBER: builtins.int + TOP_K_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + FILTER_FIELD_NUMBER: builtins.int + top_k: builtins.int + """An override for the number of results to return for this query vector.""" + namespace: builtins.str + """An override the namespace to search.""" + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """The query vector values. This should be the same length as the dimension of the index being queried.""" @property - def sparse_values(self) -> type___SparseValues: ... + def sparse_values(self) -> global___SparseValues: + """The query sparse values.""" @property - def filter(self) -> google___protobuf___struct_pb2___Struct: ... + def filter(self) -> google.protobuf.struct_pb2.Struct: + """An override for the metadata filter to apply. This replaces the request-level filter.""" - def __init__(self, + def __init__( + self, *, - values : typing___Optional[typing___Iterable[builtin___float]] = None, - sparse_values : typing___Optional[type___SparseValues] = None, - top_k : typing___Optional[builtin___int] = None, - namespace : typing___Optional[typing___Text] = None, - filter : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"filter",b"filter",u"sparse_values",b"sparse_values"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"filter",b"filter",u"namespace",b"namespace",u"sparse_values",b"sparse_values",u"top_k",b"top_k",u"values",b"values"]) -> None: ... -type___QueryVector = QueryVector - -class QueryRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - namespace: typing___Text = ... - top_k: builtin___int = ... - include_values: builtin___bool = ... - include_metadata: builtin___bool = ... - vector: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... - id: typing___Text = ... + values: collections.abc.Iterable[builtins.float] | None = ..., + sparse_values: global___SparseValues | None = ..., + top_k: builtins.int = ..., + namespace: builtins.str = ..., + filter: google.protobuf.struct_pb2.Struct | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["filter", b"filter", "sparse_values", b"sparse_values"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["filter", b"filter", "namespace", b"namespace", "sparse_values", b"sparse_values", "top_k", b"top_k", "values", b"values"]) -> None: ... + +global___QueryVector = QueryVector + +@typing.final +class QueryRequest(google.protobuf.message.Message): + """The request for the `query` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAMESPACE_FIELD_NUMBER: builtins.int + TOP_K_FIELD_NUMBER: builtins.int + FILTER_FIELD_NUMBER: builtins.int + INCLUDE_VALUES_FIELD_NUMBER: builtins.int + INCLUDE_METADATA_FIELD_NUMBER: builtins.int + QUERIES_FIELD_NUMBER: builtins.int + VECTOR_FIELD_NUMBER: builtins.int + SPARSE_VECTOR_FIELD_NUMBER: builtins.int + ID_FIELD_NUMBER: builtins.int + namespace: builtins.str + """The namespace to query.""" + top_k: builtins.int + """The number of results to return for each query.""" + include_values: builtins.bool + """Indicates whether vector values are included in the response.""" + include_metadata: builtins.bool + """Indicates whether metadata is included in the response as well as the ids.""" + id: builtins.str + """The unique ID of the vector to be used as a query vector. Each `query()` request can contain only one of the parameters `queries`, `vector`, or `id`.""" + @property + def filter(self) -> google.protobuf.struct_pb2.Struct: + """The filter to apply. You can use vector metadata to limit your search. See https://www.pinecone.io/docs/metadata-filtering/.""" @property - def filter(self) -> google___protobuf___struct_pb2___Struct: ... + def queries(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___QueryVector]: + """DEPRECATED. The query vectors. Each `query()` request can contain only one of the parameters `queries`, `vector`, or `id`.""" @property - def queries(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___QueryVector]: ... + def vector(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """The query vector. This should be the same length as the dimension of the index being queried. Each `query()` request can contain only one of the parameters `id` or `vector`.""" @property - def sparse_vector(self) -> type___SparseValues: ... + def sparse_vector(self) -> global___SparseValues: + """The query sparse values.""" - def __init__(self, + def __init__( + self, *, - namespace : typing___Optional[typing___Text] = None, - top_k : typing___Optional[builtin___int] = None, - filter : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - include_values : typing___Optional[builtin___bool] = None, - include_metadata : typing___Optional[builtin___bool] = None, - queries : typing___Optional[typing___Iterable[type___QueryVector]] = None, - vector : typing___Optional[typing___Iterable[builtin___float]] = None, - sparse_vector : typing___Optional[type___SparseValues] = None, - id : typing___Optional[typing___Text] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"filter",b"filter",u"sparse_vector",b"sparse_vector"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"filter",b"filter",u"id",b"id",u"include_metadata",b"include_metadata",u"include_values",b"include_values",u"namespace",b"namespace",u"queries",b"queries",u"sparse_vector",b"sparse_vector",u"top_k",b"top_k",u"vector",b"vector"]) -> None: ... -type___QueryRequest = QueryRequest - -class SingleQueryResults(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - namespace: typing___Text = ... - + namespace: builtins.str = ..., + top_k: builtins.int = ..., + filter: google.protobuf.struct_pb2.Struct | None = ..., + include_values: builtins.bool = ..., + include_metadata: builtins.bool = ..., + queries: collections.abc.Iterable[global___QueryVector] | None = ..., + vector: collections.abc.Iterable[builtins.float] | None = ..., + sparse_vector: global___SparseValues | None = ..., + id: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["filter", b"filter", "sparse_vector", b"sparse_vector"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["filter", b"filter", "id", b"id", "include_metadata", b"include_metadata", "include_values", b"include_values", "namespace", b"namespace", "queries", b"queries", "sparse_vector", b"sparse_vector", "top_k", b"top_k", "vector", b"vector"]) -> None: ... + +global___QueryRequest = QueryRequest + +@typing.final +class SingleQueryResults(google.protobuf.message.Message): + """The query results for a single `QueryVector`""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MATCHES_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + namespace: builtins.str + """The namespace for the vectors.""" @property - def matches(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___ScoredVector]: ... + def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScoredVector]: + """The matches for the vectors.""" - def __init__(self, + def __init__( + self, *, - matches : typing___Optional[typing___Iterable[type___ScoredVector]] = None, - namespace : typing___Optional[typing___Text] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"matches",b"matches",u"namespace",b"namespace"]) -> None: ... -type___SingleQueryResults = SingleQueryResults + matches: collections.abc.Iterable[global___ScoredVector] | None = ..., + namespace: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["matches", b"matches", "namespace", b"namespace"]) -> None: ... + +global___SingleQueryResults = SingleQueryResults + +@typing.final +class QueryResponse(google.protobuf.message.Message): + """The response for the `query` operation. These are the matches found for a particular query vector. The matches are ordered from most similar to least similar.""" -class QueryResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - namespace: typing___Text = ... + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RESULTS_FIELD_NUMBER: builtins.int + MATCHES_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + USAGE_FIELD_NUMBER: builtins.int + namespace: builtins.str + """The namespace for the vectors.""" @property - def results(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___SingleQueryResults]: ... + def results(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SingleQueryResults]: + """DEPRECATED. The results of each query. The order is the same as `QueryRequest.queries`.""" @property - def matches(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[type___ScoredVector]: ... + def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScoredVector]: + """The matches for the vectors.""" @property - def usage(self) -> type___Usage: ... + def usage(self) -> global___Usage: + """The usage for this operation.""" - def __init__(self, + def __init__( + self, *, - results : typing___Optional[typing___Iterable[type___SingleQueryResults]] = None, - matches : typing___Optional[typing___Iterable[type___ScoredVector]] = None, - namespace : typing___Optional[typing___Text] = None, - usage : typing___Optional[type___Usage] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"_usage",b"_usage",u"usage",b"usage"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"_usage",b"_usage",u"matches",b"matches",u"namespace",b"namespace",u"results",b"results",u"usage",b"usage"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_usage",b"_usage"]) -> typing_extensions___Literal["usage"]: ... -type___QueryResponse = QueryResponse - -class Usage(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - read_units: builtin___int = ... - - def __init__(self, + results: collections.abc.Iterable[global___SingleQueryResults] | None = ..., + matches: collections.abc.Iterable[global___ScoredVector] | None = ..., + namespace: builtins.str = ..., + usage: global___Usage | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_usage", b"_usage", "usage", b"usage"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_usage", b"_usage", "matches", b"matches", "namespace", b"namespace", "results", b"results", "usage", b"usage"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_usage", b"_usage"]) -> typing.Literal["usage"] | None: ... + +global___QueryResponse = QueryResponse + +@typing.final +class Usage(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + READ_UNITS_FIELD_NUMBER: builtins.int + read_units: builtins.int + """The number of read units consumed by this operation.""" + def __init__( + self, *, - read_units : typing___Optional[builtin___int] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"_read_units",b"_read_units",u"read_units",b"read_units"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"_read_units",b"_read_units",u"read_units",b"read_units"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"_read_units",b"_read_units"]) -> typing_extensions___Literal["read_units"]: ... -type___Usage = Usage - -class UpdateRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - id: typing___Text = ... - values: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] = ... - namespace: typing___Text = ... - + read_units: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_read_units", b"_read_units", "read_units", b"read_units"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_read_units", b"_read_units", "read_units", b"read_units"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_read_units", b"_read_units"]) -> typing.Literal["read_units"] | None: ... + +global___Usage = Usage + +@typing.final +class UpdateRequest(google.protobuf.message.Message): + """The request for the `update` operation.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ID_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + SPARSE_VALUES_FIELD_NUMBER: builtins.int + SET_METADATA_FIELD_NUMBER: builtins.int + NAMESPACE_FIELD_NUMBER: builtins.int + id: builtins.str + """Vector's unique id.""" + namespace: builtins.str + """Namespace name where to update the vector.""" @property - def sparse_values(self) -> type___SparseValues: ... + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """Vector data.""" @property - def set_metadata(self) -> google___protobuf___struct_pb2___Struct: ... + def sparse_values(self) -> global___SparseValues: ... + @property + def set_metadata(self) -> google.protobuf.struct_pb2.Struct: + """Metadata to *set* for the vector.""" - def __init__(self, + def __init__( + self, *, - id : typing___Optional[typing___Text] = None, - values : typing___Optional[typing___Iterable[builtin___float]] = None, - sparse_values : typing___Optional[type___SparseValues] = None, - set_metadata : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - namespace : typing___Optional[typing___Text] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"set_metadata",b"set_metadata",u"sparse_values",b"sparse_values"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"id",b"id",u"namespace",b"namespace",u"set_metadata",b"set_metadata",u"sparse_values",b"sparse_values",u"values",b"values"]) -> None: ... -type___UpdateRequest = UpdateRequest + id: builtins.str = ..., + values: collections.abc.Iterable[builtins.float] | None = ..., + sparse_values: global___SparseValues | None = ..., + set_metadata: google.protobuf.struct_pb2.Struct | None = ..., + namespace: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["set_metadata", b"set_metadata", "sparse_values", b"sparse_values"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "namespace", b"namespace", "set_metadata", b"set_metadata", "sparse_values", b"sparse_values", "values", b"values"]) -> None: ... -class UpdateResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... +global___UpdateRequest = UpdateRequest - def __init__(self, - ) -> None: ... -type___UpdateResponse = UpdateResponse +@typing.final +class UpdateResponse(google.protobuf.message.Message): + """The response for the `update` operation.""" -class DescribeIndexStatsRequest(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + DESCRIPTOR: google.protobuf.descriptor.Descriptor - @property - def filter(self) -> google___protobuf___struct_pb2___Struct: ... + def __init__( + self, + ) -> None: ... - def __init__(self, - *, - filter : typing___Optional[google___protobuf___struct_pb2___Struct] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"filter",b"filter"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"filter",b"filter"]) -> None: ... -type___DescribeIndexStatsRequest = DescribeIndexStatsRequest +global___UpdateResponse = UpdateResponse + +@typing.final +class DescribeIndexStatsRequest(google.protobuf.message.Message): + """The request for the `describe_index_stats` operation.""" -class NamespaceSummary(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - vector_count: builtin___int = ... + DESCRIPTOR: google.protobuf.descriptor.Descriptor - def __init__(self, + FILTER_FIELD_NUMBER: builtins.int + @property + def filter(self) -> google.protobuf.struct_pb2.Struct: + """If this parameter is present, the operation only returns statistics + for vectors that satisfy the filter. + See https://www.pinecone.io/docs/metadata-filtering/. + """ + + def __init__( + self, *, - vector_count : typing___Optional[builtin___int] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"vector_count",b"vector_count"]) -> None: ... -type___NamespaceSummary = NamespaceSummary + filter: google.protobuf.struct_pb2.Struct | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["filter", b"filter"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["filter", b"filter"]) -> None: ... + +global___DescribeIndexStatsRequest = DescribeIndexStatsRequest + +@typing.final +class NamespaceSummary(google.protobuf.message.Message): + """A summary of the contents of a namespace.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VECTOR_COUNT_FIELD_NUMBER: builtins.int + vector_count: builtins.int + """The number of vectors stored in this namespace. Note that updates to this field may lag behind updates to the + underlying index and corresponding query results, etc. + """ + def __init__( + self, + *, + vector_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["vector_count", b"vector_count"]) -> None: ... -class DescribeIndexStatsResponse(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - class NamespacesEntry(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - key: typing___Text = ... +global___NamespaceSummary = NamespaceSummary - @property - def value(self) -> type___NamespaceSummary: ... +@typing.final +class DescribeIndexStatsResponse(google.protobuf.message.Message): + """The response for the `describe_index_stats` operation.""" - def __init__(self, - *, - key : typing___Optional[typing___Text] = None, - value : typing___Optional[type___NamespaceSummary] = None, - ) -> None: ... - def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... - type___NamespacesEntry = NamespacesEntry + DESCRIPTOR: google.protobuf.descriptor.Descriptor - dimension: builtin___int = ... - index_fullness: builtin___float = ... - total_vector_count: builtin___int = ... + @typing.final + class NamespacesEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___NamespaceSummary: ... + def __init__( + self, + *, + key: builtins.str = ..., + value: global___NamespaceSummary | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... + + NAMESPACES_FIELD_NUMBER: builtins.int + DIMENSION_FIELD_NUMBER: builtins.int + INDEX_FULLNESS_FIELD_NUMBER: builtins.int + TOTAL_VECTOR_COUNT_FIELD_NUMBER: builtins.int + dimension: builtins.int + """The dimension of the indexed vectors.""" + index_fullness: builtins.float + """The fullness of the index, regardless of whether a metadata filter expression was passed. The granularity of this metric is 10%.""" + total_vector_count: builtins.int + """The total number of vectors in the index, regardless of whether a metadata filter expression was passed""" @property - def namespaces(self) -> google___protobuf___internal___containers___MessageMap[typing___Text, type___NamespaceSummary]: ... - - def __init__(self, + def namespaces(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___NamespaceSummary]: + """A mapping for each namespace in the index from the namespace name to a + summary of its contents. If a metadata filter expression is present, the + summary will reflect only vectors matching that expression. + """ + + def __init__( + self, *, - namespaces : typing___Optional[typing___Mapping[typing___Text, type___NamespaceSummary]] = None, - dimension : typing___Optional[builtin___int] = None, - index_fullness : typing___Optional[builtin___float] = None, - total_vector_count : typing___Optional[builtin___int] = None, - ) -> None: ... - def ClearField(self, field_name: typing_extensions___Literal[u"dimension",b"dimension",u"index_fullness",b"index_fullness",u"namespaces",b"namespaces",u"total_vector_count",b"total_vector_count"]) -> None: ... -type___DescribeIndexStatsResponse = DescribeIndexStatsResponse + namespaces: collections.abc.Mapping[builtins.str, global___NamespaceSummary] | None = ..., + dimension: builtins.int = ..., + index_fullness: builtins.float = ..., + total_vector_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dimension", b"dimension", "index_fullness", b"index_fullness", "namespaces", b"namespaces", "total_vector_count", b"total_vector_count"]) -> None: ... + +global___DescribeIndexStatsResponse = DescribeIndexStatsResponse diff --git a/pinecone/core/grpc/protos/vector_service_pb2_grpc.py b/pinecone/core/grpc/protos/vector_service_pb2_grpc.py index cdde2f85..f3126923 100644 --- a/pinecone/core/grpc/protos/vector_service_pb2_grpc.py +++ b/pinecone/core/grpc/protos/vector_service_pb2_grpc.py @@ -84,7 +84,7 @@ def Fetch(self, request, context): The `fetch` operation looks up and returns vectors, by ID, from a single namespace. The returned vectors include the vector data and/or metadata. - For guidance and examples, see [Fetch data](https://docs.pinecone.io/reference/fetch). + For guidance and examples, see [Fetch data](https://docs.pinecone.io/docs/fetch-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -121,7 +121,7 @@ def Update(self, request, context): The `update` operation updates a vector in a namespace. If a value is included, it will overwrite the previous value. If a `set_metadata` is included, the values of the fields specified in it will be added or overwrite the previous value. - For guidance and examples, see [Update data](https://docs.pinecone.io/reference/update). + For guidance and examples, see [Update data](https://docs.pinecone.io/docs/update-data). """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') diff --git a/pinecone/data/__init__.py b/pinecone/data/__init__.py index 5144527c..4caf309e 100644 --- a/pinecone/data/__init__.py +++ b/pinecone/data/__init__.py @@ -1,5 +1,5 @@ from .index import * -from .vector_factory import ( +from .errors import ( VectorDictionaryMissingKeysError, VectorDictionaryExcessKeysError, VectorTupleLengthError, diff --git a/pinecone/data/errors.py b/pinecone/data/errors.py new file mode 100644 index 00000000..7749a9cf --- /dev/null +++ b/pinecone/data/errors.py @@ -0,0 +1,37 @@ +from ..utils.constants import REQUIRED_VECTOR_FIELDS, OPTIONAL_VECTOR_FIELDS + +class VectorDictionaryMissingKeysError(ValueError): + def __init__(self, item): + message = f"Vector dictionary is missing required fields: {list(REQUIRED_VECTOR_FIELDS - set(item.keys()))}" + super().__init__(message) + +class VectorDictionaryExcessKeysError(ValueError): + def __init__(self, item): + invalid_keys = list(set(item.keys()) - (REQUIRED_VECTOR_FIELDS | OPTIONAL_VECTOR_FIELDS)) + message = f"Found excess keys in the vector dictionary: {invalid_keys}. The allowed keys are: {list(REQUIRED_VECTOR_FIELDS | OPTIONAL_VECTOR_FIELDS)}" + super().__init__(message) + +class VectorTupleLengthError(ValueError): + def __init__(self, item): + message = f"Found a tuple of length {len(item)} which is not supported. Vectors can be represented as tuples either the form (id, values, metadata) or (id, values). To pass sparse values please use either dicts or Vector objects as inputs." + super().__init__(message) + +class SparseValuesTypeError(ValueError, TypeError): + def __init__(self): + message = "Found unexpected data in column `sparse_values`. Expected format is `'sparse_values': {'indices': List[int], 'values': List[float]}`." + super().__init__(message) + +class SparseValuesMissingKeysError(ValueError): + def __init__(self, sparse_values_dict): + message = f"Missing required keys in data in column `sparse_values`. Expected format is `'sparse_values': {{'indices': List[int], 'values': List[float]}}`. Found keys {list(sparse_values_dict.keys())}" + super().__init__(message) + +class SparseValuesDictionaryExpectedError(ValueError, TypeError): + def __init__(self, sparse_values_dict): + message = f"Column `sparse_values` is expected to be a dictionary, found {type(sparse_values_dict)}" + super().__init__(message) + +class MetadataDictionaryExpectedError(ValueError, TypeError): + def __init__(self, item): + message = f"Column `metadata` is expected to be a dictionary, found {type(item['metadata'])}" + super().__init__(message) diff --git a/pinecone/data/index.py b/pinecone/data/index.py index 6befe5eb..8596c7eb 100644 --- a/pinecone/data/index.py +++ b/pinecone/data/index.py @@ -24,7 +24,7 @@ ListResponse ) from pinecone.core.client.api.data_plane_api import DataPlaneApi -from ..utils import get_user_agent +from ..utils import setup_openapi_client from .vector_factory import VectorFactory __all__ = [ @@ -75,27 +75,24 @@ def __init__( host: str, pool_threads: Optional[int] = 1, additional_headers: Optional[Dict[str, str]] = {}, + openapi_config = None, **kwargs ): - self._config = ConfigBuilder.build(api_key=api_key, host=host, **kwargs) + self._config = ConfigBuilder.build( + api_key=api_key, + host=host, + additional_headers=additional_headers, + **kwargs + ) + openapi_config = ConfigBuilder.build_openapi_config(self._config, openapi_config) - api_client = ApiClient(configuration=self._config.openapi_config, - pool_threads=pool_threads) - - # Configure request headers - api_client.user_agent = get_user_agent() - extra_headers = additional_headers or {} - for key, value in extra_headers.items(): - api_client.set_default_header(key, value) - - self._api_client = api_client - self._vector_api = DataPlaneApi(api_client=api_client) + self._vector_api = setup_openapi_client(DataPlaneApi, self._config, openapi_config, pool_threads) def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): - self._api_client.close() + self._vector_api.api_client.close() @validate_and_convert_errors def upsert( diff --git a/pinecone/data/sparse_vector_factory.py b/pinecone/data/sparse_vector_factory.py new file mode 100644 index 00000000..e759ffdd --- /dev/null +++ b/pinecone/data/sparse_vector_factory.py @@ -0,0 +1,54 @@ +import numbers + +from collections.abc import Mapping +from typing import Union, Dict + +from ..utils import convert_to_list + +from .errors import ( + SparseValuesTypeError, + SparseValuesMissingKeysError, + SparseValuesDictionaryExpectedError +) + +from pinecone.core.client.models import ( + SparseValues +) + +class SparseValuesFactory: + @staticmethod + def build(input: Union[Dict, SparseValues]) -> SparseValues: + if input is None: + return input + if isinstance(input, SparseValues): + return input + if not isinstance(input, Mapping): + raise SparseValuesDictionaryExpectedError(input) + if not {"indices", "values"}.issubset(input): + raise SparseValuesMissingKeysError(input) + + indices = SparseValuesFactory._convert_to_list(input.get("indices"), int) + values = SparseValuesFactory._convert_to_list(input.get("values"), float) + + if len(indices) != len(values): + raise ValueError("Sparse values indices and values must have the same length") + + try: + return SparseValues(indices=indices, values=values) + except TypeError as e: + raise SparseValuesTypeError() from e + + @staticmethod + def _convert_to_list(input, expected_type): + try: + converted = convert_to_list(input) + except TypeError as e: + raise SparseValuesTypeError() from e + + SparseValuesFactory._validate_list_items_type(converted, expected_type) + return converted + + @staticmethod + def _validate_list_items_type(input, expected_type): + if len(input) > 0 and not isinstance(input[0], expected_type): + raise SparseValuesTypeError() \ No newline at end of file diff --git a/pinecone/data/vector_factory.py b/pinecone/data/vector_factory.py index ff1f0bd6..3b486b1c 100644 --- a/pinecone/data/vector_factory.py +++ b/pinecone/data/vector_factory.py @@ -5,47 +5,19 @@ from ..utils import fix_tuple_length, convert_to_list from ..utils.constants import REQUIRED_VECTOR_FIELDS, OPTIONAL_VECTOR_FIELDS +from .sparse_vector_factory import SparseValuesFactory from pinecone.core.client.models import ( Vector, SparseValues ) -class VectorDictionaryMissingKeysError(ValueError): - def __init__(self, item): - message = f"Vector dictionary is missing required fields: {list(REQUIRED_VECTOR_FIELDS - set(item.keys()))}" - super().__init__(message) - -class VectorDictionaryExcessKeysError(ValueError): - def __init__(self, item): - invalid_keys = list(set(item.keys()) - (REQUIRED_VECTOR_FIELDS | OPTIONAL_VECTOR_FIELDS)) - message = f"Found excess keys in the vector dictionary: {invalid_keys}. The allowed keys are: {list(REQUIRED_VECTOR_FIELDS | OPTIONAL_VECTOR_FIELDS)}" - super().__init__(message) - -class VectorTupleLengthError(ValueError): - def __init__(self, item): - message = f"Found a tuple of length {len(item)} which is not supported. Vectors can be represented as tuples either the form (id, values, metadata) or (id, values). To pass sparse values please use either dicts or Vector objects as inputs." - super().__init__(message) - -class SparseValuesTypeError(ValueError, TypeError): - def __init__(self): - message = "Found unexpected data in column `sparse_values`. Expected format is `'sparse_values': {'indices': List[int], 'values': List[float]}`." - super().__init__(message) - -class SparseValuesMissingKeysError(ValueError): - def __init__(self, sparse_values_dict): - message = f"Missing required keys in data in column `sparse_values`. Expected format is `'sparse_values': {{'indices': List[int], 'values': List[float]}}`. Found keys {list(sparse_values_dict.keys())}" - super().__init__(message) - -class SparseValuesDictionaryExpectedError(ValueError, TypeError): - def __init__(self, sparse_values_dict): - message = f"Column `sparse_values` is expected to be a dictionary, found {type(sparse_values_dict)}" - super().__init__(message) - -class MetadataDictionaryExpectedError(ValueError, TypeError): - def __init__(self, item): - message = f"Column `metadata` is expected to be a dictionary, found {type(item['metadata'])}" - super().__init__(message) +from .errors import ( + VectorDictionaryMissingKeysError, + VectorDictionaryExcessKeysError, + VectorTupleLengthError, + MetadataDictionaryExpectedError, +) class VectorFactory: @staticmethod @@ -84,8 +56,10 @@ def _dict_to_vector(item, check_type: bool) -> Vector: item["values"] = convert_to_list(values) sparse_values = item.get("sparse_values") - if sparse_values and not isinstance(sparse_values, SparseValues): - item["sparse_values"] = VectorFactory._dict_to_sparse_values(sparse_values, check_type) + if sparse_values is None: + item.pop("sparse_values", None) + else: + item["sparse_values"] = SparseValuesFactory.build(sparse_values) metadata = item.get("metadata") if metadata and not isinstance(metadata, Mapping): @@ -97,18 +71,3 @@ def _dict_to_vector(item, check_type: bool) -> Vector: if not isinstance(item["values"], Iterable) or not isinstance(item["values"].__iter__().__next__(), numbers.Real): raise TypeError(f"Column `values` is expected to be a list of floats") raise e - - @staticmethod - def _dict_to_sparse_values(sparse_values_dict: Dict, check_type: bool) -> SparseValues: - if not isinstance(sparse_values_dict, Mapping): - raise SparseValuesDictionaryExpectedError(sparse_values_dict) - if not {"indices", "values"}.issubset(sparse_values_dict): - raise SparseValuesMissingKeysError(sparse_values_dict) - - indices = convert_to_list(sparse_values_dict.get("indices")) - values = convert_to_list(sparse_values_dict.get("values")) - - try: - return SparseValues(indices=indices, values=values, _check_type=check_type) - except TypeError: - raise SparseValuesTypeError() \ No newline at end of file diff --git a/pinecone/exceptions.py b/pinecone/exceptions.py index 24319f65..81a52f61 100644 --- a/pinecone/exceptions.py +++ b/pinecone/exceptions.py @@ -17,6 +17,10 @@ class PineconeProtocolError(PineconeException): class PineconeConfigurationError(PineconeException): """Raised when a configuration error occurs.""" +class ListConversionException(PineconeException, TypeError): + def __init__(self, message): + super().__init__(message) + __all__ = [ "PineconeConfigurationError", "PineconeProtocolError", @@ -30,4 +34,5 @@ class PineconeConfigurationError(PineconeException): "UnauthorizedException", "ForbiddenException", "ServiceException", + "ListConversionException" ] diff --git a/pinecone/grpc/base.py b/pinecone/grpc/base.py index 70864ba2..00a98e6b 100644 --- a/pinecone/grpc/base.py +++ b/pinecone/grpc/base.py @@ -14,6 +14,7 @@ from .utils import _generate_request_id from .config import GRPCClientConfig from pinecone.utils.constants import MAX_MSG_SIZE, REQUEST_ID, CLIENT_VERSION +from pinecone.utils.user_agent import get_user_agent_grpc from pinecone.exceptions import PineconeException _logger = logging.getLogger(__name__) @@ -77,7 +78,8 @@ def __init__( } ) - self._channel = channel or self._gen_channel() + options = {"grpc.primary_user_agent": get_user_agent_grpc(config)} + self._channel = channel or self._gen_channel(options=options) self.stub = self.stub_class(self._channel) @property @@ -99,6 +101,8 @@ def _gen_channel(self, options=None): } if self.grpc_client_config.secure: default_options["grpc.ssl_target_name_override"] = target.split(":")[0] + if self.config.proxy_url: + default_options["grpc.http_proxy"] = self.config.proxy_url user_provided_options = options or {} _options = tuple((k, v) for k, v in {**default_options, **user_provided_options}.items()) _logger.debug( @@ -107,7 +111,8 @@ def _gen_channel(self, options=None): if not self.grpc_client_config.secure: channel = grpc.insecure_channel(target, options=_options) else: - root_cas = open(certifi.where(), "rb").read() + ca_certs = self.config.ssl_ca_certs if self.config.ssl_ca_certs else certifi.where() + root_cas = open(ca_certs, "rb").read() tls = grpc.ssl_channel_credentials(root_certificates=root_cas) channel = grpc.secure_channel(target, tls, options=_options) diff --git a/pinecone/grpc/pinecone.py b/pinecone/grpc/pinecone.py index c7141d79..3f2ddb46 100644 --- a/pinecone/grpc/pinecone.py +++ b/pinecone/grpc/pinecone.py @@ -120,13 +120,12 @@ def Index(self, name: str = '', host: str = '', **kwargs): if name == '' and host == '': raise ValueError("Either name or host must be specified") - if host != '': - # Use host if it is provided - config = ConfigBuilder.build(api_key=self.config.api_key, host=host) - return GRPCIndex(index_name=name, config=config, **kwargs) - - if name != '': - # Otherwise, get host url from describe_index using the index name - index_host = self.index_host_store.get_host(self.index_api, self.config, name) - config = ConfigBuilder.build(api_key=self.config.api_key, host=index_host) - return GRPCIndex(index_name=name, config=config, **kwargs) \ No newline at end of file + # Use host if it is provided, otherwise get host from describe_index + index_host = host or self.index_host_store.get_host(self.index_api, self.config, name) + + config = ConfigBuilder.build(api_key=self.config.api_key, + host=index_host, + source_tag=self.config.source_tag, + proxy_url=self.config.proxy_url, + ssl_ca_certs=self.config.ssl_ca_certs) + return GRPCIndex(index_name=name, config=config, **kwargs) \ No newline at end of file diff --git a/pinecone/grpc/sparse_values_factory.py b/pinecone/grpc/sparse_values_factory.py new file mode 100644 index 00000000..452f131d --- /dev/null +++ b/pinecone/grpc/sparse_values_factory.py @@ -0,0 +1,59 @@ +import numbers + +from collections.abc import Mapping +from typing import Union, Dict + +from ..utils import convert_to_list + +from ..data import ( + SparseValuesTypeError, + SparseValuesMissingKeysError, + SparseValuesDictionaryExpectedError +) + +from pinecone.core.grpc.protos.vector_service_pb2 import ( + SparseValues as GRPCSparseValues, +) +from pinecone import ( + SparseValues as NonGRPCSparseValues +) + +class SparseValuesFactory: + @staticmethod + def build(input: Union[Dict, GRPCSparseValues, NonGRPCSparseValues]) -> GRPCSparseValues: + if input is None: + return input + if isinstance(input, GRPCSparseValues): + return input + if isinstance(input, NonGRPCSparseValues): + return GRPCSparseValues(indices=input.indices, values=input.values) + if not isinstance(input, Mapping): + raise SparseValuesDictionaryExpectedError(input) + if not {"indices", "values"}.issubset(input): + raise SparseValuesMissingKeysError(input) + + indices = SparseValuesFactory._convert_to_list(input.get("indices"), int) + values = SparseValuesFactory._convert_to_list(input.get("values"), float) + + if len(indices) != len(values): + raise ValueError("Sparse values indices and values must have the same length") + + try: + return GRPCSparseValues(indices=indices, values=values) + except TypeError as e: + raise SparseValuesTypeError() from e + + @staticmethod + def _convert_to_list(input, expected_type): + try: + converted = convert_to_list(input) + except TypeError as e: + raise SparseValuesTypeError() from e + + SparseValuesFactory._validate_list_items_type(converted, expected_type) + return converted + + @staticmethod + def _validate_list_items_type(input, expected_type): + if len(input) > 0 and not isinstance(input[0], expected_type): + raise SparseValuesTypeError() \ No newline at end of file diff --git a/pinecone/grpc/vector_factory_grpc.py b/pinecone/grpc/vector_factory_grpc.py index c5368d73..2ea62a08 100644 --- a/pinecone/grpc/vector_factory_grpc.py +++ b/pinecone/grpc/vector_factory_grpc.py @@ -12,11 +12,9 @@ VectorDictionaryMissingKeysError, VectorDictionaryExcessKeysError, VectorTupleLengthError, - SparseValuesTypeError, - SparseValuesMissingKeysError, - SparseValuesDictionaryExpectedError, MetadataDictionaryExpectedError ) +from .sparse_values_factory import SparseValuesFactory from pinecone.core.grpc.protos.vector_service_pb2 import ( Vector as GRPCVector, @@ -73,8 +71,8 @@ def _dict_to_vector(item) -> GRPCVector: raise TypeError(f"Column `values` is expected to be a list of floats") from e sparse_values = item.get("sparse_values") - if sparse_values and not isinstance(sparse_values, GRPCSparseValues): - item["sparse_values"] = VectorFactoryGRPC._dict_to_sparse_values(sparse_values) + if sparse_values != None and not isinstance(sparse_values, GRPCSparseValues): + item["sparse_values"] = SparseValuesFactory.build(sparse_values) metadata = item.get("metadata") if metadata: @@ -88,34 +86,11 @@ def _dict_to_vector(item) -> GRPCVector: try: return GRPCVector(**item) except TypeError as e: + # Where possible raise a more specific error to the user. + vid = item.get("id") + if not isinstance(vid, bytes) and not isinstance(vid, str): + raise TypeError(f"Cannot set Vector.id to {vid}: {vid} has type {type(vid)}, " + "but expected one of: (, ) for field Vector.id") if not isinstance(item["values"], Iterable) or not isinstance(item["values"].__iter__().__next__(), numbers.Real): raise TypeError(f"Column `values` is expected to be a list of floats") - raise e - - @staticmethod - def _dict_to_sparse_values(sparse_values_dict: Union[Dict, GRPCSparseValues, NonGRPCSparseValues]) -> GRPCSparseValues: - if isinstance(sparse_values_dict, GRPCSparseValues): - return sparse_values_dict - if isinstance(sparse_values_dict, NonGRPCSparseValues): - return GRPCSparseValues(indices=sparse_values_dict.indices, values=sparse_values_dict.values) - - if not isinstance(sparse_values_dict, Mapping): - raise SparseValuesDictionaryExpectedError(sparse_values_dict) - if not {"indices", "values"}.issubset(sparse_values_dict): - raise SparseValuesMissingKeysError(sparse_values_dict) - - - try: - indices = convert_to_list(sparse_values_dict.get("indices")) - except TypeError as e: - raise SparseValuesTypeError() from e - - try: - values = convert_to_list(sparse_values_dict.get("values")) - except TypeError as e: - raise SparseValuesTypeError() from e - - try: - return GRPCSparseValues(indices=indices, values=values) - except TypeError as e: - raise SparseValuesTypeError() from e \ No newline at end of file + raise e \ No newline at end of file diff --git a/pinecone/utils/__init__.py b/pinecone/utils/__init__.py index e4ce28b6..56599293 100644 --- a/pinecone/utils/__init__.py +++ b/pinecone/utils/__init__.py @@ -4,4 +4,6 @@ from .deprecation_notice import warn_deprecated from .fix_tuple_length import fix_tuple_length from .convert_to_list import convert_to_list -from .normalize_host import normalize_host \ No newline at end of file +from .normalize_host import normalize_host +from .setup_openapi_client import setup_openapi_client +from .docslinks import docslinks \ No newline at end of file diff --git a/pinecone/utils/constants.py b/pinecone/utils/constants.py index 0f29331b..cd49b401 100644 --- a/pinecone/utils/constants.py +++ b/pinecone/utils/constants.py @@ -28,3 +28,5 @@ class NodeType(str, enum.Enum): REQUIRED_VECTOR_FIELDS = {"id", "values"} OPTIONAL_VECTOR_FIELDS = {"sparse_values", "metadata"} + +SOURCE_TAG = "source_tag" diff --git a/pinecone/utils/convert_to_list.py b/pinecone/utils/convert_to_list.py index ce28a9f5..eb57ef72 100644 --- a/pinecone/utils/convert_to_list.py +++ b/pinecone/utils/convert_to_list.py @@ -1,3 +1,5 @@ +from ..exceptions import ListConversionException + def convert_to_list(obj): class_name = obj.__class__.__name__ @@ -5,5 +7,12 @@ def convert_to_list(obj): return obj elif hasattr(obj, 'tolist') and callable(getattr(obj, 'tolist')): return obj.tolist() + elif obj is None or isinstance(obj, str) or isinstance(obj, dict): + # The string and dictionary classes in python can be passed to list() + # but they're not going to yield sensible results for our use case. + raise ListConversionException(f"Expected a list or list-like data structure, but got: {obj}") else: - return list(obj) \ No newline at end of file + try: + return list(obj) + except Exception as e: + raise ListConversionException(f"Expected a list or list-like data structure, but got: {obj}") from e \ No newline at end of file diff --git a/pinecone/utils/docslinks.py b/pinecone/utils/docslinks.py new file mode 100644 index 00000000..aa2ba24d --- /dev/null +++ b/pinecone/utils/docslinks.py @@ -0,0 +1,4 @@ +docslinks = { + 'GITHUB_REPO': 'https://github.com/pinecone-io/pinecone-python-client', + 'LANGCHAIN_IMPORT_KB_ARTICLE': 'https://docs.pinecone.io/troubleshooting/pinecone-attribute-errors-with-langchain' +} \ No newline at end of file diff --git a/pinecone/utils/setup_openapi_client.py b/pinecone/utils/setup_openapi_client.py new file mode 100644 index 00000000..02e0b14f --- /dev/null +++ b/pinecone/utils/setup_openapi_client.py @@ -0,0 +1,14 @@ +from pinecone.core.client.api_client import ApiClient +from .user_agent import get_user_agent + +def setup_openapi_client(api_klass, config, openapi_config, pool_threads): + api_client = ApiClient( + configuration=openapi_config, + pool_threads=pool_threads + ) + api_client.user_agent = get_user_agent(config) + extra_headers = config.additional_headers or {} + for key, value in extra_headers.items(): + api_client.set_default_header(key, value) + client = api_klass(api_client) + return client diff --git a/pinecone/utils/user_agent.py b/pinecone/utils/user_agent.py index 5fd23a8c..179b9a53 100644 --- a/pinecone/utils/user_agent.py +++ b/pinecone/utils/user_agent.py @@ -1,9 +1,29 @@ import urllib3 from .version import __version__ +from .constants import SOURCE_TAG +import re -def get_user_agent(): - client_id = f"python-client-{__version__}" +def _build_source_tag_field(source_tag): + # normalize source tag + # 1. Lowercase + # 2. Limit charset to [a-z0-9_ ] + # 3. Trim left/right whitespace + # 4. Condense multiple spaces to one, and replace with underscore + tag = source_tag.lower() + tag = re.sub(r'[^a-z0-9_ ]', '', tag) + tag = tag.strip() + tag = "_".join(tag.split()) + return f"{SOURCE_TAG}={tag}" + +def _get_user_agent(client_id, config): user_agent_details = {"urllib3": urllib3.__version__} user_agent = "{} ({})".format(client_id, ", ".join([f"{k}:{v}" for k, v in user_agent_details.items()])) - return user_agent \ No newline at end of file + user_agent += f"; {_build_source_tag_field(config.source_tag)}" if config.source_tag else "" + return user_agent + +def get_user_agent(config): + return _get_user_agent(f"python-client-{__version__}", config) + +def get_user_agent_grpc(config): + return _get_user_agent(f"python-client[grpc]-{__version__}", config) \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index eb295655..ed05c50f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "astunparse" @@ -231,20 +231,6 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] -[[package]] -name = "grpc-gateway-protoc-gen-openapiv2" -version = "0.1.0" -description = "Provides the missing pieces for gRPC Gateway." -optional = true -python-versions = ">=3.6" -files = [ - {file = "grpc-gateway-protoc-gen-openapiv2-0.1.0.tar.gz", hash = "sha256:03b8934080ae81f709af041e4f89694db586a95ff35abba05d033d499811d4f6"}, - {file = "grpc_gateway_protoc_gen_openapiv2-0.1.0-py3-none-any.whl", hash = "sha256:45ba00a6e9df13d35fe46d4149c62361a63c27e61fb08faa192aea0f4fbed609"}, -] - -[package.dependencies] -googleapis-common-protos = "*" - [[package]] name = "grpc-stubs" version = "1.53.0.3" @@ -327,13 +313,13 @@ protobuf = ["grpcio-tools (>=1.59.2)"] [[package]] name = "idna" -version = "3.4" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -349,13 +335,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.3" +version = "3.1.4" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, - {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] @@ -765,35 +751,39 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "3.20.3" -description = "Protocol Buffers" +version = "4.25.3" +description = "" optional = true -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, - {file = "protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, - {file = "protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, - {file = "protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, - {file = "protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, - {file = "protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, - {file = "protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, - {file = "protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, - {file = "protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, - {file = "protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, - {file = "protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, - {file = "protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, - {file = "protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, - {file = "protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, - {file = "protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, - {file = "protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, + {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, + {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, + {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, + {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, + {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, + {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, + {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, + {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, + {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, ] +[[package]] +name = "protoc-gen-openapiv2" +version = "0.0.1" +description = "Provides the missing pieces for gRPC Gateway." +optional = true +python-versions = ">=3.6" +files = [ + {file = "protoc-gen-openapiv2-0.0.1.tar.gz", hash = "sha256:6f79188d842c13177c9c0558845442c340b43011bf67dfef1dfc3bc067506409"}, + {file = "protoc_gen_openapiv2-0.0.1-py3-none-any.whl", hash = "sha256:18090c8be3877c438e7da0f7eb7cace45a9a210306bca4707708dbad367857be"}, +] + +[package.dependencies] +googleapis-common-protos = "*" +protobuf = ">=4.21.0" + [[package]] name = "pygments" version = "2.16.1" @@ -946,6 +936,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1044,13 +1035,13 @@ files = [ [[package]] name = "tqdm" -version = "4.66.1" +version = "4.66.3" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, - {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, + {file = "tqdm-4.66.3-py3-none-any.whl", hash = "sha256:4f41d54107ff9a223dca80b53efe4fb654c67efaba7f47bada3ee9d50e05bd53"}, + {file = "tqdm-4.66.3.tar.gz", hash = "sha256:23097a41eba115ba99ecae40d06444c15d1c0c698d527a01c6c8bd1c5d0647e5"}, ] [package.dependencies] @@ -1174,9 +1165,9 @@ files = [ test = ["pytest (>=6.0.0)", "setuptools (>=65)"] [extras] -grpc = ["googleapis-common-protos", "grpc-gateway-protoc-gen-openapiv2", "grpcio", "grpcio", "lz4", "protobuf"] +grpc = ["googleapis-common-protos", "grpcio", "grpcio", "lz4", "protobuf", "protoc-gen-openapiv2"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "3f9d76204d6753bdba849cc43cc9827e021e3cbdca7328cc9f411bb6133c6091" +content-hash = "4dd1a293f07b49e250679ca58f6ab3c5a090f2d4807d721dab64d5d574a38c10" diff --git a/pyproject.toml b/pyproject.toml index 698b74a8..2071996e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ exclude = ''' [tool.poetry] name = "pinecone-client" -version = "3.1.0" +version = "4.1.0" packages = [ { include="pinecone", from="." }, ] @@ -63,10 +63,10 @@ grpcio = [ { version = ">=1.44.0", optional = true, python = "^3.8,<3.11" }, { version = ">=1.59.0", optional = true, python = "^3.11" } ] -grpc-gateway-protoc-gen-openapiv2 = { version = "0.1.0", optional = true } googleapis-common-protos = { version = ">=1.53.0", optional = true } lz4 = { version = ">=3.1.3", optional = true } -protobuf = { version = "~=3.20.0", optional = true } +protobuf = { version = "^4.25", optional = true } +protoc-gen-openapiv2 = {version = "^0.0.1", optional = true } [tool.poetry.group.types] optional = true @@ -98,7 +98,7 @@ urllib3_mock = "0.3.3" responses = ">=0.8.1" [tool.poetry.extras] -grpc = ["grpcio", "grpc-gateway-protoc-gen-openapiv2", "googleapis-common-protos", "lz4", "protobuf"] +grpc = ["grpcio", "googleapis-common-protos", "lz4", "protobuf", "protoc-gen-openapiv2"] [build-system] requires = ["poetry-core"] diff --git a/tests/integration/data/conftest.py b/tests/integration/data/conftest.py index 90753b20..16b3e13b 100644 --- a/tests/integration/data/conftest.py +++ b/tests/integration/data/conftest.py @@ -27,6 +27,10 @@ def build_client(): from pinecone import Pinecone return Pinecone(api_key=api_key(), additional_headers={'sdk-test-suite': 'pinecone-python-client'}) +@pytest.fixture(scope='session') +def api_key_fixture(): + return api_key() + @pytest.fixture(scope='session') def client(): return build_client() diff --git a/tests/integration/data/test_openapi_configuration.py b/tests/integration/data/test_openapi_configuration.py new file mode 100644 index 00000000..e8b93389 --- /dev/null +++ b/tests/integration/data/test_openapi_configuration.py @@ -0,0 +1,18 @@ +import pytest +import os + +from pinecone import Pinecone +from pinecone.core.client.configuration import Configuration as OpenApiConfiguration +from urllib3 import make_headers + +@pytest.mark.skipif(os.getenv('USE_GRPC') != 'false', reason='Only test when using REST') +class TestIndexOpenapiConfig: + def test_passing_openapi_config(self, api_key_fixture, index_host): + oai_config = OpenApiConfiguration.get_default_copy() + p = Pinecone(api_key=api_key_fixture, openapi_config=oai_config) + assert p.config.api_key == api_key_fixture + p.list_indexes() # should not throw + + index = p.Index(host=index_host) + assert index._config.api_key == api_key_fixture + index.describe_index_stats() \ No newline at end of file diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.cer b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.cer new file mode 100644 index 00000000..5f133756 --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUG5Ji5NxWD3Q7h8remh7vYloa1UMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAI96RxFM2U3cXyhJre0DbJvZDvrr5IEFJhEO9+7vRFM73cTax2jhUDQx +ZLx5LgWWQmqTfNop5ON1XKqYMxpjTJrHEbIcnybLRmLL+SXVsj547vRH1rps+G4m +3iJWorGju3PieJYj8ppro0mhlynZRHOM8EzkX9TgxdtFpz3hejy9btOwEkRGrjM1 +5prsDubYn0JwGz6N2N/yAf9mviWKnP1xc1CD2xIJwJKX1Tyqi9B93w1YL5JFV7yg +rdlRw4X0a3wav7GiJJkylv8cZrtZ4Kt4TwNMLpqh21LRqJkwyFE8NLXMD/aS4q2U +3K5ml6H9MthNkrheH0RlsiOe5RQJMAcCAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FM83YTNU3L2z9vvQvHrGX0U/XAf2MA0GCSqGSIb3DQEBCwUAA4IBAQARURZnD7Nm +d/kN1gIpl+x9aAaMLlvS3hgn6quuVVJzyiHYZKmBq/76VPIyn4dSFQakvS5nob3R +FNzlq3QR6o4jAR6BIEzuKDKExFdYz7hfBA6JgGUxTsofJPBmqC2BvRZlkt/Qb3ea +HDCJUYOXfppABimlVi5gOVf6r80wcuqTK6sIp+V+HVhAf2RbpAFnLWOSzkZ7Qaa9 +jZJ5Jd2nYTx+eOjkNZL2kiV6R9tvuJK0C9nQeJJDTwkmksLJEg+5CS6D51zdRgdc +dCvvesmF6dWQmOxZdm3pqusTkIWNq2RBb2kEqZA84cfVLX4+OOhbieC9XKQjsOcE +h+rsI/lmeuR9 +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.p12 b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.p12 new file mode 100644 index 00000000..10e4d4e6 Binary files /dev/null and b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.p12 differ diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.pem b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.pem new file mode 100644 index 00000000..5f133756 --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUG5Ji5NxWD3Q7h8remh7vYloa1UMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAI96RxFM2U3cXyhJre0DbJvZDvrr5IEFJhEO9+7vRFM73cTax2jhUDQx +ZLx5LgWWQmqTfNop5ON1XKqYMxpjTJrHEbIcnybLRmLL+SXVsj547vRH1rps+G4m +3iJWorGju3PieJYj8ppro0mhlynZRHOM8EzkX9TgxdtFpz3hejy9btOwEkRGrjM1 +5prsDubYn0JwGz6N2N/yAf9mviWKnP1xc1CD2xIJwJKX1Tyqi9B93w1YL5JFV7yg +rdlRw4X0a3wav7GiJJkylv8cZrtZ4Kt4TwNMLpqh21LRqJkwyFE8NLXMD/aS4q2U +3K5ml6H9MthNkrheH0RlsiOe5RQJMAcCAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FM83YTNU3L2z9vvQvHrGX0U/XAf2MA0GCSqGSIb3DQEBCwUAA4IBAQARURZnD7Nm +d/kN1gIpl+x9aAaMLlvS3hgn6quuVVJzyiHYZKmBq/76VPIyn4dSFQakvS5nob3R +FNzlq3QR6o4jAR6BIEzuKDKExFdYz7hfBA6JgGUxTsofJPBmqC2BvRZlkt/Qb3ea +HDCJUYOXfppABimlVi5gOVf6r80wcuqTK6sIp+V+HVhAf2RbpAFnLWOSzkZ7Qaa9 +jZJ5Jd2nYTx+eOjkNZL2kiV6R9tvuJK0C9nQeJJDTwkmksLJEg+5CS6D51zdRgdc +dCvvesmF6dWQmOxZdm3pqusTkIWNq2RBb2kEqZA84cfVLX4+OOhbieC9XKQjsOcE +h+rsI/lmeuR9 +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.p12 b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.p12 new file mode 100644 index 00000000..e0177f8a Binary files /dev/null and b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.p12 differ diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.pem b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.pem new file mode 100644 index 00000000..b681605c --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-ca.pem @@ -0,0 +1,47 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAj3pHEUzZTdxfKEmt7QNsm9kO+uvkgQUmEQ737u9EUzvdxNrH +aOFQNDFkvHkuBZZCapN82ink43VcqpgzGmNMmscRshyfJstGYsv5JdWyPnju9EfW +umz4bibeIlaisaO7c+J4liPymmujSaGXKdlEc4zwTORf1ODF20WnPeF6PL1u07AS +REauMzXmmuwO5tifQnAbPo3Y3/IB/2a+JYqc/XFzUIPbEgnAkpfVPKqL0H3fDVgv +kkVXvKCt2VHDhfRrfBq/saIkmTKW/xxmu1ngq3hPA0wumqHbUtGomTDIUTw0tcwP +9pLirZTcrmaXof0y2E2SuF4fRGWyI57lFAkwBwIDAQABAoIBABaZiSY1d6knBCoh +aO8DchEeYJivnX+hIvze4bjWIWoG7Qi7+VsQ2oROH3L8l34zy+RjtO/cV3xomR8Z ++Dq413Et2CC5F2yR6lVXkbge8AOdIu6BflZBIeSf5K99/ASFKNq5GotzwBwIxmCr +vlbOLVUSJyvFcT7j5OaEEzLRGGMGq01Wvn6p4D3W3Fo7Upoj6gG8C+ndISHfCPWZ +pzJYW2iqnlvz3SAWKIhBYYq9OJrdFfi9ZNbKGYMUi2csMjVmDrAyRUi5qqVxM40x +Jumj4+0T8la8j9fms/9lkBzDh05pWGuuRfFj2ztTkIXUA23shNkpRwnuzu9kn786 +NqulHdkCgYEAxcLDgXGTc5n47f/jRf7qV4iau0FjdhRElgB6ld18tVIGbj4dbQjS +NOTVbMgRp4ng+V9M8Na9UyTzrnTTkfvGG9eDHcTNEQSbYCGMzP3TFGV8YnB7jFPa +Q/Cj5eV7O4vns2YrFZOV6QPhzyM4tgV6xuM/YKvHxNtvKA1uBPq7stUCgYEAubsX +99P0pqek0xUaXxPDObkjRv5nilM/1t0bNMFhzlloN4YOnVqM9npNu9n7PGjLJsG5 +qrPrZ6KcWHPnLtjDJwprAdkE54885YPYdRezWQIpeDMePYgP1VQz+PQ+vHX1CH1d +oiKqIZWxEp4jHLV7u0wSbmFBPw0+FL3VRTuOLWsCgYEAiYP5dxWHNyemVblOTOoK +AnxXPEcn5oAJgVUr6PJvOZakKhy/UYaExYsqbc5hmGLkMgP2+LIaTKqxWGqchDLT +e6DM5/JltqPBd4Nc6V7HXLOFXt5gyx+z8vJuxfphSvLqV3GAHCzYXYP5jZQsZ0ZA +LfTvqUVKULVWAj/0dTn1M1ECgYB9gX46zBHgpBxvPy1o3jPoR8Ec8kEJaiQTj6oY +xizPgf84tfAeSNhEnnT04eIx+iZ9dB+AyL/kci/wXbH1KCkHsrSItRvpVhOyjJuy +1GcvWJSpUvG2ZsE8SQAt1O6n75W7POwO6hnJRBw6Fn5nogOQl2FFEZdDgjFXVshN +VmdHLQKBgQCtqBqkyldZDVXxKIZnYKErxN2JeWZHOGCHLJbO+eN/ncQDpQlZV5Lr +Er2mThLRrqApjobQL7bF0IRTfQsOkLYlGd/36JkvRlkpSTixyJRn0PRvR/PdIrbk +LT6c0+82drLGyJHXHUR2P1kDJ03Snh2EMqVLVhm3hmXT9I9lQolRow== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUG5Ji5NxWD3Q7h8remh7vYloa1UMwDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAI96RxFM2U3cXyhJre0DbJvZDvrr5IEFJhEO9+7vRFM73cTax2jhUDQx +ZLx5LgWWQmqTfNop5ON1XKqYMxpjTJrHEbIcnybLRmLL+SXVsj547vRH1rps+G4m +3iJWorGju3PieJYj8ppro0mhlynZRHOM8EzkX9TgxdtFpz3hejy9btOwEkRGrjM1 +5prsDubYn0JwGz6N2N/yAf9mviWKnP1xc1CD2xIJwJKX1Tyqi9B93w1YL5JFV7yg +rdlRw4X0a3wav7GiJJkylv8cZrtZ4Kt4TwNMLpqh21LRqJkwyFE8NLXMD/aS4q2U +3K5ml6H9MthNkrheH0RlsiOe5RQJMAcCAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FM83YTNU3L2z9vvQvHrGX0U/XAf2MA0GCSqGSIb3DQEBCwUAA4IBAQARURZnD7Nm +d/kN1gIpl+x9aAaMLlvS3hgn6quuVVJzyiHYZKmBq/76VPIyn4dSFQakvS5nob3R +FNzlq3QR6o4jAR6BIEzuKDKExFdYz7hfBA6JgGUxTsofJPBmqC2BvRZlkt/Qb3ea +HDCJUYOXfppABimlVi5gOVf6r80wcuqTK6sIp+V+HVhAf2RbpAFnLWOSzkZ7Qaa9 +jZJ5Jd2nYTx+eOjkNZL2kiV6R9tvuJK0C9nQeJJDTwkmksLJEg+5CS6D51zdRgdc +dCvvesmF6dWQmOxZdm3pqusTkIWNq2RBb2kEqZA84cfVLX4+OOhbieC9XKQjsOcE +h+rsI/lmeuR9 +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-dhparam.pem b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-dhparam.pem new file mode 100644 index 00000000..c10121fb --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy1/mitmproxy-dhparam.pem @@ -0,0 +1,14 @@ + +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEAyT6LzpwVFS3gryIo29J5icvgxCnCebcdSe/NHMkD8dKJf8suFCg3 +O2+dguLakSVif/t6dhImxInJk230HmfC8q93hdcg/j8rLGJYDKu3ik6H//BAHKIv +j5O9yjU3rXCfmVJQic2Nne39sg3CreAepEts2TvYHhVv3TEAzEqCtOuTjgDv0ntJ +Gwpj+BJBRQGG9NvprX1YGJ7WOFBP/hWU7d6tgvE6Xa7T/u9QIKpYHMIkcN/l3ZFB +chZEqVlyrcngtSXCROTPcDOQ6Q8QzhaBJS+Z6rcsd7X+haiQqvoFcmaJ08Ks6LQC +ZIL2EtYJw8V8z7C0igVEBIADZBI6OTbuuhDwRw//zU1uq52Oc48CIZlGxTYG/Evq +o9EWAXUYVzWkDSTeBH1r4z/qLPE2cnhtMxbFxuvK53jGB0emy2y1Ei6IhKshJ5qX +IB/aE7SSHyQ3MDHHkCmQJCsOd4Mo26YX61NZ+n501XjqpCBQ2+DfZCBh8Va2wDyv +A2Ryg9SUz8j0AXViRNMJgJrr446yro/FuJZwnQcO3WQnXeqSBnURqKjmqkeFP+d8 +6mk2tqJaY507lRNqtGlLnj7f5RNoBFJDCLBNurVgfvq9TCVWKDIFD4vZRjCrnl6I +rD693XKIHUCWOjMh1if6omGXKHH40QuME2gNa50+YPn1iYDl88uDbbMCAQI= +-----END DH PARAMETERS----- diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.cer b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.cer new file mode 100644 index 00000000..fb885197 --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUUo4sMqY4s3aM0RqjLhD1ZzGOhnowDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAJ/BEbexCoDvIEB2zF8R13tNVqc5eW5kS4Rp0IqKSfWmmrghA0bc6X22 +p6juusl1KSpoWcR1L0iD1Wa2Tlaip0c/DJUwJHwJ70UZyWjwAJPbF282dYqqwygC +hWP1EFKVlctHE6MEMc+o1W7hLC690n0EKtatT5lCHSuUwK69RoNijfPqJrqstQKN +hJZ9bDIHVwi86jUbUcfjb9Uo/AiMjAonuy82wiarHdNmRIIcRcBvXkhx7on/5X5z +/Vq4+lgR91lP+6qYotHI988e4plF0KuzjrTPyki7+OiyJkMxJwJW/E1DU6bvTchN +H9wB27kJ6GtFW21n1YqRWpCR7JyQ4D8CAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBNhRsjEjijaA8rS3XezhrtEpVvRMA0GCSqGSIb3DQEBCwUAA4IBAQAc8wSUSk7y +Sz4pQmi6EciZmU9jEnBHld9uYJ4mqRR2oPm+eRPq0yW1VifNEgMLSqNcv8/EH93o +C16jHHQ5TrV0C+wMnnUN3BxliDsi6FdbMa92Df09K9C/LP/v68H4rtMaMskvOrHw +k/r/NsKCxZ1GywLA7s/yVKgtr7ARARf6hHJS6/bxqohdaCFZtxmQIH26sOkTV2Ds +pf1ey+d3xitOl/roLXV91KjGfML4PRCzIPOw0+odSw62e2kikI77OQxOEn4zjyg+ +a0B344gMV7LaNTyqLTx41wU0hk62CeHHS4Gc0XLMfw9NYPTrjyQYK1+lEWDSEHCn +TiBThXoIGeAU +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.p12 b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.p12 new file mode 100644 index 00000000..33125261 Binary files /dev/null and b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.p12 differ diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.pem b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.pem new file mode 100644 index 00000000..fb885197 --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUUo4sMqY4s3aM0RqjLhD1ZzGOhnowDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAJ/BEbexCoDvIEB2zF8R13tNVqc5eW5kS4Rp0IqKSfWmmrghA0bc6X22 +p6juusl1KSpoWcR1L0iD1Wa2Tlaip0c/DJUwJHwJ70UZyWjwAJPbF282dYqqwygC +hWP1EFKVlctHE6MEMc+o1W7hLC690n0EKtatT5lCHSuUwK69RoNijfPqJrqstQKN +hJZ9bDIHVwi86jUbUcfjb9Uo/AiMjAonuy82wiarHdNmRIIcRcBvXkhx7on/5X5z +/Vq4+lgR91lP+6qYotHI988e4plF0KuzjrTPyki7+OiyJkMxJwJW/E1DU6bvTchN +H9wB27kJ6GtFW21n1YqRWpCR7JyQ4D8CAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBNhRsjEjijaA8rS3XezhrtEpVvRMA0GCSqGSIb3DQEBCwUAA4IBAQAc8wSUSk7y +Sz4pQmi6EciZmU9jEnBHld9uYJ4mqRR2oPm+eRPq0yW1VifNEgMLSqNcv8/EH93o +C16jHHQ5TrV0C+wMnnUN3BxliDsi6FdbMa92Df09K9C/LP/v68H4rtMaMskvOrHw +k/r/NsKCxZ1GywLA7s/yVKgtr7ARARf6hHJS6/bxqohdaCFZtxmQIH26sOkTV2Ds +pf1ey+d3xitOl/roLXV91KjGfML4PRCzIPOw0+odSw62e2kikI77OQxOEn4zjyg+ +a0B344gMV7LaNTyqLTx41wU0hk62CeHHS4Gc0XLMfw9NYPTrjyQYK1+lEWDSEHCn +TiBThXoIGeAU +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.p12 b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.p12 new file mode 100644 index 00000000..5f144538 Binary files /dev/null and b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.p12 differ diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.pem b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.pem new file mode 100644 index 00000000..103f5f22 --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-ca.pem @@ -0,0 +1,47 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAn8ERt7EKgO8gQHbMXxHXe01Wpzl5bmRLhGnQiopJ9aaauCED +RtzpfbanqO66yXUpKmhZxHUvSIPVZrZOVqKnRz8MlTAkfAnvRRnJaPAAk9sXbzZ1 +iqrDKAKFY/UQUpWVy0cTowQxz6jVbuEsLr3SfQQq1q1PmUIdK5TArr1Gg2KN8+om +uqy1Ao2Eln1sMgdXCLzqNRtRx+Nv1Sj8CIyMCie7LzbCJqsd02ZEghxFwG9eSHHu +if/lfnP9Wrj6WBH3WU/7qpii0cj3zx7imUXQq7OOtM/KSLv46LImQzEnAlb8TUNT +pu9NyE0f3AHbuQnoa0VbbWfVipFakJHsnJDgPwIDAQABAoIBAA+PjzNxuHCZDW7G +1sVaR/KOTloSv4Daa0vfwRzQt4xVlbOvU4UvHRDOHkQ9Bk8VOggT15qXp4SZHGVy +07kDz7NuF49FYmhkN1aajZz95uOzO/Ps10PFU/KtVcmuVzattCrAWgNPWnxVsuR0 +yzu9gnRqJLOtRTGY2DdXt/HNWFvEfqhM1pCfi/NjpUjZx3d7+P+Vp9eXBnOcrIPN +9fV00sqHgD/Ddm7swAs4Nh3errm3EYsSOBVu0OEMHob7MrgZ2ewG6wFdFDHXB8vp +vc4WmHbqqQ4GW5lkJ/qKwuPxfSS4vZ+eYaZmZkerN3oyeEYvqifbitRcxBnzc/v1 +YMT4+ZECgYEA2yNW3w7kHmgn7+lBknVYjQgRQ5Z7O9H/xyx+2FCt5qyBu7l4463g +KZ7c1zoJg087MkFxIsC2BAenPdA+wxmdou6PwlKMxzvKGtI1Xi0AzcPezrFKcZCI +cp7oh0rUJIrXAz4M6f1R6X+Hg8MYMl/CZthVSxfH5paC0afCdEaZTP0CgYEAuqCB +Gk/1tHdY3X/b5V1Cu52O8bjl4QPtoZ0Yj1ho6Q2bjlXhKuiA8xVkC68nSMlboXmH +tBuHADhocbamSvA/R+jpneTysOE2F18utsAuOhMQmb6JHYF+r7Xf/S7zuGmhBQ9P +AEHXyUKh31EnrG81wD/rzSh8OS3KYPVlbNo0ROsCgYA5sjFCI2KOWvAA65IXJIw+ +/ZvGBs3Fb0H/x8hR3dQbgtnZejjJAVOewbP1etNcXjUAw1gtRT3nC7jNvpF3vrvR +VSxGhoOIRUauDyB7/i9S/bohA27NPbefLhWc4We/g0qfEOxHgynY53nfiDNLuAiw +GU9DqSw5mvEwkBHTmW7tZQKBgDvlESoJqXh+qRWFWGRXNviRi3PGfHhn01b/3Qb8 +P8cz582ZgEdOETxyjAY382qnvPGo2EWUZBJNCDAeh2YbjqOce4WCGeVskfiUQqDC +MtPOlJBTFxxSF/96ZmWSMQPpWpUOIbOabg+Yg+zw1cPAeUa2/Q19xchwCrhtaVyy +9v17AoGAEnWqMtZGCl9XKrRLtowLS2GxI/iEfnPaxtZkbOTso/oFB/fFf+Cez5wQ +RIZ7/QYNYCrSVGMu0vvMiG+u5Am4yDpVmTCY6PIiZXfpXdwh9GZ33CjM8Mwgp5mu +5aOBmmdrxnPmO/rnWHJLnuacmCXiGThj4o7W5pAT87MAIZvWGZ8= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUUo4sMqY4s3aM0RqjLhD1ZzGOhnowDQYJKoZIhvcNAQEL +BQAwKDESMBAGA1UEAwwJbWl0bXByb3h5MRIwEAYDVQQKDAltaXRtcHJveHkwHhcN +MjQwMzE3MDQwNjA2WhcNMzQwMzE3MDQwNjA2WjAoMRIwEAYDVQQDDAltaXRtcHJv +eHkxEjAQBgNVBAoMCW1pdG1wcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAJ/BEbexCoDvIEB2zF8R13tNVqc5eW5kS4Rp0IqKSfWmmrghA0bc6X22 +p6juusl1KSpoWcR1L0iD1Wa2Tlaip0c/DJUwJHwJ70UZyWjwAJPbF282dYqqwygC +hWP1EFKVlctHE6MEMc+o1W7hLC690n0EKtatT5lCHSuUwK69RoNijfPqJrqstQKN +hJZ9bDIHVwi86jUbUcfjb9Uo/AiMjAonuy82wiarHdNmRIIcRcBvXkhx7on/5X5z +/Vq4+lgR91lP+6qYotHI988e4plF0KuzjrTPyki7+OiyJkMxJwJW/E1DU6bvTchN +H9wB27kJ6GtFW21n1YqRWpCR7JyQ4D8CAwEAAaNXMFUwDwYDVR0TAQH/BAUwAwEB +/zATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBNhRsjEjijaA8rS3XezhrtEpVvRMA0GCSqGSIb3DQEBCwUAA4IBAQAc8wSUSk7y +Sz4pQmi6EciZmU9jEnBHld9uYJ4mqRR2oPm+eRPq0yW1VifNEgMLSqNcv8/EH93o +C16jHHQ5TrV0C+wMnnUN3BxliDsi6FdbMa92Df09K9C/LP/v68H4rtMaMskvOrHw +k/r/NsKCxZ1GywLA7s/yVKgtr7ARARf6hHJS6/bxqohdaCFZtxmQIH26sOkTV2Ds +pf1ey+d3xitOl/roLXV91KjGfML4PRCzIPOw0+odSw62e2kikI77OQxOEn4zjyg+ +a0B344gMV7LaNTyqLTx41wU0hk62CeHHS4Gc0XLMfw9NYPTrjyQYK1+lEWDSEHCn +TiBThXoIGeAU +-----END CERTIFICATE----- diff --git a/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-dhparam.pem b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-dhparam.pem new file mode 100644 index 00000000..c10121fb --- /dev/null +++ b/tests/integration/proxy_config/.mitm/proxy2/mitmproxy-dhparam.pem @@ -0,0 +1,14 @@ + +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEAyT6LzpwVFS3gryIo29J5icvgxCnCebcdSe/NHMkD8dKJf8suFCg3 +O2+dguLakSVif/t6dhImxInJk230HmfC8q93hdcg/j8rLGJYDKu3ik6H//BAHKIv +j5O9yjU3rXCfmVJQic2Nne39sg3CreAepEts2TvYHhVv3TEAzEqCtOuTjgDv0ntJ +Gwpj+BJBRQGG9NvprX1YGJ7WOFBP/hWU7d6tgvE6Xa7T/u9QIKpYHMIkcN/l3ZFB +chZEqVlyrcngtSXCROTPcDOQ6Q8QzhaBJS+Z6rcsd7X+haiQqvoFcmaJ08Ks6LQC +ZIL2EtYJw8V8z7C0igVEBIADZBI6OTbuuhDwRw//zU1uq52Oc48CIZlGxTYG/Evq +o9EWAXUYVzWkDSTeBH1r4z/qLPE2cnhtMxbFxuvK53jGB0emy2y1Ei6IhKshJ5qX +IB/aE7SSHyQ3MDHHkCmQJCsOd4Mo26YX61NZ+n501XjqpCBQ2+DfZCBh8Va2wDyv +A2Ryg9SUz8j0AXViRNMJgJrr446yro/FuJZwnQcO3WQnXeqSBnURqKjmqkeFP+d8 +6mk2tqJaY507lRNqtGlLnj7f5RNoBFJDCLBNurVgfvq9TCVWKDIFD4vZRjCrnl6I +rD693XKIHUCWOjMh1if6omGXKHH40QuME2gNa50+YPn1iYDl88uDbbMCAQI= +-----END DH PARAMETERS----- diff --git a/tests/integration/proxy_config/__init__.py b/tests/integration/proxy_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/proxy_config/conftest.py b/tests/integration/proxy_config/conftest.py new file mode 100644 index 00000000..9f775efc --- /dev/null +++ b/tests/integration/proxy_config/conftest.py @@ -0,0 +1,84 @@ +import time +import os +import pytest +import subprocess +from ..helpers import get_environment_var + +PROXIES = { + 'proxy1': { + 'name': 'proxy1', + 'port': 8080, + 'ssl_ca_certs': os.path.abspath('./tests/integration/proxy_config/.mitm/proxy1'), + 'auth': None + }, + 'proxy2': { + 'name': 'proxy2', + 'port': 8081, + 'ssl_ca_certs': os.path.abspath('./tests/integration/proxy_config/.mitm/proxy2'), + 'auth': ('testuser', 'testpassword') + } +} + +def docker_command(proxy): + cmd = [ + "docker", "run", "-d", # detach to run in background + "--rm", # remove container when stopped + "--name", proxy['name'], # name the container + "-p", f"{proxy['port']}:8080", # map the port + "-v", f"{proxy['ssl_ca_certs']}:/home/mitmproxy/.mitmproxy", # mount config as volume + "mitmproxy/mitmproxy", # docker image name + "mitmdump" # command to run + ] + if proxy['auth']: + cmd.append(f"--set proxyauth={proxy['auth'][0]}:{proxy['auth'][1]}") + print(" ".join(cmd)) + return " ".join(cmd) + +def run_cmd(cmd, output): + output.write("Going to run: " + cmd + "\n") + exit_code = subprocess.call(cmd, shell=True, stdout=output, stderr=output) + if exit_code != 0: + raise Exception(f"Failed to run command: {cmd}") + +def use_grpc(): + return os.environ.get('USE_GRPC', 'false') == 'true' + +@pytest.fixture(scope='session', autouse=True) +def start_docker(): + with open("tests/integration/proxy_config/logs/proxyconfig-docker-start.log", "a") as output: + run_cmd(docker_command(PROXIES['proxy1']), output) + run_cmd(docker_command(PROXIES['proxy2']), output) + + time.sleep(5) + with open("tests/integration/proxy_config/logs/proxyconfig-docker-ps.log", "a") as output: + run_cmd("docker ps --all", output) + + yield + with open("tests/integration/proxy_config/logs/proxyconfig-docker-stop.log", "a") as output: + run_cmd("docker stop proxy1", output) + run_cmd("docker stop proxy2", output) + +@pytest.fixture() +def proxy1(): + return PROXIES['proxy1'] + +@pytest.fixture() +def proxy2(): + return PROXIES['proxy2'] + +@pytest.fixture() +def client_cls(): + if use_grpc(): + from pinecone.grpc import PineconeGRPC + return PineconeGRPC + else: + from pinecone import Pinecone + return Pinecone + +@pytest.fixture() +def api_key(): + return get_environment_var('PINECONE_API_KEY') + +@pytest.fixture() +def index_name(): + return get_environment_var('PINECONE_INDEX_NAME') \ No newline at end of file diff --git a/tests/integration/proxy_config/logs/.gitkeep b/tests/integration/proxy_config/logs/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/proxy_config/test_proxy_settings.py b/tests/integration/proxy_config/test_proxy_settings.py new file mode 100644 index 00000000..f71346ea --- /dev/null +++ b/tests/integration/proxy_config/test_proxy_settings.py @@ -0,0 +1,88 @@ +import os +import pytest +from pinecone import Pinecone +from urllib3 import make_headers +from urllib3.exceptions import InsecureRequestWarning + +PROXY1_URL_HTTPS = 'https://localhost:8080' +PROXY1_URL_HTTP = 'http://localhost:8080' + +PROXY2_URL = 'https://localhost:8081' + +def exercise_all_apis(client, index_name): + # Control plane + client.list_indexes() + # Data plane + index = client.Index(index_name) + index.describe_index_stats() + +class TestProxyConfig: + @pytest.mark.skipif(os.getenv('USE_GRPC') != 'false', + reason="gRPC doesn't support 'https://' proxy URLs") + def test_https_proxy_with_self_signed_cert(self, client_cls, api_key, index_name, proxy1): + ssl_ca_certs = os.path.join(proxy1['ssl_ca_certs'], 'mitmproxy-ca-cert.pem') + pc = client_cls( + api_key=api_key, + proxy_url=PROXY1_URL_HTTPS, + ssl_ca_certs=ssl_ca_certs, + ) + exercise_all_apis(pc, index_name) + + def test_http_proxy_with_self_signed_cert(self, client_cls, api_key, index_name, proxy1): + ssl_ca_certs = os.path.join(proxy1['ssl_ca_certs'], 'mitmproxy-ca-cert.pem') + pc = client_cls( + api_key=api_key, + proxy_url=PROXY1_URL_HTTP, + ssl_ca_certs=ssl_ca_certs, + ) + exercise_all_apis(pc, index_name) + + @pytest.mark.skipif(os.getenv('USE_GRPC') != 'false', + reason="gRPC doesn't support disabling ssl_verify") + def test_proxy_with_ssl_verification_disabled_emits_warning(self, client_cls, api_key, index_name): + pc = client_cls( + api_key=api_key, + proxy_url=PROXY1_URL_HTTPS, + ssl_verify=False, + ) + + with pytest.warns(InsecureRequestWarning): + pc.list_indexes() + + def test_proxy_with_incorrect_cert_path(self, client_cls, api_key): + with pytest.raises(Exception) as e: + pc = client_cls( + api_key=api_key, + proxy_url=PROXY1_URL_HTTPS, + ssl_ca_certs='~/incorrect/path', + ) + pc.list_indexes() + + assert 'No such file or directory' in str(e.value) + + def test_proxy_with_valid_path_to_incorrect_cert(self, client_cls, api_key, proxy2): + ssl_ca_certs = os.path.join(proxy2['ssl_ca_certs'], 'mitmproxy-ca-cert.pem') + with pytest.raises(Exception) as e: + pc = client_cls( + api_key=api_key, + proxy_url=PROXY1_URL_HTTPS, + ssl_ca_certs=ssl_ca_certs, + ) + pc.list_indexes() + + assert 'CERTIFICATE_VERIFY_FAILED' in str(e.value) + + @pytest.mark.skipif(os.getenv('USE_GRPC') != 'false', + reason="gRPC doesn't support proxy auth") + def test_proxy_that_requires_proxyauth(self, client_cls, api_key, index_name, proxy2): + ssl_ca_certs = os.path.join(proxy2['ssl_ca_certs'], 'mitmproxy-ca-cert.pem') + username = proxy2['auth'][0] + password = proxy2['auth'][1] + pc = client_cls( + api_key=api_key, + proxy_url=PROXY2_URL, + proxy_headers=make_headers(proxy_basic_auth=f'{username}:{password}'), + ssl_ca_certs=ssl_ca_certs + ) + exercise_all_apis(pc, index_name) + diff --git a/tests/unit/data/test_vector_factory.py b/tests/unit/data/test_vector_factory.py index bf713a66..0f1a92fa 100644 --- a/tests/unit/data/test_vector_factory.py +++ b/tests/unit/data/test_vector_factory.py @@ -3,7 +3,7 @@ import pytest from pinecone.data.vector_factory import VectorFactory -from pinecone import Vector, SparseValues +from pinecone import Vector, SparseValues, ListConversionException class TestVectorFactory: def test_build_when_returns_vector_unmodified(self): @@ -11,29 +11,43 @@ def test_build_when_returns_vector_unmodified(self): assert VectorFactory.build(vec) == vec assert VectorFactory.build(vec).__class__ == Vector - def test_build_when_tuple_with_two_values(self): - tup = ('1', [0.1, 0.2, 0.3]) + @pytest.mark.parametrize('values_array', [ + [0.1, 0.2, 0.3], + np.array([0.1, 0.2, 0.3]), + pd.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_tuple_with_two_values(self, values_array): + tup = ('1', values_array) actual = VectorFactory.build(tup) expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={}) assert actual == expected - def test_build_when_tuple_with_three_values(self): - tup = ('1', [0.1, 0.2, 0.3], {'genre': 'comedy'}) + @pytest.mark.parametrize('values_array', [ + [0.1, 0.2, 0.3], + np.array([0.1, 0.2, 0.3]), + pd.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_tuple_with_three_values(self, values_array): + tup = ('1', values_array, {'genre': 'comedy'}) actual = VectorFactory.build(tup) expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) assert actual == expected - def test_build_when_tuple_with_numpy_array(self): - tup = ('1', np.array([0.1, 0.2, 0.3]), {'genre': 'comedy'}) - actual = VectorFactory.build(tup) - expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) - assert actual == expected + @pytest.mark.parametrize("vector_tup", [ + ("1", 'not an array'), + ("1", {}), + ("1", None), + ("1", 'not an array', {"genre": "comedy"}), + ("1", {}, {"genre": "comedy"}), + ("1", None, {"genre": "comedy"}), + ]) + def test_build_when_tuple_values_must_be_list(self, vector_tup): + with pytest.raises( + ListConversionException, + match="Expected a list or list-like data structure", + ): + VectorFactory.build(vector_tup) - def test_build_when_tuple_with_pandas_array(self): - tup = ('1', pd.array([0.1, 0.2, 0.3])) - actual = VectorFactory.build(tup) - expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={}) - assert actual == expected def test_build_when_tuple_errors_when_additional_fields(self): with pytest.raises(ValueError, match="Found a tuple of length 4 which is not supported"): @@ -45,20 +59,13 @@ def test_build_when_tuple_too_short(self): tup = ('1',) VectorFactory.build(tup) - def test_build_when_dict(self): - d = { 'id': '1', 'values': [0.1, 0.2, 0.3], 'metadata': {'genre': 'comedy'}} - actual = VectorFactory.build(d) - expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) - assert actual == expected - - def test_build_when_dict_with_numpy_values(self): - d = { 'id': '1', 'values': np.array([0.1, 0.2, 0.3]), 'metadata': {'genre': 'comedy'}} - actual = VectorFactory.build(d) - expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) - assert actual == expected - - def test_build_when_dict_with_pandas_values(self): - d = { 'id': '1', 'values': pd.array([0.1, 0.2, 0.3]), 'metadata': {'genre': 'comedy'}} + @pytest.mark.parametrize('values_array', [ + [0.1, 0.2, 0.3], + np.array([0.1, 0.2, 0.3]), + pd.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_dict(self, values_array): + d = { 'id': '1', 'values': values_array, 'metadata': {'genre': 'comedy'}} actual = VectorFactory.build(d) expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) assert actual == expected @@ -137,3 +144,14 @@ def test_build_when_dict_sparse_values_when_indices_is_ndarray(self): def test_build_when_errors_when_other_type(self): with pytest.raises(ValueError, match="Invalid vector value passed: cannot interpret type"): VectorFactory.build(1) + + def test_build_when_sparse_values_is_None(self): + d = { + 'id': '1', + 'values': [0.1, 0.2, 0.3], + 'metadata': {'genre': 'comedy'}, + 'sparse_values': None + } + actual = VectorFactory.build(d) + expected = Vector(id='1', values=[0.1, 0.2, 0.3], metadata={'genre': 'comedy'}) + assert actual == expected \ No newline at end of file diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index e8917e50..cf3996e1 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -6,6 +6,8 @@ import pytest import os +from urllib3 import make_headers + class TestConfig: @pytest.fixture(autouse=True) def run_before_and_after_tests(tmpdir): @@ -49,13 +51,15 @@ def test_init_with_positional_args(self): def test_init_with_kwargs(self): api_key = "my-api-key" controller_host = "my-controller-host" - openapi_config = OpenApiConfiguration(api_key="openapi-api-key") + ssl_ca_cert = 'path/to/cert-bundle.pem' + + openapi_config = OpenApiConfiguration() - config = PineconeConfig.build(api_key=api_key, host=controller_host, openapi_config=openapi_config) + config = PineconeConfig.build(api_key=api_key, host=controller_host, ssl_ca_certs=ssl_ca_cert, openapi_config=openapi_config) assert config.api_key == api_key assert config.host == 'https://' + controller_host - assert config.openapi_config == openapi_config + assert config.ssl_ca_certs == 'path/to/cert-bundle.pem' def test_resolution_order_kwargs_over_env_vars(self): """ @@ -84,5 +88,60 @@ def test_config_pool_threads(self): pc = Pinecone(api_key="test-api-key", host="test-controller-host", pool_threads=10) assert pc.index_api.api_client.pool_threads == 10 idx = pc.Index(host='my-index-host', name='my-index-name') - assert idx._api_client.pool_threads == 10 + assert idx._vector_api.api_client.pool_threads == 10 + + def test_config_when_openapi_config_is_passed_merges_api_key(self): + oai_config = OpenApiConfiguration() + pc = Pinecone(api_key='asdf', openapi_config=oai_config) + assert pc.openapi_config.api_key == {'ApiKeyAuth': 'asdf'} + + def test_ssl_config_passed_to_index_client(self): + oai_config = OpenApiConfiguration() + oai_config.ssl_ca_cert = 'path/to/cert' + proxy_headers = make_headers(proxy_basic_auth='asdf') + oai_config.proxy_headers = proxy_headers + + pc = Pinecone(api_key='key', openapi_config=oai_config) + + assert pc.openapi_config.ssl_ca_cert == 'path/to/cert' + assert pc.openapi_config.proxy_headers == proxy_headers + + idx = pc.Index(host='host') + assert idx._vector_api.api_client.configuration.ssl_ca_cert == 'path/to/cert' + assert idx._vector_api.api_client.configuration.proxy_headers == proxy_headers + + def test_host_config_not_clobbered_by_index(self): + oai_config = OpenApiConfiguration() + oai_config.ssl_ca_cert = 'path/to/cert' + proxy_headers = make_headers(proxy_basic_auth='asdf') + oai_config.proxy_headers = proxy_headers + pc = Pinecone(api_key='key', openapi_config=oai_config) + + assert pc.openapi_config.ssl_ca_cert == 'path/to/cert' + assert pc.openapi_config.proxy_headers == proxy_headers + assert pc.openapi_config.host == 'https://api.pinecone.io' + + idx = pc.Index(host='host') + assert idx._vector_api.api_client.configuration.ssl_ca_cert == 'path/to/cert' + assert idx._vector_api.api_client.configuration.proxy_headers == proxy_headers + assert idx._vector_api.api_client.configuration.host == 'https://host' + + assert pc.openapi_config.host == 'https://api.pinecone.io' + + def test_proxy_config(self): + pc = Pinecone( + api_key='asdf', + proxy_url='http://localhost:8080', + ssl_ca_certs='path/to/cert-bundle.pem', + ) + + assert pc.config.proxy_url == 'http://localhost:8080' + assert pc.config.ssl_ca_certs == 'path/to/cert-bundle.pem' + + assert pc.openapi_config.proxy == 'http://localhost:8080' + assert pc.openapi_config.ssl_ca_cert == 'path/to/cert-bundle.pem' + + assert pc.index_api.api_client.configuration.proxy == 'http://localhost:8080' + assert pc.index_api.api_client.configuration.ssl_ca_cert == 'path/to/cert-bundle.pem' + \ No newline at end of file diff --git a/tests/unit/test_config_builder.py b/tests/unit/test_config_builder.py new file mode 100644 index 00000000..d651595f --- /dev/null +++ b/tests/unit/test_config_builder.py @@ -0,0 +1,83 @@ +import pytest + +from pinecone.core.client.configuration import Configuration as OpenApiConfiguration +from pinecone.config import ConfigBuilder +from pinecone import PineconeConfigurationError + +class TestConfigBuilder: + def test_build_simple(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") + assert config.api_key == "my-api-key" + assert config.host == "https://my-controller-host" + assert config.additional_headers == {} + + def test_build_merges_key_and_host_when_openapi_config_provided(self): + config = ConfigBuilder.build( + api_key="my-api-key", + host="https://my-controller-host", + openapi_config=OpenApiConfiguration() + ) + assert config.api_key == "my-api-key" + assert config.host == "https://my-controller-host" + assert config.additional_headers == {} + + def test_build_with_source_tag(self): + config = ConfigBuilder.build( + api_key="my-api-key", + host="https://my-controller-host", + source_tag="my-source-tag", + ) + assert config.api_key == "my-api-key" + assert config.host == "https://my-controller-host" + assert config.additional_headers == {} + assert config.source_tag == "my-source-tag" + + def test_build_errors_when_no_api_key_is_present(self): + with pytest.raises(PineconeConfigurationError) as e: + ConfigBuilder.build() + assert str(e.value) == "You haven't specified an Api-Key." + + def test_build_errors_when_no_host_is_present(self): + with pytest.raises(PineconeConfigurationError) as e: + ConfigBuilder.build(api_key='my-api-key') + assert str(e.value) == "You haven't specified a host." + + def test_build_openapi_config(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") + openapi_config = ConfigBuilder.build_openapi_config(config) + assert openapi_config.host == "https://my-controller-host" + assert openapi_config.api_key == {"ApiKeyAuth": "my-api-key"} + + def test_build_openapi_config_merges_with_existing_config(self): + config = ConfigBuilder.build( + api_key="my-api-key", + host="https://my-controller-host" + ) + openapi_config = OpenApiConfiguration() + openapi_config.ssl_ca_cert = "path/to/bundle" + openapi_config.proxy = 'http://my-proxy:8080' + + openapi_config = ConfigBuilder.build_openapi_config(config, openapi_config) + + assert openapi_config.api_key == {"ApiKeyAuth": "my-api-key"} + assert openapi_config.host == "https://my-controller-host" + assert openapi_config.ssl_ca_cert == "path/to/bundle" + assert openapi_config.proxy == 'http://my-proxy:8080' + + def test_build_openapi_config_does_not_mutate_input(self): + config = ConfigBuilder.build( + api_key="my-api-key", + host="foo", + ssl_ca_certs="path/to/bundle.foo" + ) + + input_openapi_config = OpenApiConfiguration() + input_openapi_config.host = 'bar' + input_openapi_config.ssl_ca_cert = "asdfasdf" + + openapi_config = ConfigBuilder.build_openapi_config(config, input_openapi_config) + assert openapi_config.host == "https://foo" + assert openapi_config.ssl_ca_cert == "path/to/bundle.foo" + + assert input_openapi_config.host == 'bar' + assert input_openapi_config.ssl_ca_cert == "asdfasdf" \ No newline at end of file diff --git a/tests/unit/test_control.py b/tests/unit/test_control.py index 18ccae9e..7e4bd6e1 100644 --- a/tests/unit/test_control.py +++ b/tests/unit/test_control.py @@ -1,7 +1,10 @@ import pytest -from pinecone import Pinecone, PodSpec, ServerlessSpec +import re +from pinecone import ConfigBuilder, Pinecone, PodSpec, ServerlessSpec from pinecone.core.client.models import IndexList, IndexModel from pinecone.core.client.api.manage_indexes_api import ManageIndexesApi +from pinecone.core.client.configuration import Configuration as OpenApiConfiguration + import time @pytest.fixture @@ -39,6 +42,15 @@ def test_overwrite_useragent(self): assert p.index_api.api_client.default_headers['User-Agent'] == 'test-user-agent' assert len(p.index_api.api_client.default_headers) == 1 + def test_set_source_tag_in_useragent(self): + p = Pinecone(api_key="123-456-789", source_tag="test_source_tag") + assert re.search(r"source_tag=test_source_tag", p.index_api.api_client.user_agent) is not None + + def test_set_source_tag_in_useragent_via_config(self): + config = ConfigBuilder.build(api_key='YOUR_API_KEY', host='https://my-host', source_tag='my_source_tag') + p = Pinecone(config=config) + assert re.search(r"source_tag=my_source_tag", p.index_api.api_client.user_agent) is not None + @pytest.mark.parametrize("timeout_value, describe_index_responses, expected_describe_index_calls, expected_sleep_calls", [ # When timeout=None, describe_index is called until ready (None, [{ "status": {"ready": False}}, {"status": {"ready": True}}], 2, 1), @@ -107,25 +119,29 @@ def test_list_indexes_returns_iterable(self, mocker, index_list_response): response = p.list_indexes() assert [i.name for i in response] == ["index1", "index2", "index3"] + def test_api_key_and_openapi_config(self, mocker): + p = Pinecone(api_key="123", openapi_config=OpenApiConfiguration.get_default_copy()) + assert p.config.api_key == "123" class TestIndexConfig: def test_default_pool_threads(self): pc = Pinecone(api_key="123-456-789") index = pc.Index(host='my-host.svg.pinecone.io') - assert index._api_client.pool_threads == 1 + assert index._vector_api.api_client.pool_threads == 1 def test_pool_threads_when_indexapi_passed(self): pc = Pinecone(api_key="123-456-789", pool_threads=2, index_api=ManageIndexesApi()) index = pc.Index(host='my-host.svg.pinecone.io') - assert index._api_client.pool_threads == 2 + assert index._vector_api.api_client.pool_threads == 2 def test_target_index_with_pool_threads_inherited(self): pc = Pinecone(api_key="123-456-789", pool_threads=10, foo='bar') index = pc.Index(host='my-host.svg.pinecone.io') - assert index._api_client.pool_threads == 10 + assert index._vector_api.api_client.pool_threads == 10 def test_target_index_with_pool_threads_kwarg(self): pc = Pinecone(api_key="123-456-789", pool_threads=10) index = pc.Index(host='my-host.svg.pinecone.io', pool_threads=5) - assert index._api_client.pool_threads == 5 + assert index._vector_api.api_client.pool_threads == 5 + diff --git a/tests/unit/test_index_initialization.py b/tests/unit/test_index_initialization.py index 0dc2545d..4fc12500 100644 --- a/tests/unit/test_index_initialization.py +++ b/tests/unit/test_index_initialization.py @@ -1,5 +1,6 @@ import pytest -from pinecone import Pinecone +import re +from pinecone import ConfigBuilder, Pinecone class TestIndexClientInitialization(): @pytest.mark.parametrize( @@ -12,9 +13,9 @@ class TestIndexClientInitialization(): def test_no_additional_headers_leaves_useragent_only(self, additional_headers): pc = Pinecone(api_key='YOUR_API_KEY') index = pc.Index(host='myhost', additional_headers=additional_headers) - assert len(index._api_client.default_headers) == 1 - assert 'User-Agent' in index._api_client.default_headers - assert 'python-client-' in index._api_client.default_headers['User-Agent'] + assert len(index._vector_api.api_client.default_headers) == 1 + assert 'User-Agent' in index._vector_api.api_client.default_headers + assert 'python-client-' in index._vector_api.api_client.default_headers['User-Agent'] def test_additional_headers_one_additional(self): pc = Pinecone(api_key='YOUR_API_KEY') @@ -22,8 +23,8 @@ def test_additional_headers_one_additional(self): host='myhost', additional_headers={'test-header': 'test-header-value'} ) - assert 'test-header' in index._api_client.default_headers - assert len(index._api_client.default_headers) == 2 + assert 'test-header' in index._vector_api.api_client.default_headers + assert len(index._vector_api.api_client.default_headers) == 2 def test_multiple_additional_headers(self): pc = Pinecone(api_key='YOUR_API_KEY') @@ -34,9 +35,9 @@ def test_multiple_additional_headers(self): 'test-header2': 'test-header-value2' } ) - assert 'test-header' in index._api_client.default_headers - assert 'test-header2' in index._api_client.default_headers - assert len(index._api_client.default_headers) == 3 + assert 'test-header' in index._vector_api.api_client.default_headers + assert 'test-header2' in index._vector_api.api_client.default_headers + assert len(index._vector_api.api_client.default_headers) == 3 def test_overwrite_useragent(self): # This doesn't seem like a common use case, but we may want to allow this @@ -48,6 +49,17 @@ def test_overwrite_useragent(self): 'User-Agent': 'test-user-agent' } ) - assert len(index._api_client.default_headers) == 1 - assert 'User-Agent' in index._api_client.default_headers - assert index._api_client.default_headers['User-Agent'] == 'test-user-agent' \ No newline at end of file + assert len(index._vector_api.api_client.default_headers) == 1 + assert 'User-Agent' in index._vector_api.api_client.default_headers + assert index._vector_api.api_client.default_headers['User-Agent'] == 'test-user-agent' + + def test_set_source_tag(self): + pc = Pinecone(api_key="123-456-789", source_tag="test_source_tag") + index = pc.Index(host='myhost') + assert re.search(r"source_tag=test_source_tag", pc.index_api.api_client.user_agent) is not None + + def test_set_source_tag_via_config(self): + config = ConfigBuilder.build(api_key='YOUR_API_KEY', host='https://my-host', source_tag='my_source_tag') + pc = Pinecone(config=config) + index = pc.Index(host='myhost') + assert re.search(r"source_tag=my_source_tag", pc.index_api.api_client.user_agent) is not None diff --git a/tests/unit/test_langchain_helpful_errors.py b/tests/unit/test_langchain_helpful_errors.py new file mode 100644 index 00000000..006572c3 --- /dev/null +++ b/tests/unit/test_langchain_helpful_errors.py @@ -0,0 +1,19 @@ +import pytest +from pinecone import Pinecone + +class TestLangchainErrorMessages(): + def test_error_from_texts_positional_args(self): + with pytest.raises(AttributeError) as e: + Pinecone.from_texts("texts", "id") + assert "from_texts is not a top-level attribute of the Pinecone class" in str(e.value) + + def test_error_from_texts_kwargs(self): + with pytest.raises(AttributeError) as e: + Pinecone.from_texts(foo="texts", bar="id", num_threads=1) + assert "from_texts is not a top-level attribute of the Pinecone class" in str(e.value) + + def test_error_from_documents(self): + with pytest.raises(AttributeError) as e: + Pinecone.from_documents("documents", "id") + assert "from_documents is not a top-level attribute of the Pinecone class" in str(e.value) + diff --git a/tests/unit/utils/test_convert_to_list.py b/tests/unit/utils/test_convert_to_list.py index 384e169f..8107c125 100644 --- a/tests/unit/utils/test_convert_to_list.py +++ b/tests/unit/utils/test_convert_to_list.py @@ -37,3 +37,23 @@ def test_convert_to_list_when_already_list(): actual = convert_to_list(obj) expected = [1, 2, 3] assert actual == expected + +@pytest.mark.parametrize("input", [ + "", + "not a list", + {} +]) +def test_invalid_iterable_inputs(input): + with pytest.raises(TypeError, match="Expected a list or list-like data structure"): + convert_to_list(input) + +@pytest.mark.parametrize("invalid_input", [ + None, + 1, + 0, + 1.0, + True +]) +def test_invalid_non_iterable_input(invalid_input): + with pytest.raises(TypeError, match="Expected a list or list-like data structure"): + convert_to_list(invalid_input) \ No newline at end of file diff --git a/tests/unit/utils/test_docs_links.py b/tests/unit/utils/test_docs_links.py new file mode 100644 index 00000000..deb9f512 --- /dev/null +++ b/tests/unit/utils/test_docs_links.py @@ -0,0 +1,10 @@ +import pytest +import requests +from pinecone.utils import docslinks + +urls = list(docslinks.values()) + +@pytest.mark.parametrize("url", urls) +def test_valid_links(url): + response = requests.get(url) + assert response.status_code == 200, f"Docs link is invalid: {url}" \ No newline at end of file diff --git a/tests/unit/utils/test_setup_openapi_client.py b/tests/unit/utils/test_setup_openapi_client.py new file mode 100644 index 00000000..0c44688a --- /dev/null +++ b/tests/unit/utils/test_setup_openapi_client.py @@ -0,0 +1,11 @@ +import re +from pinecone.config import ConfigBuilder +from pinecone.core.client.api.manage_indexes_api import ManageIndexesApi +from pinecone.utils.setup_openapi_client import setup_openapi_client + +class TestSetupOpenAPIClient(): + def test_setup_openapi_client(self): + "" + # config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") + # api_client = setup_openapi_client(ManageIndexesApi, config=config, pool_threads=2) + # # assert api_client.user_agent == "pinecone-python-client/0.0.1" diff --git a/tests/unit/utils/test_user_agent.py b/tests/unit/utils/test_user_agent.py index 38272be4..a9f6db41 100644 --- a/tests/unit/utils/test_user_agent.py +++ b/tests/unit/utils/test_user_agent.py @@ -1,8 +1,47 @@ import re -from pinecone.utils.user_agent import get_user_agent +from pinecone.utils.user_agent import get_user_agent, get_user_agent_grpc +from pinecone.config import ConfigBuilder class TestUserAgent(): def test_user_agent(self): - useragent = get_user_agent() + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") + useragent = get_user_agent(config) assert re.search(r"python-client-\d+\.\d+\.\d+", useragent) is not None - assert re.search(r"urllib3:\d+\.\d+\.\d+", useragent) is not None \ No newline at end of file + assert re.search(r"urllib3:\d+\.\d+\.\d+", useragent) is not None + + def test_user_agent_with_source_tag(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag="my_source_tag") + useragent = get_user_agent(config) + assert re.search(r"python-client-\d+\.\d+\.\d+", useragent) is not None + assert re.search(r"urllib3:\d+\.\d+\.\d+", useragent) is not None + assert re.search(r"source_tag=my_source_tag", useragent) is not None + + def test_source_tag_is_normalized(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag="my source tag!!!!") + useragent = get_user_agent(config) + assert re.search(r"source_tag=my_source_tag", useragent) is not None + + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag="My Source Tag") + useragent = get_user_agent(config) + assert re.search(r"source_tag=my_source_tag", useragent) is not None + + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag=" My Source Tag 123 ") + useragent = get_user_agent(config) + assert re.search(r"source_tag=my_source_tag_123", useragent) is not None + + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag=" My Source Tag 123 #### !! ") + useragent = get_user_agent(config) + assert re.search(r"source_tag=my_source_tag_123", useragent) is not None + + def test_user_agent_grpc(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") + useragent = get_user_agent_grpc(config) + assert re.search(r"python-client\[grpc\]-\d+\.\d+\.\d+", useragent) is not None + assert re.search(r"urllib3:\d+\.\d+\.\d+", useragent) is not None + + def test_user_agent_grpc_with_source_tag(self): + config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host", source_tag="my_source_tag") + useragent = get_user_agent_grpc(config) + assert re.search(r"python-client\[grpc\]-\d+\.\d+\.\d+", useragent) is not None + assert re.search(r"urllib3:\d+\.\d+\.\d+", useragent) is not None + assert re.search(r"source_tag=my_source_tag", useragent) is not None \ No newline at end of file diff --git a/tests/unit_grpc/test_grpc_index_initialization.py b/tests/unit_grpc/test_grpc_index_initialization.py index 4d050c44..59cb2967 100644 --- a/tests/unit_grpc/test_grpc_index_initialization.py +++ b/tests/unit_grpc/test_grpc_index_initialization.py @@ -1,4 +1,6 @@ +import re from pinecone.grpc import PineconeGRPC, GRPCClientConfig +from pinecone import ConfigBuilder class TestGRPCIndexInitialization: def test_init_with_default_config(self): @@ -85,3 +87,8 @@ def test_config_passed_when_target_by_host(self): # Unset fields still get default values assert index.grpc_client_config.reuse_channel == True assert index.grpc_client_config.conn_timeout == 1 + + def test_config_passes_source_tag_when_set(self): + pc = PineconeGRPC(api_key='YOUR_API_KEY', source_tag='my_source_tag') + index = pc.Index(name='my-index', host='host') + assert re.search(r"source_tag=my_source_tag", pc.index_api.api_client.user_agent) is not None diff --git a/tests/unit_grpc/test_sparse_values_factory.py b/tests/unit_grpc/test_sparse_values_factory.py new file mode 100644 index 00000000..5bd6a50b --- /dev/null +++ b/tests/unit_grpc/test_sparse_values_factory.py @@ -0,0 +1,88 @@ +import pytest +from pinecone.grpc import SparseValues as GRPCSparseValues +from pinecone import SparseValues as NonGRPCSparseValues + +import numpy as np +import pandas as pd + + +from pinecone.grpc.sparse_values_factory import SparseValuesFactory + +class TestSparseValuesFactory: + def test_build_when_None(self): + assert SparseValuesFactory.build(None) == None + + def test_build_when_passed_GRPCSparseValues(self): + """ + Return without modification when given GRPCSparseValues + """ + sv = GRPCSparseValues(indices=[0, 2], values=[0.1, 0.3]) + actual = SparseValuesFactory.build(sv) + assert actual == sv + + def test_build_when_passed_NonGRPCSparseValues(self): + """ + Convert when given NonGRPCSparseValues + """ + sv = NonGRPCSparseValues(indices=[0, 2], values=[0.1, 0.3]) + actual = SparseValuesFactory.build(sv) + expected = GRPCSparseValues(indices=[0, 2], values=[0.1, 0.3]) + assert actual == expected + + @pytest.mark.parametrize('input', [ + {'indices': [2], 'values': [0.3]}, + {'indices': [88, 102], 'values': [-0.1, 0.3]}, + {'indices': [0, 2, 4], 'values': [0.1, 0.3, 0.5]}, + {'indices': [0, 2, 4, 6], 'values': [0.1, 0.3, 0.5, 0.7]}, + ]) + def test_build_when_valid_dictionary(self, input): + actual = SparseValuesFactory.build(input) + expected = GRPCSparseValues(indices=input['indices'], values=input['values']) + assert actual == expected + + @pytest.mark.parametrize('input', [ + {'indices': np.array([0, 2]), 'values': [0.1, 0.3]}, + {'indices': [0, 2], 'values': np.array([0.1, 0.3])}, + {'indices': np.array([0, 2]), 'values': np.array([0.1, 0.3])}, + {'indices': pd.array([0, 2]), 'values': [0.1, 0.3]}, + {'indices': [0, 2], 'values': pd.array([0.1, 0.3])}, + {'indices': pd.array([0, 2]), 'values': pd.array([0.1, 0.3])}, + {'indices': np.array([0, 2]), 'values': pd.array([0.1, 0.3])}, + {'indices': pd.array([0, 2]), 'values': np.array([0.1, 0.3])}, + ]) + def test_build_when_special_data_types(self, input): + """ + Test that the factory can handle special data types like + numpy/pandas integer and float arrays. + """ + actual = SparseValuesFactory.build(input) + expected = GRPCSparseValues(indices=[0, 2], values=[0.1, 0.3]) + assert actual == expected + + @pytest.mark.parametrize('input', [ + {'indices': [2], 'values': [0.3, 0.3]}, + {'indices': [88, 102], 'values': [-0.1]}, + ]) + def test_build_when_list_sizes_dont_match(self, input): + with pytest.raises(ValueError, match="Sparse values indices and values must have the same length"): + SparseValuesFactory.build(input) + + @pytest.mark.parametrize('input', [ + {'indices': [2.0], 'values': [0.3]}, + {'indices': ['2'], 'values': [0.3]}, + {'indices': np.array([2.0]), 'values': [0.3]}, + {'indices': pd.array([2.0]), 'values': [0.3]}, + ]) + def test_build_when_non_integer_indices(self, input): + with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): + SparseValuesFactory.build(input) + + @pytest.mark.parametrize('input', [ + {'indices': [2], 'values': [3]}, + {'indices': [2], 'values': ['3.2']}, + {'indices': [2], 'values': np.array([3])}, + {'indices': [2], 'values': pd.array([3])}, + ]) + def test_build_when_non_float_values(self, input): + with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): + SparseValuesFactory.build(input) diff --git a/tests/unit_grpc/test_vector_factory_grpc.py b/tests/unit_grpc/test_vector_factory_grpc.py index 491f1c39..954ab919 100644 --- a/tests/unit_grpc/test_vector_factory_grpc.py +++ b/tests/unit_grpc/test_vector_factory_grpc.py @@ -2,29 +2,31 @@ import pandas as pd import pytest +from collections.abc import Iterable, Mapping + from pinecone.grpc.vector_factory_grpc import VectorFactoryGRPC from pinecone.grpc import Vector, SparseValues from pinecone.grpc.utils import dict_to_proto_struct from pinecone import Vector as NonGRPCVector, SparseValues as NonGRPCSparseValues -class TestVectorFactory: +class TestVectorFactoryGRPC: def test_build_when_returns_vector_unmodified(self): vec = Vector(id="1", values=[0.1, 0.2, 0.3]) assert VectorFactoryGRPC.build(vec) == vec assert VectorFactoryGRPC.build(vec).__class__ == Vector - def test_build_when_nongrpc_vector(self): + def test_build_when_nongrpc_vector_it_converts(self): vec = NonGRPCVector(id="1", values=[0.1, 0.2, 0.3]) assert VectorFactoryGRPC.build(vec) == Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({})) - def test_build_when_nongrpc_vector_with_metadata(self): + def test_build_when_nongrpc_vector_with_metadata_it_converts(self): vec = NonGRPCVector(id="1", values=[0.1, 0.2, 0.3], metadata={"genre": "comedy"}) assert VectorFactoryGRPC.build(vec) == Vector( id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({"genre": "comedy"}) ) - def test_build_when_nongrpc_vector_with_sparse_values(self): + def test_build_when_nongrpc_vector_with_sparse_values_it_converts(self): vec = NonGRPCVector( id="1", values=[0.1, 0.2, 0.3], sparse_values=NonGRPCSparseValues(indices=[0, 2], values=[0.1, 0.3]) ) @@ -35,20 +37,37 @@ def test_build_when_nongrpc_vector_with_sparse_values(self): sparse_values=SparseValues(indices=[0, 2], values=[0.1, 0.3]), ) - def test_build_when_tuple_with_two_values(self): - tup = ("1", [0.1, 0.2, 0.3]) - actual = VectorFactoryGRPC.build(tup) - expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata={}) - assert actual == expected - - def test_build_when_tuple_with_three_values(self): - tup = ("1", [0.1, 0.2, 0.3], {"genre": "comedy"}) + @pytest.mark.parametrize("values_array", [ + [0.1, 0.2, 0.3], + np.array([0.1, 0.2, 0.3]), + pd.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_tuple_with_two_values(self, values_array): + tup = ("1", values_array) actual = VectorFactoryGRPC.build(tup) - expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({"genre": "comedy"})) + expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({})) assert actual == expected - def test_build_when_tuple_with_numpy_array(self): - tup = ("1", np.array([0.1, 0.2, 0.3]), {"genre": "comedy"}) + @pytest.mark.parametrize("vector_tup", [ + ("1", 'not an array'), + ("1", {}), + ("1", 'not an array', {"genre": "comedy"}), + ("1", {}, {"genre": "comedy"}) + ]) + def test_build_when_tuple_values_must_be_list(self, vector_tup): + with pytest.raises( + TypeError, + match="Expected a list or list-like data structure", + ): + VectorFactoryGRPC.build(vector_tup) + + @pytest.mark.parametrize("values_array", [ + [0.1, 0.2, 0.3], + np.array([0.1, 0.2, 0.3]), + pd.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_tuple_with_three_values(self, values_array): + tup = ("1", values_array, {"genre": "comedy"}) actual = VectorFactoryGRPC.build(tup) expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({"genre": "comedy"})) assert actual == expected @@ -62,12 +81,6 @@ def test_build_vector_with_tuple_with_sparse_values(self, sv_klass): ): VectorFactoryGRPC.build(tup) - def test_build_when_tuple_with_pandas_array(self): - tup = ("1", pd.array([0.1, 0.2, 0.3])) - actual = VectorFactoryGRPC.build(tup) - expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({})) - assert actual == expected - def test_build_when_tuple_errors_when_additional_fields(self): with pytest.raises(ValueError, match="Found a tuple of length 4 which is not supported"): tup = ("1", [0.1, 0.2, 0.3], {"a": "b"}, "extra") @@ -78,7 +91,10 @@ def test_build_when_tuple_too_short(self): tup = ("1",) VectorFactoryGRPC.build(tup) - @pytest.mark.parametrize("metadata", [{"genre": "comedy"}, dict_to_proto_struct({"genre": "comedy"})]) + @pytest.mark.parametrize("metadata", [ + {"genre": "comedy"}, + dict_to_proto_struct({"genre": "comedy"})] + ) def test_build_when_dict(self, metadata): d = {"id": "1", "values": [0.1, 0.2, 0.3], "metadata": metadata} actual = VectorFactoryGRPC.build(d) @@ -124,16 +140,12 @@ def test_build_with_dict_with_sparse_values_object(self, sv_klass): ) assert actual == expected - @pytest.mark.parametrize("metadata", [{"genre": "comedy"}, dict_to_proto_struct({"genre": "comedy"})]) - def test_build_when_dict_with_numpy_values(self, metadata): - d = {"id": "1", "values": np.array([0.1, 0.2, 0.3]), "metadata": metadata} - actual = VectorFactoryGRPC.build(d) - expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({"genre": "comedy"})) - assert actual == expected - - @pytest.mark.parametrize("metadata", [{"genre": "comedy"}, dict_to_proto_struct({"genre": "comedy"})]) - def test_build_when_dict_with_pandas_values(self, metadata): - d = {"id": "1", "values": pd.array([0.1, 0.2, 0.3]), "metadata": metadata} + @pytest.mark.parametrize("input_values", [ + pd.array([0.1, 0.2, 0.3]), + np.array([0.1, 0.2, 0.3]) + ]) + def test_build_when_dict_with_special_values(self, input_values): + d = {"id": "1", "values": input_values, "metadata": {"genre": "comedy"}} actual = VectorFactoryGRPC.build(d) expected = Vector(id="1", values=[0.1, 0.2, 0.3], metadata=dict_to_proto_struct({"genre": "comedy"})) assert actual == expected @@ -148,12 +160,20 @@ def test_build_when_dict_excess_keys(self): d = {"id": "1", "values": [0.1, 0.2, 0.3], "metadata": {"genre": "comedy"}, "extra": "field"} VectorFactoryGRPC.build(d) - def test_build_when_dict_sparse_values(self): + @pytest.mark.parametrize("sv_indices,sv_values", [ + ([0, 2], [0.1, 0.3]), + (pd.array([0, 2]), [0.1, 0.3]), + ([0, 2], pd.array([0.1, 0.3])), + (pd.array([0, 2]), pd.array([0.1, 0.3])), + (np.array([0, 2]), [0.1, 0.3]), + ([0, 2], np.array([0.1, 0.3])) + ]) + def test_build_when_dict_sparse_values(self, sv_indices, sv_values): d = { "id": "1", "values": [0.1, 0.2, 0.3], "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": [0, 2], "values": [0.1, 0.3]}, + "sparse_values": {"indices": sv_indices, "values": sv_values}, } actual = VectorFactoryGRPC.build(d) expected = Vector( @@ -180,115 +200,84 @@ def test_build_when_dict_sparse_values_when_SparseValues(self): ) assert actual == expected - def test_build_when_dict_sparse_values_errors_when_not_dict(self): - with pytest.raises(ValueError, match="Column `sparse_values` is expected to be a dictionary"): - d = {"id": "1", "values": [0.1, 0.2, 0.3], "metadata": {"genre": "comedy"}, "sparse_values": "not a dict"} - VectorFactoryGRPC.build(d) - - def test_build_when_dict_sparse_values_errors_when_missing_indices(self): - with pytest.raises(ValueError, match="Missing required keys in data in column `sparse_values`"): + @pytest.mark.parametrize("bogus_sparse_values", [ + 1, + "not an array", + [1, 2], + {} + ]) + def test_build_when_dict_sparse_values_errors_when_invalid_sparse_values_values(self, bogus_sparse_values): + with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): d = { "id": "1", "values": [0.1, 0.2, 0.3], "metadata": {"genre": "comedy"}, - "sparse_values": {"values": [0.1, 0.3]}, + "sparse_values": {"indices": [1, 2], "values": bogus_sparse_values}, } VectorFactoryGRPC.build(d) - def test_build_when_dict_sparse_values_errors_when_missing_values(self): - with pytest.raises(ValueError, match="Missing required keys in data in column `sparse_values`"): + @pytest.mark.parametrize("bogus_sparse_indices", [ + 1, + "not an array", + [0.1, 0.2], + {} + ]) + def test_build_when_dict_sparse_values_errors_when_indices_not_valid_list(self, bogus_sparse_indices): + with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): d = { "id": "1", "values": [0.1, 0.2, 0.3], "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": [0, 2]}, + "sparse_values": {"indices": bogus_sparse_indices, "values": [0.1, 0.1]}, } VectorFactoryGRPC.build(d) - def test_build_when_dict_sparse_values_errors_when_indices_not_list(self): - with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): + def test_build_when_errors_when_other_type(self): + with pytest.raises(ValueError, match="Invalid vector value passed: cannot interpret type"): + VectorFactoryGRPC.build(1) + + @pytest.mark.parametrize("bogus_sparse_values", [ + 1, + "not a dict", + [1, 2, 3], + [], + ]) + def test_build_when_invalid_sparse_values_type_in_dict(self, bogus_sparse_values): + with pytest.raises(ValueError, match="Column `sparse_values` is expected to be a dictionary"): d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": "not a list", "values": [0.1, 0.3]}, + 'id': '1', + 'values': [0.1, 0.2, 0.3], + 'metadata': {'genre': 'comedy'}, + 'sparse_values': bogus_sparse_values # not a valid dict } VectorFactoryGRPC.build(d) - def test_build_when_dict_sparse_values_errors_when_values_not_list(self): - with pytest.raises(ValueError, match="Found unexpected data in column `sparse_values`"): + @pytest.mark.parametrize("bogus_sparse_values", [ + {}, + {'indices': [0, 2]}, + {'values': [0.1, 0.3]}, + ]) + def test_build_when_missing_keys_in_sparse_values_dict(self, bogus_sparse_values): + with pytest.raises(ValueError, match="Missing required keys in data in column `sparse_values`"): d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": [0, 2], "values": "not a list"}, + 'id': '1', + 'values': [0.1, 0.2, 0.3], + 'metadata': {'genre': 'comedy'}, + 'sparse_values': bogus_sparse_values } VectorFactoryGRPC.build(d) - def test_build_when_dict_sparse_values_when_values_is_ndarray(self): - d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": [0, 2], "values": np.array([0.1, 0.3])}, - } - actual = VectorFactoryGRPC.build(d) - expected = Vector( - id="1", - values=[0.1, 0.2, 0.3], - metadata=dict_to_proto_struct({"genre": "comedy"}), - sparse_values=SparseValues(indices=[0, 2], values=[0.1, 0.3]), - ) - assert actual == expected - - def test_build_when_dict_sparse_values_when_indices_is_pandas_IntegerArray(self): - d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": pd.array([0, 2]), "values": [0.1, 0.3]}, - } - actual = VectorFactoryGRPC.build(d) - expected = Vector( - id="1", - values=[0.1, 0.2, 0.3], - metadata=dict_to_proto_struct({"genre": "comedy"}), - sparse_values=SparseValues(indices=[0, 2], values=[0.1, 0.3]), - ) - assert actual == expected - - def test_build_when_dict_sparse_values_when_values_is_pandas_FloatingArray(self): - d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": [0, 2], "values": pd.array([0.1, 0.3])}, - } - actual = VectorFactoryGRPC.build(d) - expected = Vector( - id="1", - values=[0.1, 0.2, 0.3], - metadata=dict_to_proto_struct({"genre": "comedy"}), - sparse_values=SparseValues(indices=[0, 2], values=[0.1, 0.3]), - ) - assert actual == expected - - def test_build_when_dict_sparse_values_when_indices_is_ndarray(self): + def test_build_when_sparse_values_is_None(self): d = { - "id": "1", - "values": [0.1, 0.2, 0.3], - "metadata": {"genre": "comedy"}, - "sparse_values": {"indices": np.array([0, 2]), "values": [0.1, 0.3]}, + 'id': '1', + 'values': [0.1, 0.2, 0.3], + 'metadata': {'genre': 'comedy'}, + 'sparse_values': None } actual = VectorFactoryGRPC.build(d) expected = Vector( - id="1", - values=[0.1, 0.2, 0.3], - metadata=dict_to_proto_struct({"genre": "comedy"}), - sparse_values=SparseValues(indices=[0, 2], values=[0.1, 0.3]), + id='1', + values=[0.1, 0.2, 0.3], + metadata=dict_to_proto_struct({'genre': 'comedy'}) ) - assert actual == expected - - def test_build_when_errors_when_other_type(self): - with pytest.raises(ValueError, match="Invalid vector value passed: cannot interpret type"): - VectorFactoryGRPC.build(1) + assert actual == expected \ No newline at end of file