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

0.3 #12

Merged
merged 3 commits into from
Nov 20, 2022
Merged

0.3 #12

Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
for x in os.walk("src/python3_captchaai/"):
sys.path.insert(0, x[0])

from python3_captchaai import (core, fun_captcha, gee_test, hcaptcha,
image_to_text, recaptcha)
from python3_captchaai import (core, datadome_slider, fun_captcha, gee_test,
hcaptcha, image_to_text, recaptcha)
from python3_captchaai.__version__ import __version__

# -- Project information -----------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The library is intended for software developers and is used to work with the `Ca
modules/h-captcha/example.rst
modules/gee-test/example.rst
modules/fun-captcha/example.rst
modules/datadome/example.rst

.. toctree::
:maxdepth: 2
Expand Down
12 changes: 12 additions & 0 deletions docs/modules/datadome/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Datadome Slider
===============

To import this module:

.. code-block:: python

from python3_captchaai.datadome_slider import DatadomeSlider


.. autoclass:: datadome_slider.DatadomeSlider
:members:
2 changes: 1 addition & 1 deletion docs/modules/fun-captcha/example.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Fun Captcha
========
===========

To import this module:

Expand Down
2 changes: 1 addition & 1 deletion src/python3_captchaai/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.1"
__version__ = "0.3"
5 changes: 5 additions & 0 deletions src/python3_captchaai/core/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,8 @@ class FunCaptchaProxyLessOptionsSer(BaseModel):

class FunCaptchaOptionsSer(FunCaptchaProxyLessOptionsSer, ProxyDataOptionsSer):
pass


class DatadomeSliderOptionsSer(ProxyDataOptionsSer):
websiteURL: str = Field(..., description="Address of a webpage with DatadomeSlider")
captchaUrl: str = Field(..., description="Captcha Url where is the captcha")
161 changes: 161 additions & 0 deletions src/python3_captchaai/datadome_slider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
from typing import Union, Optional

from python3_captchaai.core.base import BaseCaptcha
from python3_captchaai.core.enum import ProxyType, CaptchaTypeEnm
from python3_captchaai.core.config import REQUEST_URL
from python3_captchaai.core.serializer import CaptchaResponseSer, RequestCreateTaskSer, DatadomeSliderOptionsSer


class BaseDatadomeSlider(BaseCaptcha):
"""
The class is used to work with CaptchaAI DatadomeSlider method.

Args:
api_key: CaptchaAI API key
websiteURL: Address of the webpage
captchaUrl: Captcha Url where is the captcha
proxyType: Type of the proxy
proxyAddress: Proxy IP address IPv4/IPv6. Not allowed to use:
host names instead of IPs,
transparent proxies (where client IP is visible),
proxies from local networks (192.., 10.., 127...)
proxyPort: Proxy port.
sleep_time: The waiting time between requests to get the result of the Captcha
request_url: API address for sending requests

Examples:
>>> DatadomeSlider(api_key="CAI-1324...",
... websiteURL="https://www.some-url.com/",
... captchaUrl="https://www.some-url.com/to-page-with-captcha",
... proxyType="http",
... proxyAddress="0.0.0.0",
... proxyPort=9090,
... ).captcha_handler()
CaptchaResponseSer(errorId=False,
errorCode=None,
errorDescription=None,
taskId='73bdcd28-6c77-4414-8....',
status=<ResponseStatusEnm.Ready: 'ready'>,
solution={'gRecaptchaResponse': '44795sds...'}
)

>>> await DatadomeSlider(api_key="CAI-1324...",
... websiteURL="https://www.some-url.com/",
... captchaUrl="https://www.some-url.com/to-page-with-captcha",
... proxyType="http",
... proxyAddress="0.0.0.0",
... proxyPort=9090,
... ).aio_captcha_handler()
CaptchaResponseSer(errorId=False,
errorCode=None,
errorDescription=None,
taskId='73bdcd28-6c77-4414-8....',
status=<ResponseStatusEnm.Ready: 'ready'>,
solution={'gRecaptchaResponse': '44795sds...'}
)

Returns:
CaptchaResponseSer model with full server response

Notes:
https://captchaai.atlassian.net/wiki/spaces/CAPTCHAAI/pages/426393/
"""

def __init__(
self,
api_key: str,
websiteURL: str,
captchaUrl: str,
proxyType: Union[ProxyType, str],
proxyAddress: str,
proxyPort: int,
sleep_time: Optional[int] = 5,
request_url: Optional[str] = REQUEST_URL,
):

super().__init__(
api_key=api_key,
captcha_type=CaptchaTypeEnm.DatadomeSliderTask,
sleep_time=sleep_time,
request_url=request_url,
)

self.task_params = DatadomeSliderOptionsSer(**locals()).dict()


class DatadomeSlider(BaseDatadomeSlider):
__doc__ = BaseDatadomeSlider.__doc__

