From 3dbab6e98d99e9307037a74b3367f1ecaf8b5e86 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:02:33 +0300 Subject: [PATCH 1/7] Update test_image.py --- tests/test_image.py | 63 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/test_image.py b/tests/test_image.py index 50a23a58..aea9bae3 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -52,6 +52,26 @@ def test_basic_data_file(self, save_format): assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) + def test_basic_data_base64(self, save_format): + instance = ImageCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY, save_format=save_format) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = instance.captcha_handler(captcha_base64=f.read()) + + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) async def test_aio_basic_data_link(self, save_format): @@ -86,6 +106,26 @@ async def test_aio_basic_data_file(self, save_format): assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio + @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) + async def test_aio_basic_data_base64(self, save_format): + instance = ImageCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY, save_format=save_format) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = instance.captcha_handler(captcha_base64=f.read()) + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + assert result.keys() == ResponseSer().dict().keys() + """ Fail tests """ @@ -123,6 +163,16 @@ def test_wrong_link(self): assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + def test_wrong_base64(self): + instance = ImageCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + result = instance.captcha_handler(captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8")) + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio async def test_aio_wrong_link(self): instance = ImageCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) @@ -134,6 +184,19 @@ async def test_aio_wrong_link(self): assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio + async def test_aio_wrong_base64(self): + instance = ImageCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + result = await instance.aio_captcha_handler( + captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8") + ) + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() + class TestDeathByImageCaptcha(BaseImageCaptcha, DeathByTest): """ From 098f44ea6fe3ffefe0b8a6286e0878679696ad10 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:14:42 +0300 Subject: [PATCH 2/7] Update test_image.py --- tests/test_image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_image.py b/tests/test_image.py index aea9bae3..76bc9da3 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -114,7 +114,7 @@ async def test_aio_basic_data_base64(self, save_format): assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY with open(self.captcha_file, "rb") as f: - result = instance.captcha_handler(captcha_base64=f.read()) + result = await instance.aio_captcha_handler(captcha_base64=f.read()) assert isinstance(result, dict) is True if result["error"] is False: assert result["error"] is False From 3b623b1a8537b848a386a68d06220d66a2cfd15c Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:15:31 +0300 Subject: [PATCH 3/7] Update test.yml --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d5b96f9..0d39b127 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ on: paths: - '.github/workflows/test.yml' - 'src/**' + - 'tests/**' - 'Makefile' - 'requirements.test.txt' pull_request: @@ -13,6 +14,7 @@ on: paths: - '.github/workflows/test.yml' - 'src/**' + - 'tests/**' - 'Makefile' - 'requirements.test.txt' schedule: From 95429e31ca8f29a0cc0b94af15c1b07e9aadd0ef Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:17:14 +0300 Subject: [PATCH 4/7] Update test_rotate.py --- tests/test_rotate.py | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/test_rotate.py b/tests/test_rotate.py index 16ff130a..a3f1418b 100644 --- a/tests/test_rotate.py +++ b/tests/test_rotate.py @@ -55,6 +55,26 @@ def test_basic_data_file(self): assert result.keys() == ResponseSer().dict().keys() + def test_basic_data_base64(self): + instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = instance.captcha_handler(captcha_base64=f.read()) + + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio async def test_aio_basic_data_link(self): instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) @@ -95,6 +115,27 @@ async def test_aio_basic_data_file(self): assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio + async def test_aio_basic_data_base64(self): + instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = await instance.aio_captcha_handler(captcha_base64=f.read()) + + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + + assert result.keys() == ResponseSer().dict().keys() + """ Fail tests """ @@ -146,6 +187,19 @@ def test_wrong_link(self): assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + def test_wrong_base64(self): + instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + result = instance.captcha_handler(captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8")) + + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio async def test_aio_wrong_link(self): instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) @@ -159,3 +213,19 @@ async def test_aio_wrong_link(self): assert result["taskId"] is None assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + + @pytest.mark.asyncio + async def test_aio_wrong_base64(self): + instance = RotateCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + result = await instance.aio_captcha_handler( + captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8") + ) + + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() From 5f62a306b04c2b1236c160d681744c9e84c5cd38 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:19:26 +0300 Subject: [PATCH 5/7] Update test_audio.py --- tests/test_audio.py | 70 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/tests/test_audio.py b/tests/test_audio.py index 97edcc8e..5059f92a 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -58,6 +58,27 @@ def test_basic_data_link(self, save_format): assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) + def test_basic_data_base64(self, save_format): + instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY, save_format=save_format) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = instance.captcha_handler(captcha_base64=f.read()) + + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) async def test_aio_basic_data_file(self, save_format): @@ -100,6 +121,28 @@ async def test_aio_basic_data_link(self, save_format): assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio + @pytest.mark.parametrize("save_format", [SaveFormatsEnm.TEMP, SaveFormatsEnm.CONST]) + async def test_aio_basic_data_base64(self, save_format): + instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY, save_format=save_format) + + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + + with open(self.captcha_file, "rb") as f: + result = await instance.aio_captcha_handler(captcha_base64=f.read()) + + assert isinstance(result, dict) is True + if result["error"] is False: + assert result["error"] is False + assert isinstance(result["taskId"], int) is True + assert result["errorBody"] is None + assert isinstance(result["captchaSolve"], str) is True + else: + assert result["error"] is True + assert result["errorBody"] == "ERROR_CAPTCHA_UNSOLVABLE" + + assert result.keys() == ResponseSer().dict().keys() + """ Fail tests """ @@ -134,10 +177,6 @@ async def test_aio_no_captcha(self): assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() - """ - Failed tests - """ - def test_wrong_link(self): instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) @@ -165,6 +204,16 @@ def test_wrong_path(self): assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + def test_wrong_base64(self): + instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + result = instance.captcha_handler(captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8")) + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() + @pytest.mark.asyncio async def test_aio_wrong_link(self): instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) @@ -193,3 +242,16 @@ async def test_aio_wrong_path(self): assert result["taskId"] is None assert result["captchaSolve"] == {} assert result.keys() == ResponseSer().dict().keys() + + @pytest.mark.asyncio + async def test_aio_wrong_base64(self): + instance = AudioCaptcha(rucaptcha_key=self.RUCAPTCHA_KEY) + assert instance.params.rucaptcha_key == self.RUCAPTCHA_KEY + result = await instance.aio_captcha_handler( + captcha_base64=self.get_random_string(length=50).encode(encoding="UTF-8") + ) + assert isinstance(result, dict) is True + assert result["error"] is True + assert result["taskId"] is None + assert result["captchaSolve"] == {} + assert result.keys() == ResponseSer().dict().keys() From 9d0396bc5e1fee6699bfe3bcf626f1259d85f118 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 21:24:10 +0300 Subject: [PATCH 6/7] added more docs and examples --- src/python_rucaptcha/audio_captcha.py | 22 ++++++++++++++++++++++ src/python_rucaptcha/image_captcha.py | 21 +++++++++++++++++++++ src/python_rucaptcha/rotate_captcha.py | 23 +++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/python_rucaptcha/audio_captcha.py b/src/python_rucaptcha/audio_captcha.py index 932df3cf..6a5ff739 100644 --- a/src/python_rucaptcha/audio_captcha.py +++ b/src/python_rucaptcha/audio_captcha.py @@ -38,6 +38,17 @@ def __init__( 'errorBody': None } + >>> with open("src/examples/mediacaptcha_audio/recaptcha_55914.mp3", "rb") as f: + ... file_data = f.read() + >>> AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': 'five five nine one four', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } + >>> await AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122", ... lang='en' ... ).aio_captcha_handler(captcha_file='examples/mediacaptcha_audio/recaptcha_55914.mp3') @@ -48,6 +59,17 @@ def __init__( 'errorBody': None } + >>> with open("src/examples/mediacaptcha_audio/recaptcha_55914.mp3", "rb") as f: + ... file_data = f.read() + >>> await AudioCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).aio_captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': 'five five nine one four', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } + Returns: Dict with full server response diff --git a/src/python_rucaptcha/image_captcha.py b/src/python_rucaptcha/image_captcha.py index e1d662e9..65f4a55a 100644 --- a/src/python_rucaptcha/image_captcha.py +++ b/src/python_rucaptcha/image_captcha.py @@ -44,6 +44,17 @@ def __init__( 'errorBody': None } + >>> with open("src/examples/088636.png", "rb") as f: + ... file_data = f.read() + >>> ImageCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': 'W9H5K', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } + >>> await ImageCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122", ... ).aio_captcha_handler(captcha_link="https://rucaptcha.com/dist/web/99581b9d446a509a0a01954438a5e36a.jpg") { @@ -84,6 +95,16 @@ def __init__( 'errorBody': None } + >>> with open("src/examples/088636.png", "rb") as f: + ... file_data = f.read() + >>> await ImageCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).aio_captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': 'W9H5K', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } Returns: Dict with full server response diff --git a/src/python_rucaptcha/rotate_captcha.py b/src/python_rucaptcha/rotate_captcha.py index 141ac26a..f3f83603 100644 --- a/src/python_rucaptcha/rotate_captcha.py +++ b/src/python_rucaptcha/rotate_captcha.py @@ -29,6 +29,17 @@ def __init__(self, method: str = RotateCaptchaEnm.ROTATECAPTCHA.value, *args, ** 'errorBody': None } + >>> with open("src/examples/rotate/rotate_ex.png", "rb") as f: + ... file_data = f.read() + >>> RotateCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': '160', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } + >>> await RotateCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122", ... ).aio_captcha_handler(captcha_file="examples/rotate/rotate_ex.png") { @@ -47,6 +58,18 @@ def __init__(self, method: str = RotateCaptchaEnm.ROTATECAPTCHA.value, *args, ** 'errorBody': None } + >>> with open("src/examples/rotate/rotate_ex.png", "rb") as f: + ... file_data = f.read() + >>> await RotateCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122" + ... ).aio_captcha_handler(captcha_base64=file_data) + { + 'captchaSolve': '160', + 'taskId': 73243152973, + 'error': False, + 'errorBody': None + } + + Returns: Dict with full server response From 493e3cb3eb0a6c609c11facb4d0746669c1a7363 Mon Sep 17 00:00:00 2001 From: Andrei Date: Tue, 4 Apr 2023 22:25:51 +0300 Subject: [PATCH 7/7] 5.3.1 --- src/python_rucaptcha/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_rucaptcha/__version__.py b/src/python_rucaptcha/__version__.py index f0b4b81b..0419a93d 100644 --- a/src/python_rucaptcha/__version__.py +++ b/src/python_rucaptcha/__version__.py @@ -1 +1 @@ -__version__ = "5.3" +__version__ = "5.3.1"