Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upd structure #190

Merged
merged 25 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/python3_anticaptcha/FunCaptchaTaskProxyless.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import aiohttp
import requests

from python3_anticaptcha.core.config import create_task_url, get_sync_result, get_async_result
from python3_anticaptcha.core.const import create_task_url, get_sync_result, get_async_result


class FunCaptchaTaskProxyless:
Expand Down
78 changes: 42 additions & 36 deletions src/python3_anticaptcha/control.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from typing import Optional

from .core.base import BaseCaptcha
from .core.base import CaptchaParams, CaptchaHandler
from .core.enum import ControlPostfixEnm
from .core.aio_captcha_handler import AIOCaptchaHandler
from .core.sio_captcha_handler import SIOCaptchaHandler

__all__ = ("Control",)


class Control(BaseCaptcha):
class Control(CaptchaParams):
def __init__(
self,
api_key: str,
Expand Down Expand Up @@ -113,8 +115,8 @@ def __init__(

https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha
"""

super().__init__(api_key=api_key, *args, **kwargs)
self.captcha_handling_instrument = CaptchaHandler

def get_balance(self) -> dict:
"""
Expand All @@ -133,8 +135,9 @@ def get_balance(self) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getBalance
"""
return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.GET_BALANCE,
payload={"clientKey": self.create_task_payload.clientKey},
)
Expand All @@ -156,8 +159,8 @@ async def aio_get_balance(self) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getBalance
"""

return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -194,8 +197,7 @@ def get_queue_status(queue_id: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getQueueStats
"""

return BaseCaptcha._send_post_request(
return SIOCaptchaHandler.send_post_request(
url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id}
)

Expand Down Expand Up @@ -232,8 +234,7 @@ async def aio_get_queue_status(queue_id: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getQueueStats
"""

return await BaseCaptcha._aio_send_post_request(
return await AIOCaptchaHandler.send_post_request(
url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id}
)

Expand Down Expand Up @@ -288,8 +289,9 @@ def get_spending_stats(self, **kwargs) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getSpendingStats
"""
return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.GET_SPENDING_STATS,
payload={"clientKey": self.create_task_payload.clientKey, **kwargs},
)
Expand Down Expand Up @@ -345,7 +347,8 @@ async def aio_get_spending_stats(self, **kwargs) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getSpendingStats
"""
return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -386,9 +389,9 @@ def get_app_stats(self, softId: int, mode: Optional[str] = None) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/getAppStats
"""

return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.GET_APP_STATS,
payload={"clientKey": self.create_task_payload.clientKey, "softId": softId, "mode": mode},
)
Expand Down Expand Up @@ -429,8 +432,8 @@ async def aio_get_app_stats(self, softId: int, mode: Optional[str] = None) -> di
Notes:
https://anti-captcha.com/apidoc/methods/getAppStats
"""

return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -453,9 +456,9 @@ def report_incorrect_image(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha
"""

return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_IMAGE_CAPTCHA,
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
)
Expand All @@ -478,8 +481,8 @@ async def aio_report_incorrect_image(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha
"""

return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -502,9 +505,9 @@ def report_incorrect_recaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha
"""

return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_RECAPTCHA,
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
)
Expand All @@ -527,7 +530,8 @@ async def aio_report_incorrect_recaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha
"""
return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -550,9 +554,9 @@ def report_correct_recaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha
"""

return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.REPORT_CORRECT_RECAPTCHA,
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
)
Expand All @@ -575,7 +579,8 @@ async def aio_report_correct_recaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha
"""
return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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 @@ -598,9 +603,9 @@ def report_incorrect_hcaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha
"""

return self._send_post_request(
session=self._session,
self.captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
return self.captcha_handling_instrument.send_post_request(
session=self.captcha_handling_instrument.session,
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_HCAPTCHA,
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
)
Expand All @@ -623,7 +628,8 @@ async def aio_report_incorrect_hcaptcha(self, taskId: int) -> dict:
Notes:
https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha
"""
return await self._aio_send_post_request(
self.captcha_handling_instrument = AIOCaptchaHandler(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},
)
148 changes: 148 additions & 0 deletions src/python3_anticaptcha/core/aio_captcha_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import base64
import asyncio
import logging
from typing import 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

__all__ = ("AIOCaptchaHandler",)


class AIOCaptchaHandler(CaptchaHandler):
"""
Basic Captcha solving class

Args:
api_key: Capsolver API key
sleep_time: The waiting time between requests to get the result of the Captcha
"""

def __init__(self, captcha_params: CaptchaParams):
super().__init__()
self.captcha_params = captcha_params

async def processing_captcha(self) -> dict:
# added task params to payload
self.captcha_params.create_task_payload.task.update(self.captcha_params.task_params)

created_task = await self._create_task()

if created_task.errorId == 0:
self.captcha_params.get_result_params.taskId = created_task.taskId
else:
return created_task.to_dict()

await asyncio.sleep(self.captcha_params.sleep_time)

return await self._get_result()

async def body_file_processing(
self,
save_format: SaveFormatsEnm,
file_path: str,
file_extension: str = "png",
captcha_link: Optional[str] = None,
captcha_file: Optional[str] = None,
captcha_base64: Optional[bytes] = None,
**kwargs,
):
# if a local file link is passed
if captcha_file:
self.captcha_params.create_task_payload.task.update(
{"body": base64.b64encode(self._local_file_captcha(captcha_file=captcha_file)).decode("utf-8")}
)
# if the file is transferred in base64 encoding
elif captcha_base64:
self.captcha_params.create_task_payload.task.update(
{"body": base64.b64encode(captcha_base64).decode("utf-8")}
)
# if a URL is passed
elif captcha_link:
try:
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)
self.captcha_params.create_task_payload.task.update({"body": base64.b64encode(content).decode("utf-8")})
except Exception as error:
self.result.errorId = 12
self.result.errorCode = self.NO_CAPTCHA_ERR
self.result.errorDescription = str(error)

else:
self.result.errorId = 12
self.result.errorCode = self.NO_CAPTCHA_ERR

async def _url_read(self, url: str, **kwargs) -> bytes:
"""
Async method read bytes from link
"""
async with aiohttp.ClientSession() as session:
async for attempt in ASYNC_RETRIES:
with attempt:
async with session.get(url=url, **kwargs) as resp:
return await resp.content.read()

async def _create_task(self, url_postfix: str = CREATE_TASK_POSTFIX) -> CreateTaskResponseSer:
"""
Function send SYNC request to service and wait for result
"""
async with aiohttp.ClientSession() as session:
try:
async with session.post(
parse.urljoin(BASE_REQUEST_URL, url_postfix), json=self.captcha_params.create_task_payload.to_dict()
) as resp:
if resp.status == 200:
return CreateTaskResponseSer(**await resp.json())
else:
raise ValueError(resp.reason)
except Exception as error:
logging.exception(error)
raise

@staticmethod
async def send_post_request(payload: Optional[dict] = None, url_postfix: str = CREATE_TASK_POSTFIX) -> dict:
"""
Function send ASYNC request to service and wait for result
"""

async with aiohttp.ClientSession() as session:
try:
async with session.post(parse.urljoin(BASE_REQUEST_URL, url_postfix), json=payload) as resp:
if resp.status == 200:
return await resp.json()
else:
raise ValueError(resp.reason)
except Exception as error:
logging.exception(error)
raise

async def _get_result(self, url_response: str = GET_RESULT_POSTFIX) -> dict:
attempts = attempts_generator()
# Send request for status of captcha solution.
async with aiohttp.ClientSession() as session:
for _ in attempts:
async with session.post(
url=urljoin(BASE_REQUEST_URL, url_response), json=self.captcha_params.get_result_params.to_dict()
) as resp:
json_result = await resp.json()
# if there is no error, check CAPTCHA status
if json_result["errorId"] == 0:
# If not yet resolved, wait
if json_result["status"] == "processing":
await asyncio.sleep(self.captcha_params.sleep_time)
# otherwise return response
else:
json_result.update({"taskId": self.captcha_params.get_result_params.taskId})
return json_result
else:
json_result.update({"taskId": self.captcha_params.get_result_params.taskId})
return json_result
Loading
Loading