Examples¶
This section provides some different examples of how pytvdbapi can be used.
Basic Usage¶
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
Working with a show object¶
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
Working with a Season object¶
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>
Working with an episode object¶
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>
Searching and Filtering¶
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
Case insensitive attributes¶
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
Working with Actor and Banner Objects¶
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
Handle Network Issues¶
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