From 42ea8459fb1d6b493f19c1bd7a4e184160839f05 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 17:04:01 +0300 Subject: [PATCH 01/11] Update .gitignore --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index 57ff8a3..4fc9afe 100644 --- a/.gitignore +++ b/.gitignore @@ -20,11 +20,6 @@ dist/ venv/ env/ /.coverage -/src/python3_captchaai.egg-info/ -/src/.coverage -/src/coverage/lcov.info -/src/htmlcov/ -/src/coverage/ /docs/_build/ /src/python3_anticaptcha.egg-info/ /coverage/ From e65b38515d77aa7e0d1359466696db3d4bd81600 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 17:23:59 +0300 Subject: [PATCH 02/11] refactored --- src/python3_anticaptcha/control.py | 36 ++++----- ...a_handler.py => aio_captcha_instrument.py} | 7 +- src/python3_anticaptcha/core/base.py | 79 +++++++++---------- .../core/captcha_instrument.py | 46 +++++++++++ ...a_handler.py => sio_captcha_instrument.py} | 7 +- src/python3_anticaptcha/custom_task.py | 40 ---------- src/python3_anticaptcha/fun_captcha.py | 40 ---------- src/python3_anticaptcha/gee_test.py | 40 ---------- .../image_to_coordinates.py | 8 +- src/python3_anticaptcha/image_to_text.py | 8 +- src/python3_anticaptcha/recaptcha_v2.py | 40 ---------- src/python3_anticaptcha/recaptcha_v3.py | 40 ---------- src/python3_anticaptcha/turnstile.py | 42 ---------- tests/test_image_to_coordinates.py | 12 +-- tests/test_image_to_text.py | 12 +-- 15 files changed, 128 insertions(+), 329 deletions(-) rename src/python3_anticaptcha/core/{aio_captcha_handler.py => aio_captcha_instrument.py} (97%) create mode 100644 src/python3_anticaptcha/core/captcha_instrument.py rename src/python3_anticaptcha/core/{sio_captcha_handler.py => sio_captcha_instrument.py} (97%) diff --git a/src/python3_anticaptcha/control.py b/src/python3_anticaptcha/control.py index 7ea0014..d8fcfa2 100644 --- a/src/python3_anticaptcha/control.py +++ b/src/python3_anticaptcha/control.py @@ -2,8 +2,8 @@ from .core.base import CaptchaParams from .core.enum import ControlPostfixEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler +from .core.aio_captcha_instrument import AIOCaptchaInstrument +from .core.sio_captcha_instrument import SIOCaptchaInstrument __all__ = ("Control",) @@ -134,7 +134,7 @@ def get_balance(self) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getBalance """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.GET_BALANCE, @@ -158,7 +158,7 @@ async def aio_get_balance(self) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getBalance """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.GET_BALANCE, payload={"clientKey": self.create_task_payload.clientKey} ) @@ -196,7 +196,7 @@ def get_queue_status(queue_id: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getQueueStats """ - return SIOCaptchaHandler.send_post_request( + return SIOCaptchaInstrument.send_post_request( url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id} ) @@ -233,7 +233,7 @@ async def aio_get_queue_status(queue_id: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getQueueStats """ - return await AIOCaptchaHandler.send_post_request( + return await AIOCaptchaInstrument.send_post_request( url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id} ) @@ -288,7 +288,7 @@ def get_spending_stats(self, **kwargs) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getSpendingStats """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.GET_SPENDING_STATS, @@ -346,7 +346,7 @@ async def aio_get_spending_stats(self, **kwargs) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getSpendingStats """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.GET_SPENDING_STATS, payload={"clientKey": self.create_task_payload.clientKey, **kwargs}, @@ -388,7 +388,7 @@ def get_app_stats(self, softId: int, mode: Optional[str] = None) -> dict: Notes: https://anti-captcha.com/apidoc/methods/getAppStats """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.GET_APP_STATS, @@ -431,7 +431,7 @@ async def aio_get_app_stats(self, softId: int, mode: Optional[str] = None) -> di Notes: https://anti-captcha.com/apidoc/methods/getAppStats """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.GET_APP_STATS, payload={"clientKey": self.create_task_payload.clientKey, "softId": softId, "mode": mode}, @@ -455,7 +455,7 @@ def report_incorrect_image(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.REPORT_INCORRECT_IMAGE_CAPTCHA, @@ -480,7 +480,7 @@ async def aio_report_incorrect_image(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.REPORT_INCORRECT_IMAGE_CAPTCHA, payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId}, @@ -504,7 +504,7 @@ def report_incorrect_recaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.REPORT_INCORRECT_RECAPTCHA, @@ -529,7 +529,7 @@ async def aio_report_incorrect_recaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.REPORT_INCORRECT_RECAPTCHA, payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId}, @@ -553,7 +553,7 @@ def report_correct_recaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.REPORT_CORRECT_RECAPTCHA, @@ -578,7 +578,7 @@ async def aio_report_correct_recaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.REPORT_CORRECT_RECAPTCHA, payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId}, @@ -602,7 +602,7 @@ def report_incorrect_hcaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha """ - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) return self._captcha_handling_instrument.send_post_request( session=self._captcha_handling_instrument.session, url_postfix=ControlPostfixEnm.REPORT_INCORRECT_HCAPTCHA, @@ -627,7 +627,7 @@ async def aio_report_incorrect_hcaptcha(self, taskId: int) -> dict: Notes: https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha """ - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) return await self._captcha_handling_instrument.send_post_request( url_postfix=ControlPostfixEnm.REPORT_INCORRECT_HCAPTCHA, payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId}, diff --git a/src/python3_anticaptcha/core/aio_captcha_handler.py b/src/python3_anticaptcha/core/aio_captcha_instrument.py similarity index 97% rename from src/python3_anticaptcha/core/aio_captcha_handler.py rename to src/python3_anticaptcha/core/aio_captcha_instrument.py index 7276967..5f299b6 100644 --- a/src/python3_anticaptcha/core/aio_captcha_handler.py +++ b/src/python3_anticaptcha/core/aio_captcha_instrument.py @@ -7,16 +7,17 @@ import aiohttp -from .base import CaptchaParams, CaptchaHandler +from .base import CaptchaParams from .enum import SaveFormatsEnm from .const import ASYNC_RETRIES, BASE_REQUEST_URL, GET_RESULT_POSTFIX, CREATE_TASK_POSTFIX from .utils import attempts_generator from .serializer import CreateTaskResponseSer +from .captcha_instrument import CaptchaInstrument -__all__ = ("AIOCaptchaHandler",) +__all__ = ("AIOCaptchaInstrument",) -class AIOCaptchaHandler(CaptchaHandler): +class AIOCaptchaInstrument(CaptchaInstrument): """ Basic Captcha solving class diff --git a/src/python3_anticaptcha/core/base.py b/src/python3_anticaptcha/core/base.py index 1fdc08d..37bc624 100644 --- a/src/python3_anticaptcha/core/base.py +++ b/src/python3_anticaptcha/core/base.py @@ -1,11 +1,11 @@ -import os -import uuid -from pathlib import Path - -from .serializer import CreateTaskBaseSer, GetTaskResultRequestSer, GetTaskResultResponseSer +from .serializer import CreateTaskBaseSer, GetTaskResultRequestSer from .context_instr import AIOContextManager, SIOContextManager +from .captcha_instrument import CaptchaInstrument +from .aio_captcha_instrument import AIOCaptchaInstrument + +__all__ = ("CaptchaParams",) -__all__ = ("CaptchaParams", "CaptchaHandler") +from .sio_captcha_instrument import SIOCaptchaInstrument class CaptchaParams(SIOContextManager, AIOContextManager): @@ -28,49 +28,42 @@ def __init__(self, api_key: str, sleep_time: int = 15, *args, **kwargs): # prepare `get task result` payload self.get_result_params = GetTaskResultRequestSer(clientKey=api_key) - self._captcha_handling_instrument = CaptchaHandler() - - @classmethod - def captcha_handler(cls): - pass - - @classmethod - def aio_captcha_handler(cls): - pass + self._captcha_handling_instrument = CaptchaInstrument() + def captcha_handler(self, **additional_params) -> dict: + """ + Synchronous method for captcha solving -class CaptchaHandler: - NO_CAPTCHA_ERR = "You did not send any file, local link or URL." - """ - Basic Captcha solving class - - Args: - api_key: Capsolver API key - captcha_type: Captcha type name, like `ReCaptchaV2Task` and etc. - sleep_time: The waiting time between requests to get the result of the Captcha - request_url: API address for sending requests - """ + Args: + additional_params: Some additional parameters that will be used in creating the task + and will be passed to the payload under ``task`` key. + Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - def __init__(self): - self.result = GetTaskResultResponseSer() + Returns: + Dict with full server response - @staticmethod - def _local_file_captcha(captcha_file: str): + Notes: + Check class docstirng for more info """ - Method get local file, read it and prepare for sending to Captcha solving service - """ - with open(captcha_file, "rb") as file: - return file.read() + self.task_params.update({**additional_params}) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) + return self._captcha_handling_instrument.processing_captcha() - def _file_const_saver(self, content: bytes, file_path: str, file_extension: str = "png"): - """ - Method create and save file in folder + async def aio_captcha_handler(self, **additional_params) -> dict: """ - Path(file_path).mkdir(parents=True, exist_ok=True) + Asynchronous method for captcha solving - # generate image name - self.file_name = f"file-{uuid.uuid4()}.{file_extension}" + Args: + additional_params: Some additional parameters that will be used in creating the task + and will be passed to the payload under ``task`` key. + Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - # save image to folder - with open(os.path.join(file_path, self.file_name), "wb") as out_image: - out_image.write(content) + Returns: + Dict with full server response + + Notes: + Check class docstirng for more info + """ + self.task_params.update({**additional_params}) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) + return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/core/captcha_instrument.py b/src/python3_anticaptcha/core/captcha_instrument.py new file mode 100644 index 0000000..7a0c27d --- /dev/null +++ b/src/python3_anticaptcha/core/captcha_instrument.py @@ -0,0 +1,46 @@ +import os +import uuid +from pathlib import Path + +from .serializer import GetTaskResultResponseSer + +__all__ = ("CaptchaInstrument",) + + +class FileInstrument: + @staticmethod + def _local_file_captcha(captcha_file: str): + """ + Method get local file, read it and prepare for sending to Captcha solving service + """ + with open(captcha_file, "rb") as file: + return file.read() + + def _file_const_saver(self, content: bytes, file_path: str, file_extension: str = "png"): + """ + Method create and save file in folder + """ + Path(file_path).mkdir(parents=True, exist_ok=True) + + # generate image name + self.file_name = f"file-{uuid.uuid4()}.{file_extension}" + + # save image to folder + with open(os.path.join(file_path, self.file_name), "wb") as out_image: + out_image.write(content) + + +class CaptchaInstrument(FileInstrument): + NO_CAPTCHA_ERR = "You did not send any file, local link or URL." + """ + Basic Captcha solving class + + Args: + api_key: Capsolver API key + captcha_type: Captcha type name, like `ReCaptchaV2Task` and etc. + sleep_time: The waiting time between requests to get the result of the Captcha + request_url: API address for sending requests + """ + + def __init__(self): + self.result = GetTaskResultResponseSer() diff --git a/src/python3_anticaptcha/core/sio_captcha_handler.py b/src/python3_anticaptcha/core/sio_captcha_instrument.py similarity index 97% rename from src/python3_anticaptcha/core/sio_captcha_handler.py rename to src/python3_anticaptcha/core/sio_captcha_instrument.py index e58d2fd..ac51e22 100644 --- a/src/python3_anticaptcha/core/sio_captcha_handler.py +++ b/src/python3_anticaptcha/core/sio_captcha_instrument.py @@ -8,16 +8,17 @@ import requests from requests.adapters import HTTPAdapter -from .base import CaptchaParams, CaptchaHandler +from .base import CaptchaParams from .enum import SaveFormatsEnm, ResponseStatusEnm from .const import RETRIES, BASE_REQUEST_URL, GET_RESULT_POSTFIX, CREATE_TASK_POSTFIX from .utils import attempts_generator from .serializer import CreateTaskResponseSer, GetTaskResultResponseSer +from .captcha_instrument import CaptchaInstrument -__all__ = ("SIOCaptchaHandler",) +__all__ = ("SIOCaptchaInstrument",) -class SIOCaptchaHandler(CaptchaHandler): +class SIOCaptchaInstrument(CaptchaInstrument): """ Basic Captcha solving class diff --git a/src/python3_anticaptcha/custom_task.py b/src/python3_anticaptcha/custom_task.py index 5304c91..fd7889b 100644 --- a/src/python3_anticaptcha/custom_task.py +++ b/src/python3_anticaptcha/custom_task.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import ProxyTypeEnm, CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class CustomTask(CaptchaParams): @@ -118,41 +116,3 @@ def __init__( proxyLogin=proxyLogin, proxyPassword=proxyPassword, ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/fun_captcha.py b/src/python3_anticaptcha/fun_captcha.py index b24e34d..c4a2f52 100644 --- a/src/python3_anticaptcha/fun_captcha.py +++ b/src/python3_anticaptcha/fun_captcha.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import ProxyTypeEnm, CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class FunCaptcha(CaptchaParams): @@ -147,41 +145,3 @@ def __init__( f"Invalid `captcha_type` parameter set for `{self.__class__.__name__}`, \ available - {CaptchaTypeEnm.FunCaptchaTaskProxyless.value,CaptchaTypeEnm.FunCaptchaTask.value}" ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/gee_test.py b/src/python3_anticaptcha/gee_test.py index 4fefa17..cf4cbe3 100644 --- a/src/python3_anticaptcha/gee_test.py +++ b/src/python3_anticaptcha/gee_test.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import ProxyTypeEnm, CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class GeeTest(CaptchaParams): @@ -170,41 +168,3 @@ def __init__( f"Invalid `captcha_type` parameter set for `{self.__class__.__name__}`, \ available - {CaptchaTypeEnm.GeeTestTask.value,CaptchaTypeEnm.GeeTestTaskProxyless.value}" ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/image_to_coordinates.py b/src/python3_anticaptcha/image_to_coordinates.py index dcb29bf..a8d38cf 100644 --- a/src/python3_anticaptcha/image_to_coordinates.py +++ b/src/python3_anticaptcha/image_to_coordinates.py @@ -3,8 +3,8 @@ from .core.base import CaptchaParams from .core.enum import CaptchaTypeEnm, SaveFormatsEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler +from .core.aio_captcha_instrument import AIOCaptchaInstrument +from .core.sio_captcha_instrument import SIOCaptchaInstrument __all__ = ("ImageToCoordinates",) @@ -158,7 +158,7 @@ def captcha_handler( """ self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) self._captcha_handling_instrument.body_file_processing( save_format=self.save_format, file_path=self.img_path, @@ -196,7 +196,7 @@ async def aio_captcha_handler( """ self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) await self._captcha_handling_instrument.body_file_processing( save_format=self.save_format, file_path=self.img_path, diff --git a/src/python3_anticaptcha/image_to_text.py b/src/python3_anticaptcha/image_to_text.py index 457925c..8e3d8c4 100644 --- a/src/python3_anticaptcha/image_to_text.py +++ b/src/python3_anticaptcha/image_to_text.py @@ -3,8 +3,8 @@ from .core.base import CaptchaParams from .core.enum import CaptchaTypeEnm, SaveFormatsEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler +from .core.aio_captcha_instrument import AIOCaptchaInstrument +from .core.sio_captcha_instrument import SIOCaptchaInstrument __all__ = ("ImageToText",) @@ -131,7 +131,7 @@ def captcha_handler( """ self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) self._captcha_handling_instrument.body_file_processing( save_format=self.save_format, file_path=self.img_path, @@ -169,7 +169,7 @@ async def aio_captcha_handler( """ self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) + self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) await self._captcha_handling_instrument.body_file_processing( save_format=self.save_format, file_path=self.img_path, diff --git a/src/python3_anticaptcha/recaptcha_v2.py b/src/python3_anticaptcha/recaptcha_v2.py index 9cf2430..cb960c0 100644 --- a/src/python3_anticaptcha/recaptcha_v2.py +++ b/src/python3_anticaptcha/recaptcha_v2.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import ProxyTypeEnm, CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class ReCaptchaV2(CaptchaParams): @@ -201,41 +199,3 @@ def __init__( CaptchaTypeEnm.RecaptchaV2EnterpriseTask.value, CaptchaTypeEnm.RecaptchaV2EnterpriseTaskProxyless.value}" ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/recaptcha_v3.py b/src/python3_anticaptcha/recaptcha_v3.py index 87303a0..861dffe 100644 --- a/src/python3_anticaptcha/recaptcha_v3.py +++ b/src/python3_anticaptcha/recaptcha_v3.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class ReCaptchaV3(CaptchaParams): @@ -126,41 +124,3 @@ def __init__( isEnterprise=isEnterprise, apiDomain=apiDomain, ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/src/python3_anticaptcha/turnstile.py b/src/python3_anticaptcha/turnstile.py index c2757b5..7b19f29 100644 --- a/src/python3_anticaptcha/turnstile.py +++ b/src/python3_anticaptcha/turnstile.py @@ -2,8 +2,6 @@ from .core.base import CaptchaParams from .core.enum import ProxyTypeEnm, CaptchaTypeEnm -from .core.aio_captcha_handler import AIOCaptchaHandler -from .core.sio_captcha_handler import SIOCaptchaHandler class Turnstile(CaptchaParams): @@ -171,43 +169,3 @@ def __init__( f"Invalid `captcha_type` parameter set for `{self.__class__.__name__}`, \ available - {CaptchaTypeEnm.TurnstileTaskProxyless.value,CaptchaTypeEnm.TurnstileTask.value}" ) - - def captcha_handler(self, **additional_params) -> dict: - """ - Synchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self) - return self._captcha_handling_instrument.processing_captcha() - - async def aio_captcha_handler(self, **additional_params) -> dict: - """ - Asynchronous method for captcha solving - - Args: - additional_params: Some additional parameters that will be used in creating the task - and will be passed to the payload under ``task`` key. - Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs - - Returns: - Dict with full server response - - Notes: - Check class docstirng for more info - """ - - self.task_params.update({**additional_params}) - self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self) - return await self._captcha_handling_instrument.processing_captcha() diff --git a/tests/test_image_to_coordinates.py b/tests/test_image_to_coordinates.py index a5af0e6..9baf1fd 100644 --- a/tests/test_image_to_coordinates.py +++ b/tests/test_image_to_coordinates.py @@ -7,8 +7,8 @@ from python3_anticaptcha.core.enum import SaveFormatsEnm, ResponseStatusEnm from python3_anticaptcha.core.serializer import GetTaskResultResponseSer from python3_anticaptcha.image_to_coordinates import ImageToCoordinates -from python3_anticaptcha.core.aio_captcha_handler import AIOCaptchaHandler -from python3_anticaptcha.core.sio_captcha_handler import SIOCaptchaHandler +from python3_anticaptcha.core.aio_captcha_instrument import AIOCaptchaInstrument +from python3_anticaptcha.core.sio_captcha_instrument import SIOCaptchaInstrument class TestImageToCoordinates(BaseTest): @@ -47,7 +47,7 @@ def test_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( "python3_anticaptcha.image_to_coordinates.SIOCaptchaHandler", - side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaHandler(*args, **kwargs)) + side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( @@ -70,7 +70,7 @@ async def test_aio_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( "python3_anticaptcha.image_to_coordinates.AIOCaptchaHandler", - side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaHandler(*args, **kwargs)) + side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( @@ -118,7 +118,7 @@ async def test_aio_err_captcha_link(self, mocker): assert ser_result.cost == 0.0 def test_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(SIOCaptchaHandler, "body_file_processing") + captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "body_file_processing") mocked_method: MagicMock = mocker.patch( "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" ) @@ -136,7 +136,7 @@ def test_captcha_base64(self, mocker): assert result == mocked_method.return_value async def test_aio_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(AIOCaptchaHandler, "body_file_processing") + captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "body_file_processing") mocked_method: MagicMock = mocker.patch( "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" ) diff --git a/tests/test_image_to_text.py b/tests/test_image_to_text.py index 4d16310..39f6cb6 100644 --- a/tests/test_image_to_text.py +++ b/tests/test_image_to_text.py @@ -7,8 +7,8 @@ from python3_anticaptcha.core.enum import SaveFormatsEnm, ResponseStatusEnm from python3_anticaptcha.image_to_text import ImageToText from python3_anticaptcha.core.serializer import GetTaskResultResponseSer -from python3_anticaptcha.core.aio_captcha_handler import AIOCaptchaHandler -from python3_anticaptcha.core.sio_captcha_handler import SIOCaptchaHandler +from python3_anticaptcha.core.aio_captcha_instrument import AIOCaptchaInstrument +from python3_anticaptcha.core.sio_captcha_instrument import SIOCaptchaInstrument class TestImageToText(BaseTest): @@ -53,7 +53,7 @@ def test_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( "python3_anticaptcha.image_to_text.SIOCaptchaHandler", - side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaHandler(*args, **kwargs)) + side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( @@ -76,7 +76,7 @@ async def test_aio_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( "python3_anticaptcha.image_to_text.AIOCaptchaHandler", - side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaHandler(*args, **kwargs)) + side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( @@ -124,7 +124,7 @@ async def test_aio_err_captcha_link(self, mocker): assert ser_result.cost == 0.0 def test_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(SIOCaptchaHandler, "body_file_processing") + captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "body_file_processing") mocked_method: MagicMock = mocker.patch( "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" ) @@ -142,7 +142,7 @@ def test_captcha_base64(self, mocker): assert result == mocked_method.return_value async def test_aio_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(AIOCaptchaHandler, "body_file_processing") + captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "body_file_processing") mocked_method: MagicMock = mocker.patch( "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" ) From e416296b24ed82fecf421042977651ebd23b0bcd Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 18:33:05 +0300 Subject: [PATCH 03/11] Update aio_captcha_instrument.py --- src/python3_anticaptcha/core/aio_captcha_instrument.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/python3_anticaptcha/core/aio_captcha_instrument.py b/src/python3_anticaptcha/core/aio_captcha_instrument.py index 5f299b6..31b52e7 100644 --- a/src/python3_anticaptcha/core/aio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/aio_captcha_instrument.py @@ -19,11 +19,7 @@ class AIOCaptchaInstrument(CaptchaInstrument): """ - Basic Captcha solving class - - Args: - api_key: Capsolver API key - sleep_time: The waiting time between requests to get the result of the Captcha + Instrument for working with async captcha """ def __init__(self, captcha_params: CaptchaParams): From 4fd66bd0ee37cdf18b72b3eb3e6284a19197b185 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 18:33:07 +0300 Subject: [PATCH 04/11] Update sio_captcha_instrument.py --- src/python3_anticaptcha/core/sio_captcha_instrument.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/python3_anticaptcha/core/sio_captcha_instrument.py b/src/python3_anticaptcha/core/sio_captcha_instrument.py index ac51e22..442d637 100644 --- a/src/python3_anticaptcha/core/sio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/sio_captcha_instrument.py @@ -20,11 +20,7 @@ class SIOCaptchaInstrument(CaptchaInstrument): """ - Basic Captcha solving class - - Args: - api_key: Capsolver API key - sleep_time: The waiting time between requests to get the result of the Captcha + Instrument for working with sync captcha """ def __init__(self, captcha_params: CaptchaParams): From 15e5faf87bef64edb8a32028176a6eb5e456e088 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 19:05:32 +0300 Subject: [PATCH 05/11] refactored images processing --- .../core/aio_captcha_instrument.py | 30 +++++++++++++++++-- .../core/captcha_instrument.py | 15 ++++++++-- .../core/sio_captcha_instrument.py | 30 +++++++++++++++++-- .../image_to_coordinates.py | 21 ++++--------- src/python3_anticaptcha/image_to_text.py | 21 ++++--------- 5 files changed, 78 insertions(+), 39 deletions(-) diff --git a/src/python3_anticaptcha/core/aio_captcha_instrument.py b/src/python3_anticaptcha/core/aio_captcha_instrument.py index 31b52e7..f841699 100644 --- a/src/python3_anticaptcha/core/aio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/aio_captcha_instrument.py @@ -1,7 +1,7 @@ import base64 import asyncio import logging -from typing import Optional +from typing import Union, Optional from urllib import parse from urllib.parse import urljoin @@ -41,9 +41,31 @@ async def processing_captcha(self) -> dict: return await self._get_result() - async def body_file_processing( + async def processing_image_captcha( + self, + save_format: Union[str, SaveFormatsEnm], + img_clearing: bool, + captcha_link: str, + captcha_file: str, + captcha_base64: bytes, + img_path: str, + ) -> dict: + await self.__body_file_processing( + save_format=save_format, + img_clearing=img_clearing, + file_path=img_path, + captcha_link=captcha_link, + captcha_file=captcha_file, + captcha_base64=captcha_base64, + ) + if not self.result.errorId: + return await self.processing_captcha() + return self.result.to_dict() + + async def __body_file_processing( self, save_format: SaveFormatsEnm, + img_clearing: bool, file_path: str, file_extension: str = "png", captcha_link: Optional[str] = None, @@ -67,7 +89,9 @@ async def body_file_processing( content = await self._url_read(url=captcha_link, **kwargs) # according to the value of the passed parameter, select the function to save the image if save_format == SaveFormatsEnm.CONST.value: - self._file_const_saver(content, file_path, file_extension=file_extension) + full_file_path = self._file_const_saver(content, file_path, file_extension=file_extension) + if img_clearing: + self._file_clean(full_file_path=full_file_path) self.captcha_params.create_task_payload.task.update({"body": base64.b64encode(content).decode("utf-8")}) except Exception as error: self.result.errorId = 12 diff --git a/src/python3_anticaptcha/core/captcha_instrument.py b/src/python3_anticaptcha/core/captcha_instrument.py index 7a0c27d..9fd3314 100644 --- a/src/python3_anticaptcha/core/captcha_instrument.py +++ b/src/python3_anticaptcha/core/captcha_instrument.py @@ -1,5 +1,6 @@ import os import uuid +import shutil from pathlib import Path from .serializer import GetTaskResultResponseSer @@ -16,18 +17,26 @@ def _local_file_captcha(captcha_file: str): with open(captcha_file, "rb") as file: return file.read() - def _file_const_saver(self, content: bytes, file_path: str, file_extension: str = "png"): + @staticmethod + def _file_const_saver(content: bytes, file_path: str, file_extension: str = "png") -> str: """ Method create and save file in folder """ Path(file_path).mkdir(parents=True, exist_ok=True) # generate image name - self.file_name = f"file-{uuid.uuid4()}.{file_extension}" + file_name = f"file-{uuid.uuid4()}.{file_extension}" + + full_file_path = os.path.join(file_path, file_name) # save image to folder - with open(os.path.join(file_path, self.file_name), "wb") as out_image: + with open(full_file_path, "wb") as out_image: out_image.write(content) + return full_file_path + + @staticmethod + def _file_clean(full_file_path: str): + shutil.rmtree(full_file_path, ignore_errors=True) class CaptchaInstrument(FileInstrument): diff --git a/src/python3_anticaptcha/core/sio_captcha_instrument.py b/src/python3_anticaptcha/core/sio_captcha_instrument.py index 442d637..ca79f1b 100644 --- a/src/python3_anticaptcha/core/sio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/sio_captcha_instrument.py @@ -1,7 +1,7 @@ import time import base64 import logging -from typing import Optional +from typing import Union, Optional from urllib import parse from urllib.parse import urljoin @@ -47,9 +47,31 @@ def processing_captcha(self) -> dict: return self._get_result() - def body_file_processing( + def processing_image_captcha( + self, + save_format: Union[str, SaveFormatsEnm], + img_clearing: bool, + captcha_link: str, + captcha_file: str, + captcha_base64: bytes, + img_path: str, + ) -> dict: + self.__body_file_processing( + save_format=save_format, + img_clearing=img_clearing, + file_path=img_path, + captcha_link=captcha_link, + captcha_file=captcha_file, + captcha_base64=captcha_base64, + ) + if not self.result.errorId: + return self.processing_captcha() + return self.result.to_dict() + + def __body_file_processing( self, save_format: SaveFormatsEnm, + img_clearing: bool, file_path: str, file_extension: str = "png", captcha_link: Optional[str] = None, @@ -73,7 +95,9 @@ def body_file_processing( content = self._url_read(url=captcha_link, **kwargs).content # according to the value of the passed parameter, select the function to save the image if save_format == SaveFormatsEnm.CONST.value: - self._file_const_saver(content, file_path, file_extension=file_extension) + full_file_path = self._file_const_saver(content, file_path, file_extension=file_extension) + if img_clearing: + self._file_clean(full_file_path=full_file_path) self.captcha_params.create_task_payload.task.update({"body": base64.b64encode(content).decode("utf-8")}) except Exception as error: self.result.errorId = 12 diff --git a/src/python3_anticaptcha/image_to_coordinates.py b/src/python3_anticaptcha/image_to_coordinates.py index a8d38cf..473a325 100644 --- a/src/python3_anticaptcha/image_to_coordinates.py +++ b/src/python3_anticaptcha/image_to_coordinates.py @@ -1,4 +1,3 @@ -import shutil from typing import Union, Optional from .core.base import CaptchaParams @@ -159,16 +158,14 @@ def captcha_handler( self.task_params.update({**additional_params}) self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) - self._captcha_handling_instrument.body_file_processing( + return self._captcha_handling_instrument.processing_image_captcha( save_format=self.save_format, - file_path=self.img_path, + img_clearing=self.img_clearing, + img_path=self.img_path, captcha_link=captcha_link, captcha_file=captcha_file, captcha_base64=captcha_base64, ) - if not self._captcha_handling_instrument.result.errorId: - return self._captcha_handling_instrument.processing_captcha() - return self._captcha_handling_instrument.result.to_dict() async def aio_captcha_handler( self, @@ -197,17 +194,11 @@ async def aio_captcha_handler( self.task_params.update({**additional_params}) self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) - await self._captcha_handling_instrument.body_file_processing( + return await self._captcha_handling_instrument.processing_image_captcha( save_format=self.save_format, - file_path=self.img_path, + img_clearing=self.img_clearing, + img_path=self.img_path, captcha_link=captcha_link, captcha_file=captcha_file, captcha_base64=captcha_base64, ) - if not self._captcha_handling_instrument.result.errorId: - return await self._captcha_handling_instrument.processing_captcha() - return self._captcha_handling_instrument.result.to_dict() - - def __del__(self): - if self.save_format == SaveFormatsEnm.CONST.value and self.img_clearing: - shutil.rmtree(self.img_path, ignore_errors=True) diff --git a/src/python3_anticaptcha/image_to_text.py b/src/python3_anticaptcha/image_to_text.py index 8e3d8c4..80e5f49 100644 --- a/src/python3_anticaptcha/image_to_text.py +++ b/src/python3_anticaptcha/image_to_text.py @@ -1,4 +1,3 @@ -import shutil from typing import Union, Optional from .core.base import CaptchaParams @@ -132,16 +131,14 @@ def captcha_handler( self.task_params.update({**additional_params}) self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self) - self._captcha_handling_instrument.body_file_processing( + return self._captcha_handling_instrument.processing_image_captcha( save_format=self.save_format, - file_path=self.img_path, + img_clearing=self.img_clearing, + img_path=self.img_path, captcha_link=captcha_link, captcha_file=captcha_file, captcha_base64=captcha_base64, ) - if not self._captcha_handling_instrument.result.errorId: - return self._captcha_handling_instrument.processing_captcha() - return self._captcha_handling_instrument.result.to_dict() async def aio_captcha_handler( self, @@ -170,17 +167,11 @@ async def aio_captcha_handler( self.task_params.update({**additional_params}) self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self) - await self._captcha_handling_instrument.body_file_processing( + return await self._captcha_handling_instrument.processing_image_captcha( save_format=self.save_format, - file_path=self.img_path, + img_clearing=self.img_clearing, + img_path=self.img_path, captcha_link=captcha_link, captcha_file=captcha_file, captcha_base64=captcha_base64, ) - if not self._captcha_handling_instrument.result.errorId: - return await self._captcha_handling_instrument.processing_captcha() - return self._captcha_handling_instrument.result.to_dict() - - def __del__(self): - if self.save_format == SaveFormatsEnm.CONST.value and self.img_clearing: - shutil.rmtree(self.img_path, ignore_errors=True) From e48b9dc2d34b6fef88a9223f07ec31d030d1cf09 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 19:18:55 +0300 Subject: [PATCH 06/11] Update aio_captcha_instrument.py --- src/python3_anticaptcha/core/aio_captcha_instrument.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python3_anticaptcha/core/aio_captcha_instrument.py b/src/python3_anticaptcha/core/aio_captcha_instrument.py index f841699..8204608 100644 --- a/src/python3_anticaptcha/core/aio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/aio_captcha_instrument.py @@ -7,7 +7,6 @@ import aiohttp -from .base import CaptchaParams from .enum import SaveFormatsEnm from .const import ASYNC_RETRIES, BASE_REQUEST_URL, GET_RESULT_POSTFIX, CREATE_TASK_POSTFIX from .utils import attempts_generator @@ -22,7 +21,7 @@ class AIOCaptchaInstrument(CaptchaInstrument): Instrument for working with async captcha """ - def __init__(self, captcha_params: CaptchaParams): + def __init__(self, captcha_params: "CaptchaParams"): super().__init__() self.captcha_params = captcha_params From 54ea5dc232d188fa6b2da2234ede6c3d24c81724 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 19:18:58 +0300 Subject: [PATCH 07/11] Update sio_captcha_instrument.py --- src/python3_anticaptcha/core/sio_captcha_instrument.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python3_anticaptcha/core/sio_captcha_instrument.py b/src/python3_anticaptcha/core/sio_captcha_instrument.py index ca79f1b..0f4304f 100644 --- a/src/python3_anticaptcha/core/sio_captcha_instrument.py +++ b/src/python3_anticaptcha/core/sio_captcha_instrument.py @@ -8,7 +8,6 @@ import requests from requests.adapters import HTTPAdapter -from .base import CaptchaParams from .enum import SaveFormatsEnm, ResponseStatusEnm from .const import RETRIES, BASE_REQUEST_URL, GET_RESULT_POSTFIX, CREATE_TASK_POSTFIX from .utils import attempts_generator @@ -23,7 +22,7 @@ class SIOCaptchaInstrument(CaptchaInstrument): Instrument for working with sync captcha """ - def __init__(self, captcha_params: CaptchaParams): + def __init__(self, captcha_params: "CaptchaParams"): super().__init__() self.captcha_params = captcha_params # prepare session From 6ee565726848adab6962ba8c2c5b9bf462bd4478 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 19:29:56 +0300 Subject: [PATCH 08/11] Update conftest.py --- tests/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 4280687..f9a638f 100755 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,12 +10,12 @@ @pytest.fixture(scope="function") def delay_func(): - time.sleep(0.6) + time.sleep(1) @pytest.fixture(scope="class") def delay_class(): - time.sleep(1) + time.sleep(2) @pytest.mark.usefixtures("delay_func") From 788caab5e34a2f2a697332a36008d5d6181560ee Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 18 Dec 2024 20:44:00 +0300 Subject: [PATCH 09/11] Update pydantic from 2.10.3 to 2.10.4 --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index b8dd689..c2c9cac 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,5 +2,5 @@ sphinx==8.1.3 pallets_sphinx_themes==2.3.0 myst-parser==4.0.0 autodoc_pydantic==2.2.0 -pydantic==2.10.3 +pydantic==2.10.4 pydantic-settings==2.7.0 From 5facf3f8632c5644688bd6bb718c77f690954c76 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 21:14:08 +0300 Subject: [PATCH 10/11] Update test_image_to_text.py --- tests/test_image_to_text.py | 52 +++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/test_image_to_text.py b/tests/test_image_to_text.py index 39f6cb6..7206ae6 100644 --- a/tests/test_image_to_text.py +++ b/tests/test_image_to_text.py @@ -7,6 +7,7 @@ from python3_anticaptcha.core.enum import SaveFormatsEnm, ResponseStatusEnm from python3_anticaptcha.image_to_text import ImageToText from python3_anticaptcha.core.serializer import GetTaskResultResponseSer +from python3_anticaptcha.core.captcha_instrument import FileInstrument from python3_anticaptcha.core.aio_captcha_instrument import AIOCaptchaInstrument from python3_anticaptcha.core.sio_captcha_instrument import SIOCaptchaInstrument @@ -52,12 +53,12 @@ async def test_aio_success_file(self): def test_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( - "python3_anticaptcha.image_to_text.SIOCaptchaHandler", + "python3_anticaptcha.image_to_text.SIOCaptchaInstrument", side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -75,12 +76,12 @@ def test_captcha_link(self, mocker, save_format, img_clearing): async def test_aio_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( - "python3_anticaptcha.image_to_text.AIOCaptchaHandler", + "python3_anticaptcha.image_to_text.AIOCaptchaInstrument", side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -95,7 +96,7 @@ async def test_aio_captcha_link(self, mocker, save_format, img_clearing): def test_err_captcha_link(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler._url_read" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument._url_read" ) mocked_method.side_effect = ValueError("Test error") @@ -110,7 +111,7 @@ def test_err_captcha_link(self, mocker): async def test_aio_err_captcha_link(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler._url_read" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument._url_read" ) mocked_method.side_effect = ValueError("Test error") @@ -124,9 +125,9 @@ async def test_aio_err_captcha_link(self, mocker): assert ser_result.cost == 0.0 def test_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "body_file_processing") + captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "processing_image_captcha") mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -142,9 +143,9 @@ def test_captcha_base64(self, mocker): assert result == mocked_method.return_value async def test_aio_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "body_file_processing") + captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "processing_image_captcha") mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -170,13 +171,36 @@ def test_args(self): assert instance.create_task_payload.clientKey == self.API_KEY def test_del(self, mocker): - mocked_method: MagicMock = mocker.patch("shutil.rmtree") - ImageToText(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + mocked_method: MagicMock = mocker.patch( + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" + ) + mocked_method.return_value = "tested" + del_method = mocker.spy(FileInstrument, "_file_clean") + + instance = ImageToText(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + result = instance.captcha_handler(captcha_link=self.captcha_url) + + assert mocked_method.call_count == 1 + assert result == mocked_method.return_value + assert del_method.call_count == 1 + + async def test_aio_del(self, mocker): + mocked_method: MagicMock = mocker.patch( + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" + ) + mocked_method.return_value = "tested" + del_method = mocker.spy(FileInstrument, "_file_clean") + + instance = ImageToText(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + result = await instance.aio_captcha_handler(captcha_link=self.captcha_url) + assert mocked_method.call_count == 1 + assert result == mocked_method.return_value + assert del_method.call_count == 1 def test_kwargs(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.body_file_processing" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_image_captcha" ) instance = ImageToText(api_key=self.API_KEY) @@ -189,7 +213,7 @@ def test_kwargs(self, mocker): async def test_aio_kwargs(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.body_file_processing" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_image_captcha" ) instance = ImageToText(api_key=self.API_KEY) From 31bb2b53ffd801668ad8731dd921ca315a1591a9 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 18 Dec 2024 21:28:53 +0300 Subject: [PATCH 11/11] Update test_image_to_coordinates.py --- tests/test_image_to_coordinates.py | 52 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/test_image_to_coordinates.py b/tests/test_image_to_coordinates.py index 9baf1fd..c11f0fa 100644 --- a/tests/test_image_to_coordinates.py +++ b/tests/test_image_to_coordinates.py @@ -7,6 +7,7 @@ from python3_anticaptcha.core.enum import SaveFormatsEnm, ResponseStatusEnm from python3_anticaptcha.core.serializer import GetTaskResultResponseSer from python3_anticaptcha.image_to_coordinates import ImageToCoordinates +from python3_anticaptcha.core.captcha_instrument import FileInstrument from python3_anticaptcha.core.aio_captcha_instrument import AIOCaptchaInstrument from python3_anticaptcha.core.sio_captcha_instrument import SIOCaptchaInstrument @@ -46,12 +47,12 @@ async def test_aio_success_file(self): def test_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( - "python3_anticaptcha.image_to_coordinates.SIOCaptchaHandler", + "python3_anticaptcha.image_to_coordinates.SIOCaptchaInstrument", side_effect=lambda *args, **kwargs: captured_instances.append(SIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -69,12 +70,12 @@ def test_captcha_link(self, mocker, save_format, img_clearing): async def test_aio_captcha_link(self, mocker, save_format, img_clearing): captured_instances = [] mocker.patch( - "python3_anticaptcha.image_to_coordinates.AIOCaptchaHandler", + "python3_anticaptcha.image_to_coordinates.AIOCaptchaInstrument", side_effect=lambda *args, **kwargs: captured_instances.append(AIOCaptchaInstrument(*args, **kwargs)) or captured_instances[-1], ) mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -89,7 +90,7 @@ async def test_aio_captcha_link(self, mocker, save_format, img_clearing): def test_err_captcha_link(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler._url_read" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument._url_read" ) mocked_method.side_effect = ValueError("Test error") @@ -104,7 +105,7 @@ def test_err_captcha_link(self, mocker): async def test_aio_err_captcha_link(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler._url_read" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument._url_read" ) mocked_method.side_effect = ValueError("Test error") @@ -118,9 +119,9 @@ async def test_aio_err_captcha_link(self, mocker): assert ser_result.cost == 0.0 def test_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "body_file_processing") + captcha_params_spy = mocker.spy(SIOCaptchaInstrument, "processing_image_captcha") mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -136,9 +137,9 @@ def test_captcha_base64(self, mocker): assert result == mocked_method.return_value async def test_aio_captcha_base64(self, mocker): - captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "body_file_processing") + captcha_params_spy = mocker.spy(AIOCaptchaInstrument, "processing_image_captcha") mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.processing_captcha" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" ) mocked_method.return_value = "tested" @@ -164,9 +165,32 @@ def test_args(self): assert instance.create_task_payload.clientKey == self.API_KEY def test_del(self, mocker): - mocked_method: MagicMock = mocker.patch("shutil.rmtree") - ImageToCoordinates(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + mocked_method: MagicMock = mocker.patch( + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_captcha" + ) + mocked_method.return_value = "tested" + del_method = mocker.spy(FileInstrument, "_file_clean") + + instance = ImageToCoordinates(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + result = instance.captcha_handler(captcha_link=self.captcha_url) + + assert mocked_method.call_count == 1 + assert result == mocked_method.return_value + assert del_method.call_count == 1 + + async def test_aio_del(self, mocker): + mocked_method: MagicMock = mocker.patch( + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_captcha" + ) + mocked_method.return_value = "tested" + del_method = mocker.spy(FileInstrument, "_file_clean") + + instance = ImageToCoordinates(api_key=self.API_KEY, save_format=SaveFormatsEnm.CONST, img_clearing=True) + result = await instance.aio_captcha_handler(captcha_link=self.captcha_url) + assert mocked_method.call_count == 1 + assert result == mocked_method.return_value + assert del_method.call_count == 1 def test_init_kwargs(self): instance = ImageToCoordinates(api_key=self.API_KEY, **self.kwargs_params) @@ -176,7 +200,7 @@ def test_init_kwargs(self): def test_kwargs(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.sio_captcha_handler.SIOCaptchaHandler.body_file_processing" + "python3_anticaptcha.core.sio_captcha_instrument.SIOCaptchaInstrument.processing_image_captcha" ) instance = ImageToCoordinates(api_key=self.API_KEY) @@ -189,7 +213,7 @@ def test_kwargs(self, mocker): async def test_aio_kwargs(self, mocker): mocked_method: MagicMock = mocker.patch( - "python3_anticaptcha.core.aio_captcha_handler.AIOCaptchaHandler.body_file_processing" + "python3_anticaptcha.core.aio_captcha_instrument.AIOCaptchaInstrument.processing_image_captcha" ) instance = ImageToCoordinates(api_key=self.API_KEY)