Skip to content

Commit 152dc97

Browse files
alperensertclaude
andcommitted
feat: add reportIncorrect and getUserAgent client methods
Add report_incorrect_image, report_incorrect_token, and get_user_agent methods with sync and async variants. Change default retry_delay from 1.0s to 2.0s to comply with the API's minimum 2-second polling interval. BREAKING CHANGE: default retry_delay changed from 1.0 to 2.0 seconds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5fb508a commit 152dc97

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

src/capmonster_python/client.py

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from httpx import Response, AsyncClient, Client
66

77
from .exceptions import CapmonsterAPIException, CapmonsterException
8-
from .methods import GetBalancePayload, GetTaskResultPayload, CreateTaskPayload
8+
from .methods import GetBalancePayload, GetTaskResultPayload, CreateTaskPayload, ReportIncorrectCaptchaPayload
99
from .tasks.task import TaskPayload
1010

1111

@@ -15,8 +15,12 @@ class CapmonsterClient:
1515
__TASK_RESULT_URL = "/getTaskResult"
1616
__CREATE_TASK_URL = "/createTask"
1717

18+
__REPORT_IMAGE_URL = "/reportIncorrectImageCaptcha"
19+
__REPORT_TOKEN_URL = "/reportIncorrectTokenCaptcha"
20+
__USER_AGENT_URL = "https://capmonster.cloud/api/useragent/actual"
21+
1822
def __init__(self, api_key: str, timeout: Optional[float] = 30.0,
19-
max_retries: int = 120, retry_delay: float = 1.0) -> None:
23+
max_retries: int = 120, retry_delay: float = 2.0) -> None:
2024
self.api_key = api_key
2125
self.__max_retries = max_retries
2226
self.__retry_delay = retry_delay
@@ -245,6 +249,84 @@ async def solve_async(self, task: TaskPayload, callback_url: Optional[str] = Non
245249
task_id = await self.create_task_async(task, callback_url)
246250
return await self.join_task_result_async(task_id)
247251

252+
def report_incorrect_image(self, task_id: int) -> None:
253+
"""
254+
Reports an incorrect image captcha solution.
255+
256+
Args:
257+
task_id: The identifier of the task to report.
258+
259+
Raises:
260+
CapmonsterAPIException: If the API returns an error.
261+
"""
262+
payload = ReportIncorrectCaptchaPayload(clientKey=self.api_key, taskId=task_id).model_dump()
263+
self.__make_sync_request(self.__REPORT_IMAGE_URL, payload)
264+
265+
async def report_incorrect_image_async(self, task_id: int) -> None:
266+
"""
267+
Asynchronously reports an incorrect image captcha solution.
268+
269+
Args:
270+
task_id: The identifier of the task to report.
271+
272+
Raises:
273+
CapmonsterAPIException: If the API returns an error.
274+
"""
275+
payload = ReportIncorrectCaptchaPayload(clientKey=self.api_key, taskId=task_id).model_dump()
276+
await self.__make_async_request(self.__REPORT_IMAGE_URL, payload)
277+
278+
def report_incorrect_token(self, task_id: int) -> None:
279+
"""
280+
Reports an incorrect token captcha solution (reCAPTCHA, GeeTest, Turnstile, etc.).
281+
282+
Args:
283+
task_id: The identifier of the task to report.
284+
285+
Raises:
286+
CapmonsterAPIException: If the API returns an error.
287+
"""
288+
payload = ReportIncorrectCaptchaPayload(clientKey=self.api_key, taskId=task_id).model_dump()
289+
self.__make_sync_request(self.__REPORT_TOKEN_URL, payload)
290+
291+
async def report_incorrect_token_async(self, task_id: int) -> None:
292+
"""
293+
Asynchronously reports an incorrect token captcha solution (reCAPTCHA, GeeTest, Turnstile, etc.).
294+
295+
Args:
296+
task_id: The identifier of the task to report.
297+
298+
Raises:
299+
CapmonsterAPIException: If the API returns an error.
300+
"""
301+
payload = ReportIncorrectCaptchaPayload(clientKey=self.api_key, taskId=task_id).model_dump()
302+
await self.__make_async_request(self.__REPORT_TOKEN_URL, payload)
303+
304+
def get_user_agent(self) -> str:
305+
"""
306+
Fetches the current valid Windows User-Agent string from CapMonster Cloud.
307+
308+
Returns:
309+
str: The current User-Agent string to use with captcha tasks.
310+
"""
311+
try:
312+
response = self.__sync_client.get(self.__USER_AGENT_URL)
313+
return response.text
314+
except Exception as e:
315+
raise CapmonsterException(-1, type(e).__name__, str(e))
316+
317+
async def get_user_agent_async(self) -> str:
318+
"""
319+
Asynchronously fetches the current valid Windows User-Agent string from CapMonster Cloud.
320+
321+
Returns:
322+
str: The current User-Agent string to use with captcha tasks.
323+
"""
324+
try:
325+
response = await self.__async_client.get(self.__USER_AGENT_URL)
326+
return response.text
327+
except Exception as e:
328+
raise CapmonsterException(-1, type(e).__name__, str(e))
329+
248330
def __make_sync_request(self, url: str, payload: dict) -> Response:
249331
try:
250332
response = self.__sync_client.post(url, json=payload)

src/capmonster_python/methods.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class GetTaskResultPayload(BaseModel):
2121
taskId: int = Field(..., description="ID which was obtained from create task method.")
2222

2323

24+
class ReportIncorrectCaptchaPayload(BaseModel):
25+
clientKey: str = Field(..., description="Client key")
26+
taskId: int = Field(..., description="ID of the task to report as incorrect.")
27+
28+
2429
class CreateTaskPayload(BaseModel):
2530
clientKey: str = Field(..., description="Client key")
2631
task: TaskPayload = Field(..., description="Task data")

0 commit comments

Comments
 (0)