11"""Module responsible for creating GraphQL queries and parsing responses from JustWatch GraphQL API.
2- Parsed responses are returned as Python NamedTuples for easier access.
3- Currently supported queries are:
4-
5- - ``GetTitleNode``
6- - ``GetSearchTitles``
7- - ``GetTitleOffers``
8-
9- """
2+ Parsed responses are returned as Python NamedTuples for easier access."""
103
114from typing import NamedTuple
125
@@ -158,61 +151,134 @@ class OfferPackage(NamedTuple):
158151 Contains information about platform on which given offer is available."""
159152
160153 id : str
154+ """ID, defines whole platform on which this offer is available, not a single offer."""
155+
161156 package_id : int
157+ """Package ID, defines whole platform on which this offer is available, not a single offer."""
158+
162159 name : str
160+ """Name of the platform in format suited to display for users."""
161+
163162 technical_name : str
163+ """Technical name of the platform, usually all lowercase with no whitespaces."""
164+
164165 icon : str
166+ """Platform icon URL."""
165167
166168
167169class Offer (NamedTuple ):
168170 """Parsed single offer from JustWatch GraphQL API for single entry.
169171 One platform can have multiple offers for one entry available, e.g. renting, buying, etc."""
170172
171173 id : str
174+ """Offer ID."""
175+
172176 monetization_type : str
177+ """Type of monetization of this offer, e.g. ``FLATRATE`` (streaming), ``RENT``, ``BUY``."""
178+
173179 presentation_type : str
180+ """Quality of media in this offer, e.g. ``HD``, ``SD``, ``4K``."""
181+
174182 price_string : str | None
183+ """Current price as a string with currency, suitable for displaying to users.
184+ Format can change based on used ``language`` argument."""
185+
175186 price_value : float | None
187+ """Current price as a numeric value."""
188+
176189 price_currency : str
190+ """Represents only currency, without price, or value."""
191+
177192 last_change_retail_price_value : float | None
193+ """Previous available price if change in price was recorded."""
194+
178195 type : str
196+ """Type of offer."""
197+
179198 package : OfferPackage
199+ """Information about platform on which this offer is available."""
200+
180201 url : str
202+ """URL to this offer."""
203+
181204 element_count : int
205+ """Element count, usually 0."""
206+
182207 available_to : str | None
208+ """Date until which this offer will be available."""
209+
183210 deeplink_roku : str | None
211+ """Deeplink to this offer in Roku."""
212+
184213 subtitle_languages : list [str ]
214+ """List of 2-letter language codes of available subtitles, e.g. ``["en", "pt", "de"]``."""
215+
185216 video_technology : list [str ]
217+ """List of known video technologies available in this offer, e.g. ``DOLBY_VISION``."""
218+
186219 audio_technology : list [str ]
220+ """List of known audio technologies available in this offer, e.g. ``DOLBY_ATMOS``."""
221+
187222 audio_languages : list [str ]
223+ """List of 2-letter language codes of available audio tracks, e.g. ``["en", "pt", "de"]``."""
188224
189225
190226class MediaEntry (NamedTuple ):
191227 """Parsed response from JustWatch GraphQL API for "GetSearchTitles" query for single entry."""
192228
193229 entry_id : str
230+ """Entry ID, contains type code and numeric ID."""
231+
194232 object_id : int
233+ """Object ID, the numeric part of full entry ID."""
234+
195235 object_type : str
236+ """Type of entry, e.g. ``MOVIE``, ``SHOW``."""
237+
196238 title : str
239+ """Full title."""
240+
197241 url : str
242+ """URL to JustWatch with details for this entry."""
243+
198244 release_year : int
245+ """Release year as a number."""
246+
199247 release_date : str
248+ """Full release date as a string, e.g. ``2013-12-16``."""
249+
200250 runtime_minutes : int
251+ """Runtime in minutes."""
252+
201253 short_description : str
254+ """Short description of this entry."""
255+
202256 genres : list [str ]
257+ """List of genre codes for this entry, e.g. ``["rly"]``, ``["cmy", "drm", "rma"]``."""
258+
203259 imdb_id : str | None
260+ """ID of this entry in IMDB."""
261+
204262 poster : str | None
263+ """URL to poster for this ID."""
264+
205265 backdrops : list [str ]
266+ """List of URLs for backdrops (full screen images to use as background)."""
267+
206268 offers : list [Offer ]
269+ """List of available offers for this entry, empty if there are no available offers."""
207270
208271
209272def prepare_search_request (
210273 title : str , country : str , language : str , count : int , best_only : bool
211274) -> dict :
212275 """Prepare search request for JustWatch GraphQL API.
213276 Creates a ``GetSearchTitles`` GraphQL query.
277+
214278 Country code should be two uppercase letters, however it will be auto-converted to uppercase.
215279
280+ Meant to be used together with :func:`parse_search_response`.
281+
216282 Args:
217283 title: title to search
218284 country: country to search for offers
@@ -244,8 +310,11 @@ def prepare_search_request(
244310def parse_search_response (json : dict ) -> list [MediaEntry ]:
245311 """Parse response from search query from JustWatch GraphQL API.
246312 Parses response for ``GetSearchTitles`` query.
313+
247314 If API didn't return any data, then an empty list is returned.
248315
316+ Meant to be used together with :func:`prepare_search_request`.
317+
249318 Args:
250319 json: JSON returned by JustWatch GraphQL API
251320
@@ -258,8 +327,11 @@ def parse_search_response(json: dict) -> list[MediaEntry]:
258327def prepare_details_request (node_id : str , country : str , language : str , best_only : bool ) -> dict :
259328 """Prepare a details request for specified node ID to JustWatch GraphQL API.
260329 Creates a ``GetTitleNode`` GraphQL query.
330+
261331 Country code should be two uppercase letters, however it will be auto-converted to uppercase.
262332
333+ Meant to be used together with :func:`parse_details_response`.
334+
263335 Args:
264336 node_id: node ID of entry to get details for
265337 country: country to search for offers
@@ -289,9 +361,12 @@ def prepare_details_request(node_id: str, country: str, language: str, best_only
289361def parse_details_response (json : any ) -> MediaEntry | None :
290362 """Parse response from details query from JustWatch GraphQL API.
291363 Parses response for ``GetTitleNode`` query.
364+
292365 If API responded with an internal error (mostly due to not found node ID),
293366 then ``None`` will be returned instead.
294367
368+ Meant to be used together with :func:`prepare_details_request`.
369+
295370 Args:
296371 json: JSON returned by JustWatch GraphQL API
297372
@@ -308,9 +383,12 @@ def prepare_offers_for_countries_request(
308383 """Prepare an offers request for specified node ID and for all specified countries
309384 to JustWatch GraphQL API.
310385 Creates a ``GetTitleOffers`` GraphQL query.
386+
311387 Country codes should be two uppercase letters, however they will be auto-converted to uppercase.
312388 ``countries`` argument mustn't be empty.
313389
390+ Meant to be used together with :func:`parse_offers_for_countries_response`.
391+
314392 Args:
315393 node_id: node ID of entry to get details for
316394 countries: list of country codes to search for offers
@@ -341,11 +419,14 @@ def prepare_offers_for_countries_request(
341419def parse_offers_for_countries_response (json : any , countries : set [str ]) -> dict [str , list [Offer ]]:
342420 """Parse response from offers query from JustWatch GraphQL API.
343421 Parses response for ``GetTitleOffers`` query.
422+
344423 Response if searched for country codes passed as ``countries`` argument.
345424 Countries in JSON response which are not present in ``countries`` set will be ignored.
346425 If response doesn't have offers for a country, then that country still will be present
347426 in returned dict, just with an empty list as value.
348427
428+ Meant to be used together with :func:`prepare_offers_for_countries_request`.
429+
349430 Args:
350431 json: JSON returned by JustWatch GraphQL API
351432 countries: set of countries to look for in API response
0 commit comments