Пример #1
0
    def __init__(self,
                 ep=PUBONE_EP,
                 session=CmdLineFtsType(),
                 logger=None,
                 debug=0):
        self._api = RestApi(ep=ep, session=session, logger=logger, debug=debug)

        self._ep = ep
        self._session = session
        self._logger = logger
        self._debug = debug
Пример #2
0
def test_resource_item():
    """
    Test `access to the resource item` functionality.
    """
    ep = "http://localhost/api/"
    item_x_url = "http://localhost/api/items/x"
    item_5_url = "http://localhost/api/items/5"
    api = RestApi(ep=ep)
    itemres_x = api.items("x")
    assert str(itemres_x) == item_x_url  # check that the url was normalized.
    itemres_5 = api.items(5)
    assert str(itemres_5) == item_5_url  # check that the url was normalized.
Пример #3
0
def test_get_item(requests_mock):
    ep = "http://localhost/api/"
    item_id = 5
    item_id_url = ep + f"items/{item_id}"

    # prepare response with Mocker
    payload = {"result": ["a", "b", "c"]}
    requests_mock.get(item_id_url,
                      json=payload,
                      headers={"Content-Type": "application/json"})

    # use RestApi
    api = RestApi(ep=ep)
    resp = api.items(item_id).get()
    data = resp.data
    assert data == payload
Пример #4
0
def test_create_api_instance():
    """
    Test `creation of new instance` functionality.
    """
    api_ep = "http://localhost///api/"
    api_url = "http://localhost/api/"
    api = RestApi(ep=api_ep)
    assert api is not None  # check that we have got an instance
    assert str(api) == api_url  # check that the url was normalized.
Пример #5
0
def test_resource_list():
    """
    Test `access to the resource list` functionality.
    """
    ep = "http://localhost/api/"
    resource_url = "http://localhost/api/items"
    api = RestApi(ep=ep)
    resource = api.items
    assert type(
        resource) is RestApi  # check creation of the resource of correct type
    assert str(resource) == resource_url  # check that the url was normalized.
Пример #6
0
def test_500(requests_mock):
    ep = "http://localhost/api/500"

    # prepare response with Mocker
    requests_mock.get(ep, status_code=500)

    # use RestApi
    SessionClass = FtsClassFactory(max_tries=3, max_time=2)
    api = RestApi(ep=ep, session=SessionClass())
    assert str(api._) == ep

    with pytest.raises(HttpServerError):
        resp = api._.get()
        data = resp.data
        assert data is None
Пример #7
0
def test_post_item(requests_mock):
    ep = "http://localhost/api/"
    items_url = ep + f"items"

    # prepare response with Mocker
    payload = {"a": 1, "b": 2, "c": 3}
    result = {"result": ["a", "b", "c"]}
    requests_mock.post(items_url,
                       json=result,
                       headers={"Content-Type": "application/json"})

    # use RestApi
    api = RestApi(ep=ep)
    resp = api.items.post(data=payload)
    data = resp.data
    assert data == result
