Skip to content

Commit 2da0ead

Browse files
authored
Merge pull request #197 from AndreiDrang/main
2 parents 07d2a39 + 31bb2b5 commit 2da0ead

18 files changed

+280
-409
lines changed

.gitignore

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ dist/
2020
venv/
2121
env/
2222
/.coverage
23-
/src/python3_captchaai.egg-info/
24-
/src/.coverage
25-
/src/coverage/lcov.info
26-
/src/htmlcov/
27-
/src/coverage/
2823
/docs/_build/
2924
/src/python3_anticaptcha.egg-info/
3025
/coverage/

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ sphinx==8.1.3
22
pallets_sphinx_themes==2.3.0
33
myst-parser==4.0.0
44
autodoc_pydantic==2.2.0
5-
pydantic==2.10.3
5+
pydantic==2.10.4
66
pydantic-settings==2.7.0

src/python3_anticaptcha/control.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
from .core.base import CaptchaParams
44
from .core.enum import ControlPostfixEnm
5-
from .core.aio_captcha_handler import AIOCaptchaHandler
6-
from .core.sio_captcha_handler import SIOCaptchaHandler
5+
from .core.aio_captcha_instrument import AIOCaptchaInstrument
6+
from .core.sio_captcha_instrument import SIOCaptchaInstrument
77

88
__all__ = ("Control",)
99

