Skip to content

Commit d37705f

Browse files
authored
Series expansion (#9)
* allow pulling all episodes when pulling a series * add __slots__ * provide timeout property * add strict parameter * add changelog
1 parent 274b743 commit d37705f

File tree

5 files changed

+101
-11
lines changed

5 files changed

+101
-11
lines changed

CHANGELOG.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
## Version 0.1.0
3+
* Added `timeout` property
4+
* Added ability to pull all episodes when pulling a series (optional)
5+
* `strict` property allows for swallowing exceptions
6+
* Use __slots__
7+
8+
## Version 0.0.4
9+
* Search pulls all results unless specified not to do so
10+
* Added additional exceptions
11+
* OMDBTooManyResults
12+
* OMDBInvalidAPIKey
13+
* Added ability to set the API key
14+
* Convert dictionary from camelCase to snake_case
15+
16+
## Version 0.0.3
17+
* Added doc strings for online documentation and deployed to [readthedocs.org](https://pyomdbapi.readthedocs.io/en/latest/)
18+
* Fixed a call to the formatting of results
19+
20+
## Version 0.0.2
21+
* Fixed error with formatting the results
22+
23+
## Version 0.0.1
24+
* Initial Release
25+
* Search by movie or series name
26+
* Get movie, series, or episode by name or IMDBid

README.rst

+5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@ A simple OMDB API python wrapper
55

66
.. image:: https://badge.fury.io/py/pyomdbapi.svg
77
:target: https://badge.fury.io/py/pyomdbapi
8+
:alt: PyPy Version
89
.. image:: https://api.codacy.com/project/badge/Grade/e83dad34f35a44dea103100f23cd6310
910
:target: https://www.codacy.com/app/barrust/pyomdbapi?utm_source=github.com&utm_medium=referral&utm_content=barrust/pyomdbapi&utm_campaign=Badge_Grade
11+
:alt: Code Quality
1012
.. image:: https://img.shields.io/badge/license-MIT-blue.svg
1113
:target: https://opensource.org/licenses/MIT/
1214
:alt: License
15+
.. image:: https://pepy.tech/badge/pyomdbapi
16+
:target: https://pepy.tech/project/pyomdbapi
17+
:alt: Downloads
1318

1419
Documenation
1520
-------------------------------------------------------------------------------

omdb/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
__maintainer__ = 'Tyler Barrus'
88
__email__ = '[email protected]'
99
__license__ = 'MIT'
10-
__version__ = '0.0.4'
10+
__version__ = '0.1.0'
1111
__url__ = 'https://github.com/barrust/pyomdbapi'
1212
__bugtrack_url__ = '{0}/issues'.format(__url__)
1313
__all__ = ['OMDB', 'OMDBException', 'OMDBNoResults', 'OMDBLimitReached', 'OMDBTooManyResults']

omdb/omdb.py

+55-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import requests
55

66
from .exceptions import OMDBException, OMDBNoResults, OMDBLimitReached, OMDBTooManyResults, OMDBInvalidAPIKey
7-
from .utilities import camelcase_to_snake_case, range_inclusive
7+
from .utilities import camelcase_to_snake_case, range_inclusive, to_int
88

99

1010
class OMDB(object):
@@ -13,15 +13,24 @@ class OMDB(object):
1313
Args:
1414
api_key (str): The API Key to use for the requests
1515
timeout (float): The timeout, in seconds
16+
strict (bool): To use strict error checking or not; strict (True) \
17+
will throw errors if the API returns an error code, non-strict will not
1618
Returns:
17-
OMDB: An OMDB API wrapper connection object '''
19+
OMDB: An OMDB API wrapper connection object
20+
Note:
21+
With `strict` disabled, it is up to the user to check for and handle errors '''
1822

19-
def __init__(self, api_key, timeout=5):
23+
__slots__ = ['_api_url', '_timeout', '_api_key', '_session', '_strict']
24+
25+
def __init__(self, api_key, timeout=5, strict=True):
2026
''' the init object '''
2127
self._api_url = 'https://www.omdbapi.com/'
22-
self._timeout = timeout
28+
self._timeout = None
29+
self.timeout = timeout
2330
self._api_key = None
2431
self.api_key = api_key
32+
self._strict = None
33+
self.strict = strict
2534
self._session = requests.Session()
2635

2736
def close(self):
@@ -43,6 +52,30 @@ def api_key(self, val):
4352
else:
4453
raise OMDBInvalidAPIKey(val)
4554

55+
@property
56+
def timeout(self):
57+
''' float: The timeout parameter to pass to requests for how long to wait '''
58+
return self._timeout
59+
60+
@timeout.setter
61+
def timeout(self, val):
62+
''' set the timeout property '''
63+
try:
64+
self._timeout = float(val)
65+
except ValueError:
66+
msg = "OMDB Timeout must be a float or convertable to float! {} provided".format(val)
67+
raise ValueError(msg)
68+
69+
@property
70+
def strict(self):
71+
''' bool: Whether to throw or swallow errors; True will throw exceptions '''
72+
return self._strict
73+
74+
@strict.setter
75+
def strict(self, val):
76+
''' set the strict property '''
77+
self._strict = bool(val)
78+
4679
def search(self, title, pull_all_results=True, page=1, **kwargs):
4780
''' Perform a search based on title
4881
@@ -101,7 +134,7 @@ def get(self, title=None, imdbid=None, **kwargs):
101134
}
102135
if imdbid:
103136
params['i'] = imdbid
104-
if title:
137+
elif title:
105138
params['t'] = title
106139
else:
107140
raise OMDBException("Either title or imdbid is required!")
@@ -153,20 +186,32 @@ def get_movie(self, title=None, imdbid=None, **kwargs):
153186
params.update(kwargs)
154187
return self.get(title, imdbid, **params)
155188

156-
def get_series(self, title=None, imdbid=None, **kwargs):
189+
def get_series(self, title=None, imdbid=None, pull_episodes=False, **kwargs):
157190
''' Retrieve a TV series information by title or IMDB id
158191
159192
Args:
160193
title (str): The name of the movie to retrieve
161194
imdbid (str): The IMDB id of the movie to retrieve
195+
pull_episodes (bool): `True` to pull the episodes
162196
kwargs (dict): the kwargs to add additional parameters to the API request
163197
Returns:
164198
dict: A dictionary of all the results
165199
Note:
166200
Either `title` or `imdbid` is required '''
167201
params = {'type': 'series'}
168202
params.update(kwargs)
169-
return self.get(title, imdbid, **params)
203+
res = self.get(title, imdbid, **params)
204+
num_seasons = 0
205+
if pull_episodes:
206+
num_seasons = to_int(res.get('total_seasons', 0))
207+
res['seasons'] = dict()
208+
209+
for i in range(num_seasons):
210+
season_num = i + 1
211+
season = self.get_episodes(title, imdbid, season=season_num)
212+
res['seasons'][season_num] = season
213+
214+
return res
170215

171216
def get_episode(self, title=None, imdbid=None, season=1, episode=1, **kwargs):
172217
''' Retrieve a TV series episode by title or IMDB id and season and episode number
@@ -187,7 +232,7 @@ def get_episode(self, title=None, imdbid=None, season=1, episode=1, **kwargs):
187232
if episode:
188233
params['Episode'] = episode
189234
params.update(kwargs)
190-
return self.get(title, imdbid, **params)
235+
return self.get(title=title, imdbid=imdbid, **params)
191236

192237
def get_episodes(self, title=None, imdbid=None, season=1, **kwargs):
193238
''' Retrieve all episodes of a TV series by season number
@@ -201,7 +246,7 @@ def get_episodes(self, title=None, imdbid=None, season=1, **kwargs):
201246
dict: A dictionary of all the results
202247
Note:
203248
Either `title` or `imdbid` is required '''
204-
return self.get_episode(title, imdbid, season, None, **kwargs)
249+
return self.get_episode(title=title, imdbid=imdbid, season=season, episode=None, **kwargs)
205250

206251
def _get_response(self, kwargs):
207252
''' wrapper for the `requests` library call '''
@@ -231,7 +276,7 @@ def __format_results(self, res, params):
231276
res[camelcase_to_snake_case(key)] = val
232277

233278
# NOTE: I dislike having to use string comparisons to check for specific error conditions
234-
if 'response' in res and res['response'] == 'False':
279+
if self.strict and 'response' in res and res['response'] == 'False':
235280
err = res.get('error', '').lower()
236281
if err == 'too many results.':
237282
raise OMDBTooManyResults(res['error'], params)

omdb/utilities.py

+14
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,17 @@ def range_inclusive(start, end, step=1):
3131
'''
3232
for i in range(start, end + 1, step):
3333
yield i
34+
35+
36+
def to_int(val):
37+
''' Turn the passed in variable into an int; returns 0 if errors
38+
39+
Args:
40+
val (str): The variable to turn into an int
41+
Returns:
42+
int: The int value if possible, 0 if an error occurs
43+
'''
44+
try:
45+
return int(val)
46+
except ValueError:
47+
return 0

0 commit comments

Comments
 (0)