class RegisteredDataService: """ Object to handle logic of registered data requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_registered_data(self, registered_data: RegisteredDataIn): """ Send request to graph api to create new registered data node Args: registered_data (RegisteredDataIn): Registered data to be added Returns: Result of request as registered data object """ node_response = self.graph_api_service.create_node("`Registered Data`") if node_response["errors"] is not None: return RegisteredDataOut(**registered_data.dict(), errors=node_response["errors"]) registered_data_id = node_response["id"] properties_response = self.graph_api_service.create_properties( registered_data_id, registered_data) if properties_response["errors"] is not None: return RegisteredDataOut(**registered_data.dict(), errors=properties_response["errors"]) return RegisteredDataOut(**registered_data.dict(), id=registered_data_id) def get_registered_data_nodes(self): """ Send request to graph api to get registered_data_nodes Returns: Result of request as list of registered_data_nodes objects """ get_response = self.graph_api_service.get_nodes("`Registered Data`") registered_data_nodes = [] for registered_data_node in get_response["nodes"]: properties = { 'id': registered_data_node['id'], 'additional_properties': [] } for property in registered_data_node["properties"]: if property["key"] == "source": properties[property["key"]] = property["value"] else: properties['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) registered_data = BasicRegisteredDataOut(**properties) registered_data_nodes.append(registered_data) return RegisteredDataNodesOut( registered_data_nodes=registered_data_nodes) def get_registered_data(self, registered_data_id: int): """ Send request to graph api to get given registered data Args: registered_data_id (int): Id of registered data Returns: Result of request as registered data object """ get_response = self.graph_api_service.get_node(registered_data_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=registered_data_id, errors=get_response["errors"]) if get_response["labels"][0] != "Registered Data": return NotFoundByIdModel(id=registered_data_id, errors="Node not found.") registered_data = { 'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: if property["key"] == "source": registered_data[property["key"]] = property["value"] else: registered_data['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) relations_response = self.graph_api_service.get_node_relationships( registered_data_id) for relation in relations_response["relationships"]: if relation["start_node"] == registered_data_id: registered_data['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: registered_data['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return RegisteredDataOut(**registered_data) def delete_registered_data(self, registered_data_id: int): """ Send request to graph api to delete given registered data Args: registered_data_id (int): Id of registered data Returns: Result of request as registered data object """ get_response = self.get_registered_data(registered_data_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(registered_data_id) return get_response def update_registered_data(self, registered_data_id: int, registered_data: RegisteredDataIn): """ Send request to graph api to update given registered data Args: registered_data_id (int): Id of registered data registered_data (RegisteredDataIn): Properties to update Returns: Result of request as registered data object """ get_response = self.get_registered_data(registered_data_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(registered_data_id) self.graph_api_service.create_properties(registered_data_id, registered_data) registered_data_result = { 'id': registered_data_id, 'relations': get_response.relations, 'reversed_relations': get_response.reversed_relations } registered_data_result.update(registered_data.dict()) return RegisteredDataOut(**registered_data_result)
class ExperimentService: """ Object to handle logic of experiments requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_experiment(self, experiment: ExperimentIn): """ Send request to graph api to create new experiment Args: experiment (ExperimentIn): Experiment to be added Returns: Result of request as experiment object """ node_response_experiment = self.graph_api_service.create_node("Experiment") if node_response_experiment["errors"] is not None: return ExperimentOut(**experiment.dict(), errors=node_response_experiment["errors"]) experiment_id = node_response_experiment["id"] properties_response = self.graph_api_service.create_properties(experiment_id, experiment) if properties_response["errors"] is not None: return ExperimentOut(**experiment.dict(), errors=properties_response["errors"]) return ExperimentOut(**experiment.dict(), id=experiment_id) def get_experiments(self): """ Send request to graph api to get experiments Returns: Result of request as list of experiments objects """ get_response = self.graph_api_service.get_nodes("Experiment") experiments = [] for experiment_node in get_response["nodes"]: properties = {'id': experiment_node['id'], 'additional_properties': []} for property in experiment_node["properties"]: if property["key"] == "experiment_name": properties[property["key"]] = property["value"] else: properties['additional_properties'].append({'key': property['key'], 'value': property['value']}) experiment = BasicExperimentOut(**properties) experiments.append(experiment) return ExperimentsOut(experiments=experiments) def get_experiment(self, experiment_id: int): """ Send request to graph api to get given experiment Args: experiment_id (int): Id of experiment Returns: Result of request as experiment object """ get_response = self.graph_api_service.get_node(experiment_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=experiment_id, errors=get_response["errors"]) if get_response["labels"][0] != "Experiment": return NotFoundByIdModel(id=experiment_id, errors="Node not found.") experiment = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: if property["key"] == "experiment_name": experiment[property["key"]] = property["value"] else: experiment['additional_properties'].append({'key': property['key'], 'value': property['value']}) relations_response = self.graph_api_service.get_node_relationships(experiment_id) for relation in relations_response["relationships"]: if relation["start_node"] == experiment_id: experiment['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: experiment['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ExperimentOut(**experiment) def delete_experiment(self, experiment_id: int): """ Send request to graph api to delete given experiment Args: experiment_id (int): Id of experiment Returns: Result of request as experiment object """ get_response = self.get_experiment(experiment_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(experiment_id) return get_response def update_experiment(self, experiment_id: int, experiment: ExperimentIn): """ Send request to graph api to update given experiment Args: experiment_id (int): Id of experiment experiment (ExperimentIn): Properties to update Returns: Result of request as experiment object """ get_response = self.get_experiment(experiment_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(experiment_id) self.graph_api_service.create_properties(experiment_id, experiment) experiment_result = {'id': experiment_id, 'relations': get_response.relations, 'reversed_relations': get_response.reversed_relations} experiment_result.update(experiment.dict()) return ExperimentOut(**experiment_result)
class ActivityExecutionService: """ Object to handle logic of activities requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API activity_service (ActivityService): Service used to communicate with Activity arrangement_service (ArrangementService): Service used to communicate with Arrangement """ graph_api_service = GraphApiService() activity_service = ActivityService() arrangement_service = ArrangementService() def save_activity_execution(self, activity_execution: ActivityExecutionIn): """ Send request to graph api to create new activity execution Args: activity_execution (ActivityExecutionIn): Activity execution to be added Returns: Result of request as activity execution object """ node_response = self.graph_api_service.create_node("`Activity Execution`") if node_response["errors"] is not None: return ActivityExecutionOut(**activity_execution.dict(), errors=node_response["errors"]) activity_execution_id = node_response["id"] if activity_execution.activity_id is not None and \ type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=activity_execution_id, end_node=activity_execution.activity_id, name="hasActivity") if activity_execution.arrangement_id is not None and \ type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=activity_execution_id, end_node=activity_execution.arrangement_id, name="hasArrangement") activity_execution.activity_id = activity_execution.arrangement_id = None self.graph_api_service.create_properties(activity_execution_id, activity_execution) return self.get_activity_execution(activity_execution_id) def get_activity_executions(self): """ Send request to graph api to get activity executions Returns: Result of request as list of activity executions objects """ get_response = self.graph_api_service.get_nodes("`Activity Execution`") activity_executions = [] for activity_execution_node in get_response["nodes"]: properties = {'id': activity_execution_node['id'], 'additional_properties': []} for property in activity_execution_node["properties"]: properties['additional_properties'].append({'key': property['key'], 'value': property['value']}) activity_execution = BasicActivityExecutionOut(**properties) activity_executions.append(activity_execution) return ActivityExecutionsOut(activity_executions=activity_executions) def get_activity_execution(self, activity_execution_id: int): """ Send request to graph api to get given activity execution Args: activity_execution_id (int): Id of activity execution Returns: Result of request as activity execution object """ get_response = self.graph_api_service.get_node(activity_execution_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=activity_execution_id, errors=get_response["errors"]) if get_response["labels"][0] != "Activity Execution": return NotFoundByIdModel(id=activity_execution_id, errors="Node not found.") activity_execution = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: activity_execution['additional_properties'].append({'key': property['key'], 'value': property['value']}) relations_response = self.graph_api_service.get_node_relationships(activity_execution_id) for relation in relations_response["relationships"]: if relation["start_node"] == activity_execution_id: activity_execution['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: activity_execution['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ActivityExecutionOut(**activity_execution) def delete_activity_execution(self, activity_execution_id: int): """ Send request to graph api to delete given activity execution Args: activity_execution_id (int): Id of activity execution Returns: Result of request as activity execution object """ get_response = self.get_activity_execution(activity_execution_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(activity_execution_id) return get_response def update_activity_execution(self, activity_execution_id: int, activity_execution: ActivityExecutionPropertyIn): """ Send request to graph api to update given participant state Args: activity_execution_id (int): Id of participant state activity_execution (ActivityExecutionPropertyIn): Properties to update Returns: Result of request as participant state object """ get_response = self.get_activity_execution(activity_execution_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(activity_execution_id) self.graph_api_service.create_properties(activity_execution_id, activity_execution) activity_execution_result = {"id": activity_execution_id, "relations": get_response.relations, "reversed_relations": get_response.reversed_relations} activity_execution_result.update(activity_execution.dict()) return ActivityExecutionOut(**activity_execution_result) def update_activity_execution_relationships(self, activity_execution_id: int, activity_execution: ActivityExecutionRelationIn): """ Send request to graph api to update given activity execution relationships Args: activity_execution_id (int): Id of activity execution activity_execution (ActivityExecutionIn): Relationships to update Returns: Result of request as activity execution object """ get_response = self.get_activity_execution(activity_execution_id) if type(get_response) is NotFoundByIdModel: return get_response if activity_execution.activity_id is not None and \ type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=activity_execution_id, end_node=activity_execution.activity_id, name="hasActivity") if activity_execution.arrangement_id is not None and \ type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=activity_execution_id, end_node=activity_execution.arrangement_id, name="hasArrangement") return self.get_activity_execution(activity_execution_id)
class PersonalityService: """ Object to handle logic of personality requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_personality_big_five(self, personality: PersonalityBigFiveIn): """ Send request to graph api to create new personality big five model Args: personality (PersonalityBigFiveIn): Personality big five to be added Returns: Result of request as personality big five object """ if not 0 <= personality.agreeableness <= 1 or not 0 <= personality.conscientiousness <= 1 or \ not 0 <= personality.extroversion <= 1 or not 0 <= personality.neuroticism <= 1 or \ not 0 <= personality.openess <= 1: return PersonalityBigFiveOut(**personality.dict(), errors="Value not between 0 and 1") node_response = self.graph_api_service.create_node("Personality") personality_id = node_response["id"] self.graph_api_service.create_properties(personality_id, personality) return PersonalityBigFiveOut(**personality.dict(), id=personality_id) def save_personality_panas(self, personality: PersonalityPanasIn): """ Send request to graph api to create new personality panas model Args: personality (PersonalityPanasIn): Personality to be added Returns: Result of request as personality panas object """ if not 0 <= personality.negative_affect <= 1 or not 0 <= personality.positive_affect <= 1: return PersonalityPanasOut(**personality.dict(), errors="Value not between 0 and 1") node_response = self.graph_api_service.create_node("Personality") personality_id = node_response["id"] self.graph_api_service.create_properties(personality_id, personality) return PersonalityPanasOut(**personality.dict(), id=personality_id) def get_personality(self, personality_id: int): """ Send request to graph api to get given personality Args: personality_id (int): Id of personality Returns: Result of request as personality object """ get_response = self.graph_api_service.get_node(personality_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=personality_id, errors=get_response["errors"]) if get_response["labels"][0] != "Personality": return NotFoundByIdModel(id=personality_id, errors="Node not found.") personality = { 'id': personality_id, 'relations': [], 'reversed_relations': [] } personality.update({ property["key"]: property["value"] for property in get_response["properties"] }) relations_response = self.graph_api_service.get_node_relationships( personality_id) for relation in relations_response["relationships"]: if relation["start_node"] == personality_id: personality["relations"].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: personality["reversed_relations"].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return PersonalityPanasOut(**personality) if "negative_affect" in personality.keys() \ else PersonalityBigFiveOut(**personality) def get_personalities(self): """ Send request to graph api to get personalities Returns: Result of request as list of personalities objects """ get_response = self.graph_api_service.get_nodes("Personality") personalities = [] for personality_node in get_response["nodes"]: properties = { property["key"]: property["value"] for property in personality_node["properties"] } properties["id"] = personality_node["id"] personality = BasicPersonalityPanasOut(**properties) if "negative_affect" in properties.keys() \ else BasicPersonalityBigFiveOut(**properties) personalities.append(personality) return PersonalitiesOut(personalities=personalities) def delete_personality(self, personality_id: int): """ Send request to graph api to delete given personality Args: personality_id (int): Id of personality Returns: Result of request as personality object """ get_response = self.get_personality(personality_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(personality_id) return get_response def update_personality_big_five(self, personality_id: int, personality: PersonalityBigFiveIn): """ Send request to graph api to update given personality big five model Args: personality_id (int): Id of personality personality (PersonalityBigFiveIn): Properties to update Returns: Result of request as personality object """ if not 0 <= personality.agreeableness <= 1 or not 0 <= personality.conscientiousness <= 1 or \ not 0 <= personality.extroversion <= 1 or not 0 <= personality.neuroticism <= 1 or \ not 0 <= personality.openess <= 1: return PersonalityBigFiveOut(**personality.dict(), errors="Value not between 0 and 1") get_response = self.get_personality(personality_id) if type(get_response) is NotFoundByIdModel: return get_response if type(get_response) is PersonalityPanasOut: return NotFoundByIdModel(id=personality_id, errors="Node not found.") self.graph_api_service.create_properties(personality_id, personality) personality_response = get_response.dict() personality_response.update(personality) return PersonalityBigFiveOut(**personality_response) def update_personality_panas(self, personality_id: int, personality: PersonalityPanasIn): """ Send request to graph api to update given personality panas model Args: personality_id (int): Id of personality personality (PersonalityPanasIn): Properties to update Returns: Result of request as personality object """ if not 0 <= personality.negative_affect <= 1 or not 0 <= personality.positive_affect <= 1: return PersonalityPanasOut(**personality.dict(), errors="Value not between 0 and 1") get_response = self.get_personality(personality_id) if type(get_response) is NotFoundByIdModel: return get_response if type(get_response) is PersonalityBigFiveOut: return NotFoundByIdModel(id=personality_id, errors="Node not found.") self.graph_api_service.create_properties(personality_id, personality) personality_response = get_response.dict() personality_response.update(personality) return PersonalityPanasOut(**personality_response)
class DatabaseServiceTestCase(unittest.TestCase): def setUp(self): self.graph_api_service = GraphApiService() self.response_content = {'id': 1, 'errors': [], 'links': {}} self.response = Response() self.response._content = json.dumps(self.response_content).encode('utf-8') @mock.patch('graph_api_service.requests') def test_post(self, requests_mock): requests_mock.post.return_value = self.response url_part = '/nodes' node = {} result = self.graph_api_service.post(url_part, node) self.assertEqual(result, self.response_content) requests_mock.post.assert_called_with(url=self.graph_api_service.graph_api_url + url_part, json=node) @mock.patch('graph_api_service.requests') def test_get(self, requests_mock): requests_mock.get.return_value = self.response url_part = '/nodes' params = {'label': 'Test'} result = self.graph_api_service.get(url_part, params) self.assertEqual(result, self.response_content) requests_mock.get.assert_called_with(url=self.graph_api_service.graph_api_url + url_part, params=params) @mock.patch('graph_api_service.requests') def test_delete(self, requests_mock): requests_mock.delete.return_value = self.response url_part = '/nodes' params = {'label': 'Test'} result = self.graph_api_service.delete(url_part, params) self.assertEqual(result, self.response_content) requests_mock.delete.assert_called_with(url=self.graph_api_service.graph_api_url + url_part, params=params) @mock.patch.object(GraphApiService, 'post') def test_create_node(self, post_mock): post_mock.return_value = self.response_content label = 'Test' result = self.graph_api_service.create_node(label) self.assertEqual(result, self.response_content) post_mock.assert_called_with('/nodes', {"labels": [label]}) @mock.patch.object(GraphApiService, 'get') def test_get_nodes(self, get_mock): get_mock.return_value = self.response_content label = 'Test' result = self.graph_api_service.get_nodes(label) self.assertEqual(result, self.response_content) get_mock.assert_called_with('/nodes', {"label": label}) @mock.patch.object(GraphApiService, 'get') def test_get_node_relationships(self, get_mock): get_mock.return_value = self.response_content node_id = 1 result = self.graph_api_service.get_node_relationships(node_id) self.assertEqual(result, self.response_content) get_mock.assert_called_with('/nodes/1/relationships', {}) @mock.patch.object(GraphApiService, 'delete') def test_delete_node(self, delete_mock): delete_mock.return_value = self.response_content node_id = 1 result = self.graph_api_service.delete_node(node_id) self.assertEqual(result, self.response_content) delete_mock.assert_called_with('/nodes/1', {}) @mock.patch.object(GraphApiService, 'post') def test_create_properties(self, post_mock): post_mock.return_value = self.response_content node_id = 1 node_model = ActivityExecutionIn(activity_id=1, arrangement_id=2, identifier=1, additional_properties=[{'key': 'test', 'value': 'test'}]) result = self.graph_api_service.create_properties(node_id, node_model) self.assertEqual(result, self.response_content) post_mock.assert_called_with("/nodes/1/properties", [{'key': 'activity_id', 'value': 1}, {'key':'arrangement_id', 'value': 2}, {'key': 'test', 'value': 'test'}]) @mock.patch.object(GraphApiService, 'post') def test_create_relationships(self, post_mock): post_mock.return_value = self.response_content start_node = 1 end_node = 2 name = 'hasNode' result = self.graph_api_service.create_relationships(start_node, end_node, name) self.assertEqual(result, self.response_content) post_mock.assert_called_with("/relationships", {"start_node": 1, "end_node": 2, "name": 'hasNode'}) @mock.patch.object(GraphApiService, 'delete') def test_delete_relationship(self, delete_mock): delete_mock.return_value = self.response_content relationship_id = 1 result = self.graph_api_service.delete_relationship(relationship_id) self.assertEqual(result, self.response_content) delete_mock.assert_called_with('/relationships/1', {}) def test_create_additional_properties(self): property_dict = {'additional_properties': [{'key': 'test', 'value': 'test'}, {'key': 'key', 'value': 'value'}]} result = self.graph_api_service.create_additional_properties(property_dict) self.assertEqual(result, [{'key': 'test', 'value': 'test'}, {'key': 'key', 'value': 'value'}])
class ParticipantService: """ Object to handle logic of participants requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_participant(self, participant: ParticipantIn): """ Send request to graph api to create new participant Args: participant (ParticipantIn): Participant to be added Returns: Result of request as participant object """ node_response = self.graph_api_service.create_node("Participant") if node_response["errors"] is not None: return ParticipantOut(**participant.dict(), errors=node_response["errors"]) participant_id = node_response["id"] properties_response = self.graph_api_service.create_properties(participant_id, participant) if properties_response["errors"] is not None: return ParticipantOut(**participant.dict(), errors=properties_response["errors"]) return ParticipantOut(**participant.dict(), id=participant_id) def get_participants(self): """ Send request to graph api to get participants Returns: Result of request as list of participants objects """ get_response = self.graph_api_service.get_nodes("Participant") participants = [] for participant_node in get_response["nodes"]: properties = {'id': participant_node['id'], 'additional_properties': []} for property in participant_node["properties"]: if property["key"] in ["name", "date_of_birth", "sex", "disorder"]: properties[property["key"]] = property["value"] else: properties['additional_properties'].append({'key': property['key'], 'value': property['value']}) participant = BasicParticipantOut(**properties) participants.append(participant) return ParticipantsOut(participants=participants) def get_participant(self, participant_id: int): """ Send request to graph api to get given participant Args: participant_id (int): Id of participant Returns: Result of request as participant object """ get_response = self.graph_api_service.get_node(participant_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=participant_id, errors=get_response["errors"]) if get_response["labels"][0] != "Participant": return NotFoundByIdModel(id=participant_id, errors="Node not found.") participant = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: if property["key"] in ["name", "date_of_birth", "sex", "disorder"]: participant[property["key"]] = property["value"] else: participant['additional_properties'].append({'key': property['key'], 'value': property['value']}) relations_response = self.graph_api_service.get_node_relationships(participant_id) for relation in relations_response["relationships"]: if relation["start_node"] == participant_id: participant['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: participant['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ParticipantOut(**participant) def delete_participant(self, participant_id: int): """ Send request to graph api to delete given participant Args: participant_id (int): Id of participant Returns: Result of request as participant object """ get_response = self.get_participant(participant_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(participant_id) return get_response def update_participant(self, participant_id: int, participant: ParticipantIn): """ Send request to graph api to update given participant Args: participant_id (int): Id of participant participant (ParticipantIn): Properties to update Returns: Result of request as participant object """ get_response = self.get_participant(participant_id) if type(get_response) is NotFoundByIdModel: return get_response if participant.date_of_birth is not None: participant.date_of_birth = participant.date_of_birth.__str__() self.graph_api_service.delete_node_properties(participant_id) self.graph_api_service.create_properties(participant_id, participant) participant_result = {"id": participant_id, 'relations': get_response.relations, 'reversed_relations': get_response.reversed_relations} participant_result.update(participant.dict()) return ParticipantOut(**participant_result)
class TimeSeriesService: """ Object to handle logic of time series requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API measure_service (MeasureService): Service to manage measure models observable_information_service (ObservableInformationService): Service to manage observable information models """ graph_api_service = GraphApiService() measure_service = MeasureService() observable_information_service = ObservableInformationService() def save_time_series(self, time_series: TimeSeriesIn): """ Send request to graph api to create new time series Args: time_series (TimeSeriesIn): Time series to be added Returns: Result of request as time series object """ node_response = self.graph_api_service.create_node("`Time Series`") if node_response["errors"] is not None: return TimeSeriesOut(**time_series.dict(), errors=node_response["errors"]) time_series_id = node_response["id"] if time_series.observable_information_id is not None and \ type(self.observable_information_service.get_observable_information( time_series.observable_information_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=time_series_id, end_node=time_series.observable_information_id, name="hasObservableInformation") if time_series.measure_id is not None and \ type(self.measure_service.get_measure(time_series.measure_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=time_series_id, end_node=time_series.measure_id, name="hasMeasure") time_series.observable_information_id = time_series.measure_id = None self.graph_api_service.create_properties(time_series_id, time_series) return self.get_time_series(time_series_id) def get_time_series_nodes(self): """ Send request to graph api to get time series nodes Returns: Result of request as list of time series nodes objects """ get_response = self.graph_api_service.get_nodes("`Time Series`") time_series_nodes = [] for time_series_node in get_response["nodes"]: properties = {'id': time_series_node['id'], 'additional_properties': []} for property in time_series_node["properties"]: if property["key"] in ["type", "source"]: properties[property["key"]] = property["value"] else: properties['additional_properties'].append({'key': property['key'], 'value': property['value']}) time_series = BasicTimeSeriesOut(**properties) time_series_nodes.append(time_series) return TimeSeriesNodesOut(time_series_nodes=time_series_nodes) def get_time_series(self, time_series_id: int): """ Send request to graph api to get given time series Args: time_series_id (int): Id of time series Returns: Result of request as time series object """ get_response = self.graph_api_service.get_node(time_series_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=time_series_id, errors=get_response["errors"]) if get_response["labels"][0] != "Time Series": return NotFoundByIdModel(id=time_series_id, errors="Node not found.") time_series = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: if property["key"] in ["type", "source"]: time_series[property["key"]] = property["value"] else: time_series['additional_properties'].append({'key': property['key'], 'value': property['value']}) relations_response = self.graph_api_service.get_node_relationships(time_series_id) for relation in relations_response["relationships"]: if relation["start_node"] == time_series_id: time_series['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: time_series['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return TimeSeriesOut(**time_series) def delete_time_series(self, time_series_id: int): """ Send request to graph api to delete given time series Args: time_series_id (int): Id of time series Returns: Result of request as time series object """ get_response = self.get_time_series(time_series_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(time_series_id) return get_response def update_time_series(self, time_series_id: int, time_series: TimeSeriesPropertyIn): """ Send request to graph api to update given time series Args: time_series_id (int): Id of time series time_series (TimeSeriesPropertyIn): Properties to update Returns: Result of request as time series object """ get_response = self.get_time_series(time_series_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(time_series_id) self.graph_api_service.create_properties(time_series_id, time_series) time_series_result = {"id": time_series_id, "relations": get_response.relations, "reversed_relations": get_response.reversed_relations} time_series_result.update(time_series.dict()) return TimeSeriesOut(**time_series_result) def update_time_series_relationships(self, time_series_id: int, time_series: TimeSeriesRelationIn): """ Send request to graph api to update given time series Args: time_series_id (int): Id of time series time_series (TimeSeriesRelationIn): Relationships to update Returns: Result of request as time series object """ get_response = self.get_time_series(time_series_id) if type(get_response) is NotFoundByIdModel: return get_response if time_series.observable_information_id is not None and \ type(self.observable_information_service.get_observable_information( time_series.observable_information_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=time_series_id, end_node=time_series.observable_information_id, name="hasObservableInformation") if time_series.measure_id is not None and \ type(self.measure_service.get_measure(time_series.measure_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships(start_node=time_series_id, end_node=time_series.personality_id, name="hasMeasure") return self.get_time_series(time_series_id)
class MeasureService: """ Object to handle logic of measure requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API measure_name_service (MeasureNameService): Service to manage measure name models """ graph_api_service = GraphApiService() measure_name_service = MeasureNameService() def save_measure(self, measure: MeasureIn): """ Send request to graph api to create new measure Args: measure (MeasureIn): Measure to be added Returns: Result of request as measure object """ node_response = self.graph_api_service.create_node("`Measure`") if node_response["errors"] is not None: return MeasureOut(**measure.dict(), errors=node_response["errors"]) measure_id = node_response["id"] if measure.measure_name_id is not None and \ type(self.measure_name_service.get_measure_name(measure.measure_name_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=measure_id, end_node=measure.measure_name_id, name="hasMeasureName") measure.measure_name_id = None self.graph_api_service.create_properties(measure_id, measure) return self.get_measure(measure_id) def get_measures(self): """ Send request to graph api to get measures Returns: Result of request as list of measures objects """ get_response = self.graph_api_service.get_nodes("`Measure`") measures = [] for measure_node in get_response["nodes"]: properties = {'id': measure_node['id']} for property in measure_node["properties"]: if property["key"] in ["datatype", "range", "unit"]: properties[property["key"]] = property["value"] measure = BasicMeasureOut(**properties) measures.append(measure) return MeasuresOut(measures=measures) def get_measure(self, measure_id: int): """ Send request to graph api to get given measure Args: measure_id (int): Id of measure Returns: Result of request as measure object """ get_response = self.graph_api_service.get_node(measure_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=measure_id, errors=get_response["errors"]) if get_response["labels"][0] != "Measure": return NotFoundByIdModel(id=measure_id, errors="Node not found.") measure = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: if property["key"] in ["datatype", "range", "unit"]: measure[property["key"]] = property["value"] relations_response = self.graph_api_service.get_node_relationships( measure_id) for relation in relations_response["relationships"]: if relation["start_node"] == measure_id: measure['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: measure['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return MeasureOut(**measure) def delete_measure(self, measure_id: int): """ Send request to graph api to delete given measure Args: measure_id (int): Id of measure Returns: Result of request as measure object """ get_response = self.get_measure(measure_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(measure_id) return get_response def update_measure(self, measure_id: int, measure: MeasurePropertyIn): """ Send request to graph api to update given measure Args: measure_id (int): Id of measure measure (MeasurePropertyIn): Properties to update Returns: Result of request as measure object """ get_response = self.get_measure(measure_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(measure_id) self.graph_api_service.create_properties(measure_id, measure) measure_result = { "id": measure_id, "relations": get_response.relations, "reversed_relations": get_response.reversed_relations } measure_result.update(measure.dict()) return MeasureOut(**measure_result) def update_measure_relationships(self, measure_id: int, measure: MeasureRelationIn): """ Send request to graph api to update given measure Args: measure_id (int): Id of measure measure (MeasureRelationIn): Relationships to update Returns: Result of request as measure object """ get_response = self.get_measure(measure_id) if type(get_response) is NotFoundByIdModel: return get_response if measure.measure_name_id is not None and \ type(self.measure_name_service.get_measure_name( measure.measure_name_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=measure_id, end_node=measure.measure_name_id, name="hasMeasureName") return self.get_measure(measure_id)
class ArrangementService: """ Object to handle logic of arrangement requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_arrangement(self, arrangement: ArrangementIn): """ Send request to graph api to create new arrangement Args: arrangement (ArrangementIn): Arrangement to be added Returns: Result of request as arrangement object """ node_response = self.graph_api_service.create_node("Arrangement") if node_response["errors"] is not None: return ArrangementOut(arrangement_type=arrangement.arrangement_type, arrangement_distance=arrangement.arrangement_distance, errors=node_response["errors"]) arrangement_id = node_response["id"] properties_response = self.graph_api_service.create_properties(arrangement_id, arrangement) if properties_response["errors"] is not None: return ArrangementOut(arrangement_type=arrangement.arrangement_type, arrangement_distance=arrangement.arrangement_distance, errors=properties_response["errors"]) return ArrangementOut(arrangement_type=arrangement.arrangement_type, arrangement_distance=arrangement.arrangement_distance, id=arrangement_id) def get_arrangements(self): """ Send request to graph api to get all arrangements Returns: Result of request as list of arrangement objects """ get_response = self.graph_api_service.get_nodes("Arrangement") if get_response["errors"] is not None: return ArrangementsOut(errors=get_response["errors"]) arrangements = [] for arrangement in get_response["nodes"]: if arrangement["properties"][0]["key"] == 'arrangement_distance': arrangements.append(BasicArrangementOut(id=arrangement["id"], arrangement_type=arrangement["properties"][1]["value"], arrangement_distance=arrangement["properties"][0]["value"])) else: arrangements.append(BasicArrangementOut(id=arrangement["id"], arrangement_type=arrangement["properties"][0]["value"], arrangement_distance=None)) return ArrangementsOut(arrangements=arrangements) def get_arrangement(self, arrangement_id: int): """ Send request to graph api to get given arrangement Args: arrangement_id (int): Id of arrangement Returns: Result of request as arrangement object """ get_response = self.graph_api_service.get_node(arrangement_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=arrangement_id, errors=get_response["errors"]) if get_response["labels"][0] != "Arrangement": return NotFoundByIdModel(id=arrangement_id, errors="Node not found.") arrangement = {'id': get_response['id'], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: arrangement[property["key"]] = property["value"] relations_response = self.graph_api_service.get_node_relationships(arrangement_id) for relation in relations_response["relationships"]: if relation["start_node"] == arrangement_id: arrangement['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: arrangement['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ArrangementOut(**arrangement)
class RecordingService: """ Object to handle logic of recording requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API participation_service (ParticipationService): Service to send participation requests registered_channel_service(RegisteredChannelService): Service to send registered channel requests """ graph_api_service = GraphApiService() participation_service = ParticipationService() registered_channel_service = RegisteredChannelService() def save_recording(self, recording: RecordingIn): """ Send request to graph api to create new recording node Args: recording (RecordingIn): Recording to be added Returns: Result of request as recording object """ node_response = self.graph_api_service.create_node("Recording") if node_response["errors"] is not None: return RecordingOut(**recording.dict(), errors=node_response["errors"]) recording_id = node_response["id"] if recording.participation_id is not None and \ type(self.participation_service.get_participation(recording.participation_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=recording_id, end_node=recording.participation_id, name="hasParticipation") if recording.registered_channel_id is not None and \ type(self.registered_channel_service.get_registered_channel(recording.registered_channel_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=recording_id, end_node=recording.registered_channel_id, name="hasRegisteredChannel") recording.participation_id = recording.registered_channel_id = None self.graph_api_service.create_properties(recording_id, recording) return self.get_recording(recording_id) def get_recordings(self): """ Send request to graph api to get recordings Returns: Result of request as list of recordings objects """ get_response = self.graph_api_service.get_nodes("Recording") recordings = [] for recording_node in get_response["nodes"]: properties = { 'id': recording_node['id'], 'additional_properties': [] } for property in recording_node["properties"]: properties['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) recording = BasicRecordingOut(**properties) recordings.append(recording) return RecordingsOut(recordings=recordings) def get_recording(self, recording_id: int): """ Send request to graph api to get given recording Args: recording_id (int): Id of recording Returns: Result of request as recording object """ get_response = self.graph_api_service.get_node(recording_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=recording_id, errors=get_response["errors"]) if get_response["labels"][0] != "Recording": return NotFoundByIdModel(id=recording_id, errors="Node not found.") recording = { 'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: recording['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) relations_response = self.graph_api_service.get_node_relationships( recording_id) for relation in relations_response["relationships"]: if relation["start_node"] == recording_id: recording['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: recording['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return RecordingOut(**recording) def delete_recording(self, recording_id: int): """ Send request to graph api to delete given recording Args: recording_id (int): Id of recording Returns: Result of request as recording object """ get_response = self.get_recording(recording_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(recording_id) return get_response def update_recording(self, recording_id: int, recording: RecordingPropertyIn): """ Send request to graph api to update given participant state Args: recording_id (int): Id of participant state recording (RecordingPropertyIn): Properties to update Returns: Result of request as participant state object """ get_response = self.get_recording(recording_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(recording_id) self.graph_api_service.create_properties(recording_id, recording) recording_result = { "id": recording_id, "relations": get_response.relations, "reversed_relations": get_response.reversed_relations } recording_result.update(recording.dict()) return RecordingOut(**recording_result) def update_recording_relationships(self, recording_id: int, recording: RecordingIn): """ Send request to graph api to update given recording Args: recording_id (int): Id of recording recording (RecordingIn): Relationships to update Returns: Result of request as recording object """ get_response = self.get_recording(recording_id) if type(get_response) is NotFoundByIdModel: return get_response if recording.participation_id is not None and \ type(self.participation_service.get_participation(recording.participation_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=recording_id, end_node=recording.participation_id, name="hasParticipation") if recording.registered_channel_id is not None and \ type(self.registered_channel_service.get_registered_channel(recording.registered_channel_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=recording_id, end_node=recording.registered_channel_id, name="hasRegisteredChannel") return self.get_recording(recording_id)
class ScenarioService: """ Object to handle logic of scenarios requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API activity_execution_service (ActivityExecutionService): Service used to communicate with ActivityExecution experiment_service (ExperimentService): Service used to communicate with Experiment """ graph_api_service = GraphApiService() activity_execution_service = ActivityExecutionService() experiment_service = ExperimentService() def save_scenario(self, scenario: ScenarioIn): """ Send request to graph api to create new scenario Args: scenario (ScenarioIn): Scenario to be added Returns: Result of request as scenario object """ activity_executions = [ self.activity_execution_service.save_activity_execution( activity_execution=activity_execution) for activity_execution in scenario.activity_executions ] self.graph_api_service.create_relationships(scenario.experiment_id, activity_executions[0].id, 'hasScenario') [ self.graph_api_service.create_relationships( activity_executions[index - 1].id, activity_executions[index].id, 'nextActivityExecution') for index in range(1, len(activity_executions)) ] return ScenarioOut(experiment_id=scenario.experiment_id, activity_executions=activity_executions) def add_activity_execution(self, previous_id: int, activity_execution: ActivityExecutionIn): """ Send request to graph api to add activity_execution to scenario Args: previous_id (int): Id of previous activity_execution or experiment activity_execution (ActivityExecutionIn): ActivityExecution to be added Returns: Result of request as activity_execution object """ relationships = self.graph_api_service.get_node_relationships( previous_id)['relationships'] activity_execution_result = self.activity_execution_service.save_activity_execution( activity_execution) if previous_id in [ relation['start_node'] for relation in relationships if relation['name'] == 'hasScenario' ]: self.graph_api_service.create_relationships( previous_id, activity_execution_result.id, 'hasScenario') else: self.graph_api_service.create_relationships( previous_id, activity_execution_result.id, 'nextActivityExecution') try: next_id, relation_id = [ (relation['end_node'], relation['id']) for relation in relationships if relation['name'] in ['hasScenario', 'nextActivityExecution'] and relation['start_node'] == previous_id ][0] except IndexError: return activity_execution_result self.graph_api_service.create_relationships( activity_execution_result.id, next_id, 'nextActivityExecution') self.graph_api_service.delete_relationship(relation_id) return activity_execution_result def change_order_middle_with_last(self, middle_id, last_id, middle_relationships, last_relationships): """ Changes order of the middle node and the last node Args: middle_id (int): Id of the middle node last_id (ActivityExecutionIn): Id of the last node middle_relationships: Relationships of the middle node last_relationships: Relationships of the last node Returns: """ start_node, end_node, relation_name = ( middle_relationships[0]['start_node'], last_id, middle_relationships[0]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) if middle_relationships[1] == last_relationships[0]: # nodes are next to each other start_node, end_node, relation_name = ( last_id, middle_relationships[1]['start_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) return # nodes are separated by other nodes start_node, end_node, relation_name = ( last_id, middle_relationships[1]['end_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) start_node, end_node, relation_name = ( last_relationships[0]['start_node'], middle_id, last_relationships[0]['name']) if start_node != end_node: self.graph_api_service.create_relationships( start_node, end_node, relation_name) return def change_order_middle_with_middle(self, middle_id, last_id, middle_relationships, last_relationships): """ Changes order of the two middle nodes Args: middle_id (int): Id of the middle node last_id (ActivityExecutionIn): Id of the middle node but second in order middle_relationships: Relationships of the middle node last_relationships: Relationships of the last node Returns: """ start_node, end_node, relation_name = ( middle_relationships[0]['start_node'], last_id, middle_relationships[0]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) if middle_relationships[1] == last_relationships[0]: # nodes are next to each other start_node, end_node, relation_name = ( last_id, middle_id, middle_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) start_node, end_node, relation_name = ( middle_id, last_relationships[1]['end_node'], last_relationships[1]['name']) self.graph_api_service.create_relationships( start_node, end_node, relation_name) return start_node, end_node, relation_name = ( last_id, middle_relationships[1]['end_node'], middle_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) start_node, end_node, relation_name = ( last_relationships[0]['start_node'], middle_id, last_relationships[0]['name']) if start_node != end_node: self.graph_api_service.create_relationships( start_node, end_node, relation_name) start_node, end_node, relation_name = ( middle_id, last_relationships[1]['end_node'], last_relationships[1]['name']) self.graph_api_service.create_relationships(start_node, end_node, relation_name) return def what_order(self, previous_relationships, activity_execution_relationships): """ Finds which node is in which order (starting from experiment) in the scenario Args: previous_relationships: Relationships of the previous node activity_execution_relationships: Relationships of the activity execution node Returns: True when is the first in order False when is the second in order """ p_relationships = previous_relationships p_count = False a_relationships = activity_execution_relationships a_count = False while True: if p_relationships[0]['name'] is not None and p_relationships[0][ 'name'] in ['hasScenario']: p_count = True break if a_relationships[0]['name'] is not None and a_relationships[0][ 'name'] in ['hasScenario']: a_count = True break p_id = p_relationships[0]['start_node'] p_relationships = self.graph_api_service.get_node_relationships( p_id)['relationships'] p_relationships = [ relation for relation in p_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] and relation['end_node'] == p_id ] a_id = a_relationships[0]['start_node'] a_relationships = self.graph_api_service.get_node_relationships( a_id)['relationships'] a_relationships = [ relation for relation in a_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] and relation['end_node'] == a_id ] return p_count, a_count def swap_order_in_relationships_array(self, relationships, node_id): """ Swaps order of relationships list so they are saved in order starting from experiment Args: relationships: List of relationships node_id: Id of node, that relationships belong to Returns: relationships: List of relationships in specified order """ if relationships[0]['start_node'] == node_id: relationships[0], relationships[1] = relationships[ 1], relationships[0] return relationships def change_order(self, order_change: OrderChangeIn): """ Send request to graph api to change order in scenario Args: order_change (OrderChangeIn): Ids of activity_executions to change order by Returns: Result of request as changed order ids """ # save all relationships in lists previous_relationships = self.graph_api_service.get_node_relationships( order_change.previous_id)['relationships'] activity_execution_relationships = \ self.graph_api_service.get_node_relationships(order_change.activity_execution_id)['relationships'] # check which node is before the other previous_first, activity_execution_first = self.what_order( previous_relationships, activity_execution_relationships) # delete nextActivityExecution and hasScenario relationships [ self.graph_api_service.delete_relationship(relation['id']) for relation in previous_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] [ self.graph_api_service.delete_relationship(relation['id']) for relation in activity_execution_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] # save nextActivityExecution and hasScenario relationships previous_relationships = [ relation for relation in previous_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] activity_execution_relationships = [ relation for relation in activity_execution_relationships if relation['name'] in ['nextActivityExecution', 'hasScenario'] ] # swap order of relationships if needed previous_relationships = self.swap_order_in_relationships_array( previous_relationships, order_change.previous_id) activity_execution_relationships = self.swap_order_in_relationships_array( activity_execution_relationships, order_change.activity_execution_id) if len(activity_execution_relationships) == 1: # change order when activity execution node is last self.change_order_middle_with_last( middle_id=order_change.previous_id, last_id=order_change.activity_execution_id, middle_relationships=previous_relationships, last_relationships=activity_execution_relationships) elif len(previous_relationships) == 1: # change order when previous node is last self.change_order_middle_with_last( middle_id=order_change.activity_execution_id, last_id=order_change.previous_id, middle_relationships=activity_execution_relationships, last_relationships=previous_relationships) elif len(previous_relationships) == 2 and len( activity_execution_relationships) == 2: if previous_first is True: # change order when previous node is before activity execution node self.change_order_middle_with_middle( middle_id=order_change.previous_id, last_id=order_change.activity_execution_id, middle_relationships=previous_relationships, last_relationships=activity_execution_relationships) elif activity_execution_first is True: # change order when activity execution node is before previous node self.change_order_middle_with_middle( middle_id=order_change.activity_execution_id, last_id=order_change.previous_id, middle_relationships=activity_execution_relationships, last_relationships=previous_relationships) return OrderChangeOut( previous_id=order_change.previous_id, activity_execution_id=order_change.activity_execution_id) def delete_activity_execution(self, activity_execution_id: int): """ Send request to graph api to delete activity_execution from scenario Args: activity_execution_id (int): Id of activity_execution to delete Returns: Result of request as activity_execution object """ relationships = self.graph_api_service.get_node_relationships( activity_execution_id)['relationships'] if len(relationships) == 0: return ActivityExecutionOut(errors='Relationships not found') activity_execution = self.graph_api_service.delete_node( activity_execution_id) properties = { p['key']: p['value'] for p in activity_execution['properties'] } additional_properties = [ PropertyIn(key=key, value=value) for key, value in properties.items() if key not in ['activity'] ] activity_execution_response = ActivityExecutionOut( id=activity_execution['id'], activity=properties['activity'], additional_properties=additional_properties) if len([ relationship for relationship in relationships if relationship['name'] in ['hasScenario', 'nextActivityExecution'] ]) == 1: return activity_execution_response start_node = [ relationship['start_node'] for relationship in relationships if relationship['end_node'] == activity_execution_id and relationship['name'] in ['hasScenario', 'nextActivityExecution'] ][0] end_node = [ relationship['end_node'] for relationship in relationships if relationship['start_node'] == activity_execution_id and relationship['name'] == 'nextActivityExecution' ][0] self.graph_api_service.create_relationships(start_node, end_node, relationships[0]['name']) return activity_execution_response def get_scenario(self, node_id: int): """ Send request to graph api to get activity executions and experiment from scenario Args: node_id (int): Id of experiment or activity execution which is included in scenario Returns: Result of request as Scenario object """ get_response = self.graph_api_service.get_node(node_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=node_id, errors=get_response["errors"]) if get_response["labels"][0] not in [ "Activity Execution", "Experiment" ]: return NotFoundByIdModel(id=node_id, errors="Node not found.") if get_response["labels"][0] == "Activity Execution": return self.get_scenario_by_activity_execution(node_id) elif get_response["labels"][0] == "Experiment": return self.get_scenario_by_experiment(node_id) def get_scenario_by_experiment(self, experiment_id: int): """ Send request to graph api to get activity_executions from scenario which starts in experiment Args: experiment_id (int): Id of experiment where scenario starts Returns: Result of request as Scenario object """ activity_executions = [] experiment = self.experiment_service.get_experiment(experiment_id) if type(experiment) is NotFoundByIdModel: return experiment scenario = {'experiment_id': experiment_id, 'activity_executions': []} for relation in experiment.relations: if relation.name == "hasScenario": self.get_scenario_after_activity_execution( relation.second_node_id, activity_executions) [ scenario['activity_executions'].append(a) for a in activity_executions if a not in scenario['activity_executions'] ] return ScenarioOut(**scenario) def get_scenario_by_activity_execution(self, activity_execution_id: int): """ Send request to graph api to get activity_executions from scenario which has activity execution id incuded Args: activity_execution_id (int): Id of activity execution included in scenario Returns: Result of request as Scenario object """ activity_executions = [] activity_executions_before = [] activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution experiment_id = self.get_scenario_before_activity_execution( activity_execution_id, activity_executions_before) [ activity_executions.append(a) for a in activity_executions_before if a not in activity_executions ] activity_executions_after = [] self.get_scenario_after_activity_execution(activity_execution_id, activity_executions_after) [ activity_executions.append(a) for a in activity_executions_after if a not in activity_executions ] scenario = {'experiment_id': experiment_id, 'activity_executions': []} [ scenario['activity_executions'].append(a) for a in activity_executions ] return ScenarioOut(**scenario) def get_scenario_after_activity_execution(self, activity_execution_id: int, activity_executions: []): """ Gets activity executions from scenario which are saved after activity_execution_id Args: activity_execution_id (int): Id of activity execution included in scenario activity_executions: List of activity executions in scenario """ activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) for relation in activity_execution.relations: if relation.name == "nextActivityExecution": activity_execution = self.activity_execution_service.get_activity_execution( relation.second_node_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) [ self.get_scenario_after_activity_execution( activity_execution.id, activity_executions) for r in activity_execution.relations if r.name == "nextActivityExecution" ] def get_scenario_before_activity_execution(self, activity_execution_id: int, activity_executions: []): """ Gets activity executions from scenario which are saved before activity_execution_id Args: activity_execution_id (int): Id of activity execution included in scenario activity_executions: List of activity executions in scenario """ activity_execution = self.activity_execution_service.get_activity_execution( activity_execution_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) for relation in activity_execution.reversed_relations: if relation.name == "nextActivityExecution": activity_execution = self.activity_execution_service.get_activity_execution( relation.second_node_id) if type(activity_execution) is NotFoundByIdModel: return activity_execution activity_executions.append(activity_execution) return self.get_scenario_before_activity_execution( activity_execution.id, activity_executions) elif relation.name == "hasScenario": experiment = self.experiment_service.get_experiment( relation.second_node_id) if type(experiment) is NotFoundByIdModel: return experiment return experiment.id
class ParticipantStateService: """ Object to handle logic of participant state requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API participant_service (ParticipantService): Service to manage participant models appearance_service (AppearanceService): Service to manage appearance models personality_service (PersonalityService): Service to manage personality models """ graph_api_service = GraphApiService() participant_service = ParticipantService() appearance_service = AppearanceService() personality_service = PersonalityService() def save_participant_state(self, participant_state: ParticipantStateIn): """ Send request to graph api to create new participant state Args: participant_state (ParticipantStateIn): Participant state to be added Returns: Result of request as participant state object """ node_response = self.graph_api_service.create_node( "`Participant State`") if node_response["errors"] is not None: return ParticipantStateOut(**participant_state.dict(), errors=node_response["errors"]) participant_state_id = node_response["id"] if participant_state.participant_id is not None and \ type(self.participant_service.get_participant(participant_state.participant_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.participant_id, name="hasParticipant") if participant_state.personality_id is not None and \ type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.personality_id, name="hasPersonality") if participant_state.appearance_id is not None and \ type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.appearance_id, name="hasAppearance") participant_state.participant_id = participant_state.personality_id = participant_state.appearance_id = None self.graph_api_service.create_properties(participant_state_id, participant_state) return self.get_participant_state(participant_state_id) def get_participant_states(self): """ Send request to graph api to get participant states Returns: Result of request as list of participant states objects """ get_response = self.graph_api_service.get_nodes("`Participant State`") participant_states = [] for participant_state_node in get_response["nodes"]: properties = { 'id': participant_state_node['id'], 'additional_properties': [] } for property in participant_state_node["properties"]: if property["key"] == "age": properties[property["key"]] = property["value"] else: properties['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) participant_state = BasicParticipantStateOut(**properties) participant_states.append(participant_state) return ParticipantStatesOut(participant_states=participant_states) def get_participant_state(self, participant_state_id: int): """ Send request to graph api to get given participant state Args: participant_state_id (int): Id of participant state Returns: Result of request as participant state object """ get_response = self.graph_api_service.get_node(participant_state_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=participant_state_id, errors=get_response["errors"]) if get_response["labels"][0] != "Participant State": return NotFoundByIdModel(id=participant_state_id, errors="Node not found.") participant_state = { 'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: if property["key"] == "age": participant_state[property["key"]] = property["value"] else: participant_state['additional_properties'].append({ 'key': property['key'], 'value': property['value'] }) relations_response = self.graph_api_service.get_node_relationships( participant_state_id) for relation in relations_response["relationships"]: if relation["start_node"] == participant_state_id: participant_state['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: participant_state['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ParticipantStateOut(**participant_state) def delete_participant_state(self, participant_state_id: int): """ Send request to graph api to delete given participant state Args: participant_state_id (int): Id of participant state Returns: Result of request as participant state object """ get_response = self.get_participant_state(participant_state_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(participant_state_id) return get_response def update_participant_state( self, participant_state_id: int, participant_state: ParticipantStatePropertyIn): """ Send request to graph api to update given participant state Args: participant_state_id (int): Id of participant state participant_state (ParticipantStatePropertyIn): Properties to update Returns: Result of request as participant state object """ get_response = self.get_participant_state(participant_state_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node_properties(participant_state_id) self.graph_api_service.create_properties(participant_state_id, participant_state) participant_state_result = { "id": participant_state_id, "relations": get_response.relations, "reversed_relations": get_response.reversed_relations } participant_state_result.update(participant_state.dict()) return ParticipantStateOut(**participant_state_result) def update_participant_state_relationships( self, participant_state_id: int, participant_state: ParticipantStateRelationIn): """ Send request to graph api to update given participant state Args: participant_state_id (int): Id of participant state participant_state (ParticipantStateRelationIn): Relationships to update Returns: Result of request as participant state object """ get_response = self.get_participant_state(participant_state_id) if type(get_response) is NotFoundByIdModel: return get_response if participant_state.participant_id is not None and \ type(self.participant_service.get_participant( participant_state.participant_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.participant_id, name="hasParticipant") if participant_state.personality_id is not None and \ type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.personality_id, name="hasPersonality") if participant_state.appearance_id is not None and \ type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=participant_state_id, end_node=participant_state.appearance_id, name="hasAppearance") return self.get_participant_state(participant_state_id)
class RegisteredChannelService: """ Object to handle logic of registered channels requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API channel_service (ChannelService): Service to send channel requests registered_data_service (RegisteredDataService): Service to send registered data requests """ graph_api_service = GraphApiService() channel_service = ChannelService() registered_data_service = RegisteredDataService() def save_registered_channel(self, registered_channel: RegisteredChannelIn): """ Send request to graph api to create new registered channel Args: registered_channel (RegisteredChannelIn): Registered channel to be added Returns: Result of request as registered channel object """ node_response = self.graph_api_service.create_node( "`Registered Channel`") if node_response["errors"] is not None: return RegisteredChannelOut(errors=node_response["errors"]) registered_channel_id = node_response["id"] if registered_channel.channel_id is not None and \ type(self.channel_service.get_channel(registered_channel.channel_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=registered_channel_id, end_node=registered_channel.channel_id, name="hasChannel") if registered_channel.registered_data_id is not None and \ type(self.registered_data_service.get_registered_data(registered_channel.registered_data_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=registered_channel_id, end_node=registered_channel.registered_data_id, name="hasRegisteredData") return self.get_registered_channel(registered_channel_id) def get_registered_channels(self): """ Send request to graph api to get registered channels Returns: Result of request as list of registered channels objects """ get_response = self.graph_api_service.get_nodes("`Registered Channel`") registered_channels = [] for registered_channel_node in get_response["nodes"]: properties = {'id': registered_channel_node['id']} for property in registered_channel_node["properties"]: if property["key"] == "age": properties[property["key"]] = property["value"] registered_channel = BasicRegisteredChannelOut(**properties) registered_channels.append(registered_channel) return RegisteredChannelsOut(registered_channels=registered_channels) def get_registered_channel(self, registered_channel_id: int): """ Send request to graph api to get given registered channel Args: registered_channel_id (int): Id of registered channel Returns: Result of request as registered channel object """ get_response = self.graph_api_service.get_node(registered_channel_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=registered_channel_id, errors=get_response["errors"]) if get_response["labels"][0] != "Registered Channel": return NotFoundByIdModel(id=registered_channel_id, errors="Node not found.") registered_channel = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: if property["key"] == "age": registered_channel[property["key"]] = property["value"] relations_response = self.graph_api_service.get_node_relationships( registered_channel_id) for relation in relations_response["relationships"]: if relation["start_node"] == registered_channel_id: registered_channel['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: registered_channel['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return RegisteredChannelOut(**registered_channel) def delete_registered_channel(self, registered_channel_id: int): """ Send request to graph api to delete given registered channel Args: registered_channel_id (int): Id of registered channel Returns: Result of request as registered channel object """ get_response = self.get_registered_channel(registered_channel_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(registered_channel_id) return get_response def update_registered_channel_relationships( self, registered_channel_id: int, registered_channel: RegisteredChannelIn): """ Send request to graph api to update given registered channel Args: registered_channel_id (int): Id of registered channel registered_channel (RegisteredChannelIn): Relationships to update Returns: Result of request as registered channel object """ get_response = self.get_registered_channel(registered_channel_id) if type(get_response) is NotFoundByIdModel: return get_response if registered_channel.channel_id is not None and \ type(self.channel_service.get_channel(registered_channel.channel_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=registered_channel_id, end_node=registered_channel.channel_id, name="hasChannel") if registered_channel.registered_data_id is not None and \ type(self.registered_data_service.get_registered_data(registered_channel.registered_data_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=registered_channel_id, end_node=registered_channel.registered_data_id, name="hasRegisteredData") return self.get_registered_channel(registered_channel_id)
class MeasureNameService: """ Object to handle logic of measure name requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_measure_name(self, measure_name: MeasureNameIn): """ Send request to graph api to create new measure name Args: measure_name (MeasureNameIn): Measure name to be added Returns: Result of request as measure name object """ create_response = self.graph_api_service.create_node("`Measure Name`") if create_response["errors"] is not None: return MeasureNameOut(name=measure_name.name, type=measure_name.type, errors=create_response["errors"]) measure_name_id = create_response["id"] properties_response = self.graph_api_service.create_properties( measure_name_id, measure_name) if properties_response["errors"] is not None: return MeasureNameOut(name=measure_name.name, type=measure_name.type, errors=properties_response["errors"]) return MeasureNameOut(name=measure_name.name, type=measure_name.type, id=measure_name_id) def get_measure_names(self): """ Send request to graph api to get all measure names Returns: Result of request as list of measure name objects """ get_response = self.graph_api_service.get_nodes("`Measure Name`") if get_response["errors"] is not None: return MeasureNamesOut(errors=get_response["errors"]) measure_names = [ BasicMeasureNameOut(id=measure_name["id"], **{ measure_name["properties"][0]["key"]: measure_name["properties"][0]["value"], measure_name["properties"][1]["key"]: measure_name["properties"][1]["value"] }) for measure_name in get_response["nodes"] ] return MeasureNamesOut(measure_names=measure_names) def get_measure_name(self, measure_name_id: int): """ Send request to graph api to get given measure name Args: measure_name_id (int): Id of measure name Returns: Result of request as measure name object """ get_response = self.graph_api_service.get_node(measure_name_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=measure_name_id, errors=get_response["errors"]) if get_response["labels"][0] != "Measure Name": return NotFoundByIdModel(id=measure_name_id, errors="Node not found.") measure_name = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } for property in get_response["properties"]: measure_name[property["key"]] = property["value"] relations_response = self.graph_api_service.get_node_relationships( measure_name_id) for relation in relations_response["relationships"]: if relation["start_node"] == measure_name_id: measure_name['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: measure_name['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return MeasureNameOut(**measure_name)
class ModalityService: """ Object to handle logic of modality requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_modality(self, modality: ModalityIn): """ Send request to graph api to create new modality Args: modality (ModalityIn): Modality to be added Returns: Result of request as modality object """ node_response = self.graph_api_service.create_node("Modality") if node_response["errors"] is not None: return ModalityOut(modality=modality.modality, errors=node_response["errors"]) modality_id = node_response["id"] properties_response = self.graph_api_service.create_properties(modality_id, modality) if properties_response["errors"] is not None: return ModalityOut(modality=modality.modality, errors=properties_response["errors"]) return ModalityOut(modality=modality.modality, id=modality_id) def get_modalities(self): """ Send request to graph api to get all modalities Returns: Result of request as list of modality objects """ get_response = self.graph_api_service.get_nodes("Modality") modalities = [BasicModalityOut(id=modality["id"], modality=modality["properties"][0]["value"]) for modality in get_response["nodes"]] return ModalitiesOut(modalities=modalities) def get_modality(self, modality_id: int): """ Send request to graph api to get given modality Args: modality_id (int): Id of modality Returns: Result of request as modality object """ get_response = self.graph_api_service.get_node(modality_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=modality_id, errors=get_response["errors"]) if get_response["labels"][0] != "Modality": return NotFoundByIdModel(id=modality_id, errors="Node not found.") modality = {'id': get_response['id'], 'relations': [], 'reversed_relations': []} for property in get_response["properties"]: modality[property["key"]] = property["value"] relations_response = self.graph_api_service.get_node_relationships(modality_id) for relation in relations_response["relationships"]: if relation["start_node"] == modality_id: modality['relations'].append(RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: modality['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ModalityOut(**modality)
class AppearanceService: """ Object to handle logic of appearance requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API """ graph_api_service = GraphApiService() def save_appearance_occlusion(self, appearance: AppearanceOcclusionIn): """ Send request to graph api to create new appearance occlusion model Args: appearance (AppearanceIn): Appearance to be added Returns: Result of request as appearance state object """ node_response = self.graph_api_service.create_node("Appearance") if node_response["errors"] is not None: return AppearanceOcclusionOut(glasses=appearance.glasses, beard=appearance.beard, moustache=appearance.moustache, errors=node_response["errors"]) appearance_id = node_response["id"] properties_response = self.graph_api_service.create_properties( appearance_id, appearance) if properties_response["errors"] is not None: return AppearanceOcclusionOut(glasses=appearance.glasses, beard=appearance.beard, moustache=appearance.moustache, errors=properties_response["errors"]) return AppearanceOcclusionOut(glasses=appearance.glasses, beard=appearance.beard, moustache=appearance.moustache, id=appearance_id) def save_appearance_somatotype(self, appearance: AppearanceSomatotypeIn): """ Send request to graph api to create new appearance somatotype model Args: appearance (AppearanceIn): Appearance to be added Returns: Result of request as appearance state object """ if not 1 <= appearance.ectomorph <= 7 or not 1 <= appearance.endomorph <= 7 \ or not 1 <= appearance.mesomorph <= 7: return AppearanceSomatotypeOut( ectomorph=appearance.ectomorph, endomorph=appearance.endomorph, mesomorph=appearance.mesomorph, errors="Scale range not between 1 and 7") node_response = self.graph_api_service.create_node("Appearance") if node_response["errors"] is not None: return AppearanceSomatotypeOut(ectomorph=appearance.ectomorph, endomorph=appearance.endomorph, mesomorph=appearance.mesomorph, errors=node_response["errors"]) appearance_id = node_response["id"] properties_response = self.graph_api_service.create_properties( appearance_id, appearance) if properties_response["errors"] is not None: return AppearanceSomatotypeOut( ectomorph=appearance.ectomorph, endomorph=appearance.endomorph, mesomorph=appearance.mesomorph, errors=properties_response["errors"]) return AppearanceSomatotypeOut(ectomorph=appearance.ectomorph, endomorph=appearance.endomorph, mesomorph=appearance.mesomorph, id=appearance_id) def get_appearance(self, appearance_id: int): """ Send request to graph api to get given appearance Args: appearance_id (int): Id of appearance Returns: Result of request as appearance object """ get_response = self.graph_api_service.get_node(appearance_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=appearance_id, errors=get_response["errors"]) if get_response["labels"][0] != "Appearance": return NotFoundByIdModel(id=appearance_id, errors="Node not found.") appearance = { 'id': appearance_id, 'relations': [], 'reversed_relations': [] } appearance.update({ property["key"]: property["value"] for property in get_response["properties"] }) relations_response = self.graph_api_service.get_node_relationships( appearance_id) for relation in relations_response["relationships"]: if relation["start_node"] == appearance_id: appearance["relations"].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: appearance["reversed_relations"].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return AppearanceOcclusionOut(**appearance) if "glasses" in appearance.keys() \ else AppearanceSomatotypeOut(**appearance) def get_appearances(self): """ Send request to graph api to get appearances Returns: Result of request as list of appearances objects """ get_response = self.graph_api_service.get_nodes("Appearance") appearances = [] for appearance_node in get_response["nodes"]: properties = { property["key"]: property["value"] for property in appearance_node["properties"] } properties["id"] = appearance_node["id"] appearance = BasicAppearanceOcclusionOut(**properties) if "glasses" in properties.keys() \ else BasicAppearanceSomatotypeOut(**properties) appearances.append(appearance) return AppearancesOut(appearances=appearances) def delete_appearance(self, appearance_id: int): """ Send request to graph api to delete given appearance Args: appearance_id (int): Id of appearance Returns: Result of request as appearance object """ get_response = self.get_appearance(appearance_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(appearance_id) return get_response def update_appearance_occlusion(self, appearance_id: int, appearance: AppearanceOcclusionIn): """ Send request to graph api to update given appearance occlusion model Args: appearance_id (int): Id of appearance appearance (AppearanceOcclusionIn): Properties to update Returns: Result of request as appearance object """ get_response = self.get_appearance(appearance_id) if type(get_response) is NotFoundByIdModel: return get_response if type(get_response) is AppearanceSomatotypeOut: return NotFoundByIdModel(id=appearance_id, errors="Node not found.") self.graph_api_service.create_properties(appearance_id, appearance) appearance_response = get_response.dict() appearance_response.update(appearance) return AppearanceOcclusionOut(**appearance_response) def update_appearance_somatotype(self, appearance_id: int, appearance: AppearanceSomatotypeIn): """ Send request to graph api to update given appearance somatotype model Args: appearance_id (int): Id of appearance appearance (AppearanceSomatotypeIn): Properties to update Returns: Result of request as appearance object """ if not 1 <= appearance.ectomorph <= 7 or not 1 <= appearance.endomorph <= 7 \ or not 1 <= appearance.mesomorph <= 7: return AppearanceSomatotypeOut( **appearance.dict(), errors="Scale range not between 1 and 7") get_response = self.get_appearance(appearance_id) if type(get_response) is NotFoundByIdModel: return get_response if type(get_response) is AppearanceOcclusionOut: return NotFoundByIdModel(id=appearance_id, errors="Node not found.") self.graph_api_service.create_properties(appearance_id, appearance) appearance_response = get_response.dict() appearance_response.update(appearance) return AppearanceSomatotypeOut(**appearance_response)
class ObservableInformationService: """ Object to handle logic of observable information requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API modality_service (ModalityService): Service used to communicate with Modality life_activity_service (LifeActivityService): Service used to communicate with Life Activity recording_service (RecordingService): Service used to communicate with Recording """ graph_api_service = GraphApiService() modality_service = ModalityService() life_activity_service = LifeActivityService() recording_service = RecordingService() def save_observable_information( self, observable_information: ObservableInformationIn): """ Send request to graph api to create new observable information Args: observable_information (ObservableInformationIn): Observable information to be added Returns: Result of request as observable information object """ node_response = self.graph_api_service.create_node( "`Observable Information`") if node_response["errors"] is not None: return ObservableInformationOut(errors=node_response["errors"]) observable_information_id = node_response["id"] if observable_information.modality_id is not None and \ type(self.modality_service.get_modality(observable_information.modality_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.modality_id, name="hasModality") if observable_information.life_activity_id is not None and \ type(self.life_activity_service.get_life_activity( observable_information.life_activity_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.life_activity_id, name="hasLifeActivity") if observable_information.recording_id is not None and \ type( self.recording_service.get_recording(observable_information.recording_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.recording_id, name="hasRecording") return self.get_observable_information(observable_information_id) def get_observable_informations(self): """ Send request to graph api to get observable information Returns: Result of request as list of observable information objects """ get_response = self.graph_api_service.get_nodes( "`Observable Information`") observable_informations = [] for observable_information_node in get_response["nodes"]: properties = {'id': observable_information_node['id']} observable_information = BasicObservableInformationOut( **properties) observable_informations.append(observable_information) return ObservableInformationsOut( observable_informations=observable_informations) def get_observable_information(self, observable_information_id: int): """ Send request to graph api to get given observable information Args: observable_information_id (int): Id of observable information Returns: Result of request as observable information object """ get_response = self.graph_api_service.get_node( observable_information_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=observable_information_id, errors=get_response["errors"]) if get_response["labels"][0] != "Observable Information": return NotFoundByIdModel(id=observable_information_id, errors="Node not found.") observable_information = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } relations_response = self.graph_api_service.get_node_relationships( observable_information_id) for relation in relations_response["relationships"]: if relation["start_node"] == observable_information_id: observable_information['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: observable_information['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ObservableInformationOut(**observable_information) def delete_observable_information(self, observable_information_id: int): """ Send request to graph api to delete given observable information Args: observable_information_id (int): Id of observable information Returns: Result of request as observable information object """ get_response = self.get_observable_information( observable_information_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(observable_information_id) return get_response def update_observable_information_relationships( self, observable_information_id: int, observable_information: ObservableInformationIn): """ Send request to graph api to update given observable information Args: observable_information_id (int): Id of observable information observable_information (ObservableInformationIn): Relationships to update Returns: Result of request as observable information object """ get_response = self.get_observable_information( observable_information_id) if type(get_response) is NotFoundByIdModel: return get_response if observable_information.modality_id is not None and \ type(self.modality_service.get_modality(observable_information.modality_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.modality_id, name="hasModality") if observable_information.life_activity_id is not None and \ type(self.life_activity_service.get_life_activity( observable_information.life_activity_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.life_activity_id, name="hasLifeActivity") if observable_information.recording_id is not None and \ type( self.recording_service.get_recording(observable_information.recording_id)) is not NotFoundByIdModel: self.graph_api_service.create_relationships( start_node=observable_information_id, end_node=observable_information.recording_id, name="hasRecording") return self.get_observable_information(observable_information_id)
class ParticipationService: """ Object to handle logic of participation requests Attributes: graph_api_service (GraphApiService): Service used to communicate with Graph API activity_execution_service (ActivityExecutionService): Service to send activity execution requests participant_state_service (ParticipantStateService): Service to send participant state requests """ graph_api_service = GraphApiService() activity_execution_service = ActivityExecutionService() participant_state_service = ParticipantStateService() def save_participation(self, participation: ParticipationIn): """ Send request to graph api to create new participation Args: participation (ParticipationIn): Participation to be added Returns: Result of request as participation object """ node_response = self.graph_api_service.create_node("Participation") if node_response["errors"] is not None: return ParticipationOut(errors=node_response["errors"]) participation_id = node_response["id"] if participation.activity_execution_id is not None and \ type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.activity_execution_id, "hasActivityExecution") if participation.participant_state_id is not None and \ type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.participant_state_id, "hasParticipantState") return self.get_participation(participation_id) def get_participations(self): """ Send request to graph api to get participations Returns: Result of request as list of participation objects """ get_response = self.graph_api_service.get_nodes("Participation") participations = [] for participation_node in get_response["nodes"]: properties = {'id': participation_node['id']} participation = BasicParticipationOut(**properties) participations.append(participation) return ParticipationsOut(participations=participations) def get_participation(self, participation_id: int): """ Send request to graph api to get given participation Args: participation_id (int): Id of participation Returns: Result of request as participation object """ get_response = self.graph_api_service.get_node(participation_id) if get_response["errors"] is not None: return NotFoundByIdModel(id=participation_id, errors=get_response["errors"]) if get_response["labels"][0] != "Participation": return NotFoundByIdModel(id=participation_id, errors="Node not found.") participation = { 'id': get_response['id'], 'relations': [], 'reversed_relations': [] } relations_response = self.graph_api_service.get_node_relationships( participation_id) for relation in relations_response["relationships"]: if relation["start_node"] == participation_id: participation['relations'].append( RelationInformation(second_node_id=relation["end_node"], name=relation["name"], relation_id=relation["id"])) else: participation['reversed_relations'].append( RelationInformation(second_node_id=relation["start_node"], name=relation["name"], relation_id=relation["id"])) return ParticipationOut(**participation) def delete_participation(self, participation_id: int): """ Send request to graph api to delete given participation Args: participation_id (int): Id of participation Returns: Result of request as participation object """ get_response = self.get_participation(participation_id) if type(get_response) is NotFoundByIdModel: return get_response self.graph_api_service.delete_node(participation_id) return get_response def update_participation_relationships(self, participation_id: int, participation: ParticipationIn): """ Send request to graph api to update given participation relationships Args: participation_id (int): Id of participation participation (ParticipationIn): Relationships to update Returns: Result of request as participation object """ get_response = self.get_participation(participation_id) if type(get_response) is NotFoundByIdModel: return get_response if participation.activity_execution_id is not None and \ type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.activity_execution_id, "hasActivityExecution") if participation.participant_state_id is not None and \ type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \ is not NotFoundByIdModel: self.graph_api_service.create_relationships( participation_id, participation.participant_state_id, "hasParticipantState") return self.get_participation(participation_id)
def setUp(self): self.graph_api_service = GraphApiService() self.response_content = {'id': 1, 'errors': [], 'links': {}} self.response = Response() self.response._content = json.dumps(self.response_content).encode('utf-8')