Пример #8
0
class PubOneValidator(PubOneBase):
    def __init__(self,
                 ep=PUBONE_EP,
                 session=CmdLineFtsType(),
                 logger=None,
                 debug=0):
        self._api = RestApi(ep=ep, session=session, logger=logger, debug=debug)

        self._ep = ep
        self._session = session
        self._logger = logger
        self._debug = debug

    def _lookup_pubone(self, pmid: int, pmcid: int) -> List[dict]:
        params = [
            pmid and f"pubmed_{pmid}" or None,
            pmcid and f"pmc_{pmcid}" or None,
        ]
        resource_name = ",".join(list(filter(lambda i: i is not None, params)))

        try:
            response = self._api.lojson(resource_name).get()
        except api_ex.HttpServerError as e:
            raise ex.PubOneServiceFailed(e)

        return response.data

    def _validate_item(self, data_item, pmid, pmcid):
        if not isinstance(data_item, dict):
            raise ex.PubOneServiceFailed(
                ValueError(
                    f"PubOne API returned an unexpected record `{data_item}` "
                    f"for the following data pmid={pmid} pmcid={pmcid}, "
                    "contact developer."))

        _pmcid_raw = data_item.get("pmcid")
        _pmid_raw = data_item.get("id")
        _pmcid = self._eval_pmcid(_pmcid_raw)
        _pmid = self._eval_pmid(_pmid_raw)
        _doi = data_item.get("doi", None)

        pmid_exists = pmid if pmid is None else pmid == _pmid
        pmcid_exists = pmcid if pmcid is None else pmcid == _pmcid

        # print(f"\npmid={pmid} _pmid={_pmid} pmid_exists={pmid_exists}")
        # print(f"pmid={pmcid} _pmid={_pmcid} pmcid_exists={pmcid_exists}")

        # cases 1, 4, 8
        if ((pmid_exists is True and pmcid_exists is True)  # 1
                or (pmid_exists is True and pmcid_exists is None)  # 4
                or (pmid_exists is None and pmcid_exists is True)  # 8
            ):
            self._pmcid = _pmcid
            self._pmid = _pmid
            self._doi = _doi
            return True

        # case 3
        if pmid_exists is True and pmcid_exists is False:  # 3
            raise ex.PmcidAbsent(pmcid)

        # case 5
        if pmid_exists is False and pmcid_exists is True:  # 5
            raise ex.PmidAbsent(pmid)

    def validate(self, pmid: int = None, pmcid: int = None) -> bool:
        """Validates PubMed Id and PMC Id for presence in PubOne service,
        and match to the same article.

        Keyword Arguments:
            pmid {int} -- PubMed Id (default: {None})
            pmcid {int} -- PMC Id (default: {None})

        Returns:
            bool -- True if result of validation is positive.

Case    Outcome             pmid    pmcid    match   #Recs - (from PubOne)
0       ValueError          None    None     -       -
1       True                exists  exists   yes     1
2       PmidPmcidMismatch   exists  exists   no      2
3       PmcidAbsent         exists  absent           1
4       True                exists  None             1
5       PmidAbsent          absent  exists           1
6       PmidPmcidAbsent     absent  absent           0
7       PmidAbsent          absent  None             0
8       True                None    exists           1
9       PmcidAbsent         None    absent           0

        exists = id is not None and id = _id
                 where id is one of pmid or pmcid supplied
                 and _id corresponding identifier received from PubOne.
        absent = not(exists)"""
        self._pmid = None
        self._pmcid = None
        self._doi = None

        # case 0
        if pmid is None and pmcid is None:
            raise ValueError("Both `pmid` and `pmcid` are undefined, "
                             "at least one must be provided.")

        pmid = self._validate_id(pmid, "pmid")
        pmcid = self._validate_id(pmcid, "pmcid")
        data = self._lookup_pubone(pmid, pmcid)

        # from devtools import debug as d
        # print(f"data={d.format(data)}")

        if not isinstance(data, (list)):
            raise ex.PubOneServiceFailed(
                ValueError(f"A list of records was expected from PubOne, "
                           f"data={data} was received instead."))

        # case 2
        if len(data) == 2 and pmid is not None and pmcid is not None:
            raise ex.PmidPmcidMismatch(pmid, pmcid)

        # cases 1, 4, 8 and 3, 5
        elif len(data) == 1:
            data_1 = next(iter(data),
                          {})  # get 1st item of the list `data` or {}
            return self._validate_item(data_1, pmid, pmcid)

        # cases 6, 7, 9
        elif len(data) == 0:
            if pmid is not None and pmcid is not None:  # 6
                raise ex.PmidPmcidAbsent(pmid, pmcid)
            if pmid is not None and pmcid is None:  # 7
                raise ex.PmidAbsent(pmid)
            if pmid is None and pmcid is not None:  # 9
                raise ex.PmcidAbsent(pmcid)

        raise RuntimeError(
            "PubOne client experienced unexpected outcome, contact developer "
            "with following data pmid={pmid} pmcid={pmcid} data={data}.")

    @property
    def pmid(self):
        return self._pmid

    @property
    def pmcid(self):
        return self._pmcid

    @property
    def doi(self):
        return self._doi