From 0e42c4d1d66dbc9dade61f3a319cb4718225e637 Mon Sep 17 00:00:00 2001 From: Vadim Graboys Date: Wed, 20 Apr 2016 07:31:06 -0400 Subject: [PATCH] add optional timeout Prevents hanging threads due to network issues. --- googlefinance/__init__.py | 17 ++++++++++++++++- tests/test_googlefinance.py | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/googlefinance/__init__.py b/googlefinance/__init__.py index 0dd8c65..58ba89a 100644 --- a/googlefinance/__init__.py +++ b/googlefinance/__init__.py @@ -30,6 +30,16 @@ googleFinanceKeyToFullName = { u'pcls_fix': u'PreviousClosePrice' } +DEFAULT_TIMEOUT = None +_timeout = DEFAULT_TIMEOUT + +def setTimeout(timeoutSeconds): + ''' + Sets the timeout for google finance API calls (in seconds). + ''' + global _timeout + _timeout = timeoutSeconds + def buildUrl(symbols): symbol_list = ','.join([symbol for symbol in symbols]) # a deprecated but still active & correct api @@ -37,9 +47,14 @@ def buildUrl(symbols): + symbol_list def request(symbols): + urlopenFlags = {} + if _timeout is not None: + urlopenFlags['timeout'] = _timeout + url = buildUrl(symbols) req = Request(url) - resp = urlopen(req) + resp = urlopen(req, **urlopenFlags) + # remove special symbols such as the pound symbol content = resp.read().decode('ascii', 'ignore').strip() content = content[3:] diff --git a/tests/test_googlefinance.py b/tests/test_googlefinance.py index 3dabe9c..753c7cc 100644 --- a/tests/test_googlefinance.py +++ b/tests/test_googlefinance.py @@ -1,5 +1,6 @@ import googlefinance import unittest +from urllib2 import URLError class TestQuotes(unittest.TestCase): @@ -15,3 +16,14 @@ class TestQuotes(unittest.TestCase): self.assertEqual(quotes[1]["Index"], "VIE") self.assertEqual(quotes[1]["StockSymbol"], "BKS") + def test_timeout(self): + # ensure timeout will always happen + googlefinance.setTimeout(0.0001) + with self.assertRaisesRegexp(URLError, 'timed out'): + googlefinance.getQuotes(['GOOG']) + + # reset timeout (for other tests) + googlefinance.setTimeout(googlefinance.DEFAULT_TIMEOUT) + +if __name__ == '__main__': + unittest.main()