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 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.
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
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.
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.
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
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
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