This section provides some different examples of how pytvdbapi can be used.
Search for a show, given its name and a language:
>>> from pytvdbapi import api
>>> db = api.TVDB("B43FF87DE395DF56")
>>> result = db.search("Dexter", "en")
>>> show = result[0] # If there is a perfect match, it will be the first
>>> print(show.SeriesName)
Dexter
>>> print(show.FirstAired)
2006-10-01
You can easily loop all episodes in a show:
>>> for season in show:
... for episode in season:
... print(u"{0} - {1}".format(episode.EpisodeName, episode.FirstAired))
...
Early Cuts: Alex Timmons (Chapter 1) - 2009-10-25
...
Finding Freebo - 2008-10-05
The Lion Sleeps Tonight - 2008-10-12
All In the Family - 2008-10-19
Turning Biminese - 2008-10-26
...
Dress Code - 2013-08-11
Are We There Yet? - 2013-08-18
Make Your Own Kind of Music - 2013-08-25
Goodbye Miami - 2013-09-08
Monkey In a Box - 2013-09-15
Remember the Monsters? - 2013-09-22
Basic usage:
# You can use slicing to only get a sub set of all seasons
>>> for season in show[2:5]:
... print(season.season_number)
...
2
3
4
# List the total number of seasons
# Season 0 is the "specials" season containing special episodes
>>> len(show)
9
>>> print(show[2]) # Access a particular season
<Season 002>
Access show attributes:
>>> print(show.IMDB_ID)
tt0773262
>>> hasattr(show, 'foo')
False
>>> hasattr(show, 'Genre')
True
>>> getattr(show, 'foo', -1)
-1
Episode access:
>>> from pytvdbapi.error import TVDBIndexError
>>> season = show[2] # Grab a specific season, season 0 is the specials season
>>> len(season) # The number of episodes in the season
12
>>> try:
... print(season[0])
... except TVDBIndexError:
... # Episodes start at index 1
... print('No episode at index 0')
No episode at index 0
>>> print(season[3])
<Episode - S002E003>
You can use slicing to access specific episode objects:
>>> for episode in season[3:10:2]:
... print(episode.EpisodeNumber)
...
4
6
8
10
Access the associated show:
>>> season.show
<Show - Dexter>
Accessing episode attributes:
>>> episode = show[2][4]
>>> print(episode.EpisodeName)
See-Through
>>> hasattr(episode, 'foo')
False
>>> hasattr(episode, 'Director')
True
Access the containing season:
>>> episode.season
<Season 002>
It is possible to search and filter a show or season instance to find all episodes matching a certain criteria.
Searching for all shows written by Tim Schlattmann:
>>> episodes = show.filter(key=lambda ep: ep.Writer == 'Tim Schlattmann')
>>> len(episodes)
7
>>> for ep in episodes:
... print(ep.EpisodeName)
...
The Dark Defender
Turning Biminese
Go Your Own Way
Dirty Harry
First Blood
Once Upon a Time...
Scar Tissue
Find the episode with production code 302:
>>> episode = show.find(key=lambda ep: ep.ProductionCode==302)
>>> print(episode.EpisodeName)
Finding Freebo
>>> print(episode.ProductionCode)
302
It is possible to tell the API to ignore casing when accessing the objects dynamic attributes. If you pass ignore_case=True when creating the pytvdbapi.api.TVDB instance, you can access the dynamically created attributes of the pytvdbapi.api.Show, pytvdbapi.api.Season, pytvdbapi.api.Episode, pytvdbapi.actor.Actor and pytvdbapi.banner.Banner instances in a case insensitive manner.
Example:
>>> from pytvdbapi import api
>>> db = api.TVDB("B43FF87DE395DF56", ignore_case=True) # Tell API to ignore case
>>> result = db.search("Dexter", "en")
>>> show = result[0]
>>> print(show.seriesname)
Dexter
>>> hasattr(show, 'SERIESNAME')
True
>>> hasattr(show, 'seriesname')
True
>>> hasattr(show, 'sErIeSnAmE')
True
>>> episode = show[3][5]
>>> print(episode.episodename)
Turning Biminese
>>> hasattr(episode, 'EPISODENAME')
True
>>> hasattr(episode, 'episodename')
True
By default, the extended information for pytvdbapi.actor.Actor and pytvdbapi.banner.Banner are not loaded. This is to save server resources and avoid downloading data that is not necessarily needed. The pytvdbapi.api.Show always contain a list of actor names. If you do want to use this extra actor and banner data you can pass actors=True and banners=True respectively when creating the pytvdbapi.api.TVDB instance, this will cause the actors and/or banners to be loaded for all shows. If you only want this information for some shows, you can use the pytvdbapi.api.Show.load_actors() and pytvdbapi.api.Show.load_banners() functions instead.
Using keyword arguments:
>>> from pytvdbapi import api
>>> db = api.TVDB("B43FF87DE395DF56", actors=True, banners=True)
>>> result = db.search("Dexter", "en")
>>> show = result[0]
>>> show.update()
>>> print(show.actor_objects[0])
<Actor - Michael C. Hall>
Using instance functions:
>>> from pytvdbapi import api
>>> db = api.TVDB("B43FF87DE395DF56")
>>> result = db.search("Dexter", "en")
>>> show = result[0]
>>> len(show.actor_objects)
0
>>> len(show.banner_objects)
0
>>> show.load_actors() # Load actors
>>> assert len(show.actor_objects) > 0
>>> print(show.actor_objects[0])
<Actor - Michael C. Hall>
>>> show.load_banners() # Load banners
This provides a more complete example of how to handle the fact that there could be something wrong with the connection to the backend, or the backend could be malfunctioning and return invalid data that we can not work with.
>>> from pytvdbapi import api
>>> from pytvdbapi.error import ConnectionError, BadData, TVDBIndexError
>>> db = api.TVDB("B43FF87DE395DF56")
>>> try:
... result = db.search("Dexter", "en") # This hits the network and could raise an exception
... show = result[0] # Find the show object that you want
... show.update() # this loads the full data set and could raise exceptions
... except TVDBIndexError:
... # The search did not generate any hits
... pass
... except ConnectionError:
... # Handle the fact that the server is not responding
... pass
... except BadData:
... # The server responded but did not provide valid XML data, handle this issue here,
... # maybe by trying again after a few seconds
... pass
... else:
... # At this point, we should have a valid show instance that we can work with.
... name = show.SeriesName