Skip to content

Commit bcec9bc

Browse files
committed
refactor: remove Optional from client attribute and streamline class logic
1 parent e1f6d11 commit bcec9bc

1 file changed

Lines changed: 9 additions & 58 deletions

File tree

datastew/repository/weaviate.py

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ def __init__(
7474
self.terminology_schema = terminology_schema
7575
self.concept_schema = concept_schema
7676
self.mapping_schema = mapping_schema
77-
self.client: Optional[WeaviateClient] = None
77+
self.client: WeaviateClient
7878
self.headers = None
7979
if self.use_weaviate_vectorizer:
8080
if huggingface_key:
8181
self.headers = {"X-HuggingFace-Api-Key": huggingface_key}
8282
if self.mode == "memory":
83-
self._connect_to_memory(path, http_port, grpc_port)
83+
self.client = self._connect_to_memory(path, http_port, grpc_port)
8484
elif self.mode == "remote":
85-
self._connect_to_remote(path, port)
85+
self.client = self._connect_to_remote(path, port)
8686
else:
8787
raise ValueError(f"Repository mode {mode} is not defined. Use either disk or remote.")
8888

@@ -113,13 +113,10 @@ def get_iterator(self, collection: Literal["Concept", "Mapping", "Terminology"])
113113
"""Retrieves an iterator for the specified collection from the client.
114114
115115
:param collection: The collection type to retrieve the iterator for.
116-
:raises ValueError: If the client is not initialized or is invalid.
117116
:raises ValueError: If the specified collection is not supported.
118117
:return: An iterator for the specified collection from the client's collection,
119118
with vectors and references as needed.
120119
"""
121-
if not self.client:
122-
raise ValueError("Client is not initialized or is invalid.")
123120
if collection == "Concept":
124121
return_references = QueryReference(link_on="hasTerminology")
125122
elif collection == "Mapping":
@@ -138,12 +135,9 @@ def get_all_sentence_embedders(self) -> List[str]:
138135
`self.use_weaviate_vectorizer` is True, it retrieves the names from the vector keys in the embeddings returned
139136
by an object in the collection.
140137
141-
:raises ValueError: If the client is not initialized.
142138
:raises RuntimeError: If there is an issue fetching sentence embedders or vector configurations.
143139
:return: A list of sentence embedder names.
144140
"""
145-
if not self.client:
146-
raise ValueError("Client is not initialized or is invalid.")
147141
sentence_embedders = set()
148142
mapping_collection = self.client.collections.get("Mapping")
149143
try:
@@ -164,8 +158,6 @@ def get_all_sentence_embedders(self) -> List[str]:
164158
return list(sentence_embedders)
165159

166160
def get_concept(self, concept_id: str) -> Concept:
167-
if not self.client:
168-
raise ValueError("Client is not initialized or is invalid.")
169161
try:
170162
if not self._concept_exists(concept_id):
171163
raise RuntimeError(f"Concept {concept_id} does not exists")
@@ -190,8 +182,6 @@ def get_concept(self, concept_id: str) -> Concept:
190182
return concept
191183

192184
def get_concepts(self, limit: int = 100, offset: int = 0, terminology_name: Optional[str] = None) -> Page[Concept]:
193-
if not self.client:
194-
raise ValueError("Client is not initialized or is invalid.")
195185
try:
196186
concept_collection = self.client.collections.get("Concept")
197187

@@ -234,8 +224,6 @@ def get_concepts(self, limit: int = 100, offset: int = 0, terminology_name: Opti
234224
return Page[Concept](items=concepts, limit=limit, offset=offset, total_count=total_count)
235225

236226
def get_terminology(self, terminology_name: str) -> Terminology:
237-
if not self.client:
238-
raise ValueError("Client is not initialized or is invalid.")
239227
try:
240228
if not self._terminology_exists(terminology_name):
241229
raise RuntimeError(f"Terminology {terminology_name} does not exists")
@@ -252,8 +240,6 @@ def get_terminology(self, terminology_name: str) -> Terminology:
252240
return terminology
253241

254242
def get_all_terminologies(self) -> List[Terminology]:
255-
if not self.client:
256-
raise ValueError("Client is not initialized or is invalid.")
257243
terminologies = []
258244
try:
259245
terminology_collection = self.client.collections.get("Terminology")
@@ -281,16 +267,12 @@ def get_mappings(
281267
`use_weaviate_vectorizer` is `True`, defaults to None
282268
:param limit: The maximum number of mappings to return, defaults to 1000
283269
:param offset: The number of mappings to skip before returning results, defaults to 0
284-
:raises ValueError: If the client is not initialized or is invalid.
285270
:raises ValueError: If the terminology is not found.
286271
:raises ValueError: If the sentence embedder is not found.
287272
:raises ValueError: If `sentence_embedder` is `None` and `use_weaviate_vectorizer` is `True`.
288273
:raises RuntimeError: If the fetch operation fails.
289274
:return: A page object containing a list of Mapping objects, along with pagination details.
290275
"""
291-
if not self.client:
292-
raise ValueError("Client is not initialized or is invalid.")
293-
294276
mappings = [] # List to store fetched mappings
295277
filters = None # List to store filters for query
296278
target_vector = True # Whether to include vectors in the response
@@ -410,9 +392,6 @@ def get_closest_mappings(
410392
:raises RuntimeError: If the fetch operation fails
411393
:return: A list of Mapping or MappingResult objects based on whether similarity scores are included.
412394
"""
413-
if not self.client:
414-
raise ValueError("Client is not initialized or is invalid.")
415-
416395
mappings = [] # List to store fetched mappings
417396
filters = None
418397
target_vector = None
@@ -511,8 +490,6 @@ def get_closest_mappings(
511490
return mappings
512491

513492
def store(self, model_object_instance: Union[Terminology, Concept, Mapping]):
514-
if not self.client:
515-
raise ValueError("Client is not initialized or is invalid.")
516493
try:
517494
if isinstance(model_object_instance, Terminology):
518495
properties = {"name": model_object_instance.name}
@@ -590,14 +567,10 @@ def import_from_jsonl(
590567
:param jsonl_path: Path to the JSONL file.
591568
:param object_type: Literal specifying the object type, must be "terminology", "concept", or "mapping".
592569
:param chunk_size: The number of items to process in each batch, defaults to 100.
593-
:raises ValueError: If the client is not initialized or is invalid.
594570
:raises ValueError: If 'id' or 'properties' is missing in a JSON object.
595571
:raises ValueError: If there is an invalid JSON object.
596572
:raises RuntimeError: If an unexpected error occurs during import.
597573
"""
598-
if not self.client:
599-
raise ValueError("Client is not initialized or is invalid.")
600-
601574
try:
602575
collection = self.client.collections.get(object_type.capitalize())
603576
chunk = []
@@ -635,18 +608,10 @@ def close(self):
635608
self.shut_down()
636609

637610
def shut_down(self):
638-
if not self.client:
639-
raise ValueError("Client is not initialized or is invalid.")
640611
self.client.close()
641612

642613
def clear_all(self):
643-
"""Deletes all data and schema classes (Mapping, Concept, Terminology) and re-creates them.
644-
645-
:raises ValueError: If the Weaviate client is not initialized.
646-
"""
647-
if not self.client:
648-
raise ValueError("Client is not initialized or is invalid.")
649-
614+
"""Deletes all data and schema classes (Mapping, Concept, Terminology) and re-creates them."""
650615
for schema in [self.mapping_schema, self.concept_schema, self.terminology_schema]:
651616
class_name = schema.schema["class"]
652617
if self.client.collections.exists(class_name):
@@ -665,8 +630,6 @@ def clear_all(self):
665630
self._create_schema_if_not_exists(self.mapping_schema.schema)
666631

667632
def _sentence_embedder_exists(self, name: str) -> bool:
668-
if not self.client:
669-
raise ValueError("Client is not initialized or is invalid.")
670633
try:
671634
mapping = self.client.collections.get("Mapping")
672635
if not self.use_weaviate_vectorizer:
@@ -682,8 +645,6 @@ def _sentence_embedder_exists(self, name: str) -> bool:
682645
raise RuntimeError(f"Failed to check if sentence embedder exists: {e}")
683646

684647
def _terminology_exists(self, name: str) -> bool:
685-
if not self.client:
686-
raise ValueError("Client is not initialized or is invalid.")
687648
try:
688649
terminology = self.client.collections.get("Terminology")
689650
response = terminology.query.fetch_objects(filters=Filter.by_property("name").equal(name))
@@ -695,8 +656,6 @@ def _terminology_exists(self, name: str) -> bool:
695656
raise RuntimeError(f"Failed to check if terminology exists: {e}")
696657

697658
def _concept_exists(self, concept_id: str) -> bool:
698-
if not self.client:
699-
raise ValueError("Client is not initialized or is invalid.")
700659
try:
701660
concept = self.client.collections.get("Concept")
702661
response = concept.query.fetch_objects(filters=Filter.by_property("conceptID").equal(concept_id))
@@ -717,8 +676,6 @@ def _mapping_exists(self, mapping: Mapping) -> bool:
717676
exists, otherwise `False`.
718677
"""
719678
try:
720-
if not self.client:
721-
raise ValueError("Client is not initialized or is invalid.")
722679
# Check if the concept exists first
723680
concept_properties = {
724681
"conceptID": mapping.concept.concept_identifier,
@@ -761,8 +718,6 @@ def _uuid_exists(self, collection_name: str, uuid: str) -> bool:
761718
:return: True if the object with the given UUID exists, False otherwise.
762719
"""
763720
try:
764-
if not self.client:
765-
raise ValueError("Client is not initialized or is invalid.")
766721
collection = self.client.collections.get(collection_name)
767722
obj = collection.query.fetch_object_by_id(uuid)
768723
return obj is not None
@@ -788,8 +743,6 @@ def _create_schema_if_not_exists(self, schema):
788743
:raises RuntimeError: If there is an issue checking for or creating the schema in Weaviate, such as connection
789744
error.
790745
"""
791-
if not self.client:
792-
raise ValueError("Client is not initialized or is invalid.")
793746
references = None
794747
vectorizer_config = None
795748
class_name = schema["class"]
@@ -818,28 +771,26 @@ def _is_port_in_use(port) -> bool:
818771
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
819772
return s.connect_ex(("localhost", port)) == 0
820773

821-
def _connect_to_memory(self, path: str, http_port: int, grpc_port: int):
774+
def _connect_to_memory(self, path: str, http_port: int, grpc_port: int) -> WeaviateClient:
822775
try:
823776
if path is None:
824777
raise ValueError("Path must be provided for disk mode.")
825778
if self._is_port_in_use(http_port) and self._is_port_in_use(grpc_port):
826-
if self.client:
827-
self.client.close()
828-
self.client = weaviate.connect_to_local(port=http_port, grpc_port=grpc_port, headers=self.headers)
779+
return weaviate.connect_to_local(port=http_port, grpc_port=grpc_port, headers=self.headers)
829780
else:
830-
self.client = weaviate.connect_to_embedded(
781+
return weaviate.connect_to_embedded(
831782
persistence_data_path=path,
832783
headers=self.headers,
833784
environment_variables={"ENABLE_MODULES": "text2vec-ollama"},
834785
)
835786
except Exception as e:
836787
raise ConnectionError(f"Failed to initialize Weaviate client: {e}")
837788

838-
def _connect_to_remote(self, path: str, port: int):
789+
def _connect_to_remote(self, path: str, port: int) -> WeaviateClient:
839790
try:
840791
if path is None:
841792
raise ValueError("Remote URL must be provided for remote mode.")
842-
self.client = weaviate.connect_to_local(host=path, port=port, headers=self.headers)
793+
return weaviate.connect_to_local(host=path, port=port, headers=self.headers)
843794
except Exception as e:
844795
raise ConnectionError(f"Failed to initialize Weaviate client: {e}")
845796

0 commit comments

Comments
 (0)