Package: isle
THE MOVIE DATABASE PYTHON WRAPPERisleis a clear and distinct wrapper for The Movie Database API.TABLE OF CONTENTSREQUIREMENTSINSTALLATIONTMDB API KEYFUNCTIONSOBJECTSACCOUNTREQUIREMENTSPython 3.6+No dependenciesother than the standard libraryINSTALLATIONUsingpip:pipinstallisleTMDB API KEYExport your TMDb API key as an environment variable:$exportTMDB_API_KEY='YOUR_API_KEY'Or set theTMDB_API_KEYvariable:importisleisle.TMDB_API_KEY='YOUR_API_KEY'FUNCTIONSSearchSearch functions look for movies, TV shows, people or companies by their names or titles.All search functions aregenerators.>>>importinspect>>>importisle>>>inspect.isgenerator(isle.search_movie)True>>>inspect.isgenerator(isle.search_show)True>>># and so on.isle.search_movie(query: str, **kwargs)Searches for movies. It generatesMovieinstances.Let's search for Ozu's "Tokyo Story":>>>formovieinisle.search_movie("Tokyo Story"):...print(movie)Movie(18148)Movie(528533)...Movie(104343)Let's get only the first result:>>>tokyo_story=next(isle.search_movie("Tokyo Story",year=1953))>>>tokyo_storyMovie(18148)There are several keyword arguments:year— filters a movie by release yearregion— filters release dates. Must be an ISO 3166-1 code (uppercase).include_adults— chooses whether to inlcude adult (pornography) content in the results (bool).language— displays translated data for the fields that support it (some default values inMovieobject). Must be an ISO 639-1 code.isle.search_show(query: str, **kwargs)Searches for a TV show. It generatesShowinstances.>>>castle_rock=next(isle.search_show("Castle Rock"))>>>castle_rockShow(71116)There is a keyword argumentfirst_air_date_year, which can be specified for more accurate results.isle.search_person(query: str, **kwargs)Searches for people. It generatesPersoninstances.>>>john_cassavetes=next(isle.search_person("John Cassavetes"))>>>john_cassavetesPerson(11147)There arelanguage,regionandinclude_adultskeyword arguments (see the part aboutsearch_movieabove to understand what they change).isle.search_company(query: str, **kwargs)Searches for companies. It generatesCompanyinstances.>>>lucasfilm_company=next(isle.search_company("Lucasfilm"))>>>lucasfilm_companyCompany(1)DiscoverLike search functions, all discover functions are alsogenerators. But instead of searching by name or title, these ones descover movies or TV shows by different types of data like average rating, number of votes, genres and certifications.To understandoptions, you need to readthisandthis.isle.discover_movies(options: dict)Discovers movies by different types of data.Let's discover the first 3 movies with Jason Schwartzman:>>>fromitertoolsimportislice>>>schwartzman=next(isle.search_person("Jason Schwartzman"))>>>options={"sort_by":"release_date.asc","with_cast":schwartzman.tmdb_id}>>>formovieinislice(isle.discover_movies(options),3):...print(f"'{movie.year}-{movie.title['original']}'")'1998 - Rushmore''2001 - CQ''2002 - Slackers'isle.discover_shows(options: dict)Discovers TV shows by different types of data. It works likediscover_movies, but note that the options are different.Let's discover top 3 most popular TV shows on TMDb:>>>options={'sort_by':'popularity.desc'}>>>forshowinislice(isle.discover_shows(options),3):...print(f"'{show.vote.average:<10}{show.title['original']}'")'8         ドラゴンボール''6.7       The Flash''6.8       The Big Bang Theory'Findisle.find(external_id: str, *, src: str, **options)Thefindfunction searches for objects (movies, TV shows and people) by an external ID (for example, an IMDb ID). It returns the results in a single response.>>>results=tmdb.find("tt0053604",src="imdb_id")>>>results{'movie_results':[Movie(284)],'person_results':[],'tv_results':[]}OthersOther functions return some general information, such as genres, languages, time zones supported in TMDb.Let's just list them all (you always can use the build-inhelpfunction to see more information):isle.get_movie_certifications(country=None)isle.get_show_certifications(country=None)isle.get_movie_genres(objects=False)isle.get_show_genres(objects=False)isle.get_image_configurations()isle.get_countries(objects=False)isle.get_jobs()isle.get_languages(objects=False)isle.get_primary_translations()isle.get_timezones()OBJECTSLet's take a close look atMovie,Show,PersonandCompanyobjects.They can be initialized by a TMDb ID or obtained bysearchanddiscoverfunctions (as we see above).They can be used in two different ways: usemethodsthat return raw responses or usepropertiesthat enrich objects with more functionality (you'll see this below)MovieRepresents a movie. It can be initialized with a TMDb ID.>>>movie=isle.Movie(18148)Now themoviedoesn't contain any data except the ID. It hasn't made any requests to the API yet (You can see how many requests were made by then_requestsattribute).>>>movie.data{'id':18148}>>>movie.n_requests0MethodsMovie(as well as other objects, such asShow,PersonorCompany) hasget_<something>anditer_<something>methods. Let's list them:get_all()get_alternative_titles()get_changes()get_credits()get_details()get_external_ids()get_images()get_keywords()get_release_dates()get_translations()get_videos()iter_lists()iter_recommendations()iter_reviews()iter_similar_movies()Each method makes onlyonerequest to the API. That's why the best practice is  to useget_all()method instead of calling several other methods. So instead of doing the following:>>>movie=isle.Movie(18148)>>>credits=movie.get_credits()# making first request>>>movie.n_requests1>>>keywords=movie.get_keywords()# making second request>>>movie.n_requests2Do this:>>>movie=isle.Movie(18148)>>>movie.n_requests0>>>all_data=movie.get_all()# making first request>>>movie.n_requests1>>>credits,keywords=all_data["credits"],all_data["keywords"]>>>movie.n_requests1All the received data is saved in thedataattribute. Now it contains all the data, because we've called theget_all()method.>>>all_data==movie.dataTrue>>>keywords==movie.data["keywords"]TrueAll the data received with methods is structured in the same way as in therawAPI responses.Properties ☝️Another way to get data is to use properties (it is actually the best way).Let's see an example. What if you need to get the titles of a movie in different languages? You can callget_all()and retrieve the titles from thedataattribute:>>>movie.get_all()>>>acc={}>>>acc["original"]=movie.data["original_title"]>>>acc["default"]=movie.data["title"]>>>foriteminmovie.data["translations"]["translations"]:...acc[item["iso_3166_1"]]=item["data"]["title"]>>>acc{'original':'東京物語','default':'Tokyo Story','RU':'Токийская повесть','US':'Tokyo Story',...,'FR':'Voyage à Tokyo'}Or you can just use thetitleproperty:>>>movie=isle.Movie(18148)>>>movie.title{'original':'東京物語','default':'Tokyo Story','RU':'Токийская повесть','US':'Tokyo Story',...,'FR':'Voyage à Tokyo'}>>>movie.n_requests1In the same way you can use theoverviewproperty:>>>movie.overview["FR"]"Un couple de personnes âgées rend visite à leurs enfants à Tokyo. D'abord reçus avec les égards qui leur sont dûs, ils deviennent bientôt dérangeants dans leur vie quotidienne."When a property is called, it searches for the required data in thedataattribute and if there is no such data, it callsget_all()behind the scenes. After calling thetitleattribute, all the raw data is downloaded to thedataattribute.>>>movie.genres[Genre(tmdb_id=18,name='Drama')]# Genre is a `NamedTuple` object>>>person,credit=movie.crew[0]>>>person.name,credit.job('Yasujirō Ozu','Director')>>>person,credit=movie.cast[0]>>>person.name,credit.job,credit.character('Chishū Ryū','Actor','Shukishi Hirayama')>>>movie.voteVote(average=8.3,count=292)# It is a `NamedTuple` object too>>>movie.releases["US"][{'certification':'','type':3,'date':'1972-03-13T00:00:00.000Z','note':''}]>>>movie.n_requests1Whensearch_movieanddiscover_moviefunctions returnMovieinstances, they add initial data to thedataatributes.>>>tokyo_story=next(isle.search_movie("Tokyo Story",year=1953))>>>tokyo_story.n_requests0>>>tokyo_story.year1953>>>tokyo_story.is_adultFalse>>>tokyo_story.popularity5.816>>>tokyo_story.n_requests# it did not make API requests yet0>>># but>>>person,credit=tokyo_story.crew[0]>>>tokyo_story.n_requests1In the same way,Movieadds some initial data to thedataattribute ofPersonandCompanyinstances:>>>person,_=tokyo_story.crew[0]>>>person.name'Yasujirō Ozu'>>>person.n_requests0>>>company=tokyo_story.companies[0]>>>company.name'Shochiku Co., Ltd.'>>>company.n_requests0Use the build-inhelpfunction to see all available properties.Show,PersonandCompanyThese objects are similar toMovie. They also haveget_<something>anditer_<something>methods and properties that do all the routine work.The main difference is thatCompanydoesn't have theget_all()method, so, behind the scenes, it can call severalgetmethods (though the main information is returned byget_details()).>>>company=Company(1)>>>company.name'Lucasfilm'>>>company.homepage'http://www.lucasfilm.com'>>>company.n_requests1>>>company.logos# searches for images and calls `get_images` if there are no images in the `data` attribute[Image(heigh=99,width=295,_type=logo)]>>>company.n_requests2>>>company.also_known_as# searches for alternative_names and calls `get_alternative_names` if there are no names in the `data` attribute[]>>>company.n_requests3Season,Episode,Creditand othersASeasonis returned by aShow(and  anEpisodeis returned bySeason). These ones andCreditare also similar to the main objects above.>>>show=next(isle.search_show("Castle Rock"))Season:>>>season=show.seasons[0]>>>all_raw_data=season.get_all()>>>season.n_requests1Episode:>>>season.title'Season 1'>>>episode=season.episodes[0]>>>f"{episode.n}episode of{episode.sn}season"'1 episode of 1 season'>>>episode.title['US']'Severance'>>>episode.n_requests1Credit:>>>person,credit=episode.crew[0]>>>creditCredit(5b6192b09251414064012485)>>>credit.department,credit.job('Directing','Director')>>>person.name==credit.person.nameTrueThere are a few objects such asLanguage,Country,Genre,KeywordandVote. They are justNamedTuple-like objects.>>>movie=isle.Movie(18148)>>>isinstance(movie.vote,tuple)True>>>movie.vote[0]==movie.vote.averageTrueAnd there is anImage. It contains attributes which are the same as in theraw dict:aspect_ratio,file_path,width,height, etc. And the propertyurlthat makes a request to the TMDb API forimage configurationsand returnsdictwith full URLs to the image.>>>poster=movie.posters[0]>>>poster.heightposter.width,poster.file_path(952,666,'/3Zu3MojWSaV3rt5gX5fFdDO3GoF.jpg')>>>poster.url['original']'https://image.tmdb.org/t/p//original/3Zu3MojWSaV3rt5gX5fFdDO3GoF.jpg'>>>set(poster.sizes)==poster.url.keys()TrueACCOUNTTo get started with a TMDb user account, create an instance ofAccountand log in with a user name and password:>>>importos>>>account=isle.Account()>>>account.login(os.getenv("TMDB_USERNAME"),os.getenv("TMDB_PASSWORD")){'success':True,'session_id':'7b2578cddffce240f5f3387527761802c0d5c1ef'}Don't try to seek out how to rate a movie inside aMovieinstance or how to add a new list inside aListinstance. All that can be done with a user account, can be done by anAccountinstance.Rate:>>>account.rate(isle.Movie(18148),8.5){'status_code':1,'status_message':'Success.'}>>>formovieinaccount.iter_rated_movies():...print(movie)Movie(18148)>>>account.delete_rating(isle.Movie(18148)){'status_code':13,'status_message':'The item/record was deleted successfully.'}Watchlist:>>>account.add_to_watchlist(isle.Movie(18148)){'status_code':1,'status_message':'Success.'}>>>foriteminaccount.iter_movie_watchlist():...print(item)Movie(18148)>>>account.remove_from_watchlist(isle.Movie(18148)){'status_code':13,'status_message':'The item/record was deleted successfully.'}And other things:>>>account.mark_as_favorite(isle.Movie(18148)){'status_code':1,'status_message':'Success.'}>>>formovieinaccount.iter_favorite_movies():...print(movie)Movie(18148)>>>forlinaccount.iter_lists():...print(l)List(96926)