def get_clusters(self) -> Optional[List[str]]: """ Lists all weaviate clusters registered with the this account. Returns ------- Optional[List[str]] A list of cluster names or None if no clusters. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If getting the weaviate clusters failed for a different reason, more information is given in the exception. """ try: response = self.get( path='/clusters/list', params={ 'email': self._auth_client_secret.get_credentials()['username'] }) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'WCS clusters were not fetched.') from conn_err if response.status_code == 200: return response.json()['clusterIDs'] raise UnexpectedStatusCodeException('Checking WCS instance', response)
def get_cluster_config(self, cluster_name: str) -> dict: """ Get details of a cluster. Parameters ---------- cluster_name : str The name of the weaviate server cluster. NOTE: Case insensitive. The WCS cluster's name is always lowercased. Returns ------- dict Details in a JSON format. If no cluster with such name was found then an empty dictionary is returned. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If getting the weaviate cluster failed for a different reason, more information is given in the exception. """ try: response = self.get(path='/clusters/' + cluster_name.lower(), ) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'WCS cluster info was not fetched.') from conn_err if response.status_code == 200: return response.json() if response.status_code == 404: return {} raise UnexpectedStatusCodeException('Checking WCS instance', response)
def test_get_cluster_config(self, mock_get): """ Test the `get_cluster_config` method. """ wcs = WCS(AuthClientPassword('test_secret_username', 'test_secret_password')) wcs._auth_bearer = 'test_bearer' # invalid calls ## error messages connection_error_message = 'WCS cluster info was not fetched.' unexpected_error_message = 'Checking WCS instance' ## connection error mock_get.side_effect = RequestsConnectionError('Test!') with self.assertRaises(RequestsConnectionError) as error: wcs.get_cluster_config('test_name') check_error_message(self, error, connection_error_message) mock_get.assert_called_with( path='/clusters/test_name', ) ## unexpected error mock_get.side_effect = None mock_get.return_value = Mock(status_code=400) with self.assertRaises(UnexpectedStatusCodeException) as error: wcs.get_cluster_config('test_name') check_startswith_error_message(self, error, unexpected_error_message) mock_get.assert_called_with( path='/clusters/test_name', ) # valid calls return_mock = Mock(status_code=200) return_mock.json.return_value = {'clusterIDs': 'test!'} mock_get.return_value = return_mock result = wcs.get_cluster_config('test_name') self.assertEqual(result, {'clusterIDs': 'test!'}) mock_get.assert_called_with( path='/clusters/test_name', ) return_mock = Mock(status_code=200) return_mock.json.return_value = {'clusterIDs': 'test!'} mock_get.return_value = return_mock result = wcs.get_cluster_config('Test_Name') self.assertEqual(result, {'clusterIDs': 'test!'}) mock_get.assert_called_with( path='/clusters/test_name', ) return_mock = Mock(status_code=404) return_mock.json.return_value = {'clusterIDs': 'test!'} mock_get.return_value = return_mock result = wcs.get_cluster_config('test_name') self.assertEqual(result, {}) mock_get.assert_called_with( path='/clusters/test_name', )
def test_get_concept_vector(self): """ Test `get_concept_vector` method. """ # test valid call connection_mock = mock_connection_method('get', return_json={"A": "B"}) contextionary = Contextionary(connection_mock) self.assertEqual("B", contextionary.get_concept_vector("sauce")["A"]) connection_mock.get.assert_called_with( path="/modules/text2vec-contextionary/concepts/sauce", ) # test exceptions # error messages requests_error_message = 'text2vec-contextionary vector was not retrieved.' unexpected_exception_error_message = "text2vec-contextionary vector" ## test UnexpectedStatusCodeException contextionary = Contextionary( mock_connection_method('get', status_code=404)) with self.assertRaises(UnexpectedStatusCodeException) as error: contextionary.get_concept_vector("Palantir") check_startswith_error_message(self, error, unexpected_exception_error_message) ## test requests error contextionary = Contextionary( mock_connection_method( 'get', side_effect=RequestsConnectionError("Test!"))) with self.assertRaises(RequestsConnectionError) as error: contextionary.get_concept_vector("Palantir") check_error_message(self, error, requests_error_message)
def do(self) -> dict: """ Builds and runs the query. Returns ------- dict The response of the query. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ query = self.build() try: response = self._connection.post(path="/graphql", weaviate_object={"query": query}) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'Query was not successful.') from conn_err if response.status_code == 200: return response.json() # success raise UnexpectedStatusCodeException("Query was not successful", response)
def delete_class(self, class_name: str) -> None: """ Delete a schema class from weaviate. This deletes all associated data. Parameters ---------- class_name : str The class that should be deleted from weaviate. Examples -------- >>> client.schema.delete_class('Author') Raises ------ TypeError If 'class_name' argument not of type str. requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ if not isinstance(class_name, str): raise TypeError( f"Class name was {type(class_name)} instead of str") path = f"/schema/{_capitalize_first_letter(class_name)}" try: response = self._connection.delete(path=path) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Deletion of class.') from conn_err if response.status_code != 200: raise UnexpectedStatusCodeException("Delete class from schema", response)
def update_config(self, class_name: str, config: dict) -> None: """ Update a schema configuration for a specific class. Parameters ---------- class_name : str The class for which to update the schema configuration. config : dict The configurations to update (MUST follow schema format). Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ class_name = _capitalize_first_letter(class_name) class_schema = self.get(class_name) new_class_schema = _update_nested_dict(class_schema, config) check_class(new_class_schema) path = "/schema/" + class_name try: response = self._connection.put(path=path, weaviate_object=new_class_schema) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Class schema configuration could not be updated.')\ from conn_err if response.status_code != 200: raise UnexpectedStatusCodeException( "Update class schema configuration", response)
def _start(self) -> dict: """ Start the classification based on the configuration set. Returns ------- dict Classification result. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException Unexpected error. """ try: response = self._connection.post(path='/classifications', weaviate_object=self._config) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'Classification may not started.') from conn_err if response.status_code == 201: return response.json() raise UnexpectedStatusCodeException("Start classification", response)
def delete_cluster(self, cluster_name: str) -> None: """ Delete the WCS Weaviate cluster instance. Parameters ---------- cluster_name : str The name of the weaviate server cluster. NOTE: Case insensitive. The WCS cluster's name is always lowercased. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If deleting the weaviate cluster failed for a different reason, more information is given in the exception. """ try: response = self.delete(path='/clusters/' + cluster_name.lower(), ) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'WCS cluster was not deleted.') from conn_err if response.status_code == 200 or response.status_code == 404: return raise UnexpectedStatusCodeException('Deleting WCS instance', response)
def test_get(self, mock_get_params): """ Test the `get` method. """ # error messages requests_error_message = 'Could not get object/s.' unexpected_error_message = "Get object/s" # test exceptions data_object = DataObject( mock_connection_method('get', side_effect=RequestsConnectionError("Test!")) ) with self.assertRaises(RequestsConnectionError) as error: data_object.get() check_error_message(self, error, requests_error_message) data_object = DataObject( mock_connection_method('get', status_code=204) ) with self.assertRaises(UnexpectedStatusCodeException) as error: data_object.get() check_startswith_error_message(self, error, unexpected_error_message) # test valid calls return_value_get = {"my_key": 12341} mock_get_params.return_value = {'include': "test1,test2"} connection_mock = mock_connection_method('get', return_json=return_value_get, status_code=200) data_object = DataObject(connection_mock) result = data_object.get() self.assertEqual(result, return_value_get) connection_mock.get.assert_called_with( path="/objects", params={'include': "test1,test2"} ) return_value_get = {"my_key": '12341'} mock_get_params.return_value = {'include': "test1,test2"} connection_mock = mock_connection_method('get', return_json=return_value_get, status_code=200) data_object = DataObject(connection_mock) result = data_object.get(uuid="1d420c9c98cb11ec9db61e008a366d49") self.assertEqual(result, return_value_get) connection_mock.get.assert_called_with( path="/objects/1d420c9c-98cb-11ec-9db6-1e008a366d49", params={'include': "test1,test2"} ) return_value_get = {"my_key": '12341'} mock_get_params.return_value = {'include': "test1,test2"} connection_mock = mock_connection_method('get', return_json=return_value_get, status_code=404) data_object = DataObject(connection_mock) result = data_object.get(uuid="1d420c9c-98cb-11ec-9db6-1e008a366d49") self.assertIsNone(result) connection_mock.get.assert_called_with( path="/objects/1d420c9c-98cb-11ec-9db6-1e008a366d49", params={'include': "test1,test2"} )
def create(self, schema_class_name: str, schema_property: dict) -> None: """ Create a class property. Parameters ---------- schema_class_name : str The name of the class in the schema to which the property should be added. schema_property : dict The property that should be added. Examples -------- >>> property_age = { ... "dataType": [ ... "int" ... ], ... "description": "The Author's age", ... "name": "age" ... } >>> client.schema.property.create('Author', property_age) Raises ------ TypeError If 'schema_class_name' is of wrong type. weaviate.exceptions.UnexpectedStatusCodeException If weaviate reports a none OK status. requests.ConnectionError If the network connection to weaviate fails. weaviate.SchemaValidationException If the 'schema_property' is not valid. """ if not isinstance(schema_class_name, str): raise TypeError( f"Class name must be of type str but is {type(schema_class_name)}" ) loaded_schema_property = _get_dict_from_object(schema_property) # check if valid property check_property(loaded_schema_property) schema_class_name = _capitalize_first_letter(schema_class_name) path = f"/schema/{schema_class_name}/properties" try: response = self._connection.post( path=path, weaviate_object=loaded_schema_property) except RequestsConnectionError as conn_err: raise RequestsConnectionError( 'Property was created properly.') from conn_err if response.status_code != 200: raise UnexpectedStatusCodeException("Add property to class", response)
def _create_complex_properties_from_class(self, schema_class: dict) -> None: """ Add crossreferences to already existing class. Parameters ---------- schema_class : dict Description of the class that should be added. Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ if "properties" not in schema_class: # Class has no properties nothing to do return for property_ in schema_class["properties"]: if _property_is_primitive(property_["dataType"]): continue # create the property object ## All complex dataTypes should be capitalized. schema_property = { "dataType": [ _capitalize_first_letter(dtype) for dtype in property_["dataType"] ], "description": property_["description"], "name": property_["name"] } if "indexInverted" in property_: schema_property["indexInverted"] = property_["indexInverted"] if "moduleConfig" in property_: schema_property["moduleConfig"] = property_["moduleConfig"] path = "/schema/" + _capitalize_first_letter( schema_class["class"]) + "/properties" try: response = self._connection.post( path=path, weaviate_object=schema_property) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Property may not have been created properly.')\ from conn_err if response.status_code != 200: raise UnexpectedStatusCodeException( "Add properties to classes", response)
def _create_class_with_premitives(self, weaviate_class: dict) -> None: """ Create class with only primitives. Parameters ---------- weaviate_class : dict A single weaviate formated class Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ # Create the class schema_class = { "class": _capitalize_first_letter(weaviate_class['class']), "properties": [] } if "description" in weaviate_class: schema_class['description'] = weaviate_class['description'] if "vectorIndexType" in weaviate_class: schema_class['vectorIndexType'] = weaviate_class['vectorIndexType'] if "vectorIndexConfig" in weaviate_class: schema_class['vectorIndexConfig'] = weaviate_class[ 'vectorIndexConfig'] if "vectorizer" in weaviate_class: schema_class['vectorizer'] = weaviate_class['vectorizer'] if "moduleConfig" in weaviate_class: schema_class["moduleConfig"] = weaviate_class["moduleConfig"] if "shardingConfig" in weaviate_class: schema_class["shardingConfig"] = weaviate_class["shardingConfig"] if "properties" in weaviate_class: schema_class["properties"] = _get_primitive_properties( weaviate_class["properties"]) # Add the item try: response = self._connection.post(path="/schema", weaviate_object=schema_class) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Class may not have been created properly.')\ from conn_err if response.status_code != 200: raise UnexpectedStatusCodeException("Create class", response)
def delete(self, uuid: Union[str, uuid_lib.UUID]) -> None: """ Delete an existing object from weaviate. Parameters ---------- uuid : str or uuid.UUID The ID of the object that should be deleted. Examples -------- >>> client.data_object.get("d842a0f4-ad8c-40eb-80b4-bfefc7b1b530") { "additional": {}, "class": "Author", "creationTimeUnix": 1617112817487, "id": "d842a0f4-ad8c-40eb-80b4-bfefc7b1b530", "lastUpdateTimeUnix": 1617112817487, "properties": { "age": 46, "name": "H.P. Lovecraft" }, "vectorWeights": null } >>> client.data_object.delete("d842a0f4-ad8c-40eb-80b4-bfefc7b1b530") >>> client.data_object.get("d842a0f4-ad8c-40eb-80b4-bfefc7b1b530") None Raises ------ requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. TypeError If parameter has the wrong type. ValueError If uuid is not properly formed. """ uuid = get_valid_uuid(uuid) try: response = self._connection.delete( path="/objects/" + uuid, ) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Object could not be deleted.') from conn_err if response.status_code == 204: # Successfully deleted return raise UnexpectedStatusCodeException("Delete object", response)
def test_get_clusters(self, mock_get): """ Test the `get_clusters` method. """ wcs = WCS(AuthClientPassword('*****@*****.**', 'testPassoword')) wcs._auth_bearer = 'test_bearer' # invalid calls ## error messages connection_error_message = 'WCS clusters were not fetched.' unexpected_error_message = 'Checking WCS instance' # connection error mock_get.side_effect = RequestsConnectionError('Test!') with self.assertRaises(RequestsConnectionError) as error: wcs.get_clusters() check_error_message(self, error, connection_error_message) mock_get.assert_called_with( path='/clusters/list', params={ 'email': '*****@*****.**' } ) # unexpected error mock_get.side_effect = None mock_get.return_value = Mock(status_code=400) with self.assertRaises(UnexpectedStatusCodeException) as error: wcs.get_clusters() check_startswith_error_message(self, error, unexpected_error_message) mock_get.assert_called_with( path='/clusters/list', params={ 'email': '*****@*****.**' } ) # valid calls return_mock = Mock(status_code=200) return_mock.json.return_value = {'clusterIDs': 'test!'} mock_get.return_value = return_mock result = wcs.get_clusters() self.assertEqual(result, 'test!') mock_get.assert_called_with( path='/clusters/list', params={ 'email': '*****@*****.**' } )
def test_delete(self, mock_delete): """ Test the `delete` method. """ wcs = WCS(AuthClientPassword('test_secret_username', 'test_password')) wcs._auth_bearer = 'test_bearer' # invalid calls ## error messages connection_error_message = 'WCS cluster was not deleted.' unexpected_error_message = 'Deleting WCS instance' ## connection error mock_delete.side_effect = RequestsConnectionError('Test!') with self.assertRaises(RequestsConnectionError) as error: wcs.delete_cluster('test_name') check_error_message(self, error, connection_error_message) mock_delete.assert_called_with( path='/clusters/test_name', ) ## unexpected error mock_delete.side_effect = None mock_delete.return_value = Mock(status_code=400) with self.assertRaises(UnexpectedStatusCodeException) as error: wcs.delete_cluster('test_name') check_startswith_error_message(self, error, unexpected_error_message) mock_delete.assert_called_with( path='/clusters/test_name', ) # valid calls mock_delete.return_value = Mock(status_code=200) self.assertIsNone(wcs.delete_cluster('test_name')) mock_delete.assert_called_with( path='/clusters/test_name', ) mock_delete.return_value = Mock(status_code=404) self.assertIsNone(wcs.delete_cluster('test_name')) mock_delete.assert_called_with( path='/clusters/test_name', ) mock_delete.return_value = Mock(status_code=404) self.assertIsNone(wcs.delete_cluster('TesT_naMe')) mock_delete.assert_called_with( path='/clusters/test_name', )
def test__check_status(self, mock_get): """ Test the `_check_status` method. """ mock_get.return_value = {'status': 'failed'} result = Classification(None)._check_status('uuid', 'running') self.assertFalse(result) result = Classification(None)._check_status('uuid', 'failed') self.assertTrue(result) mock_get.side_effect = RequestsConnectionError('Test!') result = Classification(None)._check_status('uuid', 'running') self.assertFalse(result)
def get(self, uuid: Union[str, uuid_lib.UUID, None]=None, additional_properties: List[str]=None, with_vector: bool=False ) -> List[dict]: """ Gets objects from weaviate, the maximum number of objects returned is 100. If 'uuid' is None, all objects are returned. If 'uuid' is specified the result is the same as for `get_by_uuid` method. Parameters ---------- uuid : str, uuid.UUID or None, optional The identifier of the object that should be retrieved. additional_properties : list of str, optional list of additional properties that should be included in the request, by default None with_vector: bool If True the `vector` property will be returned too, by default False. Returns ------- list of dicts A list of all objects. If no objects where found the list is empty. Raises ------ TypeError If argument is of wrong type. ValueError If argument contains an invalid value. requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ try: response = self._get_response(uuid, additional_properties, with_vector) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Could not get object/s.') from conn_err if response.status_code == 200: return response.json() if uuid is not None and response.status_code == 404: return None raise UnexpectedStatusCodeException("Get object/s", response)
def test_delete(self): """ Test the `delete` method. """ data_object = DataObject(Mock()) # error messages uuid_type_error_message = lambda dt: f"'uuid' must be of type str or uuid.UUID, but was: {dt}" uuid_value_error_message = "Not valid 'uuid' or 'uuid' can not be extracted from value" requests_error_message = 'Object could not be deleted.' unexpected_error_message = "Delete object" with self.assertRaises(TypeError) as error: data_object.delete(4) check_error_message(self, error, uuid_type_error_message(int)) with self.assertRaises(ValueError) as error: data_object.delete("Hallo World") check_error_message(self, error, uuid_value_error_message) connection_mock = mock_connection_method('delete', side_effect=RequestsConnectionError('Test!')) data_object = DataObject(connection_mock) with self.assertRaises(RequestsConnectionError) as error: data_object.delete("b36268d4-a6b5-5274-985f-45f13ce0c642") check_error_message(self, error, requests_error_message) connection_mock = mock_connection_method('delete', status_code=404) data_object = DataObject(connection_mock) with self.assertRaises(UnexpectedStatusCodeException) as error: data_object.delete("b36268d4-a6b5-5274-985f-45f13ce0c642") check_startswith_error_message(self, error, unexpected_error_message) # 1. Successfully delete something connection_mock = mock_connection_method('delete', status_code=204) data_object = DataObject(connection_mock) object_id = "b36268d4-a6b5-5274-985f-45f13ce0c642" data_object.delete(object_id) connection_mock.delete.assert_called_with( path="/objects/" + object_id )
def test_get(self): """ Test the `get` method. """ # invalid calls requests_error_message = 'Schema could not be retrieved.' unexpected_error_msg = "Get schema" type_error_msg = lambda dt: f"'class_name' argument must be of type `str`! Given type: {dt}" mock_conn = mock_connection_method( 'get', side_effect=RequestsConnectionError("Test!")) schema = Schema(mock_conn) with self.assertRaises(RequestsConnectionError) as error: schema.get() check_error_message(self, error, requests_error_message) mock_conn = mock_connection_method('get', status_code=404) schema = Schema(mock_conn) with self.assertRaises(UnexpectedStatusCodeException) as error: schema.get() check_startswith_error_message(self, error, unexpected_error_msg) connection_mock_file = mock_connection_method( 'get', status_code=200, return_json={'Test': 'OK!'}) schema = Schema(connection_mock_file) with self.assertRaises(TypeError) as error: schema.get(1234) check_error_message(self, error, type_error_msg(int)) # valid calls self.assertEqual(schema.get(), {'Test': 'OK!'}) connection_mock_file.get.assert_called_with(path="/schema", ) self.assertEqual(schema.get("Artist"), {'Test': 'OK!'}) connection_mock_file.get.assert_called_with(path="/schema/Artist") # with uncapitalized class_name self.assertEqual(schema.get("artist"), {'Test': 'OK!'}) connection_mock_file.get.assert_called_with(path="/schema/Artist")
def test_get(self): """ Test the `get` method. """ # error messages uuid_type_error = lambda dt: f"'uuid' must be of type str or uuid.UUID, but was: {dt}" value_error = "Not valid 'uuid' or 'uuid' can not be extracted from value" requests_error_message = 'Classification status could not be retrieved.' unexpected_error_message = "Get classification status" # invalid calls with self.assertRaises(TypeError) as error: Classification(None).get(123) check_error_message(self, error, uuid_type_error(int)) with self.assertRaises(ValueError) as error: Classification(None).get('123') check_error_message(self, error, value_error) mock_conn = mock_connection_method( 'get', side_effect=RequestsConnectionError('Test!')) with self.assertRaises(RequestsConnectionError) as error: Classification(mock_conn).get( "d087b7c6-a115-5c89-8cb2-f25bdeb9bf92") check_error_message(self, error, requests_error_message) mock_conn = mock_connection_method('get', status_code=404) with self.assertRaises(UnexpectedStatusCodeException) as error: Classification(mock_conn).get( "d087b7c6-a115-5c89-8cb2-f25bdeb9bf92") check_startswith_error_message(self, error, unexpected_error_message) # valid calls mock_conn = mock_connection_method('get', return_json='OK!', status_code=200) result = Classification(mock_conn).get( "d087b7c6-a115-5c89-8cb2-f25bdeb9bf92") self.assertEqual(result, 'OK!')
def test__start(self): """ Test the `_start` method. """ # error messages requests_error_message = 'Classification may not started.' unexpected_error_message = "Start classification" # invalid calls mock_conn = mock_connection_method( 'post', side_effect=RequestsConnectionError('Test!')) config = ConfigBuilder(mock_conn, None) with self.assertRaises(RequestsConnectionError) as error: config._start() check_error_message(self, error, requests_error_message) mock_conn.post.assert_called_with(path="/classifications", weaviate_object={}) mock_conn = mock_connection_method('post', status_code=200) config = ConfigBuilder(mock_conn, None).with_class_name('Test!') with self.assertRaises(UnexpectedStatusCodeException) as error: config._start() check_startswith_error_message(self, error, unexpected_error_message) mock_conn.post.assert_called_with(path="/classifications", weaviate_object={'class': 'Test!'}) # valid calls mock_conn = mock_connection_method('post', status_code=201, return_json='OK!') config = ConfigBuilder( mock_conn, None).with_class_name('TestClass').with_type('TestType') self.assertEqual(config._start(), 'OK!') mock_conn.post.assert_called_with(path="/classifications", weaviate_object={ 'class': 'TestClass', 'type': 'TestType' })
def test_do(self): """ Test the `do` method. """ # test exceptions requests_error_message = 'Query was not successful.' # requests.exceptions.ConnectionError mock_obj = mock_connection_method( 'post', side_effect=RequestsConnectionError("Test")) self.aggregate._connection = mock_obj with self.assertRaises(RequestsConnectionError) as error: self.aggregate.do() check_error_message(self, error, requests_error_message) # weaviate.UnexpectedStatusCodeException mock_obj = mock_connection_method('post', status_code=204) self.aggregate._connection = mock_obj with self.assertRaises(UnexpectedStatusCodeException) as error: self.aggregate.do() check_startswith_error_message(self, error, "Query was not successful") filter = {"path": ["name"], "operator": "Equal", "valueString": "B"} self.aggregate \ .with_group_by_filter(["name"]) \ .with_fields("groupedBy { value }") \ .with_fields("name { count }") \ .with_where(filter) expected_gql_clause = '{Aggregate{Object(where: {path: ["name"] operator: Equal valueString: "B"} groupBy: ["name"]){groupedBy { value }name { count }}}}' mock_obj = mock_connection_method('post', status_code=200, return_json={"status": "OK!"}) self.aggregate._connection = mock_obj self.assertEqual(self.aggregate.do(), {"status": "OK!"}) mock_obj.post.assert_called_with( path="/graphql", weaviate_object={'query': expected_gql_clause})
def test_delete_class_input(self): """ Test the 'delete_class` method. """ schema = Schema(Mock()) # invalid calls type_error_message = lambda t: f"Class name was {t} instead of str" requests_error_message = 'Deletion of class.' with self.assertRaises(TypeError) as error: schema.delete_class(1) check_error_message(self, error, type_error_message(int)) schema = Schema( mock_connection_method( 'delete', side_effect=RequestsConnectionError('Test!'))) with self.assertRaises(RequestsConnectionError) as error: schema.delete_class("uuid") check_error_message(self, error, requests_error_message) schema = Schema(mock_connection_method('delete', status_code=404)) with self.assertRaises(UnexpectedStatusCodeException) as error: schema.delete_class("uuid") check_startswith_error_message(self, error, "Delete class from schema") # valid calls mock_conn = mock_connection_method('delete', status_code=200) schema = Schema(mock_conn) schema.delete_class("Test") mock_conn.delete.assert_called_with(path="/schema/Test") # with uncapitalized class_name mock_conn = mock_connection_method('delete', status_code=200) schema = Schema(mock_conn) schema.delete_class("test") mock_conn.delete.assert_called_with(path="/schema/Test")
def test_is_ready(self): """ Test the `is_ready` method. """ client = Client("http://localhost:8080") # Request to weaviate returns 200 connection_mock = mock_connection_method('get') client._connection = connection_mock self.assertTrue(client.is_ready()) # Should be true connection_mock.get.assert_called_with(path="/.well-known/ready") # Request to weaviate returns 404 connection_mock = mock_connection_method('get', status_code=404) client._connection = connection_mock self.assertFalse(client.is_ready()) # Should be false connection_mock.get.assert_called_with(path="/.well-known/ready") # Test exception in connect connection_mock = mock_connection_method( 'get', side_effect=RequestsConnectionError("Test")) client._connection = connection_mock self.assertFalse(client.is_ready()) connection_mock.get.assert_called_with(path="/.well-known/ready")
def get(self, classification_uuid: str) -> dict: """ Polls the current state of the given classification. Parameters ---------- classification_uuid : str Identifier of the classification. Returns ------- dict A dict containing the Weaviate answer. Raises ------ ValueError If not a proper uuid. requests.ConnectionError If the network connection to weaviate fails. weaviate.UnexpectedStatusCodeException If weaviate reports a none OK status. """ classification_uuid = get_valid_uuid(classification_uuid) try: response = self._connection.get( path='/classifications/' + classification_uuid, ) except RequestsConnectionError as conn_err: raise RequestsConnectionError('Classification status could not be retrieved.')\ from conn_err if response.status_code == 200: return response.json() raise UnexpectedStatusCodeException("Get classification status", response)
def test_raw(self): """ Test the `raw` method. """ # valid calls connection_mock = mock_connection_method('post') query = Query(connection_mock) gql_query = "{Get {Group {name Members {... on Person {name}}}}}" query.raw(gql_query) connection_mock.post.assert_called_with( path="/graphql", weaviate_object={"query": gql_query}) # invalid calls type_error_message = "Query is expected to be a string" requests_error_message = 'Query not executed.' query_error_message = "GQL query failed" with self.assertRaises(TypeError) as error: query.raw(["TestQuery"]) check_error_message(self, error, type_error_message) query = Query( mock_connection_method( 'post', side_effect=RequestsConnectionError("Test!"))) with self.assertRaises(RequestsConnectionError) as error: query.raw("TestQuery") check_error_message(self, error, requests_error_message) query = Query(mock_connection_method('post', status_code=404)) with self.assertRaises(UnexpectedStatusCodeException) as error: query.raw("TestQuery") check_startswith_error_message(self, error, query_error_message)
def test_update(self): """ Test the `update` method. """ reference = Reference(Mock()) # error messages unexpected_error_msg = 'Update property reference to object' connection_error_msg = 'Reference was not updated.' # test exceptions with self.assertRaises(TypeError) as error: reference.update(1, "prop", [self.uuid_1]) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(TypeError) as error: reference.update(self.uuid_1, 1, [self.uuid_2]) check_error_message(self, error, self.name_error_message(int)) with self.assertRaises(TypeError) as error: reference.update(self.uuid_1, "prop", 1) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(TypeError) as error: reference.update(self.uuid_1, "prop", [1]) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(ValueError) as error: reference.update("my UUID", "prop", self.uuid_2) check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.update(self.uuid_1, "prop", "my uuid") check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.update(self.uuid_1, "prop", ["my uuid"]) check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.update(f"http://localhost:8080/v1/objects/{self.uuid_1}", "prop", "http://localhost:8080/v1/objects/MY_UUID") check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.update("http://localhost:8080/v1/objects/My-UUID", "prop", f"http://localhost:8080/v1/objects/{self.uuid_2}") check_error_message(self, error, self.valid_uuid_error_message) mock_obj = mock_connection_method('put', status_code=204) reference = Reference(mock_obj) with self.assertRaises(UnexpectedStatusCodeException) as error: reference.update(self.uuid_1, "myProperty", self.uuid_2) check_startswith_error_message(self, error, unexpected_error_msg) mock_obj = mock_connection_method('put', side_effect=RequestsConnectionError("Test!")) reference = Reference(mock_obj) with self.assertRaises(RequestsConnectionError) as error: reference.update(self.uuid_1, "myProperty", self.uuid_2) check_error_message(self, error, connection_error_msg) # test valid calls connection_mock = mock_connection_method('put') reference = Reference(connection_mock) reference.update( "de998e81-fa66-440e-a1de-2a2013667e77", "hasAwards", "fc041624-4ddf-4b76-8e09-a5b0b9f9f832" ) connection_mock.put.assert_called_with( path="/objects/de998e81-fa66-440e-a1de-2a2013667e77/references/hasAwards", weaviate_object=[{'beacon': 'weaviate://localhost/fc041624-4ddf-4b76-8e09-a5b0b9f9f832'}], ) reference.update( "4e44db9b-7f9c-4cf4-a3a0-b57024eefed0", "hasAwards", [ "17ee17bd-a09a-49ff-adeb-d242f25f390d", "f8c25386-707c-40c0-b7b9-26cc0e9b2bd1", "d671dc52-dce4-46e7-8731-b722f19420c8" ] ) connection_mock.put.assert_called_with( path="/objects/4e44db9b-7f9c-4cf4-a3a0-b57024eefed0/references/hasAwards", weaviate_object=[ {'beacon': 'weaviate://localhost/17ee17bd-a09a-49ff-adeb-d242f25f390d'}, {'beacon': 'weaviate://localhost/f8c25386-707c-40c0-b7b9-26cc0e9b2bd1'}, {'beacon': 'weaviate://localhost/d671dc52-dce4-46e7-8731-b722f19420c8'} ], )
def test_add(self): """ Test the `add` method. """ reference = Reference(Mock()) # error messages unexpected_error_msg = 'Add property reference to object' connection_error_msg = 'Reference was not added.' # test exceptions with self.assertRaises(TypeError) as error: reference.add(1, "prop", self.uuid_1) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(TypeError) as error: reference.add(self.uuid_1, 1, self.uuid_2) check_error_message(self, error, self.name_error_message(int)) with self.assertRaises(TypeError) as error: reference.add(self.uuid_1, "prop", 1) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(ValueError) as error: reference.add("my UUID", "prop", self.uuid_2) check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.add(self.uuid_1, "prop", "my uuid") check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.add(f"http://localhost:8080/v1/objects/{self.uuid_1}", "prop", "http://localhost:8080/v1/objects/MY_UUID") check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.add("http://localhost:8080/v1/objects/My-UUID", "prop", f"http://localhost:8080/v1/objects/{self.uuid_2}") check_error_message(self, error, self.valid_uuid_error_message) mock_obj = mock_connection_method('post', status_code=204) reference = Reference(mock_obj) with self.assertRaises(UnexpectedStatusCodeException) as error: reference.add(self.uuid_1, "myProperty", self.uuid_2) check_startswith_error_message(self, error, unexpected_error_msg) mock_obj = mock_connection_method('post', side_effect=RequestsConnectionError("Test!")) reference = Reference(mock_obj) with self.assertRaises(RequestsConnectionError) as error: reference.add(self.uuid_1, "myProperty", self.uuid_2) check_error_message(self, error, connection_error_msg) # test valid calls connection_mock = mock_connection_method('post') reference = Reference(connection_mock) # 1. Plain reference.add( "3250b0b8-eaf7-499b-ac68-9084c9c82d0f", "hasItem", "99725f35-f12a-4f36-a2e2-0d41501f4e0e" ) connection_mock.post.assert_called_with( path="/objects/3250b0b8-eaf7-499b-ac68-9084c9c82d0f/references/hasItem", weaviate_object={'beacon': 'weaviate://localhost/99725f35-f12a-4f36-a2e2-0d41501f4e0e'}, ) # 2. using url reference.add( "http://localhost:8080/v1/objects/7591be77-5959-4386-9828-423fc5096e87", "hasItem", "http://localhost:8080/v1/objects/1cd80c11-29f0-453f-823c-21547b1511f0" ) connection_mock.post.assert_called_with( path="/objects/7591be77-5959-4386-9828-423fc5096e87/references/hasItem", weaviate_object={'beacon': 'weaviate://localhost/1cd80c11-29f0-453f-823c-21547b1511f0'}, ) # 3. using weaviate url reference.add( "weaviate://localhost/f8def983-87e7-4e21-bf10-e32e2de3efcf", "hasItem", "weaviate://localhost/e40aaef5-d3e5-44f1-8ec4-3eafc8475078" ) connection_mock.post.assert_called_with( path="/objects/f8def983-87e7-4e21-bf10-e32e2de3efcf/references/hasItem", weaviate_object={'beacon': 'weaviate://localhost/e40aaef5-d3e5-44f1-8ec4-3eafc8475078'}, )
def test_delete(self): """ Test `delete` method`. """ reference = Reference(Mock()) # error messages unexpected_error_msg = 'Delete property reference to object' connection_error_msg = 'Reference was not deleted.' # invalid calls with self.assertRaises(TypeError) as error: reference.delete(1, "myProperty", self.uuid_2) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(TypeError) as error: reference.delete(self.uuid_1, "myProperty", 2) check_error_message(self, error, self.uuid_error_message) with self.assertRaises(TypeError) as error: reference.delete(self.uuid_1, 3, self.uuid_2) check_error_message(self, error, self.name_error_message(int)) with self.assertRaises(ValueError) as error: reference.delete("str", "myProperty", self.uuid_2) check_error_message(self, error, self.valid_uuid_error_message) with self.assertRaises(ValueError) as error: reference.delete(self.uuid_1, "myProperty", "str") check_error_message(self, error, self.valid_uuid_error_message) mock_obj = mock_connection_method('delete', status_code=200) reference = Reference(mock_obj) with self.assertRaises(UnexpectedStatusCodeException) as error: reference.delete(self.uuid_1, "myProperty", self.uuid_2) check_startswith_error_message(self, error, unexpected_error_msg) mock_obj = mock_connection_method('delete', side_effect=RequestsConnectionError("Test!")) reference = Reference(mock_obj) with self.assertRaises(RequestsConnectionError) as error: reference.delete(self.uuid_1, "myProperty", self.uuid_2) check_error_message(self, error, connection_error_msg) # test valid calls connection_mock = mock_connection_method('delete', status_code=204) reference = Reference(connection_mock) reference.delete( self.uuid_1, "myProperty", self.uuid_2 ) connection_mock.delete.assert_called_with( path=f"/objects/{self.uuid_1}/references/myProperty", weaviate_object={"beacon": f"weaviate://localhost/{self.uuid_2}"}, ) reference.delete( self.uuid_1, "hasItem", f"http://localhost:8080/v1/objects/{self.uuid_2}" ) connection_mock.delete.assert_called_with( path=f"/objects/{self.uuid_1}/references/hasItem", weaviate_object={"beacon": f"weaviate://localhost/{self.uuid_2}"}, )