From efad6aad656b33caceaa069ea5586fa0dee9952e Mon Sep 17 00:00:00 2001 From: Andreas Nilsson Date: Wed, 25 Jun 2014 14:42:36 +0100 Subject: [PATCH 01/43] adapting unbabel py to new architecture --- localhost.env | 3 ++ runtests | 2 + tests/tests.py | 58 +++++++++++++++-------------- unbabel/__init__.py | 1 + unbabel/api.py | 91 +++++++++++++++++++++++++++------------------ 5 files changed, 91 insertions(+), 64 deletions(-) create mode 100644 localhost.env create mode 100755 runtests diff --git a/localhost.env b/localhost.env new file mode 100644 index 0000000..2287637 --- /dev/null +++ b/localhost.env @@ -0,0 +1,3 @@ +UNBABEL_TEST_USERNAME=gracaninja +UNBABEL_TEST_API_KEY=5a6406e31f77ef779c4024b1579f0f6103944c5e +UNBABEL_TEST_API_URL=http://0.0.0.0:8000/tapi/v2/ \ No newline at end of file diff --git a/runtests b/runtests new file mode 100755 index 0000000..435b218 --- /dev/null +++ b/runtests @@ -0,0 +1,2 @@ +export $(cat .env) +python -m unittest discover -s 'tests/' -p '*test*.py' \ No newline at end of file diff --git a/tests/tests.py b/tests/tests.py index affb945..c89ee8a 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -14,18 +14,20 @@ UNBABEL_TEST_USERNAME = os.environ.get('UNBABEL_TEST_USERNAME') UNBABEL_TEST_API_KEY = os.environ.get('UNBABEL_TEST_API_KEY') +UNBABEL_TEST_API_URL = os.environ.get('UNBABEL_TEST_API_URL') class TestUnbabelAPI(unittest.TestCase): @property def api(self): if not hasattr(self, '_api'): - self._api = UnbabelApi(username=UNBABEL_TEST_USERNAME, - api_key=UNBABEL_TEST_API_KEY) - + self._api = UnbabelApi(username = UNBABEL_TEST_USERNAME, + api_key = UNBABEL_TEST_API_KEY, + sandbox = True) + self._api.api_url = UNBABEL_TEST_API_URL return self._api - def test_api_get_language_pairs(self): + def xtest_api_get_language_pairs(self): pairs = self.api.get_language_pairs() self.assertIsInstance(pairs, list, 'Got something that is not a list') @@ -35,7 +37,7 @@ def test_api_get_language_pairs(self): [isinstance(p, LangPair) for p in pairs]), 'The pairs are not all instance of LangPair') - def test_api_get_available_tones(self): + def xtest_api_get_available_tones(self): tones = self.api.get_tones() self.assertIsInstance(tones, list, 'Got something that is not a list') @@ -45,7 +47,7 @@ def test_api_get_available_tones(self): [isinstance(t, Tone) for t in tones]), 'The tones are not all instance of Tone') - def test_api_get_topics(self): + def xtest_api_get_topics(self): topics = self.api.get_topics() self.assertIsInstance(topics, list, 'Got something that is not a list') @@ -55,7 +57,7 @@ def test_api_get_topics(self): [isinstance(t, Topic) for t in topics]), 'The topics are not all instance of Topic') - def test_api_post_translation(self): + def xtest_api_post_translation(self): data = { 'text': "This is a test translation", 'source_language': 'en', @@ -92,7 +94,7 @@ def test_api_post_translation(self): self.assertEqual(translation.text, trans.text, 'text not equal') self.assertEqual(translation.status, trans.status, 'status not equal') - def test_api_get_account(self): + def xtest_api_get_account(self): account = self.api.get_account() self.assertIsInstance(account, Account, 'Should be an Account instance') @@ -104,32 +106,28 @@ def test_api_get_account(self): self.assertIsInstance(account.email, unicode, 'Email is not unicode') def test_api_get_translations(self): + data = { + 'text': "This is a test translation", + 'source_language': 'en', + 'target_language': 'pt', + } + self.api.post_translations(**data) translations = self.api.get_translations() - self.assertIsInstance(translations, list, 'Translations is not list') - if not len(translations): - data = { - 'text': "This is a test translation", - 'source_language': 'en', - 'target_language': 'pt', - } - self.api.post_translations(**data) - translations = self.api.get_translations() - self.assertIsInstance(translations, list, - 'Translations is not list') - self.assertTrue( - reduce(lambda x, y: x and y, - [isinstance(t, Translation) for t in translations]), + self.assertIsInstance(translations, list, + 'Translations is not a list!') + self.assertTrue(len(translations) > 0, + 'Translations list is empty!') + self.assertTrue(all(isinstance(t, Translation) for t in translations), 'Items are not all instance of Translation') - def test_order_post(self): + def xtest_order_post(self): order = self.api.post_order() self.assertIsInstance(order, Order, 'Result is not an Order') self.assertIsNotNone(order.id, 'ID is None') self.assertEqual(order.status, 'new', 'Order status is not new') self.assertEqual(order.price, 0, 'Price is not 0') - - def test_job_add_job_to_order(self): + def xtest_job_add_job_to_order(self): order = self.api.post_order() data = { @@ -149,10 +147,10 @@ def test_job_add_job_to_order(self): self.assertEqual(job.target_language, data['target_language'], 'Job target_language is not correct') - def test_job_fail_mandatory_fields(self): + def xtest_job_fail_mandatory_fields(self): self.assertRaises(BadRequestException, self.api.post_job, 0, '', '', '') - def test_api_unauthorized_call(self): + def xtest_api_unauthorized_call(self): api = self.api self._api = UnbabelApi(username='fake_username', api_key='fake_api_key') @@ -162,7 +160,7 @@ def test_api_unauthorized_call(self): self._api = api - def test_job_add_job_to_order_all_params(self): + def xtest_job_add_job_to_order_all_params(self): order = self.api.post_order() data = { @@ -191,3 +189,7 @@ def test_job_add_job_to_order_all_params(self): 'Job source_language is not correct') self.assertEqual(job.target_language, data['target_language'], 'Job target_language is not correct') + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/unbabel/__init__.py b/unbabel/__init__.py index ed5eca9..ef65117 100644 --- a/unbabel/__init__.py +++ b/unbabel/__init__.py @@ -1,3 +1,4 @@ +import unbabel.api LOG_CONFIG = { 'version': 1, diff --git a/unbabel/api.py b/unbabel/api.py index 5118141..23c62e3 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -99,34 +99,43 @@ def from_json(cls, json): class Translation(object): - def __init__(self, - uid=-1, - text="", - translatedText=None, - target_language="", - source_language=None, - status=None, - translators=[], - topics=None, - price=None, - **kwargs): + def __init__( + self, + uid = -1, + text = "", + translation = None, + target_language = "", + source_language = None, + status = None, + translators = [], + topics = None, + price = None, + text_format = 'text', + origin = None, + price_plan = None, + client=None, + ): self.uid = uid self.text = text - self.translation = translatedText + self.translation = translation self.source_language = source_language self.target_language = target_language self.status = status self.translators = translators self.topics = topics self.price = price + self.text_format = text_format + self.origin = origin + self.price_plan = price_plan + self.client = client - def __repr__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) + #def __repr__(self): + # return "%s %s %s_%s" % ( + # self.uid, self.status, self.source_language, self.target_language) - def __str__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) + #def __str__(self): + # return "%s %s %s_%s" % ( + # self.uid, self.status, self.source_language, self.target_language) class Account(object): @@ -189,6 +198,8 @@ def __init__(self, username, api_key, sandbox=False): def api_call(self, uri, data=None): url = "{}{}".format(self.api_url, uri) + print "URL: {}".format(url) + print "HEADERS: {}".format(self.headers) if data is None: return requests.get(url, headers=self.headers) return requests.post(url, headers=self.headers, data=json.dumps(data)) @@ -196,13 +207,16 @@ def api_call(self, uri, data=None): def post_translations(self, text, target_language, source_language=None, ttype=None, tone=None, visibility=None, public_url=None, callback_url=None, topics=None, - instructions=None, uid=None): + instructions=None, uid=None, + text_format = 'text'): data = { - "text": text, - "target_language": target_language + 'text': text, + 'text_format': text_format, + 'target_language': target_language, } + if source_language: - data["source_language"] = source_language + data['source_language'] = source_language if ttype: data["type"] = ttype if tone: @@ -219,27 +233,27 @@ def post_translations(self, text, target_language, source_language=None, data["instructions"] = instructions if uid: data["uid"] = uid + result = self.api_call('translation/', data) if result.status_code == 201: log.debug(result.content) json_object = json.loads(result.content) - source_lang = json_object.get("source_language", None) translation = json_object.get("translation", None) - status = json_object.get("status", None) - topics = json_object.get('topics', None) translators = [Translator.from_json(t) for t in json_object.get("translators", [])] - translation = Translation(uid=json_object["uid"], - text=json_object["text"], - target_language=target_language, - source_language=source_lang, - translation=translation, - status=status, - translators=translators, - topics=topics, - price=json_object['price'], + translation = Translation( + uid = json_object["uid"], + text = json_object["text"], + text_format = json_object['text_format'], + target_language = json_object['target_language'], + source_language = json_object['source_language'], + translation = translation, + status = json_object['status'], + translators = translators, + topics = json_object.get('topics', None), + price = json_object['price'], ) return translation elif result.status_code == 401: @@ -254,8 +268,13 @@ def get_translations(self): Returns the translations requested by the user ''' result = self.api_call('translation/') - translations_json = json.loads(result.content)["objects"] - translations = [Translation(**tj) for tj in translations_json] + if result.status_code == 200: + translations_json = json.loads(result.content)["objects"] + translations = [Translation(**tj) for tj in translations_json] + else: + log.critical('Error status when requesting translation from server: {}!'.format( + result.status_code)) + translations = [] return translations From 1e04a687ae434f12b93f6de2f44eecd80c9e3930 Mon Sep 17 00:00:00 2001 From: Andreas Nilsson Date: Wed, 25 Jun 2014 17:34:18 +0100 Subject: [PATCH 02/43] Added status 'insufficient_balance'. --- tests/tests.py | 58 ++++++++++++++++++++++++++++---------------------- unbabel/api.py | 14 ++---------- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index a5267fa..8d54259 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -11,23 +11,21 @@ from unbabel.api import (UnbabelApi, Order, LangPair, Tone, Topic, Translation, Account, Job, BadRequestException) - -UNBABEL_TEST_USERNAME = os.environ.get('UNBABEL_TEST_USERNAME') -UNBABEL_TEST_API_KEY = os.environ.get('UNBABEL_TEST_API_KEY') -UNBABEL_TEST_API_URL = os.environ.get('UNBABEL_TEST_API_URL') - - class TestUnbabelAPI(unittest.TestCase): + UNBABEL_TEST_USERNAME = os.environ.get('UNBABEL_TEST_USERNAME') + UNBABEL_TEST_API_KEY = os.environ.get('UNBABEL_TEST_API_KEY') + UNBABEL_TEST_API_URL = os.environ.get('UNBABEL_TEST_API_URL') + @property def api(self): if not hasattr(self, '_api'): - self._api = UnbabelApi(username = UNBABEL_TEST_USERNAME, - api_key = UNBABEL_TEST_API_KEY, + self._api = UnbabelApi(username = self.UNBABEL_TEST_USERNAME, + api_key = self.UNBABEL_TEST_API_KEY, sandbox = True) - self._api.api_url = UNBABEL_TEST_API_URL + self._api.api_url = self.UNBABEL_TEST_API_URL return self._api - def xtest_api_get_language_pairs(self): + def test_api_get_language_pairs(self): pairs = self.api.get_language_pairs() self.assertIsInstance(pairs, list, 'Got something that is not a list') @@ -37,7 +35,7 @@ def xtest_api_get_language_pairs(self): [isinstance(p, LangPair) for p in pairs]), 'The pairs are not all instance of LangPair') - def xtest_api_get_available_tones(self): + def test_api_get_available_tones(self): tones = self.api.get_tones() self.assertIsInstance(tones, list, 'Got something that is not a list') @@ -47,7 +45,7 @@ def xtest_api_get_available_tones(self): [isinstance(t, Tone) for t in tones]), 'The tones are not all instance of Tone') - def xtest_api_get_topics(self): + def test_api_get_topics(self): topics = self.api.get_topics() self.assertIsInstance(topics, list, 'Got something that is not a list') @@ -57,7 +55,7 @@ def xtest_api_get_topics(self): [isinstance(t, Topic) for t in topics]), 'The topics are not all instance of Topic') - def xtest_api_post_translation(self): + def test_api_post_translation(self): data = { 'text': "This is a test translation", 'source_language': 'en', @@ -94,18 +92,18 @@ def xtest_api_post_translation(self): self.assertEqual(translation.text, trans.text, 'text not equal') - def xtest_api_get_account(self): + def test_api_get_account(self): account = self.api.get_account() self.assertIsInstance(account, Account, 'Should be an Account instance') self.assertIsInstance(account.username, unicode, 'Username is not unicode') - self.assertEqual(account.username, UNBABEL_TEST_USERNAME, + self.assertEqual(account.username, self.UNBABEL_TEST_USERNAME, 'Wrong username') self.assertIsInstance(account.balance, float, 'Balance is not float') self.assertIsInstance(account.email, unicode, 'Email is not unicode') - def xtest_api_get_translations(self): + def test_api_get_translations(self): data = { 'text': "This is a test translation", 'source_language': 'en', @@ -120,14 +118,14 @@ def xtest_api_get_translations(self): self.assertTrue(all(isinstance(t, Translation) for t in translations), 'Items are not all instance of Translation') - def xtest_order_post(self): + def test_order_post(self): order = self.api.post_order() self.assertIsInstance(order, Order, 'Result is not an Order') self.assertIsNotNone(order.id, 'ID is None') self.assertEqual(order.status, 'new', 'Order status is not new but %s'%order.status) self.assertEqual(order.price, 0, 'Price is not 0') - def xtest_job_add_job_to_order(self): + def test_job_add_job_to_order(self): order = self.api.post_order() data = { @@ -147,10 +145,10 @@ def xtest_job_add_job_to_order(self): self.assertEqual(job.target_language, data['target_language'], 'Job target_language is not correct') - def xtest_job_fail_mandatory_fields(self): + def test_job_fail_mandatory_fields(self): self.assertRaises(BadRequestException, self.api.post_job, 0, '', '', '') - def xtest_api_unauthorized_call(self): + def test_api_unauthorized_call(self): api = self.api self._api = UnbabelApi(username='fake_username', api_key='fake_api_key') @@ -160,7 +158,7 @@ def xtest_api_unauthorized_call(self): self._api = api - def xtest_job_add_job_to_order_all_params(self): + def test_job_add_job_to_order_all_params(self): order = self.api.post_order() data = { @@ -192,16 +190,26 @@ def xtest_job_add_job_to_order_all_params(self): def test_job_no_balance(self): - UNBABEL_TEST_USERNAME="gracaninja-1", - UNBABEL_TEST_API_KEY="d004dd5659e177d11ef9c22798b767a264f74b17" + self.UNBABEL_TEST_USERNAME="gracaninja-1" + self.UNBABEL_TEST_API_KEY="d004dd5659e177d11ef9c22798b767a264f74b17" + if hasattr(self, '_api'): delattr(self, '_api') + data = { 'text': "This is a test translation", 'source_language': 'en', 'target_language': 'pt', + 'ttype': 'paid' } - account = self.api.get_account() + + self.assertEqual(self.api.username,"gracaninja-1","API Username not correct %s"%self.api.username) + self.assertEqual(self.api.api_key,"d004dd5659e177d11ef9c22798b767a264f74b17","API key not correct %s"%self.api.api_key) + translation = self.api.post_translations(**data) - self.assertEqual(translation.status, "insufficient_funding", 'Job status not insufficient_funding but %s'%translation.status) + self.assertEqual(translation.status, "insufficient_balance", 'Job status not insufficient_balance but %s'%translation.status) + + self.UNBABEL_TEST_USERNAME = os.environ.get('UNBABEL_TEST_USERNAME') + self.UNBABEL_TEST_API_KEY = os.environ.get('UNBABEL_TEST_API_KEY') + if hasattr(self, '_api'): delattr(self, '_api') if __name__ == "__main__": diff --git a/unbabel/api.py b/unbabel/api.py index 76aea35..78a5664 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -201,16 +201,12 @@ def __init__(self, username, api_key, sandbox=False): self.api_key), 'content-type': 'application/json'} - - - def api_call(self, uri, data=None): url = "{}{}".format(self.api_url, uri) if data is None: return requests.get(url, headers=self.headers) return requests.post(url, headers=self.headers, data=json.dumps(data)) - def post_translations(self, text, target_language, @@ -225,14 +221,8 @@ def post_translations(self, uid=None, text_format="text" ): - - - #data = self.create_default_translation(text, target_language) - data = {} - for k, v in locals().iteritems(): - if v is self or v is data or v is None: - continue - data[k] = v + ## Collect args + data = {k: v for k, v in locals().iteritems() if not v in (self, None)} if self.is_bulk: self.bulk_data.append(data) From 2f3f6ef9e71eb5437ef880c36a16fcef0dc32773 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Wed, 2 Jul 2014 19:10:53 +0100 Subject: [PATCH 03/43] increased version for new architecture --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b5c9bb2..f22a5bb 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.27', + version='0.28', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From a37ed7849ea0173c53ce73d4509a4b1da8e28ceb Mon Sep 17 00:00:00 2001 From: Andreas Nilsson Date: Fri, 4 Jul 2014 09:56:21 +0100 Subject: [PATCH 04/43] Added missing resources and params. --- tests/tests.py | 11 +++++----- unbabel/api.py | 54 +++++++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index 8d54259..5e50b3a 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -72,7 +72,7 @@ def test_api_post_translation(self): self.assertEqual(translation.target_language, 'pt', 'Target language is not pt but %s'%translation.target_language) self.assertEqual(translation.text, data['text']) - self.assertEqual(translation.status, 'new', 'status is not new') + self.assertEqual(translation.status, 'New', 'Wrong status: [{}]'.format(translation.status)) self.assertIsNone(translation.topics, 'Topics is not None') self.assertIsInstance(translation.translators, list, 'Translators is not a list') @@ -122,7 +122,6 @@ def test_order_post(self): order = self.api.post_order() self.assertIsInstance(order, Order, 'Result is not an Order') self.assertIsNotNone(order.id, 'ID is None') - self.assertEqual(order.status, 'new', 'Order status is not new but %s'%order.status) self.assertEqual(order.price, 0, 'Price is not 0') def test_job_add_job_to_order(self): @@ -138,7 +137,6 @@ def test_job_add_job_to_order(self): job = self.api.post_job(**data) self.assertIsInstance(job, Job) self.assertEqual(job.order_id, order.id, 'Order ID is not equal') - self.assertEqual(job.status, 'new', 'Job status is not new but %s'%job.status) self.assertEqual(job.text, data['text'], 'Job text is not correct') self.assertEqual(job.source_language, data['source_language'], 'Job source_language is not correct') @@ -163,7 +161,7 @@ def test_job_add_job_to_order_all_params(self): data = { 'order_id': order.id, - 'uid': uuid.uuid4().hex, + 'id': uuid.uuid4().hex, 'text': "This is a test translation", 'source_language': 'en', 'target_language': 'pt', @@ -181,14 +179,12 @@ def test_job_add_job_to_order_all_params(self): job = self.api.post_job(**data) self.assertIsInstance(job, Job) self.assertEqual(job.order_id, order.id, 'Order ID is not equal') - self.assertEqual(job.status, 'new', 'Job status is not new but %s'%job.status) self.assertEqual(job.text, data['text'], 'Job text is not correct') self.assertEqual(job.source_language, data['source_language'], 'Job source_language is not correct') self.assertEqual(job.target_language, data['target_language'], 'Job target_language is not correct') - def test_job_no_balance(self): self.UNBABEL_TEST_USERNAME="gracaninja-1" self.UNBABEL_TEST_API_KEY="d004dd5659e177d11ef9c22798b767a264f74b17" @@ -211,6 +207,9 @@ def test_job_no_balance(self): self.UNBABEL_TEST_API_KEY = os.environ.get('UNBABEL_TEST_API_KEY') if hasattr(self, '_api'): delattr(self, '_api') + def test_pay_order(self): + order = self.api.post_order() + self.assertTrue(self.api.pay_order(order.id)) if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/unbabel/api.py b/unbabel/api.py index 78a5664..44c1cdb 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -116,7 +116,6 @@ def __init__( price_plan = None, balance = None, client=None, - ): self.uid = uid self.text = text @@ -155,21 +154,21 @@ def __unicode__(self): class Job(object): - def __init__(self, uid, order_id, status, source_language, target_language, - text, price, priority, creation_date): - self.uid = uid + def __init__(self, id, order_id, status, source_language, target_language, + text, price, tone, text_format): + self.id = id self.order_id = order_id self.status = status self.text = text self.price = price self.source_language = source_language self.target_language = target_language - self.creation_date = creation_date - self.priority = priority + self.tone = tone + self.text_format = text_format def __unicode__(self): - return u'order_id: {}, uid: {}, status: {}'.format( - self.order_id, self.uid, self.status) + return u'order_id: {}, id: {}, status: {}'.format( + self.order_id, self.id, self.status) class Order(object): @@ -382,8 +381,8 @@ def get_account(self): account = Account(**account_data) return account - def post_order(self): - data = {} # no input data, it's just a clean post + def post_order(self, callback_url = None): + data = {callback_url: callback_url} result = self.api_call('order/', data) if result.status_code == 201: json_object = json.loads(result.content) @@ -398,22 +397,21 @@ def post_order(self): raise BadRequestException(result.content) else: logger.debug(result) - raise Exception("Unknown Error") def post_job(self, order_id, text, source_language, target_language, - target_text='', text_format="text", uid=None, tone=None, + target_text='', text_format="text", id=None, tone=None, topic=[], visibility=None, instructions='', public_url=None, callback_url=None, job_type='paid'): data = { - 'order': order_id, + 'order_id': order_id, 'text': text, 'target_text': target_text, 'text_format': text_format, 'source_language': source_language, 'target_language': target_language, - 'uid': uid, + 'id': id, 'tone': tone, 'topic': topic, 'visibility': visibility, @@ -429,15 +427,15 @@ def post_job(self, order_id, text, source_language, target_language, json_object = json.loads(result.content) #log.debug(json_object) job = Job( - uid=json_object['uid'], - order_id=json_object['order'], - status=json_object['status'], - text=json_object['text'], + id=json_object['id'], + order_id = json_object['order']['id'], price=json_object['price'], source_language=json_object['source_language'], target_language=json_object['target_language'], - creation_date=json_object['creation_date'], - priority=json_object['priority'] + tone=json_object['tone'], + text = json_object['text'], + status = json_object['status'], + text_format=json_object['text_format'] ) return job elif result.status_code == 401: @@ -449,6 +447,22 @@ def post_job(self, order_id, text, source_language, target_language, #log.debug(result.content) raise Exception("Unknown Error") + def pay_order(self, order_id): + data = { 'order_id': order_id } + result = self.api_call('pay/', data) + + if result.status_code == 201: + json_object = json.loads(result.content) + order = Order(id, status, price) + return True + elif result.status_code == 401: + raise UnauthorizedException(result.content) + elif result.status_code == 400: + raise BadRequestException(result.content) + else: + logger.debug(result) + raise Exception("Unknown Error") + def get_word_count(self, text): result = self.api_call('wordcount/', {"text": text}) From d08031bed714ccfdc0403aac48f7d4af3cc00f6e Mon Sep 17 00:00:00 2001 From: Andreas Nilsson Date: Fri, 4 Jul 2014 10:27:42 +0100 Subject: [PATCH 05/43] Added missing params. --- unbabel/api.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index 44c1cdb..b78efe3 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -154,9 +154,10 @@ def __unicode__(self): class Job(object): - def __init__(self, id, order_id, status, source_language, target_language, + def __init__(self, id, uid, order_id, status, source_language, target_language, text, price, tone, text_format): self.id = id + self.uid = uid self.order_id = order_id self.status = status self.text = text @@ -400,7 +401,7 @@ def post_order(self, callback_url = None): raise Exception("Unknown Error") def post_job(self, order_id, text, source_language, target_language, - target_text='', text_format="text", id=None, tone=None, + target_text='', text_format="text", uid=None, tone=None, topic=[], visibility=None, instructions='', public_url=None, callback_url=None, job_type='paid'): @@ -411,7 +412,7 @@ def post_job(self, order_id, text, source_language, target_language, 'text_format': text_format, 'source_language': source_language, 'target_language': target_language, - 'id': id, + 'uid': uid, 'tone': tone, 'topic': topic, 'visibility': visibility, @@ -428,6 +429,7 @@ def post_job(self, order_id, text, source_language, target_language, #log.debug(json_object) job = Job( id=json_object['id'], + uid=json_object['uid'], order_id = json_object['order']['id'], price=json_object['price'], source_language=json_object['source_language'], From 129b938e892aa899b29717bc57145fb915c4a3a2 Mon Sep 17 00:00:00 2001 From: Andreas Nilsson Date: Fri, 4 Jul 2014 10:44:35 +0100 Subject: [PATCH 06/43] Fixed failing tests. --- tests/tests.py | 2 +- unbabel/api.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index 5e50b3a..23951a6 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -161,7 +161,7 @@ def test_job_add_job_to_order_all_params(self): data = { 'order_id': order.id, - 'id': uuid.uuid4().hex, + 'uid': uuid.uuid4().hex, 'text': "This is a test translation", 'source_language': 'en', 'target_language': 'pt', diff --git a/unbabel/api.py b/unbabel/api.py index b78efe3..ec382d8 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -454,8 +454,6 @@ def pay_order(self, order_id): result = self.api_call('pay/', data) if result.status_code == 201: - json_object = json.loads(result.content) - order = Order(id, status, price) return True elif result.status_code == 401: raise UnauthorizedException(result.content) From 562977cc00823a55b6ac4fbe466fb8de43ec2a8e Mon Sep 17 00:00:00 2001 From: gracaninja Date: Fri, 4 Jul 2014 17:01:14 +0100 Subject: [PATCH 07/43] new updates to new architecture --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f22a5bb..0d30524 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.28', + version='0.29', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From 1c6b4f11d1833ca25cdc8ad093696a80a4e7a890 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Mon, 7 Jul 2014 14:37:18 +0100 Subject: [PATCH 08/43] change field translation to translationText to match the output from unbabel server --- unbabel/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index ec382d8..68b4127 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -104,7 +104,7 @@ def __init__( self, uid = -1, text = "", - translation = None, + translatedText = None, target_language = "", source_language = None, status = None, @@ -119,7 +119,7 @@ def __init__( ): self.uid = uid self.text = text - self.translation = translation + self.translation = translatedText self.source_language = source_language self.target_language = target_language self.status = status From 9d821f0ca1d907f33ace43835b9ce2e29f7bb59e Mon Sep 17 00:00:00 2001 From: gracaninja Date: Mon, 7 Jul 2014 14:37:51 +0100 Subject: [PATCH 09/43] small fix on api --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0d30524..a2270dc 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.29', + version='0.30', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From 1fc2d5ac9104bda72bb1b8a3f9b53353c37be538 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Mon, 7 Jul 2014 14:44:59 +0100 Subject: [PATCH 10/43] small bug fix --- setup.py | 2 +- unbabel/api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a2270dc..ad4ec48 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.30', + version='0.31', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 68b4127..26164c9 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -242,7 +242,7 @@ def _build_translation_object(self, json_object): text = json_object["text"], target_language = json_object.get('target_language', None), source_language = json_object.get('source_language', None), - translation = json_object.get('translation', None), + translatedText = json_object.get('translatedText', None), status = json_object.get('status', None), translators = translators, topics = json_object.get('topics', None), From ab790c077471b74b7f0e03c39a487321ab925058 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Tue, 8 Jul 2014 17:16:46 +0100 Subject: [PATCH 11/43] added target_text to unbabel-py --- setup.py | 2 +- unbabel/api.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index ad4ec48..7ee4184 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.31', + version='0.32', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 26164c9..99ebb85 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -219,7 +219,8 @@ def post_translations(self, topics = None, instructions=None, uid=None, - text_format="text" + text_format="text", + target_text=None, ): ## Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} From 53158e3344334a77fb2cde68634531dd3bd0d851 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Wed, 16 Jul 2014 14:56:33 +0100 Subject: [PATCH 12/43] added origin keyword --- setup.py | 2 +- unbabel/api.py | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 7ee4184..78c7d99 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.32', + version='0.33', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 99ebb85..e4f4122 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -221,6 +221,7 @@ def post_translations(self, uid=None, text_format="text", target_text=None, + origin = None, ): ## Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} @@ -383,8 +384,15 @@ def get_account(self): account = Account(**account_data) return account - def post_order(self, callback_url = None): - data = {callback_url: callback_url} + def post_order(self, + callback_url = None, + origin = None): + data = {} + if callback_url is not None: + data["callback_url"] = callback_url + if origin is not None: + data["origin"] = origin + result = self.api_call('order/', data) if result.status_code == 201: json_object = json.loads(result.content) @@ -398,13 +406,24 @@ def post_order(self, callback_url = None): elif result.status_code == 400: raise BadRequestException(result.content) else: - logger.debug(result) + log.debug(result) raise Exception("Unknown Error") - def post_job(self, order_id, text, source_language, target_language, - target_text='', text_format="text", uid=None, tone=None, - topic=[], visibility=None, instructions='', public_url=None, - callback_url=None, job_type='paid'): + def post_job(self, + order_id, + text, + source_language, + target_language, + target_text='', + text_format="text", + uid=None, + tone=None, + topic=[], + visibility=None, + instructions='', + public_url=None, + callback_url=None, + job_type='paid'): data = { 'order_id': order_id, From 56ec95f220d35e08f4c8ee9fae998f6a7bc31f0f Mon Sep 17 00:00:00 2001 From: gracaninja Date: Tue, 12 Aug 2014 16:11:53 +0100 Subject: [PATCH 13/43] fixed broken argument ttype to type --- setup.py | 2 +- unbabel/api.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 78c7d99..ca3cff7 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.33', + version='0.34', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index e4f4122..ab4317c 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -211,7 +211,7 @@ def post_translations(self, text, target_language, source_language=None, - ttype=None, + type=None, tone=None, visibility=None, public_url=None, @@ -465,7 +465,7 @@ def post_job(self, elif result.status_code == 400: raise BadRequestException(result.content) else: - log.debug('Got a HTTP Error [{}]'.format(result.status_code)) + log.debug('Got a HTTP Error [{}] [{}]'.format(result.status_code,result.content)) #log.debug(result.content) raise Exception("Unknown Error") From 49c942ddf60be1fde7ae0a3493b47a1af049755c Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 22 Aug 2014 12:47:37 +0100 Subject: [PATCH 14/43] get_user implemented using the internal api --- unbabel/api.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index ab4317c..e6a8026 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -201,8 +201,11 @@ def __init__(self, username, api_key, sandbox=False): self.api_key), 'content-type': 'application/json'} - def api_call(self, uri, data=None): - url = "{}{}".format(self.api_url, uri) + def api_call(self, uri, data=None, internal_api_call=False): + api_url = self.api_url + if internal_api_call: + api_url = api_url.replace('/tapi/v2/', '/api/v1/') + url = "{}{}".format(api_url, uri) if data is None: return requests.get(url, headers=self.headers) return requests.post(url, headers=self.headers, data=json.dumps(data)) @@ -320,7 +323,6 @@ def get_translations(self): translations = [] return translations - def get_translation(self, uid): ''' Returns a translation with the given id @@ -494,4 +496,14 @@ def get_word_count(self, text): raise Exception("Unknown Error") + def get_user(self): + result = self.api_call('app/user/', internal_api_call=True) + + if result.status_code == 200: + return json.loads(result.content) + else: + log.debug('Got a HTTP Error [{}]'.format(result.status_code)) + raise Exception("Unknown Error: %s" % result.status_code) + + __all__ = ['UnbabelApi'] From ad29b432c9f3374fab1bd85d596edbfb62684a01 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 22 Aug 2014 13:31:46 +0100 Subject: [PATCH 15/43] inc version number --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ca3cff7..c69c30c 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.34', + version='0.35', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From fc12d76cccd5904db812d5c143736b934a9d0eeb Mon Sep 17 00:00:00 2001 From: Arne Neumann Date: Thu, 4 Sep 2014 10:00:51 +0200 Subject: [PATCH 16/43] fixed link to documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6582c42..dda218e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Python SDK for the Unbabel REST API Documentation: ============= -Please visit our documentation page at https://github.com/Unbabel +Please visit our documentation page at https://github.com/Unbabel/unbabel_api From 6a35bb79c577f2be93ffea1270bc86a5c25d0636 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 15 Sep 2014 14:02:18 +0100 Subject: [PATCH 17/43] changing to unbabel.com --- unbabel/api.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index e6a8026..2f3b6f8 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -16,7 +16,7 @@ UNBABEL_SANDBOX_API_URL = os.environ.get('UNBABEL_SANDOX_API_URL', "http://sandbox.unbabel.com/tapi/v2/") UNBABEL_API_URL = os.environ.get('UNBABEL_API_URL', - "https://www.unbabel.co/tapi/v2/") + "https://www.unbabel.com/tapi/v2/") class UnauthorizedException(Exception): @@ -197,8 +197,7 @@ def __init__(self, username, api_key, sandbox=False): self.api_url = api_url self.is_bulk = False self.headers = { - 'Authorization': 'ApiKey {}:{}'.format(self.username, - self.api_key), + 'Authorization': 'ApiKey {}:{}'.format(self.username, self.api_key), 'content-type': 'application/json'} def api_call(self, uri, data=None, internal_api_call=False): From 0add1ef3858e92e3871a4fe1fd41ef4273d77fc8 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 15 Sep 2014 14:02:38 +0100 Subject: [PATCH 18/43] incrementing version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c69c30c..a39dce0 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.35', + version='0.36', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From d05213236b2968684c4ae69d567e0cdb7003fc95 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 15 Sep 2014 19:55:54 +0100 Subject: [PATCH 19/43] www.unbabel.com -> unbabel.com --- setup.py | 2 +- unbabel/api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a39dce0..2a12bc2 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.36', + version='0.37', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 2f3b6f8..a78b87c 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -16,7 +16,7 @@ UNBABEL_SANDBOX_API_URL = os.environ.get('UNBABEL_SANDOX_API_URL', "http://sandbox.unbabel.com/tapi/v2/") UNBABEL_API_URL = os.environ.get('UNBABEL_API_URL', - "https://www.unbabel.com/tapi/v2/") + "https://unbabel.com/tapi/v2/") class UnauthorizedException(Exception): From 481bcfeb4b7c457bae6cf0852c3afd18da9fc271 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Tue, 28 Oct 2014 14:38:50 +0000 Subject: [PATCH 20/43] update get translation so that id does not blow up on error --- setup.py | 2 +- unbabel/api.py | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 2a12bc2..86e9ed8 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.37', + version='0.38', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index a78b87c..7a48082 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -317,7 +317,7 @@ def get_translations(self): translations_json = json.loads(result.content)["objects"] translations = [Translation(**tj) for tj in translations_json] else: - log.critical('Error status when requesting translation from server: {}!'.format( + log.critical('Error status when fetching translation from server: {}!'.format( result.status_code)) translations = [] return translations @@ -327,7 +327,12 @@ def get_translation(self, uid): Returns a translation with the given id ''' result = self.api_call('translation/{}/'.format(uid)) - translation = Translation(**json.loads(result.content)) + if result.status_code == 200: + translation = Translation(**json.loads(result.content)) + else: + log.critical('Error status when fetching translation from server: {}!'.format( + result.status_code)) + raise ValueError(result.content) return translation def get_language_pairs(self, train_langs=None): From 27d547ddc22271ab6f981b66b688f0c6a8d13422 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Wed, 5 Nov 2014 18:05:54 +0000 Subject: [PATCH 21/43] added filter to get_translations --- setup.py | 2 +- unbabel/api.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 86e9ed8..1a92be7 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.38', + version='0.39', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 7a48082..682f838 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -308,11 +308,14 @@ def post_bulk_translations(self, translations): - def get_translations(self): + def get_translations(self,status=None): ''' Returns the translations requested by the user ''' - result = self.api_call('translation/') + if status is not None: + result = self.api_call('translation/?status=%s'%status) + else: + result = self.api_call('translation/') if result.status_code == 200: translations_json = json.loads(result.content)["objects"] translations = [Translation(**tj) for tj in translations_json] From b1df5d0d74266e6e7c9294a4dc02136c6d48deef Mon Sep 17 00:00:00 2001 From: gracaninja Date: Tue, 17 Feb 2015 19:02:09 +0000 Subject: [PATCH 22/43] added simple xliff parser --- requirements.py | 1 + setup.py | 2 +- unbabel/api.py | 98 -------------------------------------- unbabel/xliff_converter.py | 69 +++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 99 deletions(-) create mode 100644 unbabel/xliff_converter.py diff --git a/requirements.py b/requirements.py index f229360..1190bd8 100644 --- a/requirements.py +++ b/requirements.py @@ -1 +1,2 @@ requests +beautifulsoup4 diff --git a/setup.py b/setup.py index 1a92be7..e8c26b2 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.39', + version='0.40', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 682f838..a58eed0 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -393,104 +393,6 @@ def get_account(self): account = Account(**account_data) return account - def post_order(self, - callback_url = None, - origin = None): - data = {} - if callback_url is not None: - data["callback_url"] = callback_url - if origin is not None: - data["origin"] = origin - - result = self.api_call('order/', data) - if result.status_code == 201: - json_object = json.loads(result.content) - id = json_object.get('id') - status = json_object.get('status') - price = json_object.get('price') - order = Order(id, status, price) - return order - elif result.status_code == 401: - raise UnauthorizedException(result.content) - elif result.status_code == 400: - raise BadRequestException(result.content) - else: - log.debug(result) - raise Exception("Unknown Error") - - def post_job(self, - order_id, - text, - source_language, - target_language, - target_text='', - text_format="text", - uid=None, - tone=None, - topic=[], - visibility=None, - instructions='', - public_url=None, - callback_url=None, - job_type='paid'): - - data = { - 'order_id': order_id, - 'text': text, - 'target_text': target_text, - 'text_format': text_format, - 'source_language': source_language, - 'target_language': target_language, - 'uid': uid, - 'tone': tone, - 'topic': topic, - 'visibility': visibility, - 'instructions': instructions, - 'public_url': public_url, - 'callback_url': callback_url, - 'type': job_type, - } - - result = self.api_call('job/', data) - - if result.status_code == 201: - json_object = json.loads(result.content) - #log.debug(json_object) - job = Job( - id=json_object['id'], - uid=json_object['uid'], - order_id = json_object['order']['id'], - price=json_object['price'], - source_language=json_object['source_language'], - target_language=json_object['target_language'], - tone=json_object['tone'], - text = json_object['text'], - status = json_object['status'], - text_format=json_object['text_format'] - ) - return job - elif result.status_code == 401: - raise UnauthorizedException(result.content) - elif result.status_code == 400: - raise BadRequestException(result.content) - else: - log.debug('Got a HTTP Error [{}] [{}]'.format(result.status_code,result.content)) - #log.debug(result.content) - raise Exception("Unknown Error") - - def pay_order(self, order_id): - data = { 'order_id': order_id } - result = self.api_call('pay/', data) - - if result.status_code == 201: - return True - elif result.status_code == 401: - raise UnauthorizedException(result.content) - elif result.status_code == 400: - raise BadRequestException(result.content) - else: - logger.debug(result) - raise Exception("Unknown Error") def get_word_count(self, text): result = self.api_call('wordcount/', {"text": text}) diff --git a/unbabel/xliff_converter.py b/unbabel/xliff_converter.py new file mode 100644 index 0000000..94ed447 --- /dev/null +++ b/unbabel/xliff_converter.py @@ -0,0 +1,69 @@ +__author__ = 'joaograca' + +from bs4 import BeautifulSoup + +def generate_xliff(entry_dict): + """ + Given a dictionary with keys = ids + and values equals to strings generates + and xliff file to send to unbabel. + + Example: + {"123": "This is blue car", + "234": "This house is yellow" + } + + returns + + + + + + T2 apartment, as new building with swimming pool, sauna and gym. Inserted in Quinta da Beloura 1, which offers a variety of services such as private security 24 hours, tennis, golf, hotel, restaurants, and more. The apartment has air conditioning in all rooms, central heating, balcony and security screen for children in all windows. + + + + + + + """ + entries = "" + for key,value in entry_dict.iteritems(): + entries+=create_trans_unit(key,value).strip()+"\n" + xliff_str = get_head_xliff().strip()+"\n"+entries+get_tail_xliff().strip() + return xliff_str + +def get_head_xliff(): + return ''' + + + + + ''' +def get_tail_xliff(): + return ''' + + + + ''' + +def create_trans_unit(key, value): + return ''' + + + %s + + + '''%(key,value) + +def get_dictionary_from_xliff(xliff_text,side="target"): + soup = BeautifulSoup(xliff_text) + trans_units = soup.find_all("trans-unit") + result_dic = {} + for trans_unit in trans_units: + _id = trans_unit["id"] + if side == "target": + result_dic[_id] = trans_unit.target.text.strip() + else: + result_dic[_id] = trans_unit.source.text.strip() + return result_dic \ No newline at end of file From 7f1be617e7744d1dec82e78a97f6631c5124f8c2 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Wed, 18 Feb 2015 10:40:23 +0000 Subject: [PATCH 23/43] small fixes on xliff to remove languages from headers. Added bs4 to setup as requirements. bumped version for pipy --- setup.py | 3 ++- unbabel/xliff_converter.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index e8c26b2..e682792 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.40', + version='0.41', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', @@ -13,6 +13,7 @@ }, install_requires=[ 'requests', + 'beautifulsoup4', ], url = 'https://github.com/Unbabel/unbabel-py', download_url = 'https://github.com/Unbabel/unbabel-py/tarball/0.1', diff --git a/unbabel/xliff_converter.py b/unbabel/xliff_converter.py index 94ed447..f054818 100644 --- a/unbabel/xliff_converter.py +++ b/unbabel/xliff_converter.py @@ -36,7 +36,7 @@ def generate_xliff(entry_dict): def get_head_xliff(): return ''' - + ''' From 22834802b4e039ec84ca3382a5c54a22e5eff941 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Tue, 31 Mar 2015 03:15:24 +0100 Subject: [PATCH 24/43] small hack on building dictionary --- setup.py | 2 +- unbabel/xliff_converter.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index e682792..cbc7e6d 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.41', + version='0.42', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/xliff_converter.py b/unbabel/xliff_converter.py index f054818..a2ae736 100644 --- a/unbabel/xliff_converter.py +++ b/unbabel/xliff_converter.py @@ -63,7 +63,10 @@ def get_dictionary_from_xliff(xliff_text,side="target"): for trans_unit in trans_units: _id = trans_unit["id"] if side == "target": - result_dic[_id] = trans_unit.target.text.strip() + if trans_unit.target is None: + result_dic[_id] = trans_unit.source.text.strip() + else: + result_dic[_id] = trans_unit.target.text.strip() else: result_dic[_id] = trans_unit.source.text.strip() - return result_dic \ No newline at end of file + return result_dic From f839dfdb0c57d9a8df98f45cabb9518bcbe81e13 Mon Sep 17 00:00:00 2001 From: gracaninja Date: Wed, 29 Apr 2015 16:04:11 +0100 Subject: [PATCH 25/43] addec client_owner_email_param --- setup.py | 2 +- unbabel/api.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cbc7e6d..c6eb4ba 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.42', + version='0.43', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index a58eed0..931a4c4 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -224,6 +224,7 @@ def post_translations(self, text_format="text", target_text=None, origin = None, + client_owner_email=None, ): ## Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} From 07baa148dd3c63f53e2922d915d7bfa8749f2300 Mon Sep 17 00:00:00 2001 From: David Gomes Date: Thu, 16 Jul 2015 11:37:46 +0100 Subject: [PATCH 26/43] Fixes the BeautifulSoup call. Explicitly defines html.parser as the parser to avoid BeautifulSoup warnings when using this function. --- unbabel/xliff_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unbabel/xliff_converter.py b/unbabel/xliff_converter.py index a2ae736..34f6fb3 100644 --- a/unbabel/xliff_converter.py +++ b/unbabel/xliff_converter.py @@ -57,7 +57,7 @@ def create_trans_unit(key, value): '''%(key,value) def get_dictionary_from_xliff(xliff_text,side="target"): - soup = BeautifulSoup(xliff_text) + soup = BeautifulSoup(xliff_text, "html.parser") trans_units = soup.find_all("trans-unit") result_dic = {} for trans_unit in trans_units: From 9e5ef6573069bbcc95651809a97d0d130ccf0004 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Tue, 12 Jan 2016 18:37:00 +0000 Subject: [PATCH 27/43] Removed slash from package_dir --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c6eb4ba..622f7a7 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ 'unbabel', ], package_dir={ - 'unbabel': 'unbabel/', + 'unbabel': 'unbabel', }, install_requires=[ 'requests', From 747e4ffc7e2230e0905e3cfc1b0df63eeac3a13c Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Tue, 12 Jan 2016 18:57:52 +0000 Subject: [PATCH 28/43] Bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 622f7a7..cdd9c8b 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.43', + version='0.44', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From 4601c67fa00d1e5c395a189d2ac50f5019cf5fd7 Mon Sep 17 00:00:00 2001 From: Joao Graca Date: Tue, 10 May 2016 16:47:34 +0100 Subject: [PATCH 29/43] added endpoints for progressive translation --- setup.py | 2 +- unbabel/api.py | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cdd9c8b..adbcbf5 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.44', + version='0.45', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', diff --git a/unbabel/api.py b/unbabel/api.py index 931a4c4..dae9090 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -141,6 +141,41 @@ def __str__(self): self.uid, self.status, self.source_language, self.target_language) +class MTTranslation(object): + def __init__( + self, + uid = -1, + text = "", + translatedText = None, + target_language = "", + source_language = None, + status = None, + topics = None, + text_format = 'text', + origin = None, + client=None, + ): + self.uid = uid + self.text = text + self.translation = translatedText + self.source_language = source_language + self.target_language = target_language + self.status = status + self.topics = topics + self.text_format = text_format + self.origin = origin + self.client = client + + def __repr__(self): + return "%s %s %s_%s" % ( + self.uid, self.status, self.source_language, self.target_language) + + def __str__(self): + return "%s %s %s_%s" % ( + self.uid, self.status, self.source_language, self.target_language) + + + class Account(object): def __init__(self, username, email, balance): self.username = username @@ -235,6 +270,35 @@ def post_translations(self, return self._make_request(data) + + def post_mt_translations(self, + text, + target_language, + source_language=None, + tone=None, + callback_url = None, + topics = None, + instructions=None, + uid=None, + text_format="text", + origin = None, + client_owner_email=None, + ): + ## Collect args + data = {k: v for k, v in locals().iteritems() if not v in (self, None)} + + result = requests.post("%smt_translation/"% self.api_url, headers=self.headers, data=json.dumps(data)) + if result.status_code in (201, 202): + json_object = json.loads(result.content) + toret = self._build_mt_translation_object(json_object) + return toret + elif result.status_code == 401: + raise UnauthorizedException(result.content) + elif result.status_code == 400: + raise BadRequestException(result.content) + else: + raise Exception("Unknown Error return status %d: %s", result.status_code, result.content[0:100]) + def _build_translation_object(self, json_object): source_lang = json_object.get("source_language",None) translation = json_object.get("translation",None) @@ -261,6 +325,26 @@ def _build_translation_object(self, json_object): return translation + def _build_mt_translation_object(self, json_object): + source_lang = json_object.get("source_language",None) + translation = json_object.get("translation",None) + status = json_object.get("status",None) + + translation = MTTranslation( + uid = json_object["uid"], + text = json_object["text"], + target_language = json_object.get('target_language', None), + source_language = json_object.get('source_language', None), + translatedText = json_object.get('translatedText', None), + status = json_object.get('status', None), + topics = json_object.get('topics', None), + text_format = json_object.get('text_format', "text"), + origin = json_object.get('origin', None), + client = json_object.get('client', None), + ) + return translation + + def _make_request(self, data): #headers={'Authorization': 'ApiKey %s:%s'%(self.username,self.api_key),'content-type': 'application/json'} @@ -339,6 +423,44 @@ def get_translation(self, uid): raise ValueError(result.content) return translation + def upgrade_mt_translation(self, uid): + api_url = self.api_url + uri = 'mt_translation/{}/'.format(uid) + url = "{}{}".format(api_url, uri) + data = {"status":"upgrade"} + return requests.patch(url, headers=self.headers, data=json.dumps(data)) + + + def get_mt_translations(self,status=None): + ''' + Returns the translations requested by the user + ''' + if status is not None: + result = self.api_call('mt_translation/?status=%s'%status) + else: + result = self.api_call('mt_translation/') + if result.status_code == 200: + translations_json = json.loads(result.content)["objects"] + translations = [Translation(**tj) for tj in translations_json] + else: + log.critical('Error status when fetching machine translation from server: {}!'.format( + result.status_code)) + translations = [] + return translations + + def get_mt_translation(self, uid): + ''' + Returns a translation with the given id + ''' + result = self.api_call('mt_translation/{}/'.format(uid)) + if result.status_code == 200: + translation = Translation(**json.loads(result.content)) + else: + log.critical('Error status when fetching machine translation from server: {}!'.format( + result.status_code)) + raise ValueError(result.content) + return translation + def get_language_pairs(self, train_langs=None): ''' Returns the language pairs available on unbabel From dd5289d39eddd21ccc736181b56954586753edc8 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Fri, 27 May 2016 10:04:19 +0100 Subject: [PATCH 30/43] Passing new argument on mt upgrade to overwrite some properties --- unbabel/api.py | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index dae9090..1b78e01 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -115,8 +115,7 @@ def __init__( origin = None, price_plan = None, balance = None, - client=None, - ): + client=None): self.uid = uid self.text = text self.translation = translatedText @@ -153,8 +152,7 @@ def __init__( topics = None, text_format = 'text', origin = None, - client=None, - ): + client=None): self.uid = uid self.text = text self.translation = translatedText @@ -270,7 +268,6 @@ def post_translations(self, return self._make_request(data) - def post_mt_translations(self, text, target_language, @@ -282,9 +279,8 @@ def post_mt_translations(self, uid=None, text_format="text", origin = None, - client_owner_email=None, - ): - ## Collect args + client_owner_email=None): + # Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} result = requests.post("%smt_translation/"% self.api_url, headers=self.headers, data=json.dumps(data)) @@ -324,7 +320,6 @@ def _build_translation_object(self, json_object): ) return translation - def _build_mt_translation_object(self, json_object): source_lang = json_object.get("source_language",None) translation = json_object.get("translation",None) @@ -344,7 +339,6 @@ def _build_mt_translation_object(self, json_object): ) return translation - def _make_request(self, data): #headers={'Authorization': 'ApiKey %s:%s'%(self.username,self.api_key),'content-type': 'application/json'} @@ -370,8 +364,6 @@ def _make_request(self, data): else: raise Exception("Unknown Error return status %d: %s", result.status_code, result.content[0:100]) - - def start_bulk_transaction(self): self.bulk_data = [] self.is_bulk = True @@ -391,8 +383,6 @@ def post_bulk_translations(self, translations): return self._post_bulk() - - def get_translations(self,status=None): ''' Returns the translations requested by the user @@ -423,15 +413,20 @@ def get_translation(self, uid): raise ValueError(result.content) return translation - def upgrade_mt_translation(self, uid): + def upgrade_mt_translation(self, uid, properties=None): + """ + :param uid: + :param properties: This is suppose to be a dictionary with new + properties values to be replaced on the upgraded job + :return: + """ api_url = self.api_url uri = 'mt_translation/{}/'.format(uid) url = "{}{}".format(api_url, uri) - data = {"status":"upgrade"} + data = {"status": "upgrade", "properties": properties} return requests.patch(url, headers=self.headers, data=json.dumps(data)) - - def get_mt_translations(self,status=None): + def get_mt_translations(self, status=None): ''' Returns the translations requested by the user ''' @@ -516,7 +511,6 @@ def get_account(self): account = Account(**account_data) return account - def get_word_count(self, text): result = self.api_call('wordcount/', {"text": text}) @@ -527,7 +521,6 @@ def get_word_count(self, text): log.debug('Got a HTTP Error [{}]'.format(result.status_code)) raise Exception("Unknown Error") - def get_user(self): result = self.api_call('app/user/', internal_api_call=True) From 36273ff279c2aa1eed26fa1a7967b97b23ee9cea Mon Sep 17 00:00:00 2001 From: Artur Ventura Date: Mon, 19 Dec 2016 11:34:48 +0000 Subject: [PATCH 31/43] Bugfix raise error when not able to contact Unbabel --- unbabel/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index 1b78e01..198bb95 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -478,9 +478,9 @@ def get_language_pairs(self, train_langs=None): name=lang_json["lang_pair"][ "target_language"]["name"]) ) for lang_json in langs_json["objects"]] - except: + except Exception, e: log.exception("Error decoding get language pairs") - languages = [] + raise e return languages def get_tones(self): From d92c178f66a6428cad98eeeed39c48bd18afdd23 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Mon, 19 Dec 2016 11:41:06 +0000 Subject: [PATCH 32/43] Bumped setup version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index adbcbf5..8041060 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.45', + version='0.46', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', From 5013cb14c24296e971fe4bcd0e19c0da52fc7d6b Mon Sep 17 00:00:00 2001 From: LLCampos Date: Wed, 11 Jan 2017 19:58:12 +0000 Subject: [PATCH 33/43] fix #7 --- unbabel/api.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unbabel/api.py b/unbabel/api.py index 198bb95..0c0766e 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -115,7 +115,8 @@ def __init__( origin = None, price_plan = None, balance = None, - client=None): + client=None, + order_number=None): self.uid = uid self.text = text self.translation = translatedText @@ -130,6 +131,7 @@ def __init__( self.price_plan = price_plan self.client = client self.balance = balance + self.order_number = order_number def __repr__(self): return "%s %s %s_%s" % ( From 09ec51f935ac897bb0d3ac8d8e1eb891f4e1ee80 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Fri, 9 Jun 2017 10:46:02 +0100 Subject: [PATCH 34/43] Fix sandbox url --- unbabel/api.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index 0c0766e..20d4d21 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -1,8 +1,3 @@ -''' -Created on Dec 13, 2013 - -@author: joaograca -''' import json import logging import os @@ -13,10 +8,10 @@ import copy -UNBABEL_SANDBOX_API_URL = os.environ.get('UNBABEL_SANDOX_API_URL', - "http://sandbox.unbabel.com/tapi/v2/") -UNBABEL_API_URL = os.environ.get('UNBABEL_API_URL', - "https://unbabel.com/tapi/v2/") +UNBABEL_SANDBOX_API_URL = os.environ.get( + 'UNBABEL_SANDOX_API_URL', 'https://sandbox.unbabel.com/tapi/v2/') +UNBABEL_API_URL = os.environ.get( + 'UNBABEL_API_URL', 'https://unbabel.com/tapi/v2/') class UnauthorizedException(Exception): From 3326f86a47623296e9754eab9a0ad49d5f839649 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Fri, 9 Jun 2017 10:46:15 +0100 Subject: [PATCH 35/43] Bump version to 0.49 --- setup.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/setup.py b/setup.py index 8041060..4447677 100644 --- a/setup.py +++ b/setup.py @@ -1,25 +1,25 @@ from setuptools import setup setup(name='unbabel-py', - version='0.46', + version='0.49', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='gracaninja@unbabel.co', packages=[ 'unbabel', - ], + ], package_dir={ - 'unbabel': 'unbabel', - }, + 'unbabel': 'unbabel', + }, install_requires=[ - 'requests', - 'beautifulsoup4', - ], - url = 'https://github.com/Unbabel/unbabel-py', - download_url = 'https://github.com/Unbabel/unbabel-py/tarball/0.1', - classifiers = ['Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Programming Language :: Python ', - 'Topic :: Text Processing' - ] + 'requests', + 'beautifulsoup4', + ], + url='https://github.com/Unbabel/unbabel-py', + download_url='https://github.com/Unbabel/unbabel-py/tarball/0.1', + classifiers=['Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Programming Language :: Python ', + 'Topic :: Text Processing' + ] ) From 8315c46c80934236faf878af77fe8579324bbc5d Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Fri, 9 Jun 2017 10:46:56 +0100 Subject: [PATCH 36/43] PEP8 --- setup.cfg | 2 +- unbabel/api.py | 209 ++++++++++++++++++++++++++----------------------- 2 files changed, 112 insertions(+), 99 deletions(-) diff --git a/setup.cfg b/setup.cfg index 224a779..b88034e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,2 @@ [metadata] -description-file = README.md \ No newline at end of file +description-file = README.md diff --git a/unbabel/api.py b/unbabel/api.py index 20d4d21..d2367d4 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -3,11 +3,9 @@ import os import requests - log = logging.getLogger() import copy - UNBABEL_SANDBOX_API_URL = os.environ.get( 'UNBABEL_SANDOX_API_URL', 'https://sandbox.unbabel.com/tapi/v2/') UNBABEL_API_URL = os.environ.get( @@ -96,22 +94,22 @@ def from_json(cls, json): class Translation(object): def __init__( - self, - uid = -1, - text = "", - translatedText = None, - target_language = "", - source_language = None, - status = None, - translators = [], - topics = None, - price = None, - text_format = 'text', - origin = None, - price_plan = None, - balance = None, - client=None, - order_number=None): + self, + uid=-1, + text="", + translatedText=None, + target_language="", + source_language=None, + status=None, + translators=[], + topics=None, + price=None, + text_format='text', + origin=None, + price_plan=None, + balance=None, + client=None, + order_number=None): self.uid = uid self.text = text self.translation = translatedText @@ -139,17 +137,17 @@ def __str__(self): class MTTranslation(object): def __init__( - self, - uid = -1, - text = "", - translatedText = None, - target_language = "", - source_language = None, - status = None, - topics = None, - text_format = 'text', - origin = None, - client=None): + self, + uid=-1, + text="", + translatedText=None, + target_language="", + source_language=None, + status=None, + topics=None, + text_format='text', + origin=None, + client=None): self.uid = uid self.text = text self.translation = translatedText @@ -170,7 +168,6 @@ def __str__(self): self.uid, self.status, self.source_language, self.target_language) - class Account(object): def __init__(self, username, email, balance): self.username = username @@ -184,7 +181,8 @@ def __unicode__(self): class Job(object): - def __init__(self, id, uid, order_id, status, source_language, target_language, + def __init__(self, id, uid, order_id, status, source_language, + target_language, text, price, tone, text_format): self.id = id self.uid = uid @@ -227,7 +225,8 @@ def __init__(self, username, api_key, sandbox=False): self.api_url = api_url self.is_bulk = False self.headers = { - 'Authorization': 'ApiKey {}:{}'.format(self.username, self.api_key), + 'Authorization': 'ApiKey {}:{}'.format(self.username, + self.api_key), 'content-type': 'application/json'} def api_call(self, uri, data=None, internal_api_call=False): @@ -247,13 +246,13 @@ def post_translations(self, tone=None, visibility=None, public_url=None, - callback_url = None, - topics = None, + callback_url=None, + topics=None, instructions=None, uid=None, text_format="text", target_text=None, - origin = None, + origin=None, client_owner_email=None, ): ## Collect args @@ -266,21 +265,22 @@ def post_translations(self, return self._make_request(data) def post_mt_translations(self, - text, - target_language, - source_language=None, - tone=None, - callback_url = None, - topics = None, - instructions=None, - uid=None, - text_format="text", - origin = None, - client_owner_email=None): + text, + target_language, + source_language=None, + tone=None, + callback_url=None, + topics=None, + instructions=None, + uid=None, + text_format="text", + origin=None, + client_owner_email=None): # Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} - result = requests.post("%smt_translation/"% self.api_url, headers=self.headers, data=json.dumps(data)) + result = requests.post("%smt_translation/" % self.api_url, + headers=self.headers, data=json.dumps(data)) if result.status_code in (201, 202): json_object = json.loads(result.content) toret = self._build_mt_translation_object(json_object) @@ -290,60 +290,64 @@ def post_mt_translations(self, elif result.status_code == 400: raise BadRequestException(result.content) else: - raise Exception("Unknown Error return status %d: %s", result.status_code, result.content[0:100]) + raise Exception("Unknown Error return status %d: %s", + result.status_code, result.content[0:100]) def _build_translation_object(self, json_object): - source_lang = json_object.get("source_language",None) - translation = json_object.get("translation",None) - status = json_object.get("status",None) + source_lang = json_object.get("source_language", None) + translation = json_object.get("translation", None) + status = json_object.get("status", None) - translators = [Translator.from_json(t) for t in json_object.get("translators",[])] + translators = [Translator.from_json(t) for t in + json_object.get("translators", [])] translation = Translation( - uid = json_object["uid"], - text = json_object["text"], - target_language = json_object.get('target_language', None), - source_language = json_object.get('source_language', None), - translatedText = json_object.get('translatedText', None), - status = json_object.get('status', None), - translators = translators, - topics = json_object.get('topics', None), - price = json_object.get('price', None), - balance = json_object.get('balance', None), - text_format = json_object.get('text_format', "text"), - origin = json_object.get('origin', None), - price_plan = json_object.get('price_plan', None), - client = json_object.get('client', None), + uid=json_object["uid"], + text=json_object["text"], + target_language=json_object.get('target_language', None), + source_language=json_object.get('source_language', None), + translatedText=json_object.get('translatedText', None), + status=json_object.get('status', None), + translators=translators, + topics=json_object.get('topics', None), + price=json_object.get('price', None), + balance=json_object.get('balance', None), + text_format=json_object.get('text_format', "text"), + origin=json_object.get('origin', None), + price_plan=json_object.get('price_plan', None), + client=json_object.get('client', None), ) return translation def _build_mt_translation_object(self, json_object): - source_lang = json_object.get("source_language",None) - translation = json_object.get("translation",None) - status = json_object.get("status",None) + source_lang = json_object.get("source_language", None) + translation = json_object.get("translation", None) + status = json_object.get("status", None) translation = MTTranslation( - uid = json_object["uid"], - text = json_object["text"], - target_language = json_object.get('target_language', None), - source_language = json_object.get('source_language', None), - translatedText = json_object.get('translatedText', None), - status = json_object.get('status', None), - topics = json_object.get('topics', None), - text_format = json_object.get('text_format', "text"), - origin = json_object.get('origin', None), - client = json_object.get('client', None), + uid=json_object["uid"], + text=json_object["text"], + target_language=json_object.get('target_language', None), + source_language=json_object.get('source_language', None), + translatedText=json_object.get('translatedText', None), + status=json_object.get('status', None), + topics=json_object.get('topics', None), + text_format=json_object.get('text_format', "text"), + origin=json_object.get('origin', None), + client=json_object.get('client', None), ) return translation def _make_request(self, data): - #headers={'Authorization': 'ApiKey %s:%s'%(self.username,self.api_key),'content-type': 'application/json'} + # headers={'Authorization': 'ApiKey %s:%s'%(self.username, + # self.api_key),'content-type': 'application/json'} if self.is_bulk: f = requests.patch else: f = requests.post - result = f("%stranslation/"% self.api_url, headers=self.headers, data=json.dumps(data)) + result = f("%stranslation/" % self.api_url, headers=self.headers, + data=json.dumps(data)) if result.status_code in (201, 202): json_object = json.loads(result.content) toret = None @@ -359,14 +363,15 @@ def _make_request(self, data): elif result.status_code == 400: raise BadRequestException(result.content) else: - raise Exception("Unknown Error return status %d: %s", result.status_code, result.content[0:100]) + raise Exception("Unknown Error return status %d: %s", + result.status_code, result.content[0:100]) def start_bulk_transaction(self): self.bulk_data = [] self.is_bulk = True def _post_bulk(self): - data = {'objects' : self.bulk_data} + data = {'objects': self.bulk_data} return self._make_request(data=data) def post_bulk_translations(self, translations): @@ -380,20 +385,22 @@ def post_bulk_translations(self, translations): return self._post_bulk() - def get_translations(self,status=None): + def get_translations(self, status=None): ''' Returns the translations requested by the user ''' if status is not None: - result = self.api_call('translation/?status=%s'%status) + result = self.api_call('translation/?status=%s' % status) else: result = self.api_call('translation/') if result.status_code == 200: translations_json = json.loads(result.content)["objects"] translations = [Translation(**tj) for tj in translations_json] else: - log.critical('Error status when fetching translation from server: {}!'.format( - result.status_code)) + log.critical( + 'Error status when fetching translation from server: {' + '}!'.format( + result.status_code)) translations = [] return translations @@ -405,8 +412,10 @@ def get_translation(self, uid): if result.status_code == 200: translation = Translation(**json.loads(result.content)) else: - log.critical('Error status when fetching translation from server: {}!'.format( - result.status_code)) + log.critical( + 'Error status when fetching translation from server: {' + '}!'.format( + result.status_code)) raise ValueError(result.content) return translation @@ -428,15 +437,17 @@ def get_mt_translations(self, status=None): Returns the translations requested by the user ''' if status is not None: - result = self.api_call('mt_translation/?status=%s'%status) + result = self.api_call('mt_translation/?status=%s' % status) else: result = self.api_call('mt_translation/') if result.status_code == 200: translations_json = json.loads(result.content)["objects"] translations = [Translation(**tj) for tj in translations_json] else: - log.critical('Error status when fetching machine translation from server: {}!'.format( - result.status_code)) + log.critical( + 'Error status when fetching machine translation from server: ' + '{}!'.format( + result.status_code)) translations = [] return translations @@ -448,8 +459,10 @@ def get_mt_translation(self, uid): if result.status_code == 200: translation = Translation(**json.loads(result.content)) else: - log.critical('Error status when fetching machine translation from server: {}!'.format( - result.status_code)) + log.critical( + 'Error status when fetching machine translation from server: ' + '{}!'.format( + result.status_code)) raise ValueError(result.content) return translation @@ -470,10 +483,10 @@ def get_language_pairs(self, train_langs=None): shortname=lang_json["lang_pair"]["source_language"][ "shortname"], name=lang_json["lang_pair"]["source_language"]["name"]), - Language(shortname=lang_json["lang_pair"][ - "target_language"]["shortname"], - name=lang_json["lang_pair"][ - "target_language"]["name"]) + Language(shortname=lang_json["lang_pair"][ + "target_language"]["shortname"], + name=lang_json["lang_pair"][ + "target_language"]["name"]) ) for lang_json in langs_json["objects"]] except Exception, e: log.exception("Error decoding get language pairs") From c875917f71dde5c2a414c6749a363f6057544c6d Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Fri, 9 Jun 2017 11:03:57 +0100 Subject: [PATCH 37/43] Update setup.py --- setup.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 4447677..f1d1131 100644 --- a/setup.py +++ b/setup.py @@ -4,19 +4,15 @@ version='0.49', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', - author_email='gracaninja@unbabel.co', - packages=[ - 'unbabel', - ], - package_dir={ - 'unbabel': 'unbabel', - }, + author_email='joao@unbabel.com', + packages=['unbabel'], + package_dir={'unbabel': 'unbabel',}, install_requires=[ 'requests', 'beautifulsoup4', ], url='https://github.com/Unbabel/unbabel-py', - download_url='https://github.com/Unbabel/unbabel-py/tarball/0.1', + download_url='https://github.com/Unbabel/unbabel-py/archive/0.49.tar.gz', classifiers=['Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Programming Language :: Python ', From 647cfc090a19de44916b039f13373d4ea973eaf4 Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Thu, 15 Mar 2018 14:12:43 +0000 Subject: [PATCH 38/43] Undo changes to post_mt_translations method --- unbabel/api.py | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/unbabel/api.py b/unbabel/api.py index d2367d4..10cb6da 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -238,24 +238,9 @@ def api_call(self, uri, data=None, internal_api_call=False): return requests.get(url, headers=self.headers) return requests.post(url, headers=self.headers, data=json.dumps(data)) - def post_translations(self, - text, - target_language, - source_language=None, - type=None, - tone=None, - visibility=None, - public_url=None, - callback_url=None, - topics=None, - instructions=None, - uid=None, - text_format="text", - target_text=None, - origin=None, - client_owner_email=None, - ): - ## Collect args + def post_translations(self, text, target_language, source_language=None, type=None, tone=None, visibility=None, + public_url=None, callback_url=None, topics=None, instructions=None, uid=None, + text_format="text", target_text=None, origin=None, client_owner_email=None, context=None): data = {k: v for k, v in locals().iteritems() if not v in (self, None)} if self.is_bulk: @@ -264,19 +249,9 @@ def post_translations(self, return self._make_request(data) - def post_mt_translations(self, - text, - target_language, - source_language=None, - tone=None, - callback_url=None, - topics=None, - instructions=None, - uid=None, - text_format="text", - origin=None, + def post_mt_translations(self, text, target_language, source_language=None, tone=None, callback_url=None, + topics=None, instructions=None, uid=None, text_format="text", origin=None, client_owner_email=None): - # Collect args data = {k: v for k, v in locals().iteritems() if not v in (self, None)} result = requests.post("%smt_translation/" % self.api_url, From f3ffd180c2bf18afe712e5543f271c49ed9a2e5c Mon Sep 17 00:00:00 2001 From: Hugo Silva Date: Thu, 15 Mar 2018 14:13:34 +0000 Subject: [PATCH 39/43] Bump version to 0.50 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index f1d1131..c22f97f 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name='unbabel-py', - version='0.49', + version='0.50', description='Python Wrapper around Unbabel HTTP API', author='Joao Graca', author_email='joao@unbabel.com', @@ -12,7 +12,7 @@ 'beautifulsoup4', ], url='https://github.com/Unbabel/unbabel-py', - download_url='https://github.com/Unbabel/unbabel-py/archive/0.49.tar.gz', + download_url='https://github.com/Unbabel/unbabel-py/archive/0.50.tar.gz', classifiers=['Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Programming Language :: Python ', From f0ead56aa0e384e33fd75564776b4a35d3c58dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Pinho?= Date: Wed, 10 Oct 2018 09:57:33 +0100 Subject: [PATCH 40/43] Add MIT License to repository --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5376ceb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Unbabel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From f03023b26ed650ab44b9092263174c999cdf1c67 Mon Sep 17 00:00:00 2001 From: alvations Date: Tue, 23 Oct 2018 15:41:10 +0800 Subject: [PATCH 41/43] Support Python3 --- unbabel/abc.py | 102 ++++++++++++++++ unbabel/api.py | 252 ++++++---------------------------------- unbabel/exceptions.py | 17 +++ unbabel/translations.py | 76 ++++++++++++ 4 files changed, 231 insertions(+), 216 deletions(-) create mode 100644 unbabel/abc.py create mode 100644 unbabel/exceptions.py create mode 100644 unbabel/translations.py diff --git a/unbabel/abc.py b/unbabel/abc.py new file mode 100644 index 0000000..67ade5a --- /dev/null +++ b/unbabel/abc.py @@ -0,0 +1,102 @@ +"""Abstract base classes. Mainly Pythonic container objects from JSON.""" + +class NamedObject(object): + """Abstract object that has a name and its name is the __repr__ and __str__.""" + def __init__(self, name): + self.name + def __repr__(self): + return self.name + def __str__(self): + return self.name + + +class Language(NamedObject): + def __init__(self, shortname, name): + super(Language, self).__init__(name=name) + self.shortname = shortname + + +class Tone(NamedObject): + def __init__(self, description, name): + super(Language, self).__init__(name=name) + self.description = description + + +class Topic(NamedObject): + def __init__(self, name): + super(Language, self).__init__(name=name) + + +class LangPair(NamedObject): + def __init__(self, source_language, target_language): + name = "{}_{}".format(source_language, target_language) + super(Language, self).__init__(name=name) + self.source_language = source_language + self.target_language = target_language + + +class Translator(object): + def __init__(self, first_name="", last_name="", + picture_url="", profile_url=""): + self.first_name = first_name + self.last_name = last_name + self.picture_url = picture_url + self.profile_url = profile_url + + @classmethod + def from_json(cls, json_object): + return Translator(json_object["first_name"], json_object["last_name"], + json_object["picture_url"], json_object["profile_url"]) + + +class UnicodeReprObject: + """Abstract object that suports unicode representation objects.""" + def __init__(self): + pass + def __repr__(self): + return self._repr + def __str__(self): + return self._repr + def __unicode__(self): + return self._repr + + +class Account(UnicodeReprObject): + def __init__(self, username, email, balance): + self.username = username + self.email = email + self.balance = balance + # For __unicode__ + self._repr = u'email: {email}, balance: {balance}'.format( + email=self.email, balance=self.balance) + + +class Job(UnicodeReprObject): + def __init__(self, id, uid, order_id, status, source_language, + target_language, + text, price, tone, text_format): + self.id = id + self.uid = uid + self.order_id = order_id + self.status = status + self.text = text + self.price = price + self.source_language = source_language + self.target_language = target_language + self.tone = tone + self.text_format = text_format + # For __unicode__ + self._repr = u'order_id: {}, id: {}, status: {}'.format(self.order_id, self.id, self.status) + + +class Order(UnicodeReprObject): + def __init__(self, id, status, price): + self.id = id + self.status = status + self.price = price + # For __unicode__ + self._repr = u'{id} - {status} - {price}'.format(id=self.id, status=self.status, price=self.price) + + +__all__ = ['Language', 'Tone', 'Topic', 'LangPair', + 'Translator', 'Account', 'Job', 'Order'] diff --git a/unbabel/api.py b/unbabel/api.py index 10cb6da..b64c992 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -1,10 +1,11 @@ import json -import logging import os + import requests -log = logging.getLogger() -import copy +from unbabel.abc import * +from unbabel.exceptions import UnauthorizedException, BadRequestException +from unbabel.translations import Translation, MTTranslation UNBABEL_SANDBOX_API_URL = os.environ.get( 'UNBABEL_SANDOX_API_URL', 'https://sandbox.unbabel.com/tapi/v2/') @@ -12,236 +13,54 @@ 'UNBABEL_API_URL', 'https://unbabel.com/tapi/v2/') -class UnauthorizedException(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - - -class BadRequestException(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - - -class Language(object): - def __init__(self, shortname, name): - self.shortname = shortname - self.name = name - - def __repr__(self): - return self.name - - def __str__(self): - return self.name - - -class Tone(object): - def __init__(self, description, name): - self.description = description - self.name = name - - def __repr__(self): - return self.name - - def __str__(self): - return self.name - - -class Topic(object): - def __init__(self, name): - self.name = name - - def __repr__(self): - return self.name - - def __str__(self): - return self.name - - -class LangPair(object): - def __init__(self, source_language, target_language): - self.source_language = source_language - self.target_language = target_language - - def __repr__(self): - return "%s_%s" % ( - self.source_language.shortname, self.target_language.shortname) - - def __str__(self): - return "%s_%s" % ( - self.source_language.shortname, self.target_language.shortname) - - -class Translator(object): - def __init__(self, first_name="", last_name="", picture_url="", - profile_url=""): - self.first_name = first_name - self.last_name = last_name - self.picture_url = picture_url - self.profile_url = profile_url - - @classmethod - def from_json(cls, json): - t = Translator(json["first_name"], json["last_name"], - json["picture_url"], json["profile_url"]) - return t - - -class Translation(object): - def __init__( - self, - uid=-1, - text="", - translatedText=None, - target_language="", - source_language=None, - status=None, - translators=[], - topics=None, - price=None, - text_format='text', - origin=None, - price_plan=None, - balance=None, - client=None, - order_number=None): - self.uid = uid - self.text = text - self.translation = translatedText - self.source_language = source_language - self.target_language = target_language - self.status = status - self.translators = translators - self.topics = topics - self.price = price - self.text_format = text_format - self.origin = origin - self.price_plan = price_plan - self.client = client - self.balance = balance - self.order_number = order_number - - def __repr__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) - - def __str__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) - - -class MTTranslation(object): - def __init__( - self, - uid=-1, - text="", - translatedText=None, - target_language="", - source_language=None, - status=None, - topics=None, - text_format='text', - origin=None, - client=None): - self.uid = uid - self.text = text - self.translation = translatedText - self.source_language = source_language - self.target_language = target_language - self.status = status - self.topics = topics - self.text_format = text_format - self.origin = origin - self.client = client - - def __repr__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) - - def __str__(self): - return "%s %s %s_%s" % ( - self.uid, self.status, self.source_language, self.target_language) - - -class Account(object): - def __init__(self, username, email, balance): - self.username = username - self.email = email - self.balance = balance - - def __unicode__(self): - return u'email: {email}, balance: {balance}'.format( - email=self.email, balance=self.balance, - ) - - -class Job(object): - def __init__(self, id, uid, order_id, status, source_language, - target_language, - text, price, tone, text_format): - self.id = id - self.uid = uid - self.order_id = order_id - self.status = status - self.text = text - self.price = price - self.source_language = source_language - self.target_language = target_language - self.tone = tone - self.text_format = text_format - - def __unicode__(self): - return u'order_id: {}, id: {}, status: {}'.format( - self.order_id, self.id, self.status) - - -class Order(object): - def __init__(self, id, status, price): - self.id = id - self.status = status - self.price = price - - def __unicode__(self): - return u'{id} - {status} - {price}'.format( - id=self.id, - status=self.status, - price=self.price, - ) - - class UnbabelApi(object): def __init__(self, username, api_key, sandbox=False): - if sandbox: - api_url = UNBABEL_SANDBOX_API_URL - else: - api_url = UNBABEL_API_URL + ''' + The Unbabel Client object. + + :param username: Customer's username. + :type username: str + :param api_key: Customer's API key. + :type api_key: str + :param sandbox: Whether to use the sandbox API. + :type sandbox: bool + ''' + api_url = UNBABEL_SANDBOX_API_URL if sandbox else UNBABEL_API_URL + self.username = username self.api_key = api_key self.api_url = api_url self.is_bulk = False self.headers = { - 'Authorization': 'ApiKey {}:{}'.format(self.username, - self.api_key), + 'Authorization': 'ApiKey {}:{}'.format(self.username, self.api_key), 'content-type': 'application/json'} def api_call(self, uri, data=None, internal_api_call=False): + ''' + Wrapper function to fire GET/POST requests. + + :param uri: The request endpoint. + :type uri: str + :param data: The payload. + :param internal_api_call: Whether to re-route the endpoint to internal. + :type internal_api_call: bool + + ''' + # Routes the URL appropriately. api_url = self.api_url if internal_api_call: api_url = api_url.replace('/tapi/v2/', '/api/v1/') url = "{}{}".format(api_url, uri) - if data is None: + # Actual request firing. + if data is None: # GET requests. return requests.get(url, headers=self.headers) + # POST requests. return requests.post(url, headers=self.headers, data=json.dumps(data)) def post_translations(self, text, target_language, source_language=None, type=None, tone=None, visibility=None, public_url=None, callback_url=None, topics=None, instructions=None, uid=None, text_format="text", target_text=None, origin=None, client_owner_email=None, context=None): - data = {k: v for k, v in locals().iteritems() if not v in (self, None)} + data = {k: v for k, v in locals().items() if not v in (self, None)} if self.is_bulk: self.bulk_data.append(data) @@ -253,9 +72,9 @@ def post_mt_translations(self, text, target_language, source_language=None, tone topics=None, instructions=None, uid=None, text_format="text", origin=None, client_owner_email=None): data = {k: v for k, v in locals().iteritems() if not v in (self, None)} + endpoint = "{}/mt_translation/".format(self.api_url) + result = requests.post(endpoint, headers=self.headers, data=json.dumps(data)) - result = requests.post("%smt_translation/" % self.api_url, - headers=self.headers, data=json.dumps(data)) if result.status_code in (201, 202): json_object = json.loads(result.content) toret = self._build_mt_translation_object(json_object) @@ -321,6 +140,7 @@ def _make_request(self, data): f = requests.patch else: f = requests.post + print(self.headers) result = f("%stranslation/" % self.api_url, headers=self.headers, data=json.dumps(data)) if result.status_code in (201, 202): @@ -463,7 +283,7 @@ def get_language_pairs(self, train_langs=None): name=lang_json["lang_pair"][ "target_language"]["name"]) ) for lang_json in langs_json["objects"]] - except Exception, e: + except Exception as e: log.exception("Error decoding get language pairs") raise e return languages diff --git a/unbabel/exceptions.py b/unbabel/exceptions.py new file mode 100644 index 0000000..f7d216b --- /dev/null +++ b/unbabel/exceptions.py @@ -0,0 +1,17 @@ + + + +class UnauthorizedException(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +class BadRequestException(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) diff --git a/unbabel/translations.py b/unbabel/translations.py new file mode 100644 index 0000000..c622462 --- /dev/null +++ b/unbabel/translations.py @@ -0,0 +1,76 @@ +"""Pythonic objects to hold the translation responses from JSON.""" + +class Translation(object): + def __init__( + self, + uid=-1, + text="", + translatedText=None, + target_language="", + source_language=None, + status=None, + translators=[], + topics=None, + price=None, + text_format='text', + origin=None, + price_plan=None, + balance=None, + client=None, + order_number=None): + self.uid = uid + self.text = text + self.translation = translatedText + self.source_language = source_language + self.target_language = target_language + self.status = status + self.translators = translators + self.topics = topics + self.price = price + self.text_format = text_format + self.origin = origin + self.price_plan = price_plan + self.client = client + self.balance = balance + self.order_number = order_number + + def __repr__(self): + return "{} {} {}_{}".format( + self.uid, self.status, self.source_language, self.target_language) + + def __str__(self): + return "{} {} {}_{}".format( + self.uid, self.status, self.source_language, self.target_language) + + +class MTTranslation(object): + def __init__( + self, + uid=-1, + text="", + translatedText=None, + target_language="", + source_language=None, + status=None, + topics=None, + text_format='text', + origin=None, + client=None): + self.uid = uid + self.text = text + self.translation = translatedText + self.source_language = source_language + self.target_language = target_language + self.status = status + self.topics = topics + self.text_format = text_format + self.origin = origin + self.client = client + + def __repr__(self): + return "{} {} {}_{}".format( + self.uid, self.status, self.source_language, self.target_language) + + def __str__(self): + return "{} {} {}_{}".format( + self.uid, self.status, self.source_language, self.target_language) From b88bb8909057977c9297bdfdea064ad962a35b32 Mon Sep 17 00:00:00 2001 From: alvations Date: Tue, 23 Oct 2018 15:41:26 +0800 Subject: [PATCH 42/43] Cleans up spurious spaces --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dda218e..2d2f465 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Getting started: ``` api.post_translations(text="This is a test translation",target_language="pt", - source_language="en", + source_language="en", callback_url="http://my-awesome-service.com/unbabel_endpoint") ``` @@ -35,7 +35,7 @@ Check out the [API documentation](https://github.com/Unbabel/unbabel_api#transla Returns a translation by its uid. -`t = api.get_translation(uid)` +`t = api.get_translation(uid)` @@ -47,18 +47,18 @@ Returns all the translations for a given user. -## Getting Available Language Pairs +## Getting Available Language Pairs `api.get_language_pairs()` > [pt_en, pt_fr, - ... + ... it_en, it_fr, it_es] - - Each element of the list is a **LanguagePair** object that contains a source language and a target language. Each language is an instance of the **Language** class that contains a shortname ( iso639-1 language code ) and a name. + + Each element of the list is a **LanguagePair** object that contains a source language and a target language. Each language is an instance of the **Language** class that contains a shortname ( iso639-1 language code ) and a name. ## Getting Available Tones From 50d7714be0480b56f5b2c04bbf90a563244b7ba4 Mon Sep 17 00:00:00 2001 From: alvations Date: Tue, 23 Oct 2018 15:43:49 +0800 Subject: [PATCH 43/43] puts back the logging --- unbabel/api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unbabel/api.py b/unbabel/api.py index b64c992..fda48dc 100644 --- a/unbabel/api.py +++ b/unbabel/api.py @@ -1,5 +1,7 @@ import json import os +import copy +import logging import requests @@ -7,6 +9,8 @@ from unbabel.exceptions import UnauthorizedException, BadRequestException from unbabel.translations import Translation, MTTranslation +log = logging.getLogger() + UNBABEL_SANDBOX_API_URL = os.environ.get( 'UNBABEL_SANDOX_API_URL', 'https://sandbox.unbabel.com/tapi/v2/') UNBABEL_API_URL = os.environ.get(