Skip to content

Commit

Permalink
Merge pull request #365 from robertcv/fixes/guardian_limit
Browse files Browse the repository at this point in the history
Guardian request limit exceeded
  • Loading branch information
ajdapretnar authored Aug 2, 2018
2 parents 8e0a162 + e70b824 commit 5340e0d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
7 changes: 7 additions & 0 deletions orangecontrib/text/guardian.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
ARTICLES_PER_PAGE = 10


class APILimitError(Exception):
pass


class TheGuardianCredentials:
""" The Guardian API credentials. """
def __init__(self, key):
Expand Down Expand Up @@ -93,6 +97,9 @@ def _search(self, query, from_date, to_date, page=1):
data = self._build_query(query, from_date, to_date, page)

response = requests.get(BASE_URL, data)
if response.status_code == 429:
raise APILimitError("API limit exceeded")

parsed = json.loads(response.text)

if page == 1: # store number of pages
Expand Down
56 changes: 55 additions & 1 deletion orangecontrib/text/tests/test_guardian.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os

from datetime import date, datetime
from unittest import mock

from orangecontrib.text import guardian

Expand All @@ -10,7 +11,9 @@


class TestCredentials(unittest.TestCase):
def test_valid(self):
@mock.patch('requests.get')
def test_valid(self, mock_get):
mock_get().status_code = 200
credentials = guardian.TheGuardianCredentials(API_KEY)
self.assertTrue(credentials.valid)

Expand All @@ -19,15 +22,26 @@ def test_equal(self):
self.assertEquals(credentials, credentials)


def skip_limit_exceeded(fun):
def wrapper(*args, **kwargs):
try:
fun(*args, **kwargs)
except guardian.APILimitError as err:
raise unittest.SkipTest(str(err))
return wrapper


class TestGuardian(unittest.TestCase):
def setUp(self):
c = guardian.TheGuardianCredentials(API_KEY)
self.api = guardian.TheGuardianAPI(c)

@skip_limit_exceeded
def test_search(self):
corp = self.api.search('Slovenia', max_documents=20)
self.assertEqual(len(corp), 20)

@skip_limit_exceeded
def test_search_from_to_date(self):
from_date = date(2016, 12, 1)
to_date = date(2016, 12, 31)
Expand All @@ -41,13 +55,53 @@ def test_search_from_to_date(self):
self.assertGreaterEqual(dt.date(), from_date)
self.assertLessEqual(dt.date(), to_date)

@skip_limit_exceeded
def test_breaking(self):
self.api.should_break = lambda: True
corp = self.api.search('Slovenia', max_documents=20)
self.assertEqual(len(corp), 10)
self.api.should_break = lambda: False

@skip_limit_exceeded
def test_accumulate(self):
self.api.search('Slovenia', max_documents=10, accumulate=True)
corp = self.api.search('Ljubljana', max_documents=10, accumulate=True)
self.assertEqual(len(corp), 20)

@mock.patch('requests.get')
def test_api_limit_error(self, mock_get):
mock_get().status_code = 429
self.assertRaises(guardian.APILimitError, self.api.search, 'Slovenia')

@mock.patch('requests.get')
def test_search_mock_data(self, mock_get):
mock_get().text = """
{
"response": {
"pages": 1,
"results": [
{
"type": "article",
"sectionName": "World news",
"webPublicationDate": "2018-07-05T23:27:25Z",
"webUrl": "https://www.theguardian.com/world/2018/jul/06",
"fields": {
"headline": "Rohingya refugees reject UN-Myanmar repatriati",
"trailText": "Leaders say agreement does not address concer",
"body": "<p><strong><strong><strong></strong></strong></str",
"wordcount": "512",
"lang": "en",
"bodyText": "Rohingya community leaders have rejected an."
},
"tags": [
{
"webTitle": "Myanmar"
}
]
}
]
}
}
"""
corp = self.api.search('Slovenia', max_documents=1)
self.assertEqual(len(corp), 1)
9 changes: 7 additions & 2 deletions orangecontrib/text/widgets/owguardian.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from Orange.widgets.widget import Output

from orangecontrib.text.corpus import Corpus
from orangecontrib.text.guardian import TheGuardianCredentials, TheGuardianAPI
from orangecontrib.text.guardian import TheGuardianCredentials, TheGuardianAPI, APILimitError
from orangecontrib.text.widgets.utils import CheckListLayout, QueryBox, DatePickerInterval, gui_require, asynchronous


Expand Down Expand Up @@ -88,6 +88,7 @@ class Warning(OWWidget.Warning):
class Error(OWWidget.Error):
no_api = Msg('Please provide a valid API key.')
no_query = Msg('Please provide a query.')
limit_exceeded = Msg('Requests limit reached.')

def __init__(self):
super().__init__()
Expand Down Expand Up @@ -149,7 +150,11 @@ def start_stop(self):
@gui_require('api', 'no_api')
@gui_require('recent_queries', 'no_query')
def run_search(self):
self.search()
self.Error.limit_exceeded.clear()
try:
self.search()
except APILimitError:
self.Error.limit_exceeded()

@asynchronous
def search(self):
Expand Down

0 comments on commit 5340e0d

Please sign in to comment.