def captcha_handler(
self,
**additional_params,
) -> CaptchaResponseSer:
"""
Synchronous method for captcha solving

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 ``proxyPassword``, ``userAgent`` and etc. - more info in service docs

Examples:
>>> DatadomeSlider(api_key="CAI-1324...",
... websiteURL="https://www.some-url.com/",
... captchaUrl="https://www.some-url.com/to-page-with-captcha",
... proxyType="http",
... proxyAddress="0.0.0.0",
... proxyPort=9090,
... ).captcha_handler()
CaptchaResponseSer(errorId=False,
errorCode=None,
errorDescription=None,
taskId='73bdcd28-6c77-4414-8....',
status=<ResponseStatusEnm.Ready: 'ready'>,
solution={'gRecaptchaResponse': '44795sds...'}
)

Returns:
CaptchaResponseSer model with full service response

Notes:
Check class docstirng for more info
"""
return self._processing_captcha(serializer=RequestCreateTaskSer, type=self.captcha_type, **additional_params)

async def aio_captcha_handler(
self,
**additional_params,
) -> CaptchaResponseSer:
"""
Asynchronous method for captcha solving

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 ``coordinate``, ``enterprisePayload`` and etc. - more info in service docs

Examples:
>>> await DatadomeSlider(api_key="CAI-1324...",
... websiteURL="https://www.some-url.com/",
... captchaUrl="https://www.some-url.com/to-page-with-captcha",
... proxyType="http",
... proxyAddress="0.0.0.0",
... proxyPort=9090,
... ).aio_captcha_handler()
CaptchaResponseSer(errorId=False,
errorCode=None,
errorDescription=None,
taskId='73bdcd28-6c77-4414-8....',
status=<ResponseStatusEnm.Ready: 'ready'>,
solution={'gRecaptchaResponse': '44795sds...'}
)

Returns:
CaptchaResponseSer model with full service response

Notes:
Check class docstirng for more info
"""
return await self._aio_processing_captcha(
serializer=RequestCreateTaskSer, type=self.captcha_type, **additional_params
)
84 changes: 84 additions & 0 deletions src/tests/test_datadome_slider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import pytest

from src.tests.conftest import BaseTest
from python3_captchaai.core.enum import ProxyType, ResponseStatusEnm
from python3_captchaai.core.serializer import CaptchaResponseSer
from python3_captchaai.datadome_slider import DatadomeSlider

websiteURL = "https://www.some-url.com/"
captchaUrl = "https://www.some-url.com/to-page-with-captcha"


class TestDatadomeSliderBase(BaseTest):
def test_captcha_handler_exist(self):
assert "captcha_handler" in DatadomeSlider.__dict__.keys()

def test_aio_captcha_handler_exist(self):
assert "aio_captcha_handler" in DatadomeSlider.__dict__.keys()


class TestDatadomeSlider(BaseTest):
proxyAddress = "0.0.0.0"
proxyPort = 9999
"""
Success tests
"""

@pytest.mark.parametrize("proxy_type", ProxyType.list_values())
def test_params(self, proxy_type: str):
DatadomeSlider(
api_key=self.API_KEY,
websiteURL=websiteURL,
captchaUrl=captchaUrl,
proxyAddress=self.proxyAddress,
proxyType=proxy_type,
proxyPort=self.proxyPort,
)

@pytest.mark.parametrize("proxy_type", ProxyType.list_values())
def test_params_context(self, proxy_type: str):
with DatadomeSlider(
api_key=self.API_KEY,
websiteURL=websiteURL,
captchaUrl=captchaUrl,
proxyAddress=self.proxyAddress,
proxyType=proxy_type,
proxyPort=self.proxyPort,
) as instance:
pass

"""
Failed tests
"""

@pytest.mark.parametrize("proxy_type", ProxyType.list_values())
async def test_aio_proxy_err(self, proxy_type: str):
resp = await DatadomeSlider(
api_key=self.get_random_string(36),
websiteURL=websiteURL,
captchaUrl=captchaUrl,
proxyAddress=self.proxyAddress,
proxyType=proxy_type,
proxyPort=self.proxyPort,
).aio_captcha_handler()
assert isinstance(resp, CaptchaResponseSer)
assert resp.status == ResponseStatusEnm.Processing
assert resp.errorId is True
assert resp.errorCode == "ERROR_INVALID_TASK_DATA"
assert resp.solution is None

@pytest.mark.parametrize("proxy_type", ProxyType.list_values())
def test_proxy_err(self, proxy_type: str):
resp = DatadomeSlider(
api_key=self.get_random_string(36),
websiteURL=websiteURL,
captchaUrl=captchaUrl,
proxyAddress=self.proxyAddress,
proxyType=proxy_type,
proxyPort=self.proxyPort,
).captcha_handler()
assert isinstance(resp, CaptchaResponseSer)
assert resp.status == ResponseStatusEnm.Processing
assert resp.errorId is True
assert resp.errorCode == "ERROR_INVALID_TASK_DATA"
assert resp.solution is None