def get_investigations_for_instrument_in_facility_cycle( client, instrument_id, facilitycycle_id, filters, count_query=False, ): """ Given Instrument and Facility Cycle IDs, get investigations that use the given instrument in the given cycle :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` :param instrument_id: ID of the instrument from the request :type instrument_id: :class:`int` :param facilitycycle_id: ID of the facilityCycle from the request :type facilitycycle_id: :class:`int` :param filters: The list of filters to be applied to the request :type filters: List of specific implementations :class:`QueryFilter` :param count_query: Flag to determine if the query in this function should be used as a count query. Used for `get_investigations_for_instrument_in_facility_cycle_count()` :type count_query: :class:`bool` :return: A list of Investigations that match the query """ log.info( "Getting a list of investigations from the specified instrument and facility" " cycle, for ISIS", ) query_aggregate = "COUNT:DISTINCT" if count_query else "DISTINCT" query = ICATQuery(client, "Investigation", aggregate=query_aggregate) query.isis_endpoint = True instrument_id_check = PythonICATWhereFilter( "facility.instruments.id", instrument_id, "eq", ) investigation_instrument_id_check = PythonICATWhereFilter( "investigationInstruments.instrument.id", instrument_id, "eq", ) facility_cycle_id_check = PythonICATWhereFilter( "facility.facilityCycles.id", facilitycycle_id, "eq", ) facility_cycle_start_date_check = PythonICATWhereFilter( "facility.facilityCycles.startDate", "o.startDate", "lte", ) facility_cycle_end_date_check = PythonICATWhereFilter( "facility.facilityCycles.endDate", "o.startDate", "gte", ) required_filters = [ instrument_id_check, investigation_instrument_id_check, facility_cycle_id_check, facility_cycle_start_date_check, facility_cycle_end_date_check, ] filters.extend(required_filters) filter_handler = FilterOrderHandler() filter_handler.manage_icat_filters(filters, query.query) data = query.execute_query(client, True) return data
def test_valid_query_exeuction( self, icat_client, query_conditions, query_aggregate, query_includes, query_attributes, manual_count, return_json_format_flag, expected_query_result, ): test_query = ICATQuery( icat_client, "Investigation", conditions=query_conditions, aggregate=query_aggregate, includes=query_includes, ) test_query.query.setAttributes(query_attributes) test_query.query.manual_count = manual_count query_data = test_query.execute_query( icat_client, return_json_formattable=return_json_format_flag, ) if (test_query.query.aggregate != "COUNT" and test_query.query.aggregate != "DISTINCT"): query_data = prepare_icat_data_for_assertion( query_data, remove_id=True, remove_visit_id=True, ) assert query_data == expected_query_result
def get_count_with_filters(client, entity_type, filters): """ Get the number of results of a given entity, based on the filters provided in the request. This acts very much like `get_entity_with_filters()` but returns the number of results, as opposed to a JSON object of data. :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` :param entity_type: The type of entity requested to manipulate data with :type entity_type: :class:`str` :param filters: The list of filters to be applied to the request :type filters: List of specific implementations :class:`QueryFilter` :return: The number of records of the given entity (of type integer), using the filters to restrict the result of the query """ log.info( "Getting the number of results of %s, also using the request's filters", entity_type, ) query = ICATQuery(client, entity_type, aggregate="COUNT") filter_handler = FilterOrderHandler() filter_handler.manage_icat_filters(filters, query.query) data = query.execute_query(client, True) # Only ever 1 element in a count query result return data[0]
def test_invalid_query_execution(self, icat_client): test_query = ICATQuery(icat_client, "Investigation") # Create filter with valid value, then change to invalid value that'll cause 500 test_skip_filter = PythonICATSkipFilter(1) test_skip_filter.skip_value = -1 test_skip_filter.apply_filter(test_query.query) with pytest.raises(PythonICATError): test_query.execute_query(icat_client)
def get_entity_by_id( client, entity_type, id_, return_json_formattable_data, return_related_entities=False, ): """ Gets a record of a given ID from the specified entity :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` :param entity_type: The type of entity requested to manipulate data with :type entity_type: :class:`str` :param id_: ID number of the entity to retrieve :type id_: :class:`int` :param return_json_formattable_data: Flag to determine whether the data should be returned as a list of data ready to be converted straight to JSON (i.e. if the data will be used as a response for an API call) or whether to leave the data in a Python ICAT format :type return_json_formattable_data: :class:`bool` :param return_related_entities: Flag to determine whether related entities should automatically be returned or not. Returning related entities used as a bug fix for an `IcatException` where ICAT attempts to set a field to null because said field hasn't been included in the updated data :type return_related_entities: :class:`bool` :return: The record of the specified ID from the given entity :raises: MissingRecordError: If Python ICAT cannot find a record of the specified ID """ log.info("Getting %s of the ID %s", entity_type, id_) log.debug("Return related entities set to: %s", return_related_entities) # Set query condition for the selected ID id_condition = PythonICATWhereFilter.create_condition("id", "=", id_) includes_value = "1" if return_related_entities else None id_query = ICATQuery( client, entity_type, conditions=id_condition, includes=includes_value, ) entity_by_id_data = id_query.execute_query(client, return_json_formattable_data) if not entity_by_id_data: # Cannot find any data matching the given ID raise MissingRecordError("No result found") else: return entity_by_id_data[0]
def test_json_format_execution_output( self, icat_client, single_investigation_test_data, ): test_query = ICATQuery(icat_client, "Investigation") test_data_filter = PythonICATWhereFilter( "title", "Test data for the Python ICAT Backend on DataGateway API", "like", ) test_data_filter.apply_filter(test_query.query) query_data = test_query.execute_query(icat_client, True) query_output_json = prepare_icat_data_for_assertion(query_data) assert query_output_json == single_investigation_test_data
def test_valid_manual_count_flag_init(self, icat_client): """ Flag required for distinct filters used on count endpoints should be initialised in `__init__()` of ICATQuery` """ test_query = ICATQuery(icat_client, "User") assert not test_query.query.manual_count
def test_include_fields_list_flatten(self, icat_client): included_field_set = { "investigationUsers.investigation.datasets", "userGroups", "instrumentScientists", "studies", } test_query = ICATQuery(icat_client, "User") flat_list = test_query.flatten_query_included_fields( included_field_set) assert flat_list == [ "instrumentScientists", "investigationUsers", "investigation", "datasets", "studies", "userGroups", ]
def get_entity_with_filters(client, entity_type, filters): """ Gets all the records of a given entity, based on the filters provided in the request :param client: ICAT client containing an authenticated user :type client: :class:`icat.client.Client` :param entity_type: The type of entity requested to manipulate data with :type entity_type: :class:`str` :param filters: The list of filters to be applied to the request :type filters: List of specific implementations :class:`QueryFilter` :return: The list of records of the given entity, using the filters to restrict the result of the query """ log.info("Getting entity using request's filters") query = ICATQuery(client, entity_type) filter_handler = FilterOrderHandler() filter_handler.manage_icat_filters(filters, query.query) data = query.execute_query(client, True) return data
def test_valid_query_creation( self, icat_client, input_conditions, input_aggregate, input_includes, expected_conditions, expected_aggregate, expected_includes, ): test_query = ICATQuery( icat_client, "User", conditions=input_conditions, aggregate=input_aggregate, includes=input_includes, ) assert test_query.query.entity == icat_client.getEntityClass("User") assert test_query.query.conditions == expected_conditions assert test_query.query.aggregate == expected_aggregate assert test_query.query.includes == expected_includes
def test_valid_get_distinct_attributes(self, icat_client): test_query = ICATQuery(icat_client, "Investigation") test_query.query.setAttributes(["summary", "name"]) assert test_query.get_distinct_attributes() == ["summary", "name"]
def test_invalid_query_creation(self, icat_client): with pytest.raises(PythonICATError): ICATQuery(icat_client, "User", conditions={"invalid": "invalid"})