diff --git a/README.md b/README.md index dcfef8e..2a8682b 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,10 @@ pip install phylm 8.7 ``` -`phylm` also provides some tools around movie search results: +`phylm` also provides some tools around movie search results and more: ```python ->>> from phylm.tools import search_movies +>>> from phylm.tools import search_movies, get_streaming_providers >>> search_movies("the matrix") [{ 'title': 'The Matrix', @@ -51,6 +51,24 @@ pip install phylm 'imdb_id': '0234215', }, { ... +>>> get_streaming_providers("0234215", regions=["gb"]) +{ + 'gb': { + 'rent': [{ + 'display_priority': 8, + 'logo_path': '/pZgeSWpfvD59x6sY6stT5c6uc2h.jpg', + 'provider_id': 130, + 'provider_name': 'Sky Store', + }], + 'flatrate': [{ + 'display_priority': 8, + 'logo_path': '/ik9djlxNlex6sY6Kjsundc2h.jpg', + 'provider_id': 87, + 'provider_name': 'Netflix', + }] + }, { + ... +} ``` ## Help diff --git a/docs/tools.md b/docs/tools.md index 91f9e44..45752ee 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -2,7 +2,7 @@ # Search movies -For a given movie title query you can return a list of search results from `IMDb` +For a given movie title query you can return a list of search results from _IMDb_ through `search_movies`: ```python @@ -31,17 +31,17 @@ through `search_movies`: # TMDB -`phylm` also provides tools to interact with [The Movie Database](https://www.themoviedb.org/) (TMDb). +`phylm` also provides tools to interact with [The Movie Database](https://www.themoviedb.org/) (_TMDb_). !!! info "" - To use TMDB tools you'll need to sign up for an API key, instructions [here](https://developers.themoviedb.org/3). + To use _TMDb_ tools you'll need to sign up for an API key, instructions [here](https://developers.themoviedb.org/3). Once you have your key, export it as an env var called `TMDB_API_KEY` so that it's available to use in these tools. You also have the option of passing in the key as an argument to each function. ## Search movies -For a given movie title query you can return a list of search results from `TMDb` +For a given movie title query you can return a list of search results from _TMDb_ through `search_tmdb_movies`. Note that this search performs a lot quicker than the `imdb` `search_movies`. @@ -72,3 +72,32 @@ through `search_tmdb_movies`. Note that this search performs a lot quicker than rendering: show_signature_annotations: true heading_level: 3 + +## Get streaming providers + +For a given movie _TMDb_ id and list of regions, you can return a list of streaming +providers from _TMDb_ via _Just Watch_ through `get_streaming_providers`. + +```python +>>> from phylm.tools import get_streaming_providers +>>> get_streaming_providers(tmdb_movie_id="438631", regions=["gb"], api_key="abc") +{ + 'gb': { + 'link': 'https://www.themoviedb.org/movie/438631-dune/watch?locale=GB', + 'rent': [{ + 'display_priority': 8, + 'logo_path': '/pZgeSWpfvD59x6sY6stT5c6uc2h.jpg', + 'provider_id': 130, + 'provider_name': 'Sky Store', + }], + }, +} +``` + +Consult the [TMDb docs](https://developers.themoviedb.org/3/movies/get-movie-watch-providers) +for more information on the data that's returned. + +::: phylm.tools.get_streaming_providers + rendering: + show_signature_annotations: true + heading_level: 3 diff --git a/noxfile.py b/noxfile.py index 1fbaf14..aad758f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -117,7 +117,7 @@ def mypy(session: Session) -> None: """Type-check using mypy.""" args = session.posargs or ["src", "tests"] session.install(".") - session.install("mypy", "pytest") + session.install("mypy", "pytest", "types-requests") session.run("mypy", *args) if not session.posargs: session.run("mypy", f"--python-executable={sys.executable}", "noxfile.py") diff --git a/pyproject.toml b/pyproject.toml index 67f1802..de2a0a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "phylm" -version = "4.2.2" +version = "4.3.0" description = "Phylm" authors = ["Dom Batten "] license = "MIT" diff --git a/src/phylm/clients/tmdb.py b/src/phylm/clients/tmdb.py index d7da3d0..8fd7c71 100644 --- a/src/phylm/clients/tmdb.py +++ b/src/phylm/clients/tmdb.py @@ -33,9 +33,32 @@ def search_movies(self, query: str) -> List[Dict[str, Any]]: "api_key": self.api_key, "language": "en-GB", "query": query, - "include_adult": False, + "include_adult": "false", "region": "GB", } res = self.session.get(f"{self._base}/search/movie", params=payload) results: List[Dict[str, Any]] = res.json()["results"] return results + + def get_streaming_providers( + self, movie_id: str, regions: List[str] + ) -> Dict[str, Any]: + """Return a list of streaming providers for a given movie. + + Args: + movie_id: the tmdb id of the movie + regions: a list of regions to trim down the return list + + Returns: + Dict[str, Any]: a dictionary of streaming providers, keyed by region name + """ + payload = {"api_key": self.api_key} + res = self.session.get( + f"{self._base}/movie/{movie_id}/watch/providers", params=payload + ) + + res.raise_for_status() + + results: Dict[str, Any] = res.json()["results"] + + return {key: results[key.upper()] for key in regions} diff --git a/src/phylm/tools.py b/src/phylm/tools.py index 9692e0c..bb43644 100644 --- a/src/phylm/tools.py +++ b/src/phylm/tools.py @@ -36,6 +36,26 @@ def search_movies(query: str) -> List[Dict[str, Union[str, int]]]: ] +def _initialize_tmdb_client(api_key: Optional[str] = None) -> TmdbClient: + """Initialize and return a TmdbClient. + + Args: + api_key: an optional api_key to take precedence over an env var key + + Raises: + NoTMDbApiKeyError: when no api_key has been provided + + Returns: + TmdbClient: an authorized Tmdb client + """ + tmdb_api_key = api_key or os.environ.get("TMDB_API_KEY") + + if not tmdb_api_key: + raise NoTMDbApiKeyError("An `api_key` must be provided to use this service") + + return TmdbClient(api_key=tmdb_api_key) + + def search_tmdb_movies( query: str, api_key: Optional[str] = None ) -> List[Dict[str, Any]]: @@ -46,17 +66,30 @@ def search_tmdb_movies( api_key: an api_key can either be provided here or through a TMDB_API_KEY env var - Raises: - NoTMDbApiKeyError: when no api_key has been provided - Returns: List[Dict[str, Any]]: the search results """ - tmdb_api_key = api_key or os.environ.get("TMDB_API_KEY") + client = _initialize_tmdb_client(api_key=api_key) - if not tmdb_api_key: - raise NoTMDbApiKeyError("An `api_key` must be provided to use this service") + return client.search_movies(query=query) - client = TmdbClient(api_key=tmdb_api_key) - return client.search_movies(query=query) +def get_streaming_providers( + tmdb_movie_id: str, + regions: List[str], + api_key: Optional[str] = None, +) -> Dict[str, Any]: + """Return a list of streaming providers for a given movie. + + Args: + tmdb_movie_id: the tmdb id of the movie + regions: a list of regions to trim down the return list + api_key: an api_key can either be provided here or through a TMDB_API_KEY env + var + + Returns: + Dict[str, Any]: a dictionary of streaming providers, keyed by region name + """ + client = _initialize_tmdb_client(api_key=api_key) + + return client.get_streaming_providers(movie_id=tmdb_movie_id, regions=regions) diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/matrix_providers.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/matrix_providers.yaml new file mode 100644 index 0000000..2e855e0 --- /dev/null +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/matrix_providers.yaml @@ -0,0 +1,134 @@ +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/movie/603/watch/providers + response: + body: + string: !!binary | + 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 + 38z8AAA= + 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=28800 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json;charset=utf-8 + Date: + - Fri, 19 Nov 2021 12:29:06 GMT + ETag: + - W/"051aaa37d61d82e502fec7c75fa8fb5b" + Server: + - openresty + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + Via: + - 1.1 cd8f4ac94836dc54b056844b56c2bb70.cloudfront.net (CloudFront) + X-Amz-Cf-Id: + - s8gnJ7U710L605Db0xE0GqyuojnJOGtyc5Tr_J15Kc41ykLr8o6Nqg== + X-Amz-Cf-Pop: + - LHR62-C5 + X-Cache: + - Miss from cloudfront + X-Memc: + - HIT + X-Memc-Age: + - "13266" + X-Memc-Expires: + - "3121" + X-Memc-Key: + - ef74d3db9d756ce3497f67fdbcefc39de41f661e + 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 265733c..8195f4b 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-GB&query=aslkdjaskldjaslkdjaslkdjasd®ion=GB response: body: string: !!binary | @@ -34,7 +34,7 @@ interactions: Content-Type: - application/json;charset=utf-8 Date: - - Thu, 18 Nov 2021 13:36:12 GMT + - Fri, 19 Nov 2021 14:23:36 GMT Server: - openresty Transfer-Encoding: @@ -42,9 +42,9 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 f781469e78b7a441c6f692b1629e1519.cloudfront.net (CloudFront) + - 1.1 68126347056de2d05be3dd362ccba987.cloudfront.net (CloudFront) X-Amz-Cf-Id: - - ZzoH_Hbughh50zblladdE7sdS_RFUstsVkCVQHAykhgmOgpaqP1jmQ== + - MZgNnx0ZejBqMqIgXJ86OP5OtMBnbboSC5jTI8w_I5BKmv2vpMLJLA== X-Amz-Cf-Pop: - LHR50-C1 X-Cache: diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/no_results_providers.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/no_results_providers.yaml new file mode 100644 index 0000000..bd14208 --- /dev/null +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/no_results_providers.yaml @@ -0,0 +1,63 @@ +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/movie/-1/watch/providers + response: + body: + string: !!binary | + H4sIAAAAAAAAAz3KIQ6AMAxG4as01QQDinPgyeh+QIw1rKsghLszhXxf3sPmIjDjaQvJ0LHVUN0W + 0QiehvGHs01hb8bzASow9SKgW73F5bCKSKKeImWttII29Rx7fj94apY6ZAAAAA== + 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=28800 + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json;charset=utf-8 + Date: + - Fri, 19 Nov 2021 12:36:20 GMT + Server: + - openresty + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + Via: + - 1.1 9c46a92c66fe21525310bd5d2f471e46.cloudfront.net (CloudFront) + X-Amz-Cf-Id: + - eGBK3-_IiZnsDjldxkR9DDZX9rq9QJ3aSOotB9ZX7VWpkbUnkDRuTA== + X-Amz-Cf-Pop: + - LHR61-C2 + X-Cache: + - Error from cloudfront + X-Memc: + - MISS + X-Memc-Age: + - "0" + X-Memc-Expires: + - "14687" + X-Memc-Key: + - eae09eb6e89d7ab563e7bd6dc85e159fb173badd + status: + code: 404 + message: Not Found +version: 1 diff --git a/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml b/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml index 45c04b0..7f57bfa 100644 --- a/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml +++ b/tests/fixtures/vcr_cassettes/clients/tmdb/the_matrix.yaml @@ -11,85 +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-GB&query=The+Matrix®ion=GB response: body: string: !!binary | - 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 + pzhmMgAA headers: Access-Control-Allow-Methods: - GET, HEAD, POST, PUT, DELETE, OPTIONS @@ -98,8 +105,6 @@ interactions: Access-Control-Expose-Headers: - ETag, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After, Content-Length, Content-Range - Age: - - "54" Cache-Control: - public, max-age=600 Connection: @@ -109,7 +114,7 @@ interactions: Content-Type: - application/json;charset=utf-8 Date: - - Thu, 18 Nov 2021 13:32:48 GMT + - Fri, 19 Nov 2021 14:23:26 GMT Server: - openresty Transfer-Encoding: @@ -117,13 +122,13 @@ interactions: Vary: - Accept-Encoding Via: - - 1.1 a4ba6141247f3b441c87ee1a49ec2851.cloudfront.net (CloudFront) + - 1.1 f1b5ae62d9afc4ed1ebb4ac99a508445.cloudfront.net (CloudFront) X-Amz-Cf-Id: - - gF2BvyhPhl7nmCbKnW6QPgVc4yCb8q2BUsuosLPc8u1HFv3dMG1wAw== + - n0cFBejLSVn_QpriksKTnni-WGO0lSz7j7CW62BD2OQ_1co1Wm7CnA== X-Amz-Cf-Pop: - - LHR52-C1 + - LHR50-C1 X-Cache: - - Hit from cloudfront + - Miss from cloudfront status: code: 200 message: OK diff --git a/tests/unit/clients/test_tmdb.py b/tests/unit/clients/test_tmdb.py index 6cdb503..fc2860b 100644 --- a/tests/unit/clients/test_tmdb.py +++ b/tests/unit/clients/test_tmdb.py @@ -1,5 +1,7 @@ """Tests for the Tmdb client.""" +import pytest import vcr +from requests.exceptions import HTTPError from tests.conftest import FIXTURES_DIR from phylm.clients.tmdb import TmdbClient @@ -41,3 +43,40 @@ def test_no_results(self) -> None: results = client.search_movies(query="aslkdjaskldjaslkdjaslkdjasd") assert len(results) == 0 + + +class TestStreamingProviders: + """Tests for the `get_streaming_providers` method.""" + + @vcr.use_cassette( + f"{VCR_FIXTURES_DIR}/matrix_providers.yaml", filter_query_parameters=["api_key"] + ) + def test_results(self) -> None: + """ + Given a movie id, + When the `get_streaming_providers` method is invoked with the id, + Then search results are returned from the api and keyed by region name + """ + client = TmdbClient(api_key="dummy_key") + + results = client.get_streaming_providers(movie_id="603", regions=["gb", "fr"]) + + assert "fr" in results + assert "gb" in results + assert "flatrate" in results["gb"] + assert len(results["gb"]["flatrate"]) + + @vcr.use_cassette( + f"{VCR_FIXTURES_DIR}/no_results_providers.yaml", + filter_query_parameters=["api_key"], + ) + def test_no_results(self) -> None: + """ + Given an unrecognized movie id, + When the `get_streaming_providers` method is invoked with the id, + Then search results are returned from the api + """ + client = TmdbClient(api_key="dummy_key") + + with pytest.raises(HTTPError): + client.get_streaming_providers(movie_id="-1", regions=["gb"]) diff --git a/tests/unit/tools/test_tools.py b/tests/unit/tools/test_tools.py index 5fb9a98..fbba66e 100644 --- a/tests/unit/tools/test_tools.py +++ b/tests/unit/tools/test_tools.py @@ -9,6 +9,7 @@ from imdb.Movie import Movie from phylm.errors import NoTMDbApiKeyError +from phylm.tools import get_streaming_providers from phylm.tools import search_movies from phylm.tools import search_tmdb_movies @@ -110,3 +111,30 @@ def test_with_api_key_arg_preferred( assert results == [{"title": "The Matrix"}] mock_tmdb_client_class.assert_called_once_with(api_key=api_key) + + +class TestGetStreamingProviders: + """Tests for the `get_streaming_providers` method.""" + + @patch(f"{TOOLS_MODULE_PATH}.TmdbClient", autospec=True) + def test_success( + self, + mock_initialize_client: MagicMock, + ) -> None: + """ + Given an api_key supplied as an arg, + When the `get_streaming_providers` function is invoked, + Then the results are returned + """ + api_key = "nice_key" + mock_tmdb_client = mock_initialize_client.return_value + mock_tmdb_client.get_streaming_providers.return_value = {"gb": "Netflix"} + + results = get_streaming_providers( + tmdb_movie_id="123", + regions=["gb"], + api_key=api_key, + ) + + assert results == {"gb": "Netflix"} + mock_initialize_client.assert_called_once_with(api_key=api_key)