diff --git a/docs/tools.md b/docs/tools.md index 45752ee..9379463 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -58,7 +58,7 @@ through `search_tmdb_movies`. Note that this search performs a lot quicker than 'overview': 'Set in the 22nd century, The Matrix tells the story of a computer hacker...' 'popularity': 79.956, 'poster_path': '/f89U3ADr1oiB1s9GkdPOEpXUk5H.jpg', - 'release_date': '1999-06-11', + 'release_date': '1999-03-30', 'title': 'The Matrix', 'video': False, 'vote_average': 8.2, @@ -68,6 +68,23 @@ through `search_tmdb_movies`. Note that this search performs a lot quicker than } ``` +By default the `release_date` will be the US release date. You can specify a different +region by providing a region argument: + +```python +>>> from phylm.tools import search_tmdb_movies +>>> search_tmdb_movies("The Matrix", region="gb") +[{ + 'id': 603, + ... + 'release_date': '1999-06-11', + 'title': 'The Matrix', + ... +}, { + ... +} +``` + ::: phylm.tools.search_tmdb_movies rendering: show_signature_annotations: true diff --git a/pyproject.toml b/pyproject.toml index de2a0a0..455312d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "phylm" -version = "4.3.0" +version = "4.3.1" description = "Phylm" authors = ["Dom Batten "] license = "MIT" diff --git a/src/phylm/clients/tmdb.py b/src/phylm/clients/tmdb.py index 8fd7c71..17eb5f0 100644 --- a/src/phylm/clients/tmdb.py +++ b/src/phylm/clients/tmdb.py @@ -20,23 +20,27 @@ def __init__(self, api_key: str) -> None: self.api_key = api_key self._base = "https://api.themoviedb.org/3" - def search_movies(self, query: str) -> List[Dict[str, Any]]: + def search_movies(self, query: str, region: str = "us") -> List[Dict[str, Any]]: """Search for movies. Args: query: the search query + region: the region for the query, affects the release date value Returns: - Any: the search results + List[Dict[str, Any]]: the search results """ payload = { "api_key": self.api_key, - "language": "en-GB", + "language": "en-US", "query": query, "include_adult": "false", - "region": "GB", + "region": region.upper(), } res = self.session.get(f"{self._base}/search/movie", params=payload) + + res.raise_for_status() + results: List[Dict[str, Any]] = res.json()["results"] return results diff --git a/src/phylm/tools.py b/src/phylm/tools.py index bb43644..0993f03 100644 --- a/src/phylm/tools.py +++ b/src/phylm/tools.py @@ -57,7 +57,7 @@ def _initialize_tmdb_client(api_key: Optional[str] = None) -> TmdbClient: def search_tmdb_movies( - query: str, api_key: Optional[str] = None + query: str, api_key: Optional[str] = None, region: str = "us" ) -> List[Dict[str, Any]]: """Search for movies on TMDb. @@ -65,13 +65,16 @@ def search_tmdb_movies( query: the query string api_key: an api_key can either be provided here or through a TMDB_API_KEY env var + region: an optional region to provide with the search request, affects the + release_date value returned, must be provided in ISO 3166-1 format (eg. + "us" or "gb") Returns: List[Dict[str, Any]]: the search results """ client = _initialize_tmdb_client(api_key=api_key) - return client.search_movies(query=query) + return client.search_movies(query=query, region=region) def get_streaming_providers( diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_key.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_key.yaml new file mode 100644 index 0000000..c5428e2 --- /dev/null +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_key.yaml @@ -0,0 +1,53 @@ +interactions: + - request: + body: null + headers: + Accept: + - "*/*" + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + method: GET + uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-US&query=The+Matrix®ion=US + response: + body: + string: + '{"status_code":7,"status_message":"Invalid API key: You must be granted + a valid key.","success":false} + + ' + headers: + Access-Control-Allow-Methods: + - GET, HEAD, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - ETag, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After, + Content-Length, Content-Range + Cache-Control: + - public, max-age=300 + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Sat, 20 Nov 2021 10:19:07 GMT + Server: + - openresty + Transfer-Encoding: + - chunked + Via: + - 1.1 bdbd00aed84ab2a1b2623adb63c9331f.cloudfront.net (CloudFront) + X-Amz-Cf-Id: + - oeHPChCFqG9v3RhOYMdD7zFVgpREaR4uyeTjy26ALcug3h1GcYPHOg== + X-Amz-Cf-Pop: + - LHR61-P1 + X-Cache: + - Error from cloudfront + status: + code: 401 + message: Unauthorized +version: 1 diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_region.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_region.yaml new file mode 100644 index 0000000..0cfb198 --- /dev/null +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/invalid_region.yaml @@ -0,0 +1,137 @@ +interactions: + - request: + body: null + headers: + Accept: + - "*/*" + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-requests/2.26.0 + method: GET + uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-US&query=The+Matrix®ion=XX + response: + body: + string: !!binary | + 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 + 3mR1hzIAAA== + headers: + Access-Control-Allow-Methods: + - GET, HEAD, POST, PUT, DELETE, OPTIONS + Access-Control-Allow-Origin: + - "*" + Access-Control-Expose-Headers: + - ETag, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After, + Content-Length, Content-Range + Age: + - "65" + Cache-Control: + - public, max-age=600 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json;charset=utf-8 + Date: + - Sat, 20 Nov 2021 10:16:24 GMT + Server: + - openresty + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + Via: + - 1.1 774a6d3757afff80abe764a68fbbe545.cloudfront.net (CloudFront) + X-Amz-Cf-Id: + - yeb9F8W_my08XUB0tj3_7DWMS65xo3oVnADXkSANNZSm6XSSVIJtRw== + X-Amz-Cf-Pop: + - LHR50-C1 + X-Cache: + - Hit from cloudfront + status: + code: 200 + message: OK +version: 1 diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/no_results.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/no_results.yaml index 8195f4b..888eb36 100644 --- a/tests/fixtures/vcr_cassettes/clients/tmdb/no_results.yaml +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/no_results.yaml @@ -11,7 +11,7 @@ interactions: User-Agent: - python-requests/2.26.0 method: GET - uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-GB&query=aslkdjaskldjaslkdjaslkdjasd®ion=GB + uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-US&query=aslkdjaskldjaslkdjaslkdjasd®ion=US response: body: string: !!binary | @@ -34,7 +34,7 @@ interactions: Content-Type: - application/json;charset=utf-8 Date: - - Fri, 19 Nov 2021 14:23:36 GMT + - Sat, 20 Nov 2021 10:13:00 GMT Server: - openresty Transfer-Encoding: @@ -42,11 +42,11 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 68126347056de2d05be3dd362ccba987.cloudfront.net (CloudFront) + - 1.1 38625201ad7f896d72a7ab055328881f.cloudfront.net (CloudFront) X-Amz-Cf-Id: - - MZgNnx0ZejBqMqIgXJ86OP5OtMBnbboSC5jTI8w_I5BKmv2vpMLJLA== + - 4PLVZIxaLwY7MEg16ZKq9lvl2_7L69aF_s3fDB7kmtMiKdyPxYC2IA== X-Amz-Cf-Pop: - - LHR50-C1 + - LHR52-C1 X-Cache: - Miss from cloudfront status: diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml index 7f57bfa..ac2b480 100644 --- a/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml @@ -11,92 +11,92 @@ interactions: User-Agent: - python-requests/2.26.0 method: GET - uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-GB&query=The+Matrix®ion=GB + uri: https://api.themoviedb.org/3/search/movie?include_adult=false&language=en-US&query=The+Matrix®ion=US response: body: string: !!binary | - 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 - pzhmMgAA + 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 + /w9k3lAFhzIAAA== headers: Access-Control-Allow-Methods: - GET, HEAD, POST, PUT, DELETE, OPTIONS @@ -114,7 +114,7 @@ interactions: Content-Type: - application/json;charset=utf-8 Date: - - Fri, 19 Nov 2021 14:23:26 GMT + - Sat, 20 Nov 2021 10:11:44 GMT Server: - openresty Transfer-Encoding: @@ -122,11 +122,11 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 f1b5ae62d9afc4ed1ebb4ac99a508445.cloudfront.net (CloudFront) + - 1.1 41d0ebcbc3faecee108d3cf72e708159.cloudfront.net (CloudFront) X-Amz-Cf-Id: - - n0cFBejLSVn_QpriksKTnni-WGO0lSz7j7CW62BD2OQ_1co1Wm7CnA== + - b4I4FmwssKOdz_sstwdfJZn58MkDMoOVxMLFs5WMRfE_hu0gcj7mxg== X-Amz-Cf-Pop: - - LHR50-C1 + - LHR62-C5 X-Cache: - Miss from cloudfront status: diff --git a/tests/unit/clients/test_tmdb.py b/tests/unit/clients/test_tmdb.py index fc2860b..8b23d5f 100644 --- a/tests/unit/clients/test_tmdb.py +++ b/tests/unit/clients/test_tmdb.py @@ -27,7 +27,7 @@ def test_results(self) -> None: assert len(results) assert results[0]["title"] == "The Matrix" - assert results[0]["release_date"] == "1999-06-11" + assert results[0]["release_date"] == "1999-03-30" @vcr.use_cassette( f"{VCR_FIXTURES_DIR}/no_results.yaml", filter_query_parameters=["api_key"] @@ -44,6 +44,33 @@ def test_no_results(self) -> None: assert len(results) == 0 + @vcr.use_cassette( + f"{VCR_FIXTURES_DIR}/different_region.yaml", filter_query_parameters=["api_key"] + ) + def test_override_region(self) -> None: + """ + When the `search_movies` method is invoked with the region, + Then the region is passed to the api request + """ + client = TmdbClient(api_key="9017d5457c4e8ec5f0999d1b10012ae1") + + results = client.search_movies(query="The Matrix", region="gb") + + assert results[0]["release_date"] == "1999-06-11" + + @vcr.use_cassette( + f"{VCR_FIXTURES_DIR}/invalid_key.yaml", filter_query_parameters=["api_key"] + ) + def test_api_error(self) -> None: + """ + When the `search_movies` method is invoked with an invalid api_key, + Then an HTTP error is raised + """ + client = TmdbClient(api_key="not_a_key") + + with pytest.raises(HTTPError): + client.search_movies(query="The Matrix") + class TestStreamingProviders: """Tests for the `get_streaming_providers` method.""" diff --git a/tests/unit/tools/test_tools.py b/tests/unit/tools/test_tools.py index fbba66e..982d308 100644 --- a/tests/unit/tools/test_tools.py +++ b/tests/unit/tools/test_tools.py @@ -76,6 +76,9 @@ def test_with_api_key_as_arg(self, mock_tmdb_client_class: MagicMock) -> None: assert results == [{"title": "The Matrix"}] mock_tmdb_client_class.assert_called_once_with(api_key=api_key) + mock_tmdb_client.search_movies.assert_called_once_with( + query="The Matrix", region="us" + ) @patch(f"{TOOLS_MODULE_PATH}.TmdbClient", autospec=True) @patch.dict(os.environ, {"TMDB_API_KEY": "nice_key"}, clear=True) @@ -112,6 +115,24 @@ def test_with_api_key_arg_preferred( assert results == [{"title": "The Matrix"}] mock_tmdb_client_class.assert_called_once_with(api_key=api_key) + @patch(f"{TOOLS_MODULE_PATH}.TmdbClient", autospec=True) + def test_different_region(self, mock_tmdb_client_class: MagicMock) -> None: + """ + Given a region supplied as an arg, + When the `search_tmdb_movies` function is invoked, + Then the region is passed to the `search_movies` method + """ + api_key = "nice_key" + mock_tmdb_client = mock_tmdb_client_class.return_value + mock_tmdb_client.search_movies.return_value = [{"title": "The Matrix"}] + + results = search_tmdb_movies(query="The Matrix", api_key=api_key, region="gb") + + assert results == [{"title": "The Matrix"}] + mock_tmdb_client.search_movies.assert_called_once_with( + query="The Matrix", region="gb" + ) + class TestGetStreamingProviders: """Tests for the `get_streaming_providers` method."""