Skip to content

Commit 3102db3

Browse files
author
Konstantinos Bairaktaris
authored
Merge pull request #36 from transifex/retry_fetch
Retry fetch languages/translations on 202
2 parents c3577ff + 946ca35 commit 3102db3

2 files changed

Lines changed: 84 additions & 46 deletions

File tree

tests/native/core/test_cds.py

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ class TestCDSHandler(object):
1111

1212
def _lang_lists_equal(self, list_1, list_2):
1313
try:
14-
sorted_1, sorted_2 = [
15-
sorted(l, key=itemgetter('code')) for l in (list_1, list_2)
16-
]
14+
sorted_1, sorted_2 = [sorted(language, key=itemgetter('code'))
15+
for language in (list_1, list_2)]
1716
pairs = zip(sorted_1, sorted_2)
1817
difference = any(x != y for x, y in pairs)
1918
except Exception:
@@ -100,8 +99,8 @@ def test_fetch_languages(self, patched_logger):
10099

101100
assert cds_handler.fetch_languages() == []
102101
patched_logger.error.assert_called_with(
103-
'Error retrieving languages from CDS: UnknownError '
104-
'(`400 Client Error: Bad Request for url: https://some.host/languages`)'
102+
'Error retrieving languages from CDS: UnknownError (`400 Client '
103+
'Error: Bad Request for url: https://some.host/languages`)'
105104
)
106105
responses.reset()
107106

@@ -125,8 +124,8 @@ def test_fetch_languages(self, patched_logger):
125124

126125
assert cds_handler.fetch_languages() == []
127126
patched_logger.error.assert_called_with(
128-
'Error retrieving languages from CDS: UnknownError '
129-
'(`403 Client Error: Forbidden for url: https://some.host/languages`)'
127+
'Error retrieving languages from CDS: UnknownError (`403 Client '
128+
'Error: Forbidden for url: https://some.host/languages`)'
130129
)
131130
responses.reset()
132131

@@ -333,9 +332,8 @@ def test_fetch_translations_etags_management(self, patched_logger):
333332

334333
responses.add(
335334
responses.GET, cds_host + '/content/en',
336-
json={
337-
# whatever, we don't care about the content of json repsone atm.
338-
},
335+
# whatever, we don't care about the content of json repsone atm.
336+
json={},
339337
status=304
340338
)
341339

@@ -451,3 +449,42 @@ def test_get_headers(self):
451449
'Accept-Encoding': 'gzip',
452450
'If-None-Match': 'something'
453451
}
452+
453+
@responses.activate
454+
def test_retry_fetch_languages(self):
455+
cds_host = 'https://some.host'
456+
cds_handler = CDSHandler(
457+
['el', 'en'],
458+
'some_token',
459+
host=cds_host,
460+
)
461+
responses.add(responses.GET, cds_host + '/languages', status=202)
462+
responses.add(responses.GET, cds_host + '/languages', status=202)
463+
responses.add(responses.GET, cds_host + '/languages',
464+
json={'data': [{'code': "el"},
465+
{'code': "en"}],
466+
'meta': {'some_key': "some_value"}},
467+
status=200)
468+
languages_response = cds_handler.fetch_languages()
469+
assert self._lang_lists_equal(
470+
languages_response,
471+
[{'code': 'el'}, {'code': 'en'}]
472+
)
473+
474+
@responses.activate
475+
def test_retry_fetch_translations(self):
476+
cds_host = 'https://some.host'
477+
cds_handler = CDSHandler(
478+
['el', 'en'],
479+
'some_token',
480+
host=cds_host,
481+
)
482+
responses.add(responses.GET, cds_host + '/content/el', status=202)
483+
responses.add(responses.GET, cds_host + '/content/el', status=202)
484+
responses.add(responses.GET,
485+
cds_host + '/content/el',
486+
json={'data': {'source': {'string': "translation"}}},
487+
status=200)
488+
translations = cds_handler.fetch_translations('el')
489+
assert (translations ==
490+
{'el': (True, {'source': {'string': "translation"}})})

transifex/native/cds.py

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ def get(self, key):
4747
class CDSHandler(object):
4848
"""Handles communication with the Content Delivery Service."""
4949

