Draken007's picture
Upload 7228 files
2a0bc63 verified
# Copyright DataStax, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import Any, Dict, List, Optional
from dataclasses import dataclass
@dataclass
class DatabaseInfo:
"""
Represents the identifying information for a database,
including the region the connection is established to.
Attributes:
id: the database ID.
region: the ID of the region through which the connection to DB is done.
namespace: the namespace this DB is set to work with.
name: the database name. Not necessarily unique: there can be multiple
databases with the same name.
environment: a label, whose value is one of Environment.PROD, Environment.DEV
or Environment.TEST.
raw_info: the full response from the DevOPS API call to get this info.
Note:
The `raw_info` dictionary usually has a `region` key describing
the default region as configured in the database, which does not
necessarily (for multi-region databases) match the region through
which the connection is established: the latter is the one specified
by the "api endpoint" used for connecting. In other words, for multi-region
databases it is possible that
database_info.region != database_info.raw_info["region"]
Conversely, in case of a DatabaseInfo not obtained through a
connected database, such as when calling `Admin.list_databases()`,
all fields except `environment` (e.g. namespace, region, etc)
are set as found on the DevOps API response directly.
"""
id: str
region: str
namespace: str
name: str
environment: str
raw_info: Optional[Dict[str, Any]]
@dataclass
class AdminDatabaseInfo:
"""
Represents the full response from the DevOps API about a database info.
Most attributes just contain the corresponding part of the raw response:
for this reason, please consult the DevOps API documentation for details.
Attributes:
info: a DatabaseInfo instance for the underlying database.
The DatabaseInfo is a subset of the information described by
AdminDatabaseInfo - in terms of the DevOps API response,
it corresponds to just its "info" subdictionary.
available_actions: the "availableActions" value in the full API response.
cost: the "cost" value in the full API response.
cqlsh_url: the "cqlshUrl" value in the full API response.
creation_time: the "creationTime" value in the full API response.
data_endpoint_url: the "dataEndpointUrl" value in the full API response.
grafana_url: the "grafanaUrl" value in the full API response.
graphql_url: the "graphqlUrl" value in the full API response.
id: the "id" value in the full API response.
last_usage_time: the "lastUsageTime" value in the full API response.
metrics: the "metrics" value in the full API response.
observed_status: the "observedStatus" value in the full API response.
org_id: the "orgId" value in the full API response.
owner_id: the "ownerId" value in the full API response.
status: the "status" value in the full API response.
storage: the "storage" value in the full API response.
termination_time: the "terminationTime" value in the full API response.
raw_info: the full raw response from the DevOps API.
"""
info: DatabaseInfo
available_actions: Optional[List[str]]
cost: Dict[str, Any]
cqlsh_url: str
creation_time: str
data_endpoint_url: str
grafana_url: str
graphql_url: str
id: str
last_usage_time: str
metrics: Dict[str, Any]
observed_status: str
org_id: str
owner_id: str
status: str
storage: Dict[str, Any]
termination_time: str
raw_info: Optional[Dict[str, Any]]
@dataclass
class CollectionInfo:
"""
Represents the identifying information for a collection,
including the information about the database the collection belongs to.
Attributes:
database_info: a DatabaseInfo instance for the underlying database.
namespace: the namespace where the collection is located.
name: collection name. Unique within a namespace.
full_name: identifier for the collection within the database,
in the form "namespace.collection_name".
"""
database_info: DatabaseInfo
namespace: str
name: str
full_name: str
@dataclass
class CollectionDefaultIDOptions:
"""
The "defaultId" component of the collection options.
See the Data API specifications for allowed values.
Attributes:
default_id_type: string such as `objectId`, `uuid6` and so on.
"""
default_id_type: str
def as_dict(self) -> Dict[str, Any]:
"""Recast this object into a dictionary."""
return {"type": self.default_id_type}
@staticmethod
def from_dict(
raw_dict: Optional[Dict[str, Any]]
) -> Optional[CollectionDefaultIDOptions]:
"""
Create an instance of CollectionDefaultIDOptions from a dictionary
such as one from the Data API.
"""
if raw_dict is not None:
return CollectionDefaultIDOptions(default_id_type=raw_dict["type"])
else:
return None
@dataclass
class CollectionVectorServiceOptions:
"""
The "vector.service" component of the collection options.
See the Data API specifications for allowed values.
NOTE: This feature is under current development.
Attributes:
provider: the name of a service provider for embedding calculation.
model_name: the name of a specific model for use by the service.
"""
provider: Optional[str]
model_name: Optional[str]
def as_dict(self) -> Dict[str, Any]:
"""Recast this object into a dictionary."""
return {
k: v
for k, v in {
"provider": self.provider,
"modelName": self.model_name,
}.items()
if v is not None
}
@staticmethod
def from_dict(
raw_dict: Optional[Dict[str, Any]]
) -> Optional[CollectionVectorServiceOptions]:
"""
Create an instance of CollectionVectorServiceOptions from a dictionary
such as one from the Data API.
"""
if raw_dict is not None:
return CollectionVectorServiceOptions(
provider=raw_dict.get("provider"),
model_name=raw_dict.get("modelName"),
)
else:
return None
@dataclass
class CollectionVectorOptions:
"""
The "vector" component of the collection options.
See the Data API specifications for allowed values.
Attributes:
dimension: an optional positive integer, the dimensionality of the vector space.
metric: an optional metric among `VectorMetric.DOT_PRODUCT`,
`VectorMetric.EUCLIDEAN` and `VectorMetric.COSINE`.
service: an optional X object in case a service is configured for the collection.
NOTE: This feature is under current development.
"""
dimension: Optional[int]
metric: Optional[str]
service: Optional[CollectionVectorServiceOptions]
def as_dict(self) -> Dict[str, Any]:
"""Recast this object into a dictionary."""
return {
k: v
for k, v in {
"dimension": self.dimension,
"metric": self.metric,
"service": None if self.service is None else self.service.as_dict(),
}.items()
if v is not None
}
@staticmethod
def from_dict(
raw_dict: Optional[Dict[str, Any]]
) -> Optional[CollectionVectorOptions]:
"""
Create an instance of CollectionVectorOptions from a dictionary
such as one from the Data API.
"""
if raw_dict is not None:
return CollectionVectorOptions(
dimension=raw_dict.get("dimension"),
metric=raw_dict.get("metric"),
service=CollectionVectorServiceOptions.from_dict(
raw_dict.get("service")
),
)
else:
return None
@dataclass
class CollectionOptions:
"""
A structure expressing the options of a collection.
See the Data API specifications for detailed specification and allowed values.
Attributes:
vector: an optional CollectionVectorOptions object.
indexing: an optional dictionary with the "indexing" collection properties.
default_id: an optional CollectionDefaultIDOptions object.
raw_options: the raw response from the Data API for the collection configuration.
"""
vector: Optional[CollectionVectorOptions]
indexing: Optional[Dict[str, Any]]
default_id: Optional[CollectionDefaultIDOptions]
raw_options: Optional[Dict[str, Any]]
def __repr__(self) -> str:
not_null_pieces = [
pc
for pc in [
None if self.vector is None else f"vector={self.vector.__repr__()}",
(
None
if self.indexing is None
else f"indexing={self.indexing.__repr__()}"
),
(
None
if self.default_id is None
else f"default_id={self.default_id.__repr__()}"
),
]
if pc is not None
]
return f"{self.__class__.__name__}({', '.join(not_null_pieces)})"
def as_dict(self) -> Dict[str, Any]:
"""Recast this object into a dictionary."""
return {
k: v
for k, v in {
"vector": None if self.vector is None else self.vector.as_dict(),
"indexing": self.indexing,
"defaultId": (
None if self.default_id is None else self.default_id.as_dict()
),
}.items()
if v is not None
}
def flatten(self) -> Dict[str, Any]:
"""
Recast this object as a flat key-value pair suitable for
use as kwargs in a create_collection method call (including recasts).
"""
_dimension: Optional[int]
_metric: Optional[str]
_indexing: Optional[Dict[str, Any]]
_service: Optional[Dict[str, Any]]
_default_id_type: Optional[str]
if self.vector is not None:
_dimension = self.vector.dimension
_metric = self.vector.metric
if self.vector.service is None:
_service = None
else:
_service = self.vector.service.as_dict()
else:
_dimension = None
_metric = None
_service = None
_indexing = self.indexing
if self.default_id is not None:
_default_id_type = self.default_id.default_id_type
else:
_default_id_type = None
return {
k: v
for k, v in {
"dimension": _dimension,
"metric": _metric,
"service": _service,
"indexing": _indexing,
"default_id_type": _default_id_type,
}.items()
if v is not None
}
@staticmethod
def from_dict(raw_dict: Dict[str, Any]) -> CollectionOptions:
"""
Create an instance of CollectionOptions from a dictionary
such as one from the Data API.
"""
return CollectionOptions(
vector=CollectionVectorOptions.from_dict(raw_dict.get("vector")),
indexing=raw_dict.get("indexing"),
default_id=CollectionDefaultIDOptions.from_dict(raw_dict.get("defaultId")),
raw_options=raw_dict,
)
@dataclass
class CollectionDescriptor:
"""
A structure expressing full description of a collection as the Data API
returns it, i.e. its name and its `options` sub-structure.
Attributes:
name: the name of the collection.
options: a CollectionOptions instance.
raw_descriptor: the raw response from the Data API.
"""
name: str
options: CollectionOptions
raw_descriptor: Optional[Dict[str, Any]]
def __repr__(self) -> str:
return (
f"{self.__class__.__name__}("
f"name={self.name.__repr__()}, "
f"options={self.options.__repr__()})"
)
def as_dict(self) -> Dict[str, Any]:
"""
Recast this object into a dictionary.
Empty `options` will not be returned at all.
"""
return {
k: v
for k, v in {
"name": self.name,
"options": self.options.as_dict(),
}.items()
if v
}
def flatten(self) -> Dict[str, Any]:
"""
Recast this object as a flat key-value pair suitable for
use as kwargs in a create_collection method call (including recasts).
"""
return {
**(self.options.flatten()),
**{"name": self.name},
}
@staticmethod
def from_dict(raw_dict: Dict[str, Any]) -> CollectionDescriptor:
"""
Create an instance of CollectionDescriptor from a dictionary
such as one from the Data API.
"""
return CollectionDescriptor(
name=raw_dict["name"],
options=CollectionOptions.from_dict(raw_dict.get("options") or {}),
raw_descriptor=raw_dict,
)