Skip to content

Commit

Permalink
Merge pull request #197 from AndreiDrang/main
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiDrang authored Dec 18, 2024
2 parents 07d2a39 + 31bb2b5 commit 2da0ead
Show file tree
Hide file tree
Showing 18 changed files with 280 additions and 409 deletions.
5 changes: 0 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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/
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
36 changes: 18 additions & 18 deletions src/python3_anticaptcha/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",)

Expand Down Expand Up @@ -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,
Expand All @@ -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}
)
Expand Down Expand Up @@ -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}
)

Expand Down Expand Up @@ -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}
)

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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},
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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},
Expand All @@ -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,
Expand All @@ -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},
Expand All @@ -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,
Expand All @@ -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},
Expand All @@ -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,
Expand All @@ -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},
Expand All @@ -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,
Expand All @@ -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},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import base64
import asyncio
import logging
from typing import Optional
from typing import Union, Optional
from urllib import parse
from urllib.parse import urljoin

import aiohttp

from .base import CaptchaParams, CaptchaHandler
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
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):
def __init__(self, captcha_params: "CaptchaParams"):
super().__init__()
self.captcha_params = captcha_params

Expand All @@ -44,9 +40,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,
Expand All @@ -70,7 +88,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
Expand Down
79 changes: 36 additions & 43 deletions src/python3_anticaptcha/core/base.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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()
Loading

0 comments on commit 2da0ead

Please sign in to comment.