mirror of
https://github.com/remsky/Kokoro-FastAPI.git
synced 2025-08-21 05:44:06 +00:00
388 lines
13 KiB
Python
388 lines
13 KiB
Python
![]() |
import logging
|
||
|
from typing import Optional, Dict, Union, TYPE_CHECKING
|
||
|
from multiprocessing import cpu_count
|
||
|
import warnings
|
||
|
|
||
|
from pinecone.config import PineconeConfig, ConfigBuilder
|
||
|
|
||
|
from .legacy_pinecone_interface import LegacyPineconeDBControlInterface
|
||
|
|
||
|
from pinecone.utils import normalize_host, PluginAware, docslinks, require_kwargs
|
||
|
from .langchain_import_warnings import _build_langchain_attribute_error_message
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
""" @private """
|
||
|
|
||
|
if TYPE_CHECKING:
|
||
|
from pinecone.config import Config, OpenApiConfiguration
|
||
|
from pinecone.db_data import _Index as Index, _IndexAsyncio as IndexAsyncio
|
||
|
from pinecone.db_control.index_host_store import IndexHostStore
|
||
|
from pinecone.core.openapi.db_control.api.manage_indexes_api import ManageIndexesApi
|
||
|
from pinecone.db_control.types import CreateIndexForModelEmbedTypedDict
|
||
|
from pinecone.db_control.enums import (
|
||
|
Metric,
|
||
|
VectorType,
|
||
|
DeletionProtection,
|
||
|
PodType,
|
||
|
CloudProvider,
|
||
|
AwsRegion,
|
||
|
GcpRegion,
|
||
|
AzureRegion,
|
||
|
)
|
||
|
from pinecone.db_control.models import (
|
||
|
ServerlessSpec,
|
||
|
PodSpec,
|
||
|
ByocSpec,
|
||
|
IndexModel,
|
||
|
IndexList,
|
||
|
CollectionList,
|
||
|
IndexEmbed,
|
||
|
BackupModel,
|
||
|
BackupList,
|
||
|
RestoreJobModel,
|
||
|
RestoreJobList,
|
||
|
)
|
||
|
|
||
|
|
||
|
class Pinecone(PluginAware, LegacyPineconeDBControlInterface):
|
||
|
"""
|
||
|
A client for interacting with Pinecone APIs.
|
||
|
"""
|
||
|
|
||
|
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,
|
||
|
additional_headers: Optional[Dict[str, str]] = {},
|
||
|
pool_threads: Optional[int] = None,
|
||
|
**kwargs,
|
||
|
):
|
||
|
for deprecated_kwarg in {"config", "openapi_config", "index_api"}:
|
||
|
if deprecated_kwarg in kwargs:
|
||
|
raise NotImplementedError(
|
||
|
f"Passing {deprecated_kwarg} is no longer supported. Please pass individual 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 {docslinks['README']} for examples."
|
||
|
)
|
||
|
|
||
|
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,
|
||
|
)
|
||
|
""" @private """
|
||
|
|
||
|
self._openapi_config = ConfigBuilder.build_openapi_config(self._config, **kwargs)
|
||
|
""" @private """
|
||
|
|
||
|
if pool_threads is None:
|
||
|
self._pool_threads = 5 * cpu_count()
|
||
|
""" @private """
|
||
|
else:
|
||
|
self._pool_threads = pool_threads
|
||
|
""" @private """
|
||
|
|
||
|
self._inference = None # Lazy initialization
|
||
|
""" @private """
|
||
|
|
||
|
self._db_control = None # Lazy initialization
|
||
|
""" @private """
|
||
|
|
||
|
super().__init__() # Initialize PluginAware
|
||
|
|
||
|
@property
|
||
|
def inference(self):
|
||
|
"""
|
||
|
Inference is a namespace where an instance of the `pinecone.inference.Inference` class is lazily created and cached.
|
||
|
"""
|
||
|
if self._inference is None:
|
||
|
from pinecone.inference import Inference
|
||
|
|
||
|
self._inference = Inference(
|
||
|
config=self._config,
|
||
|
openapi_config=self._openapi_config,
|
||
|
pool_threads=self._pool_threads,
|
||
|
)
|
||
|
return self._inference
|
||
|
|
||
|
@property
|
||
|
def db(self):
|
||
|
"""
|
||
|
DBControl is a namespace where an instance of the `pinecone.db_control.DBControl` class is lazily created and cached.
|
||
|
"""
|
||
|
if self._db_control is None:
|
||
|
from pinecone.db_control import DBControl
|
||
|
|
||
|
self._db_control = DBControl(
|
||
|
config=self._config,
|
||
|
openapi_config=self._openapi_config,
|
||
|
pool_threads=self._pool_threads,
|
||
|
)
|
||
|
return self._db_control
|
||
|
|
||
|
@property
|
||
|
def index_host_store(self) -> "IndexHostStore":
|
||
|
"""@private"""
|
||
|
warnings.warn(
|
||
|
"The `index_host_store` property is deprecated. This warning will become an error in a future version of the Pinecone Python SDK.",
|
||
|
DeprecationWarning,
|
||
|
stacklevel=2,
|
||
|
)
|
||
|
return self.db.index._index_host_store
|
||
|
|
||
|
@property
|
||
|
def config(self) -> "Config":
|
||
|
"""@private"""
|
||
|
# The config property is considered private, but the name cannot be changed to include underscore
|
||
|
# without breaking compatibility with plugins in the wild.
|
||
|
return self._config
|
||
|
|
||
|
@property
|
||
|
def openapi_config(self) -> "OpenApiConfiguration":
|
||
|
"""@private"""
|
||
|
warnings.warn(
|
||
|
"The `openapi_config` property has been renamed to `_openapi_config`. It is considered private and should not be used directly. This warning will become an error in a future version of the Pinecone Python SDK.",
|
||
|
DeprecationWarning,
|
||
|
stacklevel=2,
|
||
|
)
|
||
|
return self._openapi_config
|
||
|
|
||
|
@property
|
||
|
def pool_threads(self) -> int:
|
||
|
"""@private"""
|
||
|
warnings.warn(
|
||
|
"The `pool_threads` property has been renamed to `_pool_threads`. It is considered private and should not be used directly. This warning will become an error in a future version of the Pinecone Python SDK.",
|
||
|
DeprecationWarning,
|
||
|
stacklevel=2,
|
||
|
)
|
||
|
return self._pool_threads
|
||
|
|
||
|
@property
|
||
|
def index_api(self) -> "ManageIndexesApi":
|
||
|
"""@private"""
|
||
|
warnings.warn(
|
||
|
"The `index_api` property is deprecated. This warning will become an error in a future version of the Pinecone Python SDK.",
|
||
|
DeprecationWarning,
|
||
|
stacklevel=2,
|
||
|
)
|
||
|
return self.db._index_api
|
||
|
|
||
|
def create_index(
|
||
|
self,
|
||
|
name: str,
|
||
|
spec: Union[Dict, "ServerlessSpec", "PodSpec", "ByocSpec"],
|
||
|
dimension: Optional[int] = None,
|
||
|
metric: Optional[Union["Metric", str]] = "cosine",
|
||
|
timeout: Optional[int] = None,
|
||
|
deletion_protection: Optional[Union["DeletionProtection", str]] = "disabled",
|
||
|
vector_type: Optional[Union["VectorType", str]] = "dense",
|
||
|
tags: Optional[Dict[str, str]] = None,
|
||
|
) -> "IndexModel":
|
||
|
return self.db.index.create(
|
||
|
name=name,
|
||
|
spec=spec,
|
||
|
dimension=dimension,
|
||
|
metric=metric,
|
||
|
timeout=timeout,
|
||
|
deletion_protection=deletion_protection,
|
||
|
vector_type=vector_type,
|
||
|
tags=tags,
|
||
|
)
|
||
|
|
||
|
def create_index_for_model(
|
||
|
self,
|
||
|
name: str,
|
||
|
cloud: Union["CloudProvider", str],
|
||
|
region: Union["AwsRegion", "GcpRegion", "AzureRegion", str],
|
||
|
embed: Union["IndexEmbed", "CreateIndexForModelEmbedTypedDict"],
|
||
|
tags: Optional[Dict[str, str]] = None,
|
||
|
deletion_protection: Optional[Union["DeletionProtection", str]] = "disabled",
|
||
|
timeout: Optional[int] = None,
|
||
|
) -> "IndexModel":
|
||
|
return self.db.index.create_for_model(
|
||
|
name=name,
|
||
|
cloud=cloud,
|
||
|
region=region,
|
||
|
embed=embed,
|
||
|
tags=tags,
|
||
|
deletion_protection=deletion_protection,
|
||
|
timeout=timeout,
|
||
|
)
|
||
|
|
||
|
@require_kwargs
|
||
|
def create_index_from_backup(
|
||
|
self,
|
||
|
*,
|
||
|
name: str,
|
||
|
backup_id: str,
|
||
|
deletion_protection: Optional[Union["DeletionProtection", str]] = "disabled",
|
||
|
tags: Optional[Dict[str, str]] = None,
|
||
|
timeout: Optional[int] = None,
|
||
|
) -> "IndexModel":
|
||
|
return self.db.index.create_from_backup(
|
||
|
name=name,
|
||
|
backup_id=backup_id,
|
||
|
deletion_protection=deletion_protection,
|
||
|
tags=tags,
|
||
|
timeout=timeout,
|
||
|
)
|
||
|
|
||
|
def delete_index(self, name: str, timeout: Optional[int] = None):
|
||
|
return self.db.index.delete(name=name, timeout=timeout)
|
||
|
|
||
|
def list_indexes(self) -> "IndexList":
|
||
|
return self.db.index.list()
|
||
|
|
||
|
def describe_index(self, name: str) -> "IndexModel":
|
||
|
return self.db.index.describe(name=name)
|
||
|
|
||
|
def has_index(self, name: str) -> bool:
|
||
|
return self.db.index.has(name=name)
|
||
|
|
||
|
def configure_index(
|
||
|
self,
|
||
|
name: str,
|
||
|
replicas: Optional[int] = None,
|
||
|
pod_type: Optional[Union["PodType", str]] = None,
|
||
|
deletion_protection: Optional[Union["DeletionProtection", str]] = None,
|
||
|
tags: Optional[Dict[str, str]] = None,
|
||
|
):
|
||
|
return self.db.index.configure(
|
||
|
name=name,
|
||
|
replicas=replicas,
|
||
|
pod_type=pod_type,
|
||
|
deletion_protection=deletion_protection,
|
||
|
tags=tags,
|
||
|
)
|
||
|
|
||
|
def create_collection(self, name: str, source: str) -> None:
|
||
|
return self.db.collection.create(name=name, source=source)
|
||
|
|
||
|
def list_collections(self) -> "CollectionList":
|
||
|
return self.db.collection.list()
|
||
|
|
||
|
def delete_collection(self, name: str) -> None:
|
||
|
return self.db.collection.delete(name=name)
|
||
|
|
||
|
def describe_collection(self, name: str):
|
||
|
return self.db.collection.describe(name=name)
|
||
|
|
||
|
@require_kwargs
|
||
|
def create_backup(
|
||
|
self, *, index_name: str, backup_name: str, description: str = ""
|
||
|
) -> "BackupModel":
|
||
|
return self.db.backup.create(
|
||
|
index_name=index_name, backup_name=backup_name, description=description
|
||
|
)
|
||
|
|
||
|
@require_kwargs
|
||
|
def list_backups(
|
||
|
self,
|
||
|
*,
|
||
|
index_name: Optional[str] = None,
|
||
|
limit: Optional[int] = 10,
|
||
|
pagination_token: Optional[str] = None,
|
||
|
) -> "BackupList":
|
||
|
return self.db.backup.list(
|
||
|
index_name=index_name, limit=limit, pagination_token=pagination_token
|
||
|
)
|
||
|
|
||
|
@require_kwargs
|
||
|
def describe_backup(self, *, backup_id: str) -> "BackupModel":
|
||
|
return self.db.backup.describe(backup_id=backup_id)
|
||
|
|
||
|
@require_kwargs
|
||
|
def delete_backup(self, *, backup_id: str) -> None:
|
||
|
return self.db.backup.delete(backup_id=backup_id)
|
||
|
|
||
|
@require_kwargs
|
||
|
def list_restore_jobs(
|
||
|
self, *, limit: Optional[int] = 10, pagination_token: Optional[str] = None
|
||
|
) -> "RestoreJobList":
|
||
|
return self.db.restore_job.list(limit=limit, pagination_token=pagination_token)
|
||
|
|
||
|
@require_kwargs
|
||
|
def describe_restore_job(self, *, job_id: str) -> "RestoreJobModel":
|
||
|
return self.db.restore_job.describe(job_id=job_id)
|
||
|
|
||
|
@staticmethod
|
||
|
def from_texts(*args, **kwargs):
|
||
|
"""@private"""
|
||
|
raise AttributeError(_build_langchain_attribute_error_message("from_texts"))
|
||
|
|
||
|
@staticmethod
|
||
|
def from_documents(*args, **kwargs):
|
||
|
"""@private"""
|
||
|
raise AttributeError(_build_langchain_attribute_error_message("from_documents"))
|
||
|
|
||
|
def Index(self, name: str = "", host: str = "", **kwargs) -> "Index":
|
||
|
from pinecone.db_data import _Index
|
||
|
|
||
|
if name == "" and host == "":
|
||
|
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 != "":
|
||
|
check_realistic_host(host)
|
||
|
|
||
|
# Use host url if it is provided
|
||
|
index_host = normalize_host(host)
|
||
|
else:
|
||
|
# Otherwise, get host url from describe_index using the index name
|
||
|
index_host = self.db.index._get_host(name)
|
||
|
|
||
|
return _Index(
|
||
|
host=index_host,
|
||
|
api_key=api_key,
|
||
|
pool_threads=pt,
|
||
|
openapi_config=openapi_config,
|
||
|
source_tag=self.config.source_tag,
|
||
|
**kwargs,
|
||
|
)
|
||
|
|
||
|
def IndexAsyncio(self, host: str, **kwargs) -> "IndexAsyncio":
|
||
|
from pinecone.db_data import _IndexAsyncio
|
||
|
|
||
|
api_key = self._config.api_key
|
||
|
openapi_config = self._openapi_config
|
||
|
|
||
|
if host is None or host == "":
|
||
|
raise ValueError("A host must be specified")
|
||
|
|
||
|
check_realistic_host(host)
|
||
|
index_host = normalize_host(host)
|
||
|
|
||
|
return _IndexAsyncio(
|
||
|
host=index_host,
|
||
|
api_key=api_key,
|
||
|
openapi_config=openapi_config,
|
||
|
source_tag=self.config.source_tag,
|
||
|
**kwargs,
|
||
|
)
|
||
|
|
||
|
|
||
|
def check_realistic_host(host: str) -> None:
|
||
|
"""@private
|
||
|
|
||
|
Checks whether a user-provided host string seems plausible.
|
||
|
Someone could erroneously pass an index name as the host by
|
||
|
mistake, and if they have done that we'd like to give them a
|
||
|
simple error message as feedback rather than attempting to
|
||
|
call the url and getting a more cryptic DNS resolution error.
|
||
|
"""
|
||
|
|
||
|
if "." not in host and "localhost" not in host:
|
||
|
raise ValueError(
|
||
|
f"You passed '{host}' as the host but this does not appear to be valid. Call describe_index() to confirm the host of the index."
|
||
|
)
|