Skip to content

Commit

Permalink
Merge pull request #92 from kxrob/raise_http_error
Browse files Browse the repository at this point in the history
raise_for_status(), and Session for efficient http
  • Loading branch information
terryyin authored Mar 2, 2022
2 parents 2d45d16 + 1547464 commit 8e4993e
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 29 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CI

on:
push:
branches:
- master
- _ci_test
pull_request:
branches:
- master

jobs:
test:
runs-on: ubuntu-latest
## runs-on: windows-2019
strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.10']
architecture: ['x64']

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}

- name: Show runner information
run: |
python --version
pip --version
# Minimal pip requirements for test & bdist_wheel
- name: Install requirements
run: make pip-install-build

- name: Run tests
run: make test

- name: Build wheels
run: |
python setup.py bdist_wheel
- uses: actions/upload-artifact@v2
if: ${{ always() }}
with:
name: wheels
path: dist/*.whl
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ lint:

pip-install:
pip install --user -r requirements-dev.txt
pip-install-build:
pip install --user -r requirements-build.txt

pip-upgrade:
pip install --user --upgrade -r requirements-dev.txt
Expand All @@ -30,7 +32,7 @@ cov:
cov-report:
py.test -vv --cov-report=html tests

test: pip-install
test: pip-install-build
py.test -vv -s

build: test
Expand Down
5 changes: 5 additions & 0 deletions requirements-build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r requirements.txt
pytest
pytest-cov
vcrpy
wheel
16 changes: 10 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@ def save_version():
mo = re.search(VSRE, content_file, re.M)
current_version = mo.group(1)

content_file = content_file.replace(current_version, "{}".format(version))
content_file_new = content_file.replace(current_version, "{}".format(version))

if content_file_new == content_file:
return
with open(version_path, 'w') as version_file_write:
version_file_write.write(content_file)


save_version()


class VersionCommand(Command):
description = 'Show library version'
user_options = []
Expand All @@ -57,7 +56,7 @@ def run(self):


# Get the long description
with codecs.open(os.path.join(here, 'README.rst')) as f:
with codecs.open(os.path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = '\n{}'.format(f.read())

# Get change log
Expand All @@ -73,7 +72,9 @@ def run(self):
tests_requirements = [line.replace('\n', '') for line in f.readlines() if not line == '-r requirements.txt\n']


setup(
def run():
save_version()
return setup(
author='Terry Yin',
author_email='[email protected]',
classifiers=[
Expand Down Expand Up @@ -106,3 +107,6 @@ def run(self):
url='https://github.com/terryyin/google-translate-python',
version=version,
)

if __name__ == "__main__":
run()
52 changes: 52 additions & 0 deletions tests/fixtures/cassettes/test_translate_with_HTTPError.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebit/535.19(KHTML, like
Gecko) Chrome/18.0.1025.168 Safari/535.19
method: GET
uri: http://api.mymemory.translated.net/get-nonsense?q=hello&langpair=en%7Cde
response:
body:
string: '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache/2.4.29 (Ubuntu) Server at api.mymemory.translated.net Port
80</address>
</body></html>
'
headers:
Connection:
- keep-alive
Content-Length:
- '289'
Content-Type:
- text/html; charset=iso-8859-1
Date:
- Mon, 28 Feb 2022 16:27:12 GMT
Server:
- Apache/2.4.29 (Ubuntu)
status:
code: 404
message: Not Found
version: 1
50 changes: 50 additions & 0 deletions tests/fixtures/cassettes/test_translate_with_status_error.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebit/535.19(KHTML, like
Gecko) Chrome/18.0.1025.168 Safari/535.19
method: GET
uri: http://api.mymemory.translated.net/get?q=hello+again%21&langpair=en%7Cde&de=invalid
response:
body:
string: '{"responseData":{"translatedText":"INVALID EMAIL PROVIDED"},"quotaFinished":null,"mtLangSupported":null,"responseDetails":"INVALID
EMAIL PROVIDED","responseStatus":"403","responderId":null,"exception_code":null,"matches":""}'
headers:
Access-Control-Allow-Origin:
- '*'
Cache-Control:
- no-cache, no-store, max-age=0, must-revalidate
Connection:
- keep-alive
Content-Length:
- '224'
Content-Type:
- application/json; charset=utf-8
Date:
- Mon, 28 Feb 2022 17:46:15 GMT
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Pragma:
- no-cache
Server:
- Apache/2.4.29 (Ubuntu)
X-Backend-Content-Length:
- '10'
X-Embedded-Status:
- '200'
X-Frame-Options:
- SAMEORIGIN
X-XSS-Protection:
- '0'
status:
code: 200
message: OK
version: 1
24 changes: 10 additions & 14 deletions tests/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
except Exception:
import mock

from translate.providers import MyMemoryProvider, MicrosoftProvider, LibreProvider
from translate.providers import MyMemoryProvider, MicrosoftProvider


def test_provider_mymemory_languages_attribute():
Expand All @@ -21,27 +21,23 @@ def test_provider_mymemory_default_email():
assert provider.email == ''


@mock.patch('requests.get')
@mock.patch('requests.Session.get')
def test_provider_mymemory_make_request_with_valid_email(mock_requests):
mock_requests.return_value.json.return_value = {}
valid_email = '[email protected]'
provider = MyMemoryProvider(to_lang='en', headers={}, email=valid_email)
provider._make_request('test') == {}
assert mock_requests.call_args[1]['params']['de'] == valid_email == provider.email

provider = MyMemoryProvider(to_lang='de', headers={}, email=valid_email)
provider._make_request('test')
assert mock_requests._mock_call_args[1]['params']['de'] == valid_email == provider.email

@mock.patch('requests.post')
@mock.patch('requests.get')
def xtest_provider_microsoft_make_request(mock_requests_get, mock_requests_post):
class MockRequests:
content = b'token'

@mock.patch('requests.Session.post')
def test_provider_microsoft_make_request(mock_requests_post):
class MockResponse:
text = '"dummyjson"'
def raise_for_status(self):
return False

mock_requests_get.return_value.text.return_value = ''
mock_requests_post.return_value = MockRequests()
mock_requests_post.return_value = MockResponse()
provider = MicrosoftProvider(to_lang='en', headers={}, secret_access_key='secret')
provider._make_request('test')
assert mock_requests_get.called
assert mock_requests_post.called
21 changes: 20 additions & 1 deletion tests/test_translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pytest

from translate import Translator
from translate.exceptions import InvalidProviderError
from translate.exceptions import InvalidProviderError, TranslationError
from translate.providers import MyMemoryProvider

from .vcr_conf import vcr
Expand Down Expand Up @@ -75,6 +75,25 @@ def test_translate_with_multiple_sentences():
assert u'是或否' in translation


@vcr.use_cassette
def test_translate_with_HTTPError():
import requests
t = Translator(to_lang='de', provider='mymemory')
t.provider.base_url += '-nonsense'
with pytest.raises(requests.HTTPError) as error:
t.translate('hello')
assert '404' in str(error)


@vcr.use_cassette
def test_translate_with_status_error():
import requests
t = Translator(to_lang='de', provider='mymemory', email='invalid')
with pytest.raises((TranslationError, requests.HTTPError)) as error:
t.translate('hello again!')
assert 'INVALID EMAIL' in str(error).upper()


@mock.patch('requests.get')
def test_tranlate_taking_secondary_match(mock_requests, main_translation_not_found):
mock_requests.return_value.json.return_value = main_translation_not_found
Expand Down
6 changes: 5 additions & 1 deletion translate/providers/deepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DeeplProvider(BaseProvider):
name = 'Deepl'
base_free_url = 'https://api-free.deepl.com/v2/translate'
base_pro_url = 'https://api.deepl.com/v2/translate'
session = None

def __init__(self, **kwargs):
try:
Expand All @@ -36,7 +37,10 @@ def _make_request(self, text):
if self.from_lang != TRANSLATION_FROM_DEFAULT:
params['source_lang'] = self.from_lang

response = requests.post(self.base_url, params=params, headers=self.headers, json=[{}])
if self.session is None:
self.session = requests.Session()
response = self.session.post(self.base_url, params=params, headers=self.headers, json=[{}])
response.raise_for_status()
return json.loads(response.text)

def get_translation(self, text):
Expand Down
2 changes: 0 additions & 2 deletions translate/providers/libre.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env python
# encoding: utf-8
import requests
from libretranslatepy import LibreTranslateAPI
import json

from .base import BaseProvider
from ..exceptions import TranslationError
Expand Down
8 changes: 5 additions & 3 deletions translate/providers/microsoft.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/usr/bin/env python
# encoding: utf-8
from datetime import timedelta
from datetime import datetime

import requests
import json
Expand All @@ -18,6 +16,7 @@ class MicrosoftProvider(BaseProvider):
'''
name = 'Microsoft'
base_url = 'https://api.cognitive.microsofttranslator.com/translate'
session = None

def _make_request(self, text):
self.headers.update({"Ocp-Apim-Subscription-Key": self.secret_access_key})
Expand All @@ -35,7 +34,10 @@ def _make_request(self, text):
if self.from_lang != TRANSLATION_FROM_DEFAULT:
params['from'] = self.from_lang

response = requests.post(self.base_url, params=params, headers=self.headers, json=data)
if self.session is None:
self.session = requests.Session()
response = self.session.post(self.base_url, params=params, headers=self.headers, json=data)
response.raise_for_status()

return json.loads(response.text)

Expand Down
Loading

0 comments on commit 8e4993e

Please sign in to comment.