From aa56c37c8d6f2743c0c23c6863448fff7a4b99b2 Mon Sep 17 00:00:00 2001 From: "pavel.grinkevich" Date: Wed, 22 Jan 2025 12:16:27 +0000 Subject: [PATCH 1/4] add binance and imperva requests --- .../CapMonsterCloudClient.py | 13 ++++- capmonstercloud_client/GetResultTimeouts.py | 6 ++ .../requests/BinanceTaskProxylessRequest.py | 17 ++++++ .../requests/BinanceTaskRequest.py | 22 ++++++++ .../requests/BinanceTaskRequestBase.py | 11 ++++ .../ImpervaCustomTaskProxylessRequest.py | 33 +++++++++++ .../requests/ImpervaCustomTaskRequestBase.py | 8 +++ .../requests/TurnstileRequestBase.py | 1 + capmonstercloud_client/requests/__init__.py | 6 +- examples/binance.py | 37 +++++++++++++ examples/imperva.py | 40 ++++++++++++++ test/binance_request_test.py | 45 +++++++++++++++ test/binance_response_test.py | 39 +++++++++++++ test/imperva_request_test.py | 55 +++++++++++++++++++ 14 files changed, 329 insertions(+), 4 deletions(-) create mode 100644 capmonstercloud_client/requests/BinanceTaskProxylessRequest.py create mode 100644 capmonstercloud_client/requests/BinanceTaskRequest.py create mode 100644 capmonstercloud_client/requests/BinanceTaskRequestBase.py create mode 100644 capmonstercloud_client/requests/ImpervaCustomTaskProxylessRequest.py create mode 100644 capmonstercloud_client/requests/ImpervaCustomTaskRequestBase.py create mode 100644 examples/binance.py create mode 100644 examples/imperva.py create mode 100644 test/binance_request_test.py create mode 100644 test/binance_response_test.py create mode 100644 test/imperva_request_test.py diff --git a/capmonstercloud_client/CapMonsterCloudClient.py b/capmonstercloud_client/CapMonsterCloudClient.py index a14e4fb..aa6bd5d 100644 --- a/capmonstercloud_client/CapMonsterCloudClient.py +++ b/capmonstercloud_client/CapMonsterCloudClient.py @@ -28,7 +28,8 @@ ((TenDiCustomTaskRequest, TenDiCustomTaskProxylessRequest), getTenDiTimeouts), ((BasiliskCustomTaskRequest, BasiliskCustomTaskProxylessRequest), getBasiliskTimeouts), ((AmazonWafRequest, AmazonWafProxylessRequest), getAmazonWafTimeouts), - + ((BinanceTaskRequest, BinanceTaskProxylessRequest), getBinanceTimeouts), + ((ImpervaCustomTaskProxylessRequest), getImpervaTimeouts) ) @@ -77,7 +78,10 @@ async def solve_captcha(self, request: Union[RecaptchaV2EnterpriseProxylessReque RecaptchaComplexImageTaskRequest, FunCaptchaComplexImageTaskRequest, DataDomeCustomTaskProxylessRequest, - DataDomeCustomTaskRequest], + DataDomeCustomTaskRequest, + BinanceTaskRequest, + BinanceTaskProxylessRequest, + ImpervaCustomTaskProxylessRequest], ) -> Dict[str, str]: ''' Non-blocking method for captcha solving. @@ -108,7 +112,10 @@ async def _solve(self, request: Union[RecaptchaV2EnterpriseProxylessRequest, TurnstileRequest, HcaptchaComplexImageTaskRequest, RecaptchaComplexImageTaskRequest, - FunCaptchaComplexImageTaskRequest], + FunCaptchaComplexImageTaskRequest, + BinanceTaskRequest, + BinanceTaskProxylessRequest, + ImpervaCustomTaskProxylessRequest], timeouts: GetResultTimeouts, ) -> Dict[str, str]: diff --git a/capmonstercloud_client/GetResultTimeouts.py b/capmonstercloud_client/GetResultTimeouts.py index feb70b0..cd973ff 100644 --- a/capmonstercloud_client/GetResultTimeouts.py +++ b/capmonstercloud_client/GetResultTimeouts.py @@ -43,3 +43,9 @@ def getBasiliskTimeouts() -> GetResultTimeouts: def getAmazonWafTimeouts() -> GetResultTimeouts: return GetResultTimeouts(1, 10, 3, 180) + +def getBinanceTimeouts() -> GetResultTimeouts: + return GetResultTimeouts(1, 0, 1, 20) + +def getImpervaTimeouts() -> GetResultTimeouts: + return GetResultTimeouts(1, 0, 1, 20) diff --git a/capmonstercloud_client/requests/BinanceTaskProxylessRequest.py b/capmonstercloud_client/requests/BinanceTaskProxylessRequest.py new file mode 100644 index 0000000..9655619 --- /dev/null +++ b/capmonstercloud_client/requests/BinanceTaskProxylessRequest.py @@ -0,0 +1,17 @@ +from typing import Dict, Union + +from .BinanceTaskRequestBase import BinanceTaskRequestBase + + +class BinanceTaskProxylessRequest(BinanceTaskRequestBase): + type: str = 'BinanceTaskProxyless' + + def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: + task = {} + task['type'] = self.type + task['validateId'] = self.validateId + task['websiteURL'] = self.websiteUrl + task['websiteKey'] = self.websiteKey + if self.userAgent is not None: + task['userAgent'] = self.userAgent + return task \ No newline at end of file diff --git a/capmonstercloud_client/requests/BinanceTaskRequest.py b/capmonstercloud_client/requests/BinanceTaskRequest.py new file mode 100644 index 0000000..49672f1 --- /dev/null +++ b/capmonstercloud_client/requests/BinanceTaskRequest.py @@ -0,0 +1,22 @@ +from typing import Dict, Union +from pydantic import Field, validator + +from .proxy_info import ProxyInfo +from .BinanceTaskRequestBase import BinanceTaskRequestBase + +class BinanceTaskRequest(BinanceTaskRequestBase, ProxyInfo): + + def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: + task = {} + task['type'] = self.type + task['validateId'] = self.validateId + task['websiteURL'] = self.websiteUrl + task['websiteKey'] = self.websiteKey + task['proxyType'] = self.proxyType + task['proxyAddress'] = self.proxyAddress + task['proxyPort'] = self.proxyPort + task['proxyLogin'] = self.proxyLogin + task['proxyPassword'] = self.proxyPassword + if self.userAgent is not None: + task['userAgent'] = self.userAgent + return task \ No newline at end of file diff --git a/capmonstercloud_client/requests/BinanceTaskRequestBase.py b/capmonstercloud_client/requests/BinanceTaskRequestBase.py new file mode 100644 index 0000000..d02a704 --- /dev/null +++ b/capmonstercloud_client/requests/BinanceTaskRequestBase.py @@ -0,0 +1,11 @@ +from .baseRequest import BaseRequest, Field +from typing import Optional + + +class BinanceTaskRequestBase(BaseRequest): + + type: str = Field(default='BinanceTask') + websiteKey: str = Field() + websiteUrl: str = Field() + validateId: str = Field() + userAgent: Optional[str] = None diff --git a/capmonstercloud_client/requests/ImpervaCustomTaskProxylessRequest.py b/capmonstercloud_client/requests/ImpervaCustomTaskProxylessRequest.py new file mode 100644 index 0000000..5adc53e --- /dev/null +++ b/capmonstercloud_client/requests/ImpervaCustomTaskProxylessRequest.py @@ -0,0 +1,33 @@ +from typing import Dict, Union +from pydantic import Field, validator + +from .ImpervaCustomTaskRequestBase import ImpervaCustomTaskRequestBase + +class ImpervaCustomTaskProxylessRequest(ImpervaCustomTaskRequestBase): + metadata : Dict[str, str] + + @validator('metadata') + def validate_metadata(cls, value): + if value.get('incapsulaScriptBase64') is None: + raise TypeError(f'Expect that incapsulaScriptBase64 will be defined.') + else: + if not isinstance(value.get('incapsulaScriptBase64'), str): + raise TypeError(f'Expect that incapsulaScriptBase64 will be str.') + if value.get('incapsulaSessionCookie') is None: + raise TypeError(f'Expect that incapsulaSessionCookie will be defined.') + else: + if not isinstance(value.get('incapsulaSessionCookie'), str): + raise TypeError(f'Expect that incapsulaSessionCookie will be str.') + if value.get('reese84UrlEndpoint') is not None and not isinstance(value.get('incapsulaSessionCookie'), str): + raise TypeError(f'Expect that reese84UrlEndpoint will be str.') + return value + + def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: + task = {} + task['type'] = self.type + task['class'] = self.captchaClass + task['websiteURL'] = self.websiteUrl + task['metadata'] = self.metadata + if self.userAgent is not None: + task['userAgent'] = self.userAgent + return task \ No newline at end of file diff --git a/capmonstercloud_client/requests/ImpervaCustomTaskRequestBase.py b/capmonstercloud_client/requests/ImpervaCustomTaskRequestBase.py new file mode 100644 index 0000000..c943e02 --- /dev/null +++ b/capmonstercloud_client/requests/ImpervaCustomTaskRequestBase.py @@ -0,0 +1,8 @@ +from typing import Dict, Union +from pydantic import Field + +from .CustomTaskRequestBase import CustomTaskRequestBase + +class ImpervaCustomTaskRequestBase(CustomTaskRequestBase): + type: str = Field(default='CustomTask') + captchaClass: str = Field(default='Imperva') diff --git a/capmonstercloud_client/requests/TurnstileRequestBase.py b/capmonstercloud_client/requests/TurnstileRequestBase.py index eb3645f..a26ff9d 100644 --- a/capmonstercloud_client/requests/TurnstileRequestBase.py +++ b/capmonstercloud_client/requests/TurnstileRequestBase.py @@ -13,6 +13,7 @@ class TurnstileRequestBase(BaseRequest): userAgent: Optional[str] = Field(default=None) cloudflareTaskType: Optional[str] = Field(default=None) htmlPageBase64: Optional[str] = Field(default=None) + apiJsUrl: Optional[str] = Field(default=None) @validator('cloudflareTaskType') def validate_cloudflare_task(cls, value): diff --git a/capmonstercloud_client/requests/__init__.py b/capmonstercloud_client/requests/__init__.py index caf4092..9dda430 100644 --- a/capmonstercloud_client/requests/__init__.py +++ b/capmonstercloud_client/requests/__init__.py @@ -24,6 +24,9 @@ from .BasiliskCustomTaskProxylessRequest import BasiliskCustomTaskProxylessRequest from .AmazonWafRequest import AmazonWafRequest from .AmazonWafProxylessRequest import AmazonWafProxylessRequest +from .BinanceTaskRequest import BinanceTaskRequest +from .BinanceTaskProxylessRequest import BinanceTaskProxylessRequest +from .ImpervaCustomTaskProxylessRequest import ImpervaCustomTaskProxylessRequest REQUESTS = ['RecaptchaV2EnterpiseRequest', 'RecaptchaV2EnterpriseProxylessRequest', 'RecaptchaV2ProxylessRequest', 'RecaptchaV2Request', 'RecaptchaV3ProxylessRequest', @@ -31,4 +34,5 @@ 'GeetestRequest', 'GeetestProxylessRequest', 'HcaptchaProxylessRequest', 'HcaptchaRequest', 'DataDomeCustomTaskRequest', 'DataDomeCustomTaskProxylessRequest', 'TenDiCustomTaskRequest', 'TenDiCustomTaskProxylessRequest', 'BasiliskCustomTaskRequest', - 'BasiliskCustomTaskProxylessRequest', 'AmazonWafRequest', 'AmazonWafProxylessRequest'] + 'BasiliskCustomTaskProxylessRequest', 'AmazonWafRequest', 'AmazonWafProxylessRequest', + 'BinanceTaskRequest', 'BinanceTaskProxylessRequest', 'ImpervaCustomTaskProxylessRequest'] diff --git a/examples/binance.py b/examples/binance.py new file mode 100644 index 0000000..4ee41ec --- /dev/null +++ b/examples/binance.py @@ -0,0 +1,37 @@ +import os +import time +import asyncio + +from capmonstercloudclient.requests import BinanceTaskProxylessRequest +from capmonstercloudclient import ClientOptions, CapMonsterClient + +async def solve_captcha_sync(num_requests): + return [await cap_monster_client.solve_captcha(datadome_request) for _ in range(num_requests)] + +async def solve_captcha_async(num_requests): + tasks = [asyncio.create_task(cap_monster_client.solve_captcha(datadome_request)) + for _ in range(num_requests)] + return await asyncio.gather(*tasks, return_exceptions=True) + +if __name__ == '__main__': + key = os.getenv('API_KEY') + client_options = ClientOptions(api_key=key) + cap_monster_client = CapMonsterClient(options=client_options) + datadome_request = BinanceTaskProxylessRequest( + websiteUrl='https://accounts.binance.com/ru/login?loginChannel=&return_to=', + websiteKey='login', + validateId="2b8137c0b9b44189800368819354e114" + ) + nums = 3 + + # Sync test + sync_start = time.time() + sync_responses = asyncio.run(solve_captcha_sync(nums)) + print(f'average execution time sync {1/((time.time()-sync_start)/nums):0.2f} ' \ + f'resp/sec\nsolution: {sync_responses[0]}') + + # Async test + async_start = time.time() + async_responses = asyncio.run(solve_captcha_async(nums)) + print(f'average execution time async {1/((time.time()-async_start)/nums):0.2f} ' \ + f'resp/sec\nsolution: {async_responses[0]}') \ No newline at end of file diff --git a/examples/imperva.py b/examples/imperva.py new file mode 100644 index 0000000..ba87986 --- /dev/null +++ b/examples/imperva.py @@ -0,0 +1,40 @@ +import os +import time +import asyncio + +from capmonstercloudclient.requests import ImpervaCustomTaskProxylessRequest +from capmonstercloudclient import ClientOptions, CapMonsterClient +import json + +async def solve_captcha_sync(num_requests): + return [await cap_monster_client.solve_captcha(datadome_request) for _ in range(num_requests)] + +async def solve_captcha_async(num_requests): + tasks = [asyncio.create_task(cap_monster_client.solve_captcha(datadome_request)) + for _ in range(num_requests)] + return await asyncio.gather(*tasks, return_exceptions=True) + +if __name__ == '__main__': + key = os.getenv('API_KEY') + client_options = ClientOptions(api_key=key) + cap_monster_client = CapMonsterClient(options=client_options) + metadata = {"incapsulaScriptBase64": "", + "incapsulaSessionCookie": "SAyLRzdYgUntD6v0r7nFBmxTYGcAAAAArkznhRMmVs/cBynTg3r6YA==", + "reese84UrlEndpoint": "Alarums-Exeunter-Hath-Brese-Banq-Wheth-frangerd-"} + datadome_request = ImpervaCustomTaskProxylessRequest( + websiteUrl='https://example.com/login', + metadata=metadata + ) + nums = 3 + + # Sync test + sync_start = time.time() + sync_responses = asyncio.run(solve_captcha_sync(nums)) + print(f'average execution time sync {1/((time.time()-sync_start)/nums):0.2f} ' \ + f'resp/sec\nsolution: {sync_responses[0]}') + + # Async test + async_start = time.time() + async_responses = asyncio.run(solve_captcha_async(nums)) + print(f'average execution time async {1/((time.time()-async_start)/nums):0.2f} ' \ + f'resp/sec\nsolution: {async_responses[0]}') \ No newline at end of file diff --git a/test/binance_request_test.py b/test/binance_request_test.py new file mode 100644 index 0000000..acf5793 --- /dev/null +++ b/test/binance_request_test.py @@ -0,0 +1,45 @@ +import unittest +from copy import deepcopy + +from pydantic import ValidationError +from capmonstercloudclient.requests import BinanceTaskProxylessRequest + + +class BinanceRequestTest(unittest.TestCase): + + websiteUrlExample = 'https://binance.com/login' + websiteKeyExample = 'login' + userAgentExample = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' + + def test_binance(self, + ): + required_fields = ['type', + 'websiteURL', + 'websiteKey', + 'validateId'] + request = BinanceTaskProxylessRequest(websiteKey=self.websiteKeyExample, + websiteUrl=self.websiteUrlExample, + validateId='asdgf') + task_dictionary = request.getTaskDict() + for f in required_fields: + self.assertTrue(f in list(task_dictionary.keys()), + msg=f'Required captcha input key "{f}" does not include to request.') + + def test_binance_missing(self,): + required_fields = ['type', + 'websiteURL', + 'websiteKey', + 'validateId'] + base_kwargs = {} + self.assertRaises(ValidationError, BinanceTaskProxylessRequest, **base_kwargs) + base_kwargs.update({'websiteUrl': self.websiteUrlExample}) + self.assertRaises(ValidationError, BinanceTaskProxylessRequest, **base_kwargs) + base_kwargs.update({'websiteKey': self.websiteKeyExample}) + self.assertRaises(ValidationError, BinanceTaskProxylessRequest, **base_kwargs) + base_kwargs.update({'validateId': 'asdgf'}) + BinanceTaskProxylessRequest(**base_kwargs) + base_kwargs.update({'userAgent': self.userAgentExample}) + BinanceTaskProxylessRequest(**base_kwargs) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/test/binance_response_test.py b/test/binance_response_test.py new file mode 100644 index 0000000..bef3a50 --- /dev/null +++ b/test/binance_response_test.py @@ -0,0 +1,39 @@ +import unittest +import asyncio +import os + +from pydantic.error_wrappers import ValidationError +from capmonstercloudclient.requests import BinanceTaskProxylessRequest +from capmonstercloudclient import CapMonsterClient, ClientOptions + +def get_all_keys(dictionary): + all_values = [] + def recursive_items(dictionary): + for key, value in dictionary.items(): + if type(value) is dict: + all_values.append(key) + recursive_items(value) + else: + all_values.append(key) + return all_values + return recursive_items(dictionary) + +class AmazonWafOutsTest(unittest.TestCase): + + def testOuts(self): + required_outs = ['token', 'userAgent'] + api_key = os.getenv('API_KEY') + options = ClientOptions(api_key=api_key) + client = CapMonsterClient(options) + request = BinanceTaskProxylessRequest(websiteUrl='https://accounts.binance.com/ru/login?loginChannel=&return_to=', + websiteKey='login', + validateId="2b8137c0b9b44189800368819354e114" + ) + result = asyncio.run(client.solve_captcha(request)) + for i in required_outs: + self.assertTrue(i in get_all_keys(result)) + + +if __name__ == '__main__': + unittest.main() + \ No newline at end of file diff --git a/test/imperva_request_test.py b/test/imperva_request_test.py new file mode 100644 index 0000000..d4fe517 --- /dev/null +++ b/test/imperva_request_test.py @@ -0,0 +1,55 @@ +import unittest +from copy import deepcopy + +from pydantic import ValidationError +from capmonstercloudclient.requests import ImpervaCustomTaskProxylessRequest + + +class ImpervaRequestTest(unittest.TestCase): + + websiteUrlExample = 'site.com' + userAgentExample = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' + incapsulaScriptBase64Example = 'dmFyIF8weGQ2ZmU9Wydce..eDUzXHg2YVx4NGYnKV09XzB4Mjk3MTIxO319KCkpOw==' + incapsulaSessionCookieExample = 'l/LsGnrvyB9lNhXI8borDKa2IGcAAAAAX0qAEHheCWuNDquzwb44cw=' + reese84UrlEndpointExample = "Built-with-the-For-hopence-Hurleysurfecting-the-" + + def test_imperva(self, + ): + required_fields = ['type', + 'websiteURL', + 'metadata'] + metadata_required_fields = ['incapsulaScriptBase64', 'incapsulaSessionCookie'] + metadata_example = {"incapsulaScriptBase64": self.incapsulaScriptBase64Example,"incapsulaSessionCookie": self.incapsulaSessionCookieExample} + request = ImpervaCustomTaskProxylessRequest(websiteUrl=self.websiteUrlExample, metadata=metadata_example) + task_dictionary = request.getTaskDict() + for f in required_fields: + self.assertTrue(f in list(task_dictionary.keys()), + msg=f'Required captcha input key "{f}" does not include to request.') + for f in metadata_required_fields: + self.assertTrue(f in list(task_dictionary['metadata'].keys()), + msg=f'Required captcha input key "{f}" does not include to request.') + + def test_imperva_metadata(self,): + base_kwargs = {"websiteUrl": self.websiteUrlExample, "metadata": {}} + self.assertRaises(TypeError, ImpervaCustomTaskProxylessRequest, **base_kwargs) + base_kwargs['metadata']['incapsulaScriptBase64'] = self.incapsulaScriptBase64Example + self.assertRaises(TypeError, ImpervaCustomTaskProxylessRequest, **base_kwargs) + base_kwargs['metadata']['incapsulaSessionCookie'] = self.incapsulaSessionCookieExample + ImpervaCustomTaskProxylessRequest(**base_kwargs) + base_kwargs['metadata']['reese84UrlEndpoint'] = self.reese84UrlEndpointExample + ImpervaCustomTaskProxylessRequest(**base_kwargs) + + def test_imperva_missing(self,): + required_fields = ['type', + 'websiteURL', + 'metadata'] + base_kwargs = {} + metadata_example = {"incapsulaScriptBase64": self.incapsulaScriptBase64Example,"incapsulaSessionCookie": self.incapsulaSessionCookieExample} + self.assertRaises(ValidationError, ImpervaCustomTaskProxylessRequest, **base_kwargs) + base_kwargs.update({'websiteUrl': self.websiteUrlExample}) + self.assertRaises(ValidationError, ImpervaCustomTaskProxylessRequest, **base_kwargs) + base_kwargs.update({'metadata': metadata_example}) + ImpervaCustomTaskProxylessRequest(**base_kwargs) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 87f8a7f15611241c5b04a5f53f6fb73010a8ff7c Mon Sep 17 00:00:00 2001 From: "pavel.grinkevich" Date: Wed, 22 Jan 2025 13:02:36 +0000 Subject: [PATCH 2/4] version and doc update --- README.md | 5 ++--- capmonstercloud_client/version.txt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3ffe29e..cae536a 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,6 @@ Supported captcha recognition requests: - [GeeTestProxylessRequest](https://zenno.link/doc-geetest-en) - [GeeTestRequest](https://zenno.link/doc-geetest-proxy-en) -- [HCaptchaProxylessRequest](https://zenno.link/doc-hcaptcha-en) -- [HCaptchaRequest](https://zenno.link/doc-hcaptcha-proxy-en) - [ImageToTextRequest](https://zenno.link/doc-ImageToTextTask-en) - [RecaptchaV2ProxylessRequest](https://zenno.link/doc-recaptcha2-en) - [RecaptchaV2Request](https://zenno.link/doc-recaptcha2-proxy-en) @@ -42,8 +40,9 @@ Supported captcha recognition requests: - [TurnstileProxylessRequest](https://zenno.link/doc-turnstile-en) - [TurnstileRequest](https://zenno.link/doc-turnstile-proxy-en) - [RecaptchaComplexImageTaskRequest](https://zenno.link/doc-complextask-rc-en) -- [HcaptchaComplexImageTaskRequest](https://zenno.link/doc-complextask-hc-en) - [DataDomeCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/datadome) - [TenDiCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/tendi) - [BasiliskCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/Basilisk-task) - [AmazonWafRequest](https://docs.capmonster.cloud/docs/captchas/amazon-task) +- [BinanceTaskRequest](https://docs.capmonster.cloud/docs/captchas/binance) +- [ImpervaCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/incapsula) diff --git a/capmonstercloud_client/version.txt b/capmonstercloud_client/version.txt index a73b432..1d5e9e0 100644 --- a/capmonstercloud_client/version.txt +++ b/capmonstercloud_client/version.txt @@ -1 +1 @@ -1.5.2 \ No newline at end of file +1.5.3 \ No newline at end of file From 4cb61880237ef00f3a6e7aa57b70a5adf2fe7512 Mon Sep 17 00:00:00 2001 From: "pavel.grinkevich" Date: Fri, 24 Jan 2025 11:27:03 +0000 Subject: [PATCH 3/4] version fix --- capmonstercloud_client/version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capmonstercloud_client/version.txt b/capmonstercloud_client/version.txt index 1d5e9e0..ce6a70b 100644 --- a/capmonstercloud_client/version.txt +++ b/capmonstercloud_client/version.txt @@ -1 +1 @@ -1.5.3 \ No newline at end of file +1.6.0 \ No newline at end of file From 0c7cc4e703bda1b7302998b0f00369f6af73a43b Mon Sep 17 00:00:00 2001 From: "pavel.grinkevich" Date: Fri, 24 Jan 2025 14:50:08 +0000 Subject: [PATCH 4/4] imperva proxy request --- README.md | 2 + .../CapMonsterCloudClient.py | 4 +- .../requests/ImpervaCustomTaskRequest.py | 39 +++++++++++++++++++ capmonstercloud_client/requests/__init__.py | 5 ++- 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 capmonstercloud_client/requests/ImpervaCustomTaskRequest.py diff --git a/README.md b/README.md index cae536a..93d6440 100644 --- a/README.md +++ b/README.md @@ -45,4 +45,6 @@ Supported captcha recognition requests: - [BasiliskCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/Basilisk-task) - [AmazonWafRequest](https://docs.capmonster.cloud/docs/captchas/amazon-task) - [BinanceTaskRequest](https://docs.capmonster.cloud/docs/captchas/binance) +- [BinanceTaskProxylessRequest](https://docs.capmonster.cloud/docs/captchas/binance) - [ImpervaCustomTaskRequest](https://docs.capmonster.cloud/docs/captchas/incapsula) +- [ImpervaCustomTaskProxylessRequest](https://docs.capmonster.cloud/docs/captchas/incapsula) diff --git a/capmonstercloud_client/CapMonsterCloudClient.py b/capmonstercloud_client/CapMonsterCloudClient.py index aa6bd5d..9461cd2 100644 --- a/capmonstercloud_client/CapMonsterCloudClient.py +++ b/capmonstercloud_client/CapMonsterCloudClient.py @@ -29,7 +29,7 @@ ((BasiliskCustomTaskRequest, BasiliskCustomTaskProxylessRequest), getBasiliskTimeouts), ((AmazonWafRequest, AmazonWafProxylessRequest), getAmazonWafTimeouts), ((BinanceTaskRequest, BinanceTaskProxylessRequest), getBinanceTimeouts), - ((ImpervaCustomTaskProxylessRequest), getImpervaTimeouts) + ((ImpervaCustomTaskRequest, ImpervaCustomTaskProxylessRequest), getImpervaTimeouts) ) @@ -81,6 +81,7 @@ async def solve_captcha(self, request: Union[RecaptchaV2EnterpriseProxylessReque DataDomeCustomTaskRequest, BinanceTaskRequest, BinanceTaskProxylessRequest, + ImpervaCustomTaskRequest, ImpervaCustomTaskProxylessRequest], ) -> Dict[str, str]: ''' @@ -115,6 +116,7 @@ async def _solve(self, request: Union[RecaptchaV2EnterpriseProxylessRequest, FunCaptchaComplexImageTaskRequest, BinanceTaskRequest, BinanceTaskProxylessRequest, + ImpervaCustomTaskRequest, ImpervaCustomTaskProxylessRequest], timeouts: GetResultTimeouts, ) -> Dict[str, str]: diff --git a/capmonstercloud_client/requests/ImpervaCustomTaskRequest.py b/capmonstercloud_client/requests/ImpervaCustomTaskRequest.py new file mode 100644 index 0000000..1746ad3 --- /dev/null +++ b/capmonstercloud_client/requests/ImpervaCustomTaskRequest.py @@ -0,0 +1,39 @@ +from typing import Dict, Union +from pydantic import Field, validator + +from .proxy_info import ProxyInfo +from .ImpervaCustomTaskRequestBase import ImpervaCustomTaskRequestBase + +class ImpervaCustomTaskRequest(ImpervaCustomTaskRequestBase, ProxyInfo): + metadata : Dict[str, str] + + @validator('metadata') + def validate_metadata(cls, value): + if value.get('incapsulaScriptBase64') is None: + raise TypeError(f'Expect that incapsulaScriptBase64 will be defined.') + else: + if not isinstance(value.get('incapsulaScriptBase64'), str): + raise TypeError(f'Expect that incapsulaScriptBase64 will be str.') + if value.get('incapsulaSessionCookie') is None: + raise TypeError(f'Expect that incapsulaSessionCookie will be defined.') + else: + if not isinstance(value.get('incapsulaSessionCookie'), str): + raise TypeError(f'Expect that incapsulaSessionCookie will be str.') + if value.get('reese84UrlEndpoint') is not None and not isinstance(value.get('incapsulaSessionCookie'), str): + raise TypeError(f'Expect that reese84UrlEndpoint will be str.') + return value + + def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: + task = {} + task['type'] = self.type + task['class'] = self.captchaClass + task['websiteURL'] = self.websiteUrl + task['metadata'] = self.metadata + task['proxyType'] = self.proxyType + task['proxyAddress'] = self.proxyAddress + task['proxyPort'] = self.proxyPort + task['proxyLogin'] = self.proxyLogin + task['proxyPassword'] = self.proxyPassword + if self.userAgent is not None: + task['userAgent'] = self.userAgent + return task \ No newline at end of file diff --git a/capmonstercloud_client/requests/__init__.py b/capmonstercloud_client/requests/__init__.py index 9dda430..08462d0 100644 --- a/capmonstercloud_client/requests/__init__.py +++ b/capmonstercloud_client/requests/__init__.py @@ -26,8 +26,10 @@ from .AmazonWafProxylessRequest import AmazonWafProxylessRequest from .BinanceTaskRequest import BinanceTaskRequest from .BinanceTaskProxylessRequest import BinanceTaskProxylessRequest +from .ImpervaCustomTaskRequest import ImpervaCustomTaskRequest from .ImpervaCustomTaskProxylessRequest import ImpervaCustomTaskProxylessRequest + REQUESTS = ['RecaptchaV2EnterpiseRequest', 'RecaptchaV2EnterpriseProxylessRequest', 'RecaptchaV2ProxylessRequest', 'RecaptchaV2Request', 'RecaptchaV3ProxylessRequest', 'ImageToTextRequest', 'FuncaptchaProxylessRequest', 'FuncaptchaRequest', @@ -35,4 +37,5 @@ 'HcaptchaRequest', 'DataDomeCustomTaskRequest', 'DataDomeCustomTaskProxylessRequest', 'TenDiCustomTaskRequest', 'TenDiCustomTaskProxylessRequest', 'BasiliskCustomTaskRequest', 'BasiliskCustomTaskProxylessRequest', 'AmazonWafRequest', 'AmazonWafProxylessRequest', - 'BinanceTaskRequest', 'BinanceTaskProxylessRequest', 'ImpervaCustomTaskProxylessRequest'] + 'BinanceTaskRequest', 'BinanceTaskProxylessRequest', 'ImpervaCustomTaskProxylessRequest', + 'ImpervaCustomTaskRequest']