50-
def __init__(self, configured_languages, token, secret=None, host=TRANSIFEX_CDS_HOST):
50+
def __init__(self, configured_languages, token, secret=None,
51+
host=TRANSIFEX_CDS_HOST):
5152
"""Constructor.
5253
5354
:param list configured_languages: a list of language codes for the
@@ -72,10 +73,13 @@ def fetch_languages(self):
7273
languages = []
7374

7475
try:
75-
response = requests.get(
76-
self.host + cds_url,
77-
headers=self._get_headers(),
78-
)
76+
last_response_status = 202
77+
while last_response_status == 202:
78+
response = requests.get(
79+
self.host + cds_url,
80+
headers=self._get_headers(),
81+
)
82+
last_response_status = response.status_code
7983

8084
if not response.ok:
8185
logger.error(
@@ -89,18 +93,16 @@ def fetch_languages(self):
8993
languages = json_content['data']
9094

9195
except (KeyError, ValueError):
92-
# Compatibility with python2.7 where `JSONDecodeError` doesn't exist
96+
# Compatibility with python2.7 where `JSONDecodeError` doesn't
97+
# exist
9398
logger.error(
9499
'Error retrieving languages from CDS: Malformed response')
95100
except requests.ConnectionError:
96101
logger.error(
97102
'Error retrieving languages from CDS: ConnectionError')
98103
except Exception as e:
99-
logger.error(
100-
'Error retrieving languages from CDS: UnknownError (`{}`)'.format(
101-
str(e)
102-
)
103-
)
104+
logger.error('Error retrieving languages from CDS: UnknownError '
105+
'(`{}`)'.format(str(e)))
104106

105107
return languages
106108

@@ -128,12 +130,16 @@ def fetch_translations(self, language_code=None):
128130
set(self.configured_language_codes):
129131

130132
try:
131-
response = requests.get(
132-
self.host + cds_url.format(language_code=language_code),
133-
headers=self._get_headers(
134-
etag=self.etags.get(language_code)
133+
last_response_status = 202
134+
while last_response_status == 202:
135+
response = requests.get(
136+
(self.host +
137+
cds_url.format(language_code=language_code)),
138+
headers=self._get_headers(
139+
etag=self.etags.get(language_code)
140+
)
135141
)
136-
)
142+
last_response_status = response.status_code
137143

138144
if not response.ok:
139145
logger.error(
@@ -155,19 +161,19 @@ def fetch_translations(self, language_code=None):
155161
)
156162

157163
except (KeyError, ValueError):
158-
# Compatibility with python2.7 where `JSONDecodeError` doesn't exist
159-
logger.error(
160-
'Error retrieving translations from CDS: Malformed response') # pragma no cover
164+
# Compatibility with python2.7 where `JSONDecodeError` doesn't
165+
# exist
166+
logger.error('Error retrieving translations from CDS: '
167+
'Malformed response') # pragma no cover
161168
translations[language_code] = (False, {}) # pragma no cover
162169
except requests.ConnectionError:
163170
logger.error(
164171
'Error retrieving translations from CDS: ConnectionError')
165172
translations[language_code] = (False, {})
166173
except Exception as e:
167174
logger.error(
168-
'Error retrieving translations from CDS: UnknownError (`{}`)'.format(
169-
str(e)
170-
)
175+
'Error retrieving translations from CDS: UnknownError '
176+
'(`{}`)'.format(str(e))
171177
) # pragma no cover
172178
translations[language_code] = (False, {})
173179

@@ -176,19 +182,17 @@ def fetch_translations(self, language_code=None):
176182
def push_source_strings(self, strings, purge=False):
177183
"""Push source strings to CDS.
178184
179-
:param list(SourceString) strings: a list of `SourceString` objects holding
180-
source strings
181-
:param bool purge: True deletes destination source content not included in
182-
pushed content.
183-
False appends the pushed content to destination source
184-
content.
185+
:param list(SourceString) strings: a list of `SourceString` objects
186+
holding source strings
187+
:param bool purge: True deletes destination source content not included
188+
in pushed content. False appends the pushed content to destination
189+
source content.
185190
:return: the HTTP response object
186191
:rtype: requests.Response
187192
"""
188193
if not self.secret:
189-
raise Exception(
190-
'You need to use `TRANSIFEX_SECRET` when pushing source content'
191-
)
194+
raise Exception('You need to use `TRANSIFEX_SECRET` when pushing '
195+
'source content')
192196

193197
cds_url = TRANSIFEX_CDS_URLS['PUSH_SOURCE_STRINGS']
194198

@@ -208,11 +212,8 @@ def push_source_strings(self, strings, purge=False):
208212
logger.error(
209213
'Error pushing source strings to CDS: ConnectionError')
210214
except Exception as e:
211-
logger.error(
212-
'Error pushing source strings to CDS: UnknownError (`{}`)'.format(
213-
str(e)
214-
)
215-
)
215+
logger.error('Error pushing source strings to CDS: UnknownError '
216+
'(`{}`)'.format(str(e)))
216217

217218
return response
218219

0 commit comments

Comments
 (0)