apis.shows

  1VERSION = 2026.1 # initial version!
  2
  3try:
  4    import utilities
  5    utilities.modify_system_path()
  6except:
  7    pass
  8import os
  9import requests
 10import base64
 11import time
 12import json
 13import random
 14import pickle
 15import math
 16from urllib.parse import quote
 17
 18from apis import secret_tokens
 19
 20TMDB_CACHE = "tmdb_cache.pkl"
 21__docformat__ = "google"
 22
 23__all__ = [
 24    "get_genres",
 25    "get_on_air",
 26    "get_popular",
 27    "get_recommendations",    
 28    "get_reviews",
 29    "get_streamers",
 30    "lookup_show",
 31    "generate_show_table",
 32    "generate_watchlist"
 33]
 34
 35
 36def get_on_air(limit: int = 10,
 37                    language: str = "en-US", 
 38                    region: str = "US", 
 39                    debug: bool = True, 
 40                    **kwargs):
 41    """
 42    Retrieves a list of the shows (dictionaries) currently playing in theaters.
 43
 44    Args:
 45        limit (`int`): The number of shows to include in the response.
 46        language (`str`): Which spoken language to prioritize.
 47        region (`str`): Which release region to prioritize.
 48        debug (`bool`): Whether or not you want debug text to be printed.
 49
 50    Returns:
 51        a `list` of shows.
 52    """
 53    
 54    url = f"https://api.themoviedb.org/3//tv/on_the_air?language={language}&region={region}"
 55    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
 56    return _simplify_shows_list(response['results'], debug=debug)
 57
 58
 59def get_popular(
 60    limit: int = 10,
 61    language: str = "en-US",
 62    region: str = "US",
 63    debug: bool = True,
 64    **kwargs,
 65):
 66    """
 67    Retrieves a list of the shows (dictionaries) that are currently popular.
 68
 69    Args:
 70        limit (`int`): The number of shows to include in the response.
 71        language (`str`): Which spoken language to prioritize.
 72        region (`str`): Which release region to prioritize.
 73        debug (`bool`): Whether or not you want debug text to be printed.
 74
 75    Returns:
 76        a `list` of shows.
 77    """
 78
 79    url = f"https://api.themoviedb.org/3/tv/popular?language={language}&region={region}"
 80    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
 81    return _simplify_shows_list(response['results'], debug=debug)
 82
 83
 84def get_reviews(
 85    show_id: int,
 86    limit: int = 20,
 87    language: str = "en-US",
 88    debug: bool = True,
 89    **kwargs,
 90):
 91    """
 92    Retrieves a list of reviews (dictionaries) for a show with the given `show_id`. Note that some tv shows
 93    won't have any reviews!
 94
 95    Args:
 96        show_id (`int`): A unique string that corresponds to a particular show.
 97        limit (`int`): The number of tv shows to include in the response.
 98        language (`str`): Which spoken language to prioritize.
 99        debug (`bool`): Whether or not you want debug text to be printed.
100
101    Returns:
102        a `list` of show reviews where each is a dictionary
103    """
104
105    url = f"https://api.themoviedb.org/3/tv/{show_id}/reviews?language={language}"
106    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
107    if len(response['results']) == 0:
108        return [ { "author": "n/a",
109                   "author_details": {
110                        "name": "",
111                        "username": "n/a",
112                        "avatar_path": "n/a",
113                        "rating": "n/a"
114                    },
115                "content": "n/a",
116                "created_at": "n/a",
117                "id": "n/a",
118                "updated_at": "n/a",
119                "url": "n/a"}]
120        
121    return response['results']
122
123
124def get_streamers(show_id: int, debug: bool=True, **kwargs):
125    """
126    Retrieves a list of streaming services (dictionaries) the given show is available on (powered by JustWatch).
127
128    Args:
129        show_id (`int`): A unique id that corresponds to a particular show.
130        debug (`bool`): Whether or not you want debug text to be printed.
131
132    Returns:
133        a `list` of streaming service names where the given show is available
134    """
135    
136    url = f"https://api.themoviedb.org/3/tv/{show_id}/watch/providers"
137    response = _issue_get_request(url, debug=debug, **kwargs)
138    return [x['provider_name'] for x in response['results']['US']['flatrate']]
139
140
141def get_recommendations(
142    show_id: int,
143    limit: int = 20,
144    language: str = "en-US",
145    debug: bool = True,
146    **kwargs,
147):
148    """
149    Retrieves a list of the shows (dictionaries) similar to the show with given `show_id`.
150
151    Args:
152        show_id (`int`): A unique int that corresponds to a particular show.
153        limit (`int`): The number of shows to include in the response.
154        language (`str`): Which spoken language to prioritize.
155        debug (`bool`): Whether or not you want debug text to be printed.
156
157    Returns:
158        a `list` of shows (dictionaries)
159    """
160    url = f"https://api.themoviedb.org/3/tv/{show_id}/recommendations?language={language}"
161    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
162    return _simplify_shows_list(response["results"], debug=debug)
163
164
165def get_genres(language: str="en-US", debug: bool=True):
166    """
167    Provides a list of available movie genres genres.
168
169    Args:
170        language (`str`): The predominant language for the tv shows you're interested in.
171        debug (`bool`): whether or not you want the debug messages to be printed.
172
173    Returns:
174        a `list` of `str` representing valid genres.
175    """
176
177    raw_genres = _lookup_genres(language=language, debug=debug)
178    simple_genres = []
179    for item in raw_genres:
180        simple_genres.append(raw_genres[item])
181
182    return simple_genres
183
184
185def lookup_show(show_id: int, debug: bool = True, **kwargs):
186    """
187    Lookup the details of a show with a given id.
188
189    Args:
190        show_id (`int`): The id of the show you'd like to get the details of.
191        debug (`bool`): whether or not you want the debug messages to be printed.
192
193    Returns:
194        a `dictionary` that represents the show in question
195    """
196    
197    url = f"https://api.themoviedb.org/3/tv/{show_id}"
198    show = _issue_get_request(url, debug=debug, **kwargs)
199    simple_show = {
200            'id': show['id'],
201            'name': show['name'],
202            'language': show['original_language'],
203            'genres': [x['name'] for x in show['genres']],
204            'overview': show['overview'],
205            'popularity': show['popularity'],
206            'first_air_date': show['first_air_date'],
207            'poster_path': show['poster_path'],
208            'rating': show['vote_average'],
209            'num_votes': show['vote_count']
210            }
211    
212    return simple_show
213
214
215def search_for_shows(genres: list = [], language: str = "en-US", debug: bool = True, length: int = 10, **kwargs):
216    
217    if len(genres) < 1:
218        raise Exception(f"No genre provided in the list given: {genres}")
219    
220    genres_dict = _lookup_genres(language=language, debug=debug)
221    
222    genre_ids = []
223    
224    for genre in genres:
225        if genre not in genres_dict.values():
226            raise Exception(f"{genre} is not a valid TV Show genre!")
227        the_id = [key for key, value in genres_dict.items() if value == genre][0]
228        genre_ids.append(str(the_id))
229    
230    url = f"https://api.themoviedb.org/3/discover/tv?include_adult=false&include_video=false&language={language}&page=1&sort_by=popularity.desc&with_origin_country=US&with_genres={'|'.join(genre_ids)}"
231    
232    response = _issue_get_request(url, limit=length, debug=debug, **kwargs)
233    return _simplify_shows_list(response["results"], debug=debug)
234
235
236def generate_watchlist(show_ids: list = [], genres: list = [], length: int = 10, debug: bool = True, simplify: bool = True):
237    """
238    Generate a watch list based off the inputted tv shows and genres. You must provide at least 1 genre for this function to work.
239    <mark>Keep in mind it does not accept show names.</mark> Specifying multiple genres might result in getting zero results.</mark>
240
241    Args:
242        show_ids (`list`): A list show ids (list of ints). Example: `[ 594767, 76600 ]`
243        genres (`list`): A list of genres. <b>Has to have</b> at least length 1. Example: `[ 'Adventure' ]`
244        length (`int`): How many shows to return as part of the watchlist
245        debug (`bool`): Whether or not you want debug text to be printed.
246        
247    Returns:
248        * a `list` of tv shows (dictionaries)
249    """
250
251    if not genres:
252        raise Exception('You MUST provide a genre in order to generate a watch list')
253
254    show_list = []
255
256    for show in show_ids:
257        if not isinstance(show, int):
258            raise TypeError(f"{show} is not a valid movie id!")
259        
260        the_show = lookup_show(show, debug = debug)
261        show_list.append(the_show)
262
263        recs = get_recommendations(the_show["id"], limit = 5, debug=debug)
264        show_list = show_list + recs
265        
266
267    if genres:
268        show_list = show_list + search_for_shows(genres=genres, length=length, debug=debug)
269                
270    show_list = _remove_duplicate_tv_shows(show_list)
271    random.shuffle(show_list)
272
273    return show_list[:length]
274
275def _remove_duplicate_tv_shows(tv_shows):
276    
277    unique_series_ids = []
278    unique_shows = []
279    for show in tv_shows:
280        if show['id'] in unique_series_ids:
281            continue
282        else:
283            unique_series_ids.append(show['id'])
284            unique_shows.append(show)
285
286    return unique_shows
287
288
289def _simplify_shows_list(shows, language="en-US", debug=True):
290    
291    genres_dict = _lookup_genres(language=language, debug=debug)
292    simplified_shows = []
293    for show in shows:
294        simplified_shows.append(
295            {
296                'id': show['id'],
297                'name': show['name'],
298                'language': show['original_language'],
299                'genres': [genres_dict[x] for x in show['genre_ids']],
300                'overview': show['overview'],
301                'popularity': show['popularity'],
302                'first_air_date': show['first_air_date'],
303                'poster_path': show['poster_path'],
304                'rating': show['vote_average'],
305                'num_votes': show['vote_count'],
306            }
307        )
308        
309    return simplified_shows
310
311def _lookup_genres(language="en", debug: bool = True):
312    
313    url = f"https://api.themoviedb.org/3/genre/tv/list?language={language}"
314    response = _issue_get_request(url, debug=debug)
315    return {item['id']: item['name'] for item in response['genres']}
316
317
318def _save_to_cache(url: str, response: str):
319
320    if os.path.isfile(TMDB_CACHE):
321        with open(TMDB_CACHE, "rb") as file:
322            cache = pickle.load(file)
323    else:
324        cache = {}
325
326    cache[url] = response
327
328    with open(TMDB_CACHE, "wb") as file:
329        pickle.dump(cache, file)
330
331
332def _check_cache_for(url: str, debug=False, **kwargs):
333    # Check cache
334    if "skip_cache" in kwargs:
335        print(
336            f"DEBUG - {'_check_cache_for'}: skip_cache flag set, returning None."
337        )
338        return None
339
340    if os.path.isfile(TMDB_CACHE):
341        with open(TMDB_CACHE, "rb") as file:
342            cache = pickle.load(file)
343    else:
344        cache = {}
345
346    if url in cache:
347        if debug:
348            print(
349                f"DEBUG - {'_check_cache_for'}: Found previous request! Returning cached result."
350            )
351        return cache[url]
352    else:
353        print(
354                f"DEBUG - {'_check_cache_for'}: No cache hit, issuing new request."
355            )
356        return None
357
358
359#############################
360# Some formatting utilities #
361#############################
362
363
364def generate_show_table(shows: list, to_html: bool = False):
365    """
366    Function that builds a string representation of a list shows (dictionaries).
367
368    Args:
369        shows (`list`): List of shows (dictionaries).
370        to_html (`bool`): If `True` it will generate an HTML version (for an email or web page) and if `False` (default) will generate a string to print in Python.
371
372    Returns:
373        * a `str` that has a table in it for tracks
374    """
375
376    if to_html:
377        return _get_show_table_html(shows)
378
379    line_width = 95
380    text = ""
381    template = "{0:2} | {1:<22.22} | {2:<40.40} | {3:<30.30}\n"
382
383    # header section:
384    text += "-" * line_width + "\n"
385    text += template.format("", "Name", "Genres", "First Air Date")
386    text += "-" * line_width + "\n"
387
388
389    # data section:
390    counter = 1
391    for show in shows:
392        text += template.format(
393            counter,
394            show.get("name"),
395            ", ".join(show.get("genres", [])),
396            show.get("first_air_date", "N/A")
397        )
398        counter += 1
399    text += "-" * line_width + "\n"
400    return text
401
402
403def _get_show_table_html(shows : list):
404    template = """
405        <tr>
406            <td {css}>{name}</td>
407            <td {css}><img src="{image_url}" /></td>
408            <td {css}>{genres}</td>
409            <td {css}>{first_air_date}</td>
410            <td {css}><p>{overview}</p></td>
411        </tr>
412    """
413    cell_css = (
414        'style="padding:3px;border-bottom:solid 1px #CCC;border-right:solid 1px #CCC;"'
415    )
416    table_css = 'style="width:100%;border:solid 1px #CCC;border-collapse:collapse;margin-bottom:10px;"'
417
418    rows = []
419
420    # data section:
421    for show in shows:        
422        full_path = show.get("poster_path", "Unavailable")
423        
424        if full_path != "Unavailable":
425            full_path = f"http://image.tmdb.org/t/p/w92{full_path}"
426        
427        rows.append(
428            template.format(
429                css=cell_css,
430                name=show.get("name", "Unknown"),
431                image_url=full_path,
432                genres=",".join(show.get("genres", [])),
433                first_air_date=show.get("first_air_date", "N/A"),
434                overview=show.get("overview", "Unavailable"),
435            )
436        )
437
438    return """
439        <table {table_css}>
440            <tr>
441                <th {css}>Name</th>
442                <th {css}>Poster</th>
443                <th {css}>Genres</th>
444                <th {css}>First Air Date</th>
445                <th {css}>Overview</th>
446            </tr>
447            {rows}
448        </table>
449    """.format(
450        css=cell_css, table_css=table_css, rows="".join(rows)
451    )
452
453
454############################################
455# Some private, helper functions utilities #
456############################################
457
458def _generate_authentication_header(backup=False, debug=True):
459
460    headers = {
461        "Authorization": "Bearer " + secret_tokens.TMDB_TOKEN,
462        "accept": "application/json",
463    }
464
465    return headers
466
467
468def _issue_get_request(url: str, debug: bool=True, limit:int = 20, practice: bool=True, **kwargs):
469    """
470    Private function. Retrieves data from any TMDB endpoint using the requisite headers.
471
472    * url (str): The API Endpoint + query parameters.
473    * debug (bool): Whether or not to print debug messages.
474    * practice (bool): Whether or not to return real data or practice data
475
476    Returns whatever TMDB's API endpoint gives back.
477    """
478    pages_requested = math.ceil(limit / 20)
479
480    headers = _generate_authentication_header(debug=debug)
481    url = quote(url, safe="/:?&,=-")
482
483    MAX_PAGE_LIMIT = pages_requested if pages_requested < 5 else 5 # Limits paged requests to 5
484
485    current_page = 1
486    all_responses = []
487    while current_page <= MAX_PAGE_LIMIT:
488        request_url = url if current_page == 1 else url + f"&page={current_page}"
489
490        if debug:
491            print(
492                f"DEBUG - {'_issue_get_request'}:\n",
493                request_url,
494                "\nYou can't access this in a browser, but you can double check the inputs you gave the function are part of the URL.",
495            )
496
497        response = _check_cache_for(request_url, debug=debug, **kwargs)
498
499        if response is None: # No cache hit
500            response = requests.get(request_url, headers=headers, verify=True)
501
502        if response.status_code == 429:
503            retry_length = response.headers["Retry-After"]
504
505            if int(retry_length) < 10:
506                print(
507                    f"Warning: TMDB API is overloaded! It asked us to try again in {retry_length} seconds so we're going to wait that long and try again."
508                )
509                time.sleep(retry_length)
510            else:
511                print(
512                    f"ERROR: TMDB API is overloaded! It asked us to try again in {retry_length} seconds."
513                )
514                return None
515
516        _save_to_cache(request_url, response)
517        
518        all_responses.append(response)
519        current_page += 1
520
521    if len(all_responses) == 1:
522        return all_responses[0].json()
523
524    combined_response = all_responses[0].json()
525    for response in all_responses[1:]: # if this was paginated, take all results and combine them   
526        combined_response['results'] += response.json()['results']
527        return combined_response
528
529    return None # Should never get here
def get_genres(language: str = 'en-US', debug: bool = True):
166def get_genres(language: str="en-US", debug: bool=True):
167    """
168    Provides a list of available movie genres genres.
169
170    Args:
171        language (`str`): The predominant language for the tv shows you're interested in.
172        debug (`bool`): whether or not you want the debug messages to be printed.
173
174    Returns:
175        a `list` of `str` representing valid genres.
176    """
177
178    raw_genres = _lookup_genres(language=language, debug=debug)
179    simple_genres = []
180    for item in raw_genres:
181        simple_genres.append(raw_genres[item])
182
183    return simple_genres

Provides a list of available movie genres genres.

Arguments:
  • language (str): The predominant language for the tv shows you're interested in.
  • debug (bool): whether or not you want the debug messages to be printed.
Returns:

a list of str representing valid genres.

def get_on_air( limit: int = 10, language: str = 'en-US', region: str = 'US', debug: bool = True, **kwargs):
37def get_on_air(limit: int = 10,
38                    language: str = "en-US", 
39                    region: str = "US", 
40                    debug: bool = True, 
41                    **kwargs):
42    """
43    Retrieves a list of the shows (dictionaries) currently playing in theaters.
44
45    Args:
46        limit (`int`): The number of shows to include in the response.
47        language (`str`): Which spoken language to prioritize.
48        region (`str`): Which release region to prioritize.
49        debug (`bool`): Whether or not you want debug text to be printed.
50
51    Returns:
52        a `list` of shows.
53    """
54    
55    url = f"https://api.themoviedb.org/3//tv/on_the_air?language={language}&region={region}"
56    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
57    return _simplify_shows_list(response['results'], debug=debug)

Retrieves a list of the shows (dictionaries) currently playing in theaters.

Arguments:
  • limit (int): The number of shows to include in the response.
  • language (str): Which spoken language to prioritize.
  • region (str): Which release region to prioritize.
  • debug (bool): Whether or not you want debug text to be printed.
Returns:

a list of shows.

def get_recommendations( show_id: int, limit: int = 20, language: str = 'en-US', debug: bool = True, **kwargs):
142def get_recommendations(
143    show_id: int,
144    limit: int = 20,
145    language: str = "en-US",
146    debug: bool = True,
147    **kwargs,
148):
149    """
150    Retrieves a list of the shows (dictionaries) similar to the show with given `show_id`.
151
152    Args:
153        show_id (`int`): A unique int that corresponds to a particular show.
154        limit (`int`): The number of shows to include in the response.
155        language (`str`): Which spoken language to prioritize.
156        debug (`bool`): Whether or not you want debug text to be printed.
157
158    Returns:
159        a `list` of shows (dictionaries)
160    """
161    url = f"https://api.themoviedb.org/3/tv/{show_id}/recommendations?language={language}"
162    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
163    return _simplify_shows_list(response["results"], debug=debug)

Retrieves a list of the shows (dictionaries) similar to the show with given show_id.

Arguments:
  • show_id (int): A unique int that corresponds to a particular show.
  • limit (int): The number of shows to include in the response.
  • language (str): Which spoken language to prioritize.
  • debug (bool): Whether or not you want debug text to be printed.
Returns:

a list of shows (dictionaries)

def get_reviews( show_id: int, limit: int = 20, language: str = 'en-US', debug: bool = True, **kwargs):
 85def get_reviews(
 86    show_id: int,
 87    limit: int = 20,
 88    language: str = "en-US",
 89    debug: bool = True,
 90    **kwargs,
 91):
 92    """
 93    Retrieves a list of reviews (dictionaries) for a show with the given `show_id`. Note that some tv shows
 94    won't have any reviews!
 95
 96    Args:
 97        show_id (`int`): A unique string that corresponds to a particular show.
 98        limit (`int`): The number of tv shows to include in the response.
 99        language (`str`): Which spoken language to prioritize.
100        debug (`bool`): Whether or not you want debug text to be printed.
101
102    Returns:
103        a `list` of show reviews where each is a dictionary
104    """
105
106    url = f"https://api.themoviedb.org/3/tv/{show_id}/reviews?language={language}"
107    response = _issue_get_request(url, debug=debug, limit=limit, **kwargs)
108    if len(response['results']) == 0:
109        return [ { "author": "n/a",
110                   "author_details": {
111                        "name": "",
112                        "username": "n/a",
113                        "avatar_path": "n/a",
114                        "rating": "n/a"
115                    },
116                "content": "n/a",
117                "created_at": "n/a",
118                "id": "n/a",
119                "updated_at": "n/a",
120                "url": "n/a"}]
121        
122    return response['results']

Retrieves a list of reviews (dictionaries) for a show with the given show_id. Note that some tv shows won't have any reviews!

Arguments:
  • show_id (int): A unique string that corresponds to a particular show.
  • limit (int): The number of tv shows to include in the response.
  • language (str): Which spoken language to prioritize.
  • debug (bool): Whether or not you want debug text to be printed.
Returns:

a list of show reviews where each is a dictionary

def get_streamers(show_id: int, debug: bool = True, **kwargs):
125def get_streamers(show_id: int, debug: bool=True, **kwargs):
126    """
127    Retrieves a list of streaming services (dictionaries) the given show is available on (powered by JustWatch).
128
129    Args:
130        show_id (`int`): A unique id that corresponds to a particular show.
131        debug (`bool`): Whether or not you want debug text to be printed.
132
133    Returns:
134        a `list` of streaming service names where the given show is available
135    """
136    
137    url = f"https://api.themoviedb.org/3/tv/{show_id}/watch/providers"
138    response = _issue_get_request(url, debug=debug, **kwargs)
139    return [x['provider_name'] for x in response['results']['US']['flatrate']]

Retrieves a list of streaming services (dictionaries) the given show is available on (powered by JustWatch).

Arguments:
  • show_id (int): A unique id that corresponds to a particular show.
  • debug (bool): Whether or not you want debug text to be printed.
Returns:

a list of streaming service names where the given show is available

def lookup_show(show_id: int, debug: bool = True, **kwargs):
186def lookup_show(show_id: int, debug: bool = True, **kwargs):
187    """
188    Lookup the details of a show with a given id.
189
190    Args:
191        show_id (`int`): The id of the show you'd like to get the details of.
192        debug (`bool`): whether or not you want the debug messages to be printed.
193
194    Returns:
195        a `dictionary` that represents the show in question
196    """
197    
198    url = f"https://api.themoviedb.org/3/tv/{show_id}"
199    show = _issue_get_request(url, debug=debug, **kwargs)
200    simple_show = {
201            'id': show['id'],
202            'name': show['name'],
203            'language': show['original_language'],
204            'genres': [x['name'] for x in show['genres']],
205            'overview': show['overview'],
206            'popularity': show['popularity'],
207            'first_air_date': show['first_air_date'],
208            'poster_path': show['poster_path'],
209            'rating': show['vote_average'],
210            'num_votes': show['vote_count']
211            }
212    
213    return simple_show

Lookup the details of a show with a given id.

Arguments:
  • show_id (int): The id of the show you'd like to get the details of.
  • debug (bool): whether or not you want the debug messages to be printed.
Returns:

a dictionary that represents the show in question

def generate_show_table(shows: list, to_html: bool = False):
365def generate_show_table(shows: list, to_html: bool = False):
366    """
367    Function that builds a string representation of a list shows (dictionaries).
368
369    Args:
370        shows (`list`): List of shows (dictionaries).
371        to_html (`bool`): If `True` it will generate an HTML version (for an email or web page) and if `False` (default) will generate a string to print in Python.
372
373    Returns:
374        * a `str` that has a table in it for tracks
375    """
376
377    if to_html:
378        return _get_show_table_html(shows)
379
380    line_width = 95
381    text = ""
382    template = "{0:2} | {1:<22.22} | {2:<40.40} | {3:<30.30}\n"
383
384    # header section:
385    text += "-" * line_width + "\n"
386    text += template.format("", "Name", "Genres", "First Air Date")
387    text += "-" * line_width + "\n"
388
389
390    # data section:
391    counter = 1
392    for show in shows:
393        text += template.format(
394            counter,
395            show.get("name"),
396            ", ".join(show.get("genres", [])),
397            show.get("first_air_date", "N/A")
398        )
399        counter += 1
400    text += "-" * line_width + "\n"
401    return text

Function that builds a string representation of a list shows (dictionaries).

Arguments:
  • shows (list): List of shows (dictionaries).
  • to_html (bool): If True it will generate an HTML version (for an email or web page) and if False (default) will generate a string to print in Python.
Returns:
  • a str that has a table in it for tracks
def generate_watchlist( show_ids: list = [], genres: list = [], length: int = 10, debug: bool = True, simplify: bool = True):
237def generate_watchlist(show_ids: list = [], genres: list = [], length: int = 10, debug: bool = True, simplify: bool = True):
238    """
239    Generate a watch list based off the inputted tv shows and genres. You must provide at least 1 genre for this function to work.
240    <mark>Keep in mind it does not accept show names.</mark> Specifying multiple genres might result in getting zero results.</mark>
241
242    Args:
243        show_ids (`list`): A list show ids (list of ints). Example: `[ 594767, 76600 ]`
244        genres (`list`): A list of genres. <b>Has to have</b> at least length 1. Example: `[ 'Adventure' ]`
245        length (`int`): How many shows to return as part of the watchlist
246        debug (`bool`): Whether or not you want debug text to be printed.
247        
248    Returns:
249        * a `list` of tv shows (dictionaries)
250    """
251
252    if not genres:
253        raise Exception('You MUST provide a genre in order to generate a watch list')
254
255    show_list = []
256
257    for show in show_ids:
258        if not isinstance(show, int):
259            raise TypeError(f"{show} is not a valid movie id!")
260        
261        the_show = lookup_show(show, debug = debug)
262        show_list.append(the_show)
263
264        recs = get_recommendations(the_show["id"], limit = 5, debug=debug)
265        show_list = show_list + recs
266        
267
268    if genres:
269        show_list = show_list + search_for_shows(genres=genres, length=length, debug=debug)
270                
271    show_list = _remove_duplicate_tv_shows(show_list)
272    random.shuffle(show_list)
273
274    return show_list[:length]

Generate a watch list based off the inputted tv shows and genres. You must provide at least 1 genre for this function to work. Keep in mind it does not accept show names. Specifying multiple genres might result in getting zero results.

Arguments:
  • show_ids (list): A list show ids (list of ints). Example: [ 594767, 76600 ]
  • genres (list): A list of genres. Has to have at least length 1. Example: [ 'Adventure' ]
  • length (int): How many shows to return as part of the watchlist
  • debug (bool): Whether or not you want debug text to be printed.
Returns:
  • a list of tv shows (dictionaries)