예제 #1
0
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
예제 #2
0
    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
예제 #3
0
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]
예제 #4
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)
예제 #5
0
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]
예제 #6
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
예제 #7
0
    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
예제 #8
0
    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",
        ]
예제 #9
0
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
예제 #10
0
    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
예제 #11
0
    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"]
예제 #12
0
 def test_invalid_query_creation(self, icat_client):
     with pytest.raises(PythonICATError):
         ICATQuery(icat_client, "User", conditions={"invalid": "invalid"})