@@ -134,7 +134,7 @@ def get_balance(self) -> dict:
134134
Notes:
135135
https://anti-captcha.com/apidoc/methods/getBalance
136136
"""
137-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
137+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
138138
return self._captcha_handling_instrument.send_post_request(
139139
session=self._captcha_handling_instrument.session,
140140
url_postfix=ControlPostfixEnm.GET_BALANCE,
@@ -158,7 +158,7 @@ async def aio_get_balance(self) -> dict:
158158
Notes:
159159
https://anti-captcha.com/apidoc/methods/getBalance
160160
"""
161-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
161+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
162162
return await self._captcha_handling_instrument.send_post_request(
163163
url_postfix=ControlPostfixEnm.GET_BALANCE, payload={"clientKey": self.create_task_payload.clientKey}
164164
)
@@ -196,7 +196,7 @@ def get_queue_status(queue_id: int) -> dict:
196196
Notes:
197197
https://anti-captcha.com/apidoc/methods/getQueueStats
198198
"""
199-
return SIOCaptchaHandler.send_post_request(
199+
return SIOCaptchaInstrument.send_post_request(
200200
url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id}
201201
)
202202

@@ -233,7 +233,7 @@ async def aio_get_queue_status(queue_id: int) -> dict:
233233
Notes:
234234
https://anti-captcha.com/apidoc/methods/getQueueStats
235235
"""
236-
return await AIOCaptchaHandler.send_post_request(
236+
return await AIOCaptchaInstrument.send_post_request(
237237
url_postfix=ControlPostfixEnm.GET_QUEUE_STATS, payload={"queueId": queue_id}
238238
)
239239

@@ -288,7 +288,7 @@ def get_spending_stats(self, **kwargs) -> dict:
288288
Notes:
289289
https://anti-captcha.com/apidoc/methods/getSpendingStats
290290
"""
291-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
291+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
292292
return self._captcha_handling_instrument.send_post_request(
293293
session=self._captcha_handling_instrument.session,
294294
url_postfix=ControlPostfixEnm.GET_SPENDING_STATS,
@@ -346,7 +346,7 @@ async def aio_get_spending_stats(self, **kwargs) -> dict:
346346
Notes:
347347
https://anti-captcha.com/apidoc/methods/getSpendingStats
348348
"""
349-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
349+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
350350
return await self._captcha_handling_instrument.send_post_request(
351351
url_postfix=ControlPostfixEnm.GET_SPENDING_STATS,
352352
payload={"clientKey": self.create_task_payload.clientKey, **kwargs},
@@ -388,7 +388,7 @@ def get_app_stats(self, softId: int, mode: Optional[str] = None) -> dict:
388388
Notes:
389389
https://anti-captcha.com/apidoc/methods/getAppStats
390390
"""
391-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
391+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
392392
return self._captcha_handling_instrument.send_post_request(
393393
session=self._captcha_handling_instrument.session,
394394
url_postfix=ControlPostfixEnm.GET_APP_STATS,
@@ -431,7 +431,7 @@ async def aio_get_app_stats(self, softId: int, mode: Optional[str] = None) -> di
431431
Notes:
432432
https://anti-captcha.com/apidoc/methods/getAppStats
433433
"""
434-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
434+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
435435
return await self._captcha_handling_instrument.send_post_request(
436436
url_postfix=ControlPostfixEnm.GET_APP_STATS,
437437
payload={"clientKey": self.create_task_payload.clientKey, "softId": softId, "mode": mode},
@@ -455,7 +455,7 @@ def report_incorrect_image(self, taskId: int) -> dict:
455455
Notes:
456456
https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha
457457
"""
458-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
458+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
459459
return self._captcha_handling_instrument.send_post_request(
460460
session=self._captcha_handling_instrument.session,
461461
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_IMAGE_CAPTCHA,
@@ -480,7 +480,7 @@ async def aio_report_incorrect_image(self, taskId: int) -> dict:
480480
Notes:
481481
https://anti-captcha.com/apidoc/methods/reportIncorrectImageCaptcha
482482
"""
483-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
483+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
484484
return await self._captcha_handling_instrument.send_post_request(
485485
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_IMAGE_CAPTCHA,
486486
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
@@ -504,7 +504,7 @@ def report_incorrect_recaptcha(self, taskId: int) -> dict:
504504
Notes:
505505
https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha
506506
"""
507-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
507+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
508508
return self._captcha_handling_instrument.send_post_request(
509509
session=self._captcha_handling_instrument.session,
510510
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_RECAPTCHA,
@@ -529,7 +529,7 @@ async def aio_report_incorrect_recaptcha(self, taskId: int) -> dict:
529529
Notes:
530530
https://anti-captcha.com/apidoc/methods/reportIncorrectRecaptcha
531531
"""
532-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
532+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
533533
return await self._captcha_handling_instrument.send_post_request(
534534
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_RECAPTCHA,
535535
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
@@ -553,7 +553,7 @@ def report_correct_recaptcha(self, taskId: int) -> dict:
553553
Notes:
554554
https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha
555555
"""
556-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
556+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
557557
return self._captcha_handling_instrument.send_post_request(
558558
session=self._captcha_handling_instrument.session,
559559
url_postfix=ControlPostfixEnm.REPORT_CORRECT_RECAPTCHA,
@@ -578,7 +578,7 @@ async def aio_report_correct_recaptcha(self, taskId: int) -> dict:
578578
Notes:
579579
https://anti-captcha.com/apidoc/methods/reportCorrectRecaptcha
580580
"""
581-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
581+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
582582
return await self._captcha_handling_instrument.send_post_request(
583583
url_postfix=ControlPostfixEnm.REPORT_CORRECT_RECAPTCHA,
584584
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},
@@ -602,7 +602,7 @@ def report_incorrect_hcaptcha(self, taskId: int) -> dict:
602602
Notes:
603603
https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha
604604
"""
605-
self._captcha_handling_instrument = SIOCaptchaHandler(captcha_params=self)
605+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
606606
return self._captcha_handling_instrument.send_post_request(
607607
session=self._captcha_handling_instrument.session,
608608
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_HCAPTCHA,
@@ -627,7 +627,7 @@ async def aio_report_incorrect_hcaptcha(self, taskId: int) -> dict:
627627
Notes:
628628
https://anti-captcha.com/apidoc/methods/reportIncorrectHcaptcha
629629
"""
630-
self._captcha_handling_instrument = AIOCaptchaHandler(captcha_params=self)
630+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
631631
return await self._captcha_handling_instrument.send_post_request(
632632
url_postfix=ControlPostfixEnm.REPORT_INCORRECT_HCAPTCHA,
633633
payload={"clientKey": self.create_task_payload.clientKey, "taskId": taskId},

src/python3_anticaptcha/core/aio_captcha_handler.py renamed to src/python3_anticaptcha/core/aio_captcha_instrument.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,27 @@
11
import base64
22
import asyncio
33
import logging
4-
from typing import Optional
4+
from typing import Union, Optional
55
from urllib import parse
66
from urllib.parse import urljoin
77

88
import aiohttp
99

10-
from .base import CaptchaParams, CaptchaHandler
1110
from .enum import SaveFormatsEnm
1211
from .const import ASYNC_RETRIES, BASE_REQUEST_URL, GET_RESULT_POSTFIX, CREATE_TASK_POSTFIX
1312
from .utils import attempts_generator
1413
from .serializer import CreateTaskResponseSer
14+
from .captcha_instrument import CaptchaInstrument
1515

16-
__all__ = ("AIOCaptchaHandler",)
16+
__all__ = ("AIOCaptchaInstrument",)
1717

1818

19-
class AIOCaptchaHandler(CaptchaHandler):
19+
class AIOCaptchaInstrument(CaptchaInstrument):
2020
"""
21-
Basic Captcha solving class
22-
23-
Args:
24-
api_key: Capsolver API key
25-
sleep_time: The waiting time between requests to get the result of the Captcha
21+
Instrument for working with async captcha
2622
"""
2723

28-
def __init__(self, captcha_params: CaptchaParams):
24+
def __init__(self, captcha_params: "CaptchaParams"):
2925
super().__init__()
3026
self.captcha_params = captcha_params
3127

@@ -44,9 +40,31 @@ async def processing_captcha(self) -> dict:
4440

4541
return await self._get_result()
4642

47-
async def body_file_processing(
43+
async def processing_image_captcha(
44+
self,
45+
save_format: Union[str, SaveFormatsEnm],
46+
img_clearing: bool,
47+
captcha_link: str,
48+
captcha_file: str,
49+
captcha_base64: bytes,
50+
img_path: str,
51+
) -> dict:
52+
await self.__body_file_processing(
53+
save_format=save_format,
54+
img_clearing=img_clearing,
55+
file_path=img_path,
56+
captcha_link=captcha_link,
57+
captcha_file=captcha_file,
58+
captcha_base64=captcha_base64,
59+
)
60+
if not self.result.errorId:
61+
return await self.processing_captcha()
62+
return self.result.to_dict()
63+
64+
async def __body_file_processing(
4865
self,
4966
save_format: SaveFormatsEnm,
67+
img_clearing: bool,
5068
file_path: str,
5169
file_extension: str = "png",
5270
captcha_link: Optional[str] = None,
@@ -70,7 +88,9 @@ async def body_file_processing(
7088
content = await self._url_read(url=captcha_link, **kwargs)
7189
# according to the value of the passed parameter, select the function to save the image
7290
if save_format == SaveFormatsEnm.CONST.value:
73-
self._file_const_saver(content, file_path, file_extension=file_extension)
91+
full_file_path = self._file_const_saver(content, file_path, file_extension=file_extension)
92+
if img_clearing:
93+
self._file_clean(full_file_path=full_file_path)
7494
self.captcha_params.create_task_payload.task.update({"body": base64.b64encode(content).decode("utf-8")})
7595
except Exception as error:
7696
self.result.errorId = 12
Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import os
2-
import uuid
3-
from pathlib import Path
4-
5-
from .serializer import CreateTaskBaseSer, GetTaskResultRequestSer, GetTaskResultResponseSer
1+
from .serializer import CreateTaskBaseSer, GetTaskResultRequestSer
62
from .context_instr import AIOContextManager, SIOContextManager
3+
from .captcha_instrument import CaptchaInstrument
4+
from .aio_captcha_instrument import AIOCaptchaInstrument
5+
6+
__all__ = ("CaptchaParams",)
77

8-
__all__ = ("CaptchaParams", "CaptchaHandler")
8+
from .sio_captcha_instrument import SIOCaptchaInstrument
99

1010

1111
class CaptchaParams(SIOContextManager, AIOContextManager):
@@ -28,49 +28,42 @@ def __init__(self, api_key: str, sleep_time: int = 15, *args, **kwargs):
2828
# prepare `get task result` payload
2929
self.get_result_params = GetTaskResultRequestSer(clientKey=api_key)
3030

31-
self._captcha_handling_instrument = CaptchaHandler()
32-
33-
@classmethod
34-
def captcha_handler(cls):
35-
pass
36-
37-
@classmethod
38-
def aio_captcha_handler(cls):
39-
pass
31+
self._captcha_handling_instrument = CaptchaInstrument()
4032

33+
def captcha_handler(self, **additional_params) -> dict:
34+
"""
35+
Synchronous method for captcha solving
4136
42-
class CaptchaHandler:
43-
NO_CAPTCHA_ERR = "You did not send any file, local link or URL."
44-
"""
45-
Basic Captcha solving class
46-
47-
Args:
48-
api_key: Capsolver API key
49-
captcha_type: Captcha type name, like `ReCaptchaV2Task` and etc.
50-
sleep_time: The waiting time between requests to get the result of the Captcha
51-
request_url: API address for sending requests
52-
"""
37+
Args:
38+
additional_params: Some additional parameters that will be used in creating the task
39+
and will be passed to the payload under ``task`` key.
40+
Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs
5341
54-
def __init__(self):
55-
self.result = GetTaskResultResponseSer()
42+
Returns:
43+
Dict with full server response
5644
57-
@staticmethod
58-
def _local_file_captcha(captcha_file: str):
45+
Notes:
46+
Check class docstirng for more info
5947
"""
60-
Method get local file, read it and prepare for sending to Captcha solving service
61-
"""
62-
with open(captcha_file, "rb") as file:
63-
return file.read()
48+
self.task_params.update({**additional_params})
49+
self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
50+
return self._captcha_handling_instrument.processing_captcha()
6451

65-
def _file_const_saver(self, content: bytes, file_path: str, file_extension: str = "png"):
66-
"""
67-
Method create and save file in folder
52+
async def aio_captcha_handler(self, **additional_params) -> dict:
6853
"""
69-
Path(file_path).mkdir(parents=True, exist_ok=True)
54+
Asynchronous method for captcha solving
7055
71-
# generate image name
72-
self.file_name = f"file-{uuid.uuid4()}.{file_extension}"
56+
Args:
57+
additional_params: Some additional parameters that will be used in creating the task
58+
and will be passed to the payload under ``task`` key.
59+
Like ``proxyLogin``, ``proxyPassword`` and etc. - more info in service docs
7360
74-
# save image to folder
75-
with open(os.path.join(file_path, self.file_name), "wb") as out_image:
76-
out_image.write(content)
61+
Returns:
62+
Dict with full server response
63+
64+
Notes:
65+
Check class docstirng for more info
66+
"""
67+
self.task_params.update({**additional_params})
68+
self._captcha_handling_instrument = AIOCaptchaInstrument(captcha_params=self)
69+
return await self._captcha_handling_instrument.processing_captcha()

0 commit comments

Comments
 (0)