diff --git a/bookops_worldcat/metadata_api.py b/bookops_worldcat/metadata_api.py index f29a322..30b32f0 100644 --- a/bookops_worldcat/metadata_api.py +++ b/bookops_worldcat/metadata_api.py @@ -59,25 +59,25 @@ def _url_base(self) -> str: def _url_search_base(self) -> str: return "https://americas.metadata.api.oclc.org/worldcat/search/v1" - def _url_member_shared_print_holdings(self) -> str: - base_url = self._url_search_base() - return f"{base_url}/bibs-retained-holdings" + def _url_search_shared_print_holdings(self) -> str: + base_url = self.URL_BASE() + return f"{base_url}/search/bibs-retained-holdings" - def _url_member_general_holdings(self) -> str: - base_url = self._url_search_base() - return f"{base_url}/bibs-summary-holdings" + def _url_search_general_holdings(self) -> str: + base_url = self.URL_BASE() + return f"{base_url}/search/bibs-summary-holdings" - def _url_brief_bib_search(self) -> str: - base_url = self._url_search_base() - return f"{base_url}/brief-bibs" + def _url_search_brief_bibs(self) -> str: + base_url = self.URL_BASE() + return f"{base_url}/search/brief-bibs" - def _url_brief_bib_oclc_number(self, oclcNumber: str) -> str: - base_url = self._url_search_base() - return f"{base_url}/brief-bibs/{oclcNumber}" + def _url_search_brief_bibs_oclc_number(self, oclcNumber: str) -> str: + base_url = self.URL_BASE() + return f"{base_url}/search/brief-bibs/{oclcNumber}" - def _url_brief_bib_other_editions(self, oclcNumber: str) -> str: - base_url = self._url_search_base() - return f"{base_url}/brief-bibs/{oclcNumber}/other-editions" + def _url_search_brief_bibs_other_editions(self, oclcNumber: str) -> str: + base_url = self.URL_BASE() + return f"{base_url}/search/brief-bibs/{oclcNumber}/other-editions" def _url_lhr_control_number(self, controlNumber: str) -> str: base_url = self._url_search_base() @@ -128,7 +128,7 @@ def get_brief_bib( ) -> Optional[Response]: """ Retrieve specific brief bibliographic resource. - Uses /brief-bibs/{oclcNumber} endpoint. + Uses /search/brief-bibs/{oclcNumber} endpoint. Args: oclcNumber: OCLC bibliographic record number; can be @@ -142,8 +142,8 @@ def get_brief_bib( """ oclcNumber = verify_oclc_number(oclcNumber) + url = self._url_search_brief_bibs_oclc_number(oclcNumber) header = {"Accept": "application/json"} - url = self._url_brief_bib_oclc_number(oclcNumber) # prep request req = Request("GET", url, headers=header, hooks=hooks) @@ -505,32 +505,33 @@ def holdings_unset_multi_institutions( return query.response - def search_brief_bib_other_editions( + def search_brief_bibs_other_editions( self, oclcNumber: Union[int, str], - deweyNumber: Optional[str] = None, - datePublished: Optional[str] = None, + deweyNumber: Optional[Union[str, List[str]]] = None, + datePublished: Optional[Union[str, List[str]]] = None, heldByGroup: Optional[str] = None, - heldBySymbol: Optional[str] = None, - heldByInstitutionID: Optional[Union[str, int]] = None, - inLanguage: Optional[str] = None, + heldBySymbol: Optional[Union[str, List[str]]] = None, + heldByInstitutionID: Optional[Union[str, int, List[Union[str, int]]]] = None, + inLanguage: Optional[Union[str, List[str]]] = None, inCatalogLanguage: Optional[str] = None, materialType: Optional[str] = None, catalogSource: Optional[str] = None, - itemType: Optional[str] = None, - itemSubType: Optional[str] = None, + itemType: Optional[Union[str, List[str]]] = None, + itemSubType: Optional[Union[str, List[str]]] = None, retentionCommitments: Optional[bool] = None, spProgram: Optional[str] = None, genre: Optional[str] = None, topic: Optional[str] = None, subtopic: Optional[str] = None, audience: Optional[str] = None, - content: Optional[str] = None, + content: Optional[Union[str, List[str]]] = None, openAccess: Optional[bool] = None, peerReviewed: Optional[bool] = None, - facets: Optional[str] = None, + facets: Optional[Union[str, List[str]]] = None, groupVariantRecords: Optional[bool] = None, preferredLanguage: Optional[str] = None, + showHoldingsIndicators: Optional[bool] = None, offset: Optional[int] = None, limit: Optional[int] = None, orderBy: Optional[str] = None, @@ -545,8 +546,7 @@ def search_brief_bib_other_editions( oclcNumber: OCLC bibliographic record number; can be an integer, or string with or without OCLC # prefix deweyNumber: limits the response to the - specified dewey classification number(s); - for multiple values repeat the parameter, + specified dewey classification number(s) example: '794,180' datePublished: restricts the response to one or @@ -612,7 +612,7 @@ def search_brief_bib_other_editions( """ oclcNumber = verify_oclc_number(oclcNumber) - url = self._url_brief_bib_other_editions(oclcNumber) + url = self._url_search_brief_bibs_other_editions(oclcNumber) header = {"Accept": "application/json"} payload = { "deweyNumber": deweyNumber, @@ -622,6 +622,7 @@ def search_brief_bib_other_editions( "heldByInstitutionID": heldByInstitutionID, "inLanguage": inLanguage, "inCatalogLanguage": inCatalogLanguage, + "materialType": materialType, "catalogSource": catalogSource, "itemType": itemType, "itemSubType": itemSubType, @@ -637,6 +638,7 @@ def search_brief_bib_other_editions( "facets": facets, "groupVariantRecords": groupVariantRecords, "preferredLanguage": preferredLanguage, + "showHoldingsIndicators": showHoldingsIndicators, "offset": offset, "limit": limit, "orderBy": orderBy, @@ -654,21 +656,35 @@ def search_brief_bib_other_editions( def search_brief_bibs( self, q: str, - deweyNumber: Optional[str] = None, - datePublished: Optional[str] = None, + deweyNumber: Optional[Union[str, List[str]]] = None, + datePublished: Optional[Union[str, List[str]]] = None, heldByGroup: Optional[str] = None, - inLanguage: Optional[str] = None, - inCatalogLanguage: Optional[str] = "eng", + heldBySymbol: Optional[Union[str, List[str]]] = None, + heldByInstitutionID: Optional[Union[str, int, List[str], List[int]]] = None, + inLanguage: Optional[Union[str, List[str]]] = None, + inCatalogLanguage: Optional[str] = None, materialType: Optional[str] = None, catalogSource: Optional[str] = None, - itemType: Optional[str] = None, - itemSubType: Optional[str] = None, + itemType: Optional[Union[str, List[str]]] = None, + itemSubType: Optional[Union[str, List[str]]] = None, retentionCommitments: Optional[bool] = None, spProgram: Optional[str] = None, - facets: Optional[str] = None, + genre: Optional[str] = None, + topic: Optional[str] = None, + subtopic: Optional[str] = None, + audience: Optional[str] = None, + content: Optional[Union[str, List[str]]] = None, + openAccess: Optional[bool] = None, + peerReviewed: Optional[bool] = None, + facets: Optional[Union[str, List[str]]] = None, groupRelatedEditions: Optional[bool] = None, groupVariantRecords: Optional[bool] = None, preferredLanguage: Optional[str] = None, + showHoldingsIndicators: Optional[bool] = None, + lat: Optional[float] = None, + lon: Optional[float] = None, + distance: Optional[int] = None, + unit: Optional[str] = None, orderBy: Optional[str] = "mostWidelyHeld", offset: Optional[int] = None, limit: Optional[int] = None, @@ -676,7 +692,7 @@ def search_brief_bibs( ) -> Optional[Response]: """ Send a GET request for brief bibliographic resources. - Uses /brief-bibs endpoint. + Uses /search/brief-bibs endpoint. Args: q: query in the form of a keyword search or @@ -700,6 +716,10 @@ def search_brief_bibs( '2000-2005' '2000,2005' heldByGroup: restricts to holdings held by group symbol + heldBySymbol: restricts response to holdings held by specified + institution symbol + heldByInstitutionID: restricts response to holdings held by specified + institution registryId inLanguage: restrics the response to the single specified language, example: 'fre' inCataloglanguage: restrics the response to specified @@ -718,6 +738,15 @@ def search_brief_bibs( spProgram: restricts responses to bibliographic records associated with particular shared print program + genre: genre to limit results to (ge index) + topic: topic to limit results to (s0 index) + subtopic: subtopic to limit results to (s1 index) + audience: audience to limit results to, + available values: 'juv', 'nonJuv' + content: content to limit results to + available values: 'fic', 'nonFic', 'bio' + openAccess: restricts response to just open access content + peerReviewed: restricts response to just peer reviewed content facets: list of facets to restrict responses groupRelatedEditions: whether or not use FRBR grouping, options: False, True (default is False) @@ -725,6 +754,13 @@ def search_brief_bibs( options: False, True (default False) preferredLanguage: language of metadata description, default value "en" (English) + showHoldingsIndicators: whether or not to show holdings indicators in + response. options: True, False, default is False + lat: limit to latitude, example: 37.502508 + lon: limit to longitute, example: -122.22702 + distance: distance from latitude and longitude + unit: unit of distance param; options: + 'M' (miles) or 'K' (kilometers) orderBy: results sort key; options: 'recency' @@ -742,21 +778,21 @@ def search_brief_bibs( hooks: Requests library hook system that can be used for signal event handling, see more at: https://requests.readthedocs.io/en/master/user/advanced/#event-hooks - Returns: `requests.Response` object - """ if not q: raise TypeError("Argument 'q' is requried to construct query.") - url = self._url_brief_bib_search() + url = self._url_search_brief_bibs() header = {"Accept": "application/json"} payload = { "q": q, "deweyNumber": deweyNumber, "datePublished": datePublished, "heldByGroup": heldByGroup, + "heldBySymbol": heldBySymbol, + "heldByInstitutionID": heldByInstitutionID, "inLanguage": inLanguage, "inCatalogLanguage": inCatalogLanguage, "materialType": materialType, @@ -765,10 +801,22 @@ def search_brief_bibs( "itemSubType": itemSubType, "retentionCommitments": retentionCommitments, "spProgram": spProgram, + "genre": genre, + "topic": topic, + "subtopic": subtopic, + "audience": audience, + "content": content, + "openAccess": openAccess, + "peerReviewed": peerReviewed, "facets": facets, "groupRelatedEditions": groupRelatedEditions, "groupVariantRecords": groupVariantRecords, "preferredLanguage": preferredLanguage, + "showHoldingsIndicators": showHoldingsIndicators, + "lat": lat, + "lon": lon, + "distance": distance, + "unit": unit, "orderBy": orderBy, "offset": offset, "limit": limit, @@ -820,27 +868,30 @@ def get_current_oclc_number( return query.response - def search_general_holdings( + def search_bibs_holdings( self, - oclcNumber: Union[int, str, None] = None, + oclcNumber: Optional[Union[int, str]] = None, isbn: Optional[str] = None, issn: Optional[str] = None, holdingsAllEditions: Optional[bool] = None, holdingsAllVariantRecords: Optional[bool] = None, preferredLanguage: Optional[str] = None, + holdingsFilterFormat: Optional[List[str]] = None, heldInCountry: Optional[str] = None, + heldInState: Optional[str] = None, heldByGroup: Optional[str] = None, + heldBySymbol: Optional[List[str]] = None, + heldByInstitutionID: Optional[List[int]] = None, + heldByLibraryType: Optional[List[str]] = None, lat: Optional[float] = None, lon: Optional[float] = None, distance: Optional[int] = None, unit: Optional[str] = None, - offset: Optional[int] = None, - limit: Optional[int] = None, hooks: Optional[Dict[str, Callable]] = None, ) -> Optional[Response]: """ - Given a known item gets summary of holdings. - Uses /bibs-summary-holdings endpoint. + Given a known item, get summary of holdings and brief bib record. + Uses /search/bibs-summary-holdings endpoint. Args: oclcNumber: OCLC bibliographic record number; can be @@ -855,19 +906,25 @@ def search_general_holdings( records; options: False, True preferredLanguage: language of metadata description; default 'en' (English) + holdingsFilterFormat: get holdings for specific itemSubType, + example: book-digital heldInCountry: restricts to holdings held by institutions in requested country + heldInState: limits to holdings held by institutions + in requested state, example: 'US-NY' heldByGroup: limits to holdings held by indicated by symbol group + heldBySymbol: limits to holdings held by institutions + indicated by institution symbol + heldByInstitutionID: limits to holdings held by institutions + indicated by institution registryID + heldByLibraryType: limits to holdings held by library type, + options: 'PUBLIC', 'ALL' lat: limit to latitude, example: 37.502508 lon: limit to longitute, example: -122.22702 distance: distance from latitude and longitude unit: unit of distance param; options: 'M' (miles) or 'K' (kilometers) - offset: start position of bibliographic records to - return; default 1 - limit: maximum nuber of records to return; - maximum 50, default 10 hooks: Requests library hook system that can be used for signal event handling, see more at: https://requests.readthedocs.io/en/master/user/advanced/#event-hooks @@ -882,7 +939,7 @@ def search_general_holdings( if oclcNumber is not None: oclcNumber = verify_oclc_number(oclcNumber) - url = self._url_member_general_holdings() + url = self._url_search_general_holdings() header = {"Accept": "application/json"} payload = { "oclcNumber": oclcNumber, @@ -891,14 +948,17 @@ def search_general_holdings( "holdingsAllEditions": holdingsAllEditions, "holdingsAllVariantRecords": holdingsAllVariantRecords, "preferredLanguage": preferredLanguage, + "holdingsFilterFormat": holdingsFilterFormat, "heldInCountry": heldInCountry, + "heldInState": heldInState, "heldByGroup": heldByGroup, + "heldBySymbol": heldBySymbol, + "heldByInstitutionID": heldByInstitutionID, + "heldByLibraryType": heldByLibraryType, "lat": lat, "lon": lon, "distance": distance, "unit": unit, - "offset": offset, - "limit": limit, } # prep request @@ -912,20 +972,18 @@ def search_general_holdings( def search_shared_print_holdings( self, - oclcNumber: Union[int, str, None] = None, + oclcNumber: Optional[Union[int, str]] = None, isbn: Optional[str] = None, issn: Optional[str] = None, heldByGroup: Optional[str] = None, heldInState: Optional[str] = None, - itemType: Optional[str] = None, - itemSubType: Optional[str] = None, - offset: Optional[int] = None, - limit: Optional[int] = None, + itemType: Optional[List[str]] = None, + itemSubType: Optional[List[str]] = None, hooks: Optional[Dict[str, Callable]] = None, ) -> Optional[Response]: """ Finds member shared print holdings for specified item. - Uses /bibs-retained-holdings endpoint. + Uses /search/bibs-retained-holdings endpoint. Args: oclcNumber: OCLC bibliographic record number; can be @@ -941,11 +999,9 @@ def search_shared_print_holdings( 'book' or 'vis') itemSubType: restricts results to specified item sub type examples: 'book-digital' or 'audiobook-cd' - offset: start position of bibliographic records to - return; default 1 - limit: maximum nuber of records to return; - maximum 50, default 10 - "" + hooks: Requests library hook system that can be used for + signal event handling, see more at: + https://requests.readthedocs.io/en/master/user/advanced/#event-hooks Returns: `requests.Response` object """ @@ -958,7 +1014,7 @@ def search_shared_print_holdings( if oclcNumber is not None: oclcNumber = verify_oclc_number(oclcNumber) - url = self._url_member_shared_print_holdings() + url = self._url_search_shared_print_holdings() header = {"Accept": "application/json"} payload = { "oclcNumber": oclcNumber, @@ -966,8 +1022,8 @@ def search_shared_print_holdings( "issn": issn, "heldByGroup": heldByGroup, "heldInState": heldInState, - "offset": offset, - "limit": limit, + "itemType": itemType, + "itemSubType": itemSubType, } # prep request diff --git a/tests/test_metadata_api.py b/tests/test_metadata_api.py index d0d68fd..b6b63c2 100644 --- a/tests/test_metadata_api.py +++ b/tests/test_metadata_api.py @@ -94,47 +94,38 @@ def test_url_search_base(self, stub_session): == "https://americas.metadata.api.oclc.org/worldcat/search/v1" ) - def test_url_shared_print_holdings(self, stub_session): + def test_url_search_shared_print_holdings(self, stub_session): assert ( - stub_session._url_member_shared_print_holdings() - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/bibs-retained-holdings" + stub_session._url_search_shared_print_holdings() + == "https://metadata.api.oclc.org/worldcat/search/bibs-retained-holdings" ) - def test_url_member_general_holdings(self, stub_session): + def test_url_search_general_holdings(self, stub_session): assert ( - stub_session._url_member_general_holdings() - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/bibs-summary-holdings" + stub_session._url_search_general_holdings() + == "https://metadata.api.oclc.org/worldcat/search/bibs-summary-holdings" ) - def test_url_brief_bib_search(self, stub_session): + def test_url_search_brief_bibs(self, stub_session): assert ( - stub_session._url_brief_bib_search() - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs" + stub_session._url_search_brief_bibs() + == "https://metadata.api.oclc.org/worldcat/search/brief-bibs" ) @pytest.mark.parametrize( - "argm, expectation", - [ - ( - "12345", - "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs/12345", - ), - ( - 12345, - "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs/12345", - ), - ], + "argm", + ["12345", 12345], ) - def test_url_brief_bib_oclc_number(self, argm, expectation, stub_session): + def test_url_search_brief_bibs_oclc_number(self, argm, stub_session): assert ( - stub_session._url_brief_bib_oclc_number(oclcNumber=argm) - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs/12345" + stub_session._url_search_brief_bibs_oclc_number(oclcNumber=argm) + == "https://metadata.api.oclc.org/worldcat/search/brief-bibs/12345" ) - def test_url_brief_bib_other_editions(self, stub_session): + def test_url_search_brief_bibs_other_editions(self, stub_session): assert ( - stub_session._url_brief_bib_other_editions(oclcNumber="12345") - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs/12345/other-editions" + stub_session._url_search_brief_bibs_other_editions(oclcNumber="12345") + == "https://metadata.api.oclc.org/worldcat/search/brief-bibs/12345/other-editions" ) def test_url_lhr_control_number(self, stub_session): @@ -215,21 +206,6 @@ def test_get_brief_bib_None_oclcNumber_passed(self, stub_session): with pytest.raises(InvalidOclcNumber): stub_session.get_brief_bib(oclcNumber=None) - @pytest.mark.http_code(200) - def test_get_brief_bib_with_stale_token( - self, mock_now, stub_session, mock_session_response - ): - stub_session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert stub_session.authorization.is_expired() is True - response = stub_session.get_brief_bib(oclcNumber=12345) - assert stub_session.authorization.token_expires_at == datetime.datetime( - 2020, 1, 1, 17, 19, 58, tzinfo=datetime.timezone.utc - ) - assert stub_session.authorization.is_expired() is False - assert response.status_code == 200 - @pytest.mark.http_code(206) def test_get_brief_bib_odd_206_http_code(self, stub_session, mock_session_response): with does_not_raise(): @@ -453,27 +429,12 @@ def test_holdings_unset_multi_institutions_stale_token( def test_search_brief_bibs_other_editions( self, stub_session, mock_session_response ): - assert stub_session.search_brief_bib_other_editions(12345).status_code == 200 - - @pytest.mark.http_code(200) - def test_search_brief_bibs_other_editions_stale_token( - self, mock_now, stub_session, mock_session_response - ): - stub_session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert stub_session.authorization.is_expired() is True - response = stub_session.search_brief_bib_other_editions(12345) - assert stub_session.authorization.token_expires_at == datetime.datetime( - 2020, 1, 1, 17, 19, 58, tzinfo=datetime.timezone.utc - ) - assert stub_session.authorization.is_expired() is False - assert response.status_code == 200 + assert stub_session.search_brief_bibs_other_editions(12345).status_code == 200 def test_search_brief_bibs_other_editions_invalid_oclc_number(self, stub_session): msg = "Argument 'oclcNumber' does not look like real OCLC #." with pytest.raises(InvalidOclcNumber) as exc: - stub_session.search_brief_bib_other_editions("odn12345") + stub_session.search_brief_bibs_other_editions("odn12345") assert msg in str(exc.value) @pytest.mark.http_code(200) @@ -486,21 +447,6 @@ def test_search_brief_bibs_missing_query(self, stub_session, argm): stub_session.search_brief_bibs(argm) assert "Argument 'q' is requried to construct query." in str(exc.value) - @pytest.mark.http_code(200) - def test_search_brief_bibs_with_stale_token( - self, mock_now, stub_session, mock_session_response - ): - stub_session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert stub_session.authorization.is_expired() is True - response = stub_session.search_brief_bibs(q="ti:foo") - assert stub_session.authorization.token_expires_at == datetime.datetime( - 2020, 1, 1, 17, 19, 58, tzinfo=datetime.timezone.utc - ) - assert stub_session.authorization.is_expired() is False - assert response.status_code == 200 - @pytest.mark.http_code(207) def test_get_current_oclc_number(self, stub_session, mock_session_response): assert ( @@ -527,36 +473,21 @@ def test_get_current_oclc_number_missing_numbers(self, stub_session, argm): assert err_msg in str(exc.value) @pytest.mark.http_code(200) - def test_search_general_holdings(self, stub_session, mock_session_response): - assert stub_session.search_general_holdings(oclcNumber=12345).status_code == 200 + def test_search_bibs_holdings(self, stub_session, mock_session_response): + assert stub_session.search_bibs_holdings(oclcNumber=12345).status_code == 200 - def test_search_general_holdings_missing_arguments(self, stub_session): + def test_search_bibs_holdings_missing_arguments(self, stub_session): msg = "Missing required argument. One of the following args are required: oclcNumber, issn, isbn" with pytest.raises(TypeError) as exc: - stub_session.search_general_holdings(holdingsAllEditions=True, limit=20) + stub_session.search_bibs_holdings(holdingsAllEditions=True) assert msg in str(exc.value) - def test_search_general_holdings_invalid_oclc_number(self, stub_session): + def test_search_bibs_holdings_invalid_oclc_number(self, stub_session): msg = "Argument 'oclcNumber' does not look like real OCLC #." with pytest.raises(InvalidOclcNumber) as exc: - stub_session.search_general_holdings(oclcNumber="odn12345") + stub_session.search_bibs_holdings(oclcNumber="odn12345") assert msg in str(exc.value) - @pytest.mark.http_code(200) - def test_search_general_holdings_with_stale_token( - self, mock_now, stub_session, mock_session_response - ): - stub_session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert stub_session.authorization.is_expired() is True - response = stub_session.search_general_holdings(oclcNumber=12345) - assert stub_session.authorization.token_expires_at == datetime.datetime( - 2020, 1, 1, 17, 19, 58, tzinfo=datetime.timezone.utc - ) - assert stub_session.authorization.is_expired() is False - assert response.status_code == 200 - @pytest.mark.http_code(200) def test_search_shared_print_holdings(self, stub_session, mock_session_response): assert ( @@ -567,7 +498,7 @@ def test_search_shared_print_holdings(self, stub_session, mock_session_response) def test_search_shared_print_holdings_missing_arguments(self, stub_session): msg = "Missing required argument. One of the following args are required: oclcNumber, issn, isbn" with pytest.raises(TypeError) as exc: - stub_session.search_shared_print_holdings(heldInState="NY", limit=20) + stub_session.search_shared_print_holdings(heldInState="NY") assert msg in str(exc.value) def test_search_shared_print_holdings_with_invalid_oclc_number_passsed( @@ -578,21 +509,6 @@ def test_search_shared_print_holdings_with_invalid_oclc_number_passsed( stub_session.search_shared_print_holdings(oclcNumber="odn12345") assert msg in str(exc.value) - @pytest.mark.http_code(200) - def test_search_shared_print_holdings_with_stale_token( - self, mock_now, stub_session, mock_session_response - ): - stub_session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert stub_session.authorization.is_expired() is True - response = stub_session.search_shared_print_holdings(oclcNumber=12345) - assert stub_session.authorization.token_expires_at == datetime.datetime( - 2020, 1, 1, 17, 19, 58, tzinfo=datetime.timezone.utc - ) - assert stub_session.authorization.is_expired() is False - assert response.status_code == 200 - @pytest.mark.webtest class TestLiveMetadataSession: @@ -641,7 +557,7 @@ def test_get_brief_bib_401_error(self, live_keys): principal_idns=os.getenv("WCPrincipalIDNS"), ) token.token_str = "invalid-token" - err_msg = "401 Client Error: Unauthorized for url: https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs/41266045" + err_msg = "401 Client Error: Unauthorized for url: https://metadata.api.oclc.org/worldcat/search/brief-bibs/41266045" with MetadataSession(authorization=token) as session: session.headers.update({"Authorization": "Bearer invalid-token"}) with pytest.raises(WorldcatRequestError) as exc: @@ -649,24 +565,6 @@ def test_get_brief_bib_401_error(self, live_keys): assert err_msg in str(exc.value) - def test_get_brief_bib_with_stale_token(self, live_keys): - token = WorldcatAccessToken( - key=os.getenv("WCKey"), - secret=os.getenv("WCSecret"), - scopes=os.getenv("WCScopes"), - principal_id=os.getenv("WCPrincipalID"), - principal_idns=os.getenv("WCPrincipalIDNS"), - ) - with MetadataSession(authorization=token) as session: - session.authorization.is_expired() is False - session.authorization.token_expires_at = datetime.datetime.now( - datetime.timezone.utc - ) - datetime.timedelta(0, 1) - assert session.authorization.is_expired() is True - response = session.get_brief_bib(oclcNumber=41266045) - assert session.authorization.is_expired() is False - assert response.status_code == 200 - def test_get_full_bib(self, live_keys): token = WorldcatAccessToken( key=os.getenv("WCKey"), @@ -815,7 +713,7 @@ def test_holdings_unset(self, live_keys): ] ) - def test_brief_bib_other_editions(self, live_keys): + def test_brief_bibs_other_editions(self, live_keys): fields = sorted(["briefRecords", "numberOfRecords"]) token = WorldcatAccessToken( key=os.getenv("WCKey"), @@ -826,7 +724,7 @@ def test_brief_bib_other_editions(self, live_keys): ) with MetadataSession(authorization=token) as session: - response = session.search_brief_bib_other_editions(41266045) + response = session.search_brief_bibs_other_editions(41266045) assert response.status_code == 200 assert sorted(response.json().keys()) == fields @@ -847,20 +745,19 @@ def test_search_brief_bibs(self, live_keys): inLanguage="eng", inCatalogLanguage="eng", itemType="book", - # itemSubType="printbook", + itemSubType=["book-printbook", "book-digital"], catalogSource="dlc", orderBy="mostWidelyHeld", limit=5, ) assert response.status_code == 200 assert sorted(response.json().keys()) == fields - # removed temp &itemSubType=printbook due to OCLC error/issue assert ( response.request.url - == "https://americas.metadata.api.oclc.org/worldcat/search/v1/brief-bibs?q=ti%3Azendegi+AND+au%3Aegan&inLanguage=eng&inCatalogLanguage=eng&catalogSource=dlc&itemType=book&orderBy=mostWidelyHeld&limit=5" + == "https://metadata.api.oclc.org/worldcat/search/brief-bibs?q=ti%3Azendegi+AND+au%3Aegan&inLanguage=eng&inCatalogLanguage=eng&catalogSource=dlc&itemType=book&itemSubType=book-printbook&itemSubType=book-digital&orderBy=mostWidelyHeld&limit=5" ) - def test_search_general_holdings(self, live_keys): + def test_search_bibs_holdings(self, live_keys): fields = sorted(["briefRecords", "numberOfRecords"]) token = WorldcatAccessToken( key=os.getenv("WCKey"), @@ -871,7 +768,7 @@ def test_search_general_holdings(self, live_keys): ) with MetadataSession(authorization=token) as session: - response = session.search_general_holdings(isbn="9781597801744") + response = session.search_bibs_holdings(isbn="9781597801744") assert response.status_code == 200 assert sorted(response.json().keys()) == fields