Skip to content
Merged
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
15 changes: 9 additions & 6 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4

- name: Set up Python 3.7
uses: actions/setup-python@v1
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.7"
python-version: "3.12"

- name: Install setup dependencies
run: pip install setuptools_scm wheel

- name: Build distribution
run: make install
- uses: nanasess/setup-chromedriver@v1

- uses: nanasess/setup-chromedriver@v2

- name: Run integration tests
run: make test
Expand Down
18 changes: 7 additions & 11 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ jobs:
fail-fast: false
matrix:
python-version:
- '2.7'
- '3.5'
- '3.6'
- '3.7'
- '3.8'
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -36,8 +35,5 @@ jobs:
- name: Build docs
run: make docs

- name: Build docs
run: make docs

- name: Test with pytest
run: make test
run: make test
9 changes: 3 additions & 6 deletions python_anticaptcha/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from importlib.metadata import version, PackageNotFoundError

from .base import AnticaptchaClient
try:
from importlib.metadata import version, PackageNotFoundError
except ImportError:
# Python < 3.8 fallback
from importlib_metadata import version, PackageNotFoundError
from .tasks import (
NoCaptchaTaskProxylessTask,
RecaptchaV2TaskProxyless,
Expand All @@ -20,7 +17,7 @@
GeeTestTaskProxyless,
GeeTestTask,
AntiGateTaskProxyless,
AntiGateTask
AntiGateTask,
)
from .exceptions import AnticaptchaException

Expand Down
11 changes: 4 additions & 7 deletions python_anticaptcha/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
import json
import warnings

from .compat import split
from six.moves.urllib_parse import urljoin
from urllib.parse import urljoin
from .exceptions import AnticaptchaException

SLEEP_EVERY_CHECK_FINISHED = 3
MAXIMUM_JOIN_TIME = 60 * 5


class Job(object):
class Job:
client = None
task_id = None
_last_result = None
Expand Down Expand Up @@ -74,7 +73,7 @@ def join(self, maximum_time=None):
)


class AnticaptchaClient(object):
class AnticaptchaClient:
client_key = None
CREATE_TASK_URL = "/createTask"
TASK_RESULT_URL = "/getTaskResult"
Expand Down Expand Up @@ -163,14 +162,12 @@ def createTaskSmee(self, task, timeout=MAXIMUM_JOIN_TIME):
content = line.decode("utf-8")
if '"host":"smee.io"' not in content:
continue
payload = json.loads(split(content, ":", 1)[1].strip())
payload = json.loads(content.split(":", maxsplit=1)[1].strip())
if "taskId" not in payload["body"] or str(payload["body"]["taskId"]) != str(
response["taskId"]
):
continue
r.close()
if task["type"] == "CustomCaptchaTask":
payload["body"]["solution"] = payload["body"]["data"][0]
job = Job(client=self, task_id=response["taskId"])
job._last_result = payload["body"]
return job
Expand Down
15 changes: 0 additions & 15 deletions python_anticaptcha/compat.py

This file was deleted.

6 changes: 3 additions & 3 deletions python_anticaptcha/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class AnticaptchaException(Exception):
def __init__(self, error_id, error_code, error_description, *args):
super(AnticaptchaException, self).__init__(
super().__init__(
"[{}:{}]{}".format(error_code, error_id, error_description)
)
self.error_description = error_description
Expand All @@ -17,7 +17,7 @@ def __init__(self, width):
msg = "Invalid width (%s). Can be one of these: 100, 50, 33, 25." % (
self.width,
)
super(InvalidWidthException, self).__init__("AC-1", 1, msg)
super().__init__("AC-1", 1, msg)


class MissingNameException(AnticaptchaException):
Expand All @@ -26,4 +26,4 @@ def __init__(self, cls):
msg = 'Missing name data in {0}. Provide {0}.__init__(name="X") or {0}.serialize(name="X")'.format(
str(self.cls)
)
super(MissingNameException, self).__init__("AC-2", 2, msg)
super().__init__("AC-2", 2, msg)
77 changes: 44 additions & 33 deletions python_anticaptcha/tasks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64


class BaseTask(object):
class BaseTask:
type = None

def serialize(self, **result):
Expand All @@ -12,21 +12,21 @@ def serialize(self, **result):
class UserAgentMixin(BaseTask):
def __init__(self, *args, **kwargs):
self.userAgent = kwargs.pop("user_agent")
super(UserAgentMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(UserAgentMixin, self).serialize(**result)
data = super().serialize(**result)
data["userAgent"] = self.userAgent
return data


class CookieMixin(BaseTask):
def __init__(self, *args, **kwargs):
self.cookies = kwargs.pop("cookies", "")
super(CookieMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(CookieMixin, self).serialize(**result)
data = super().serialize(**result)
if self.cookies:
data["cookies"] = self.cookies
return data
Expand All @@ -39,10 +39,10 @@ def __init__(self, *args, **kwargs):
self.proxyPort = kwargs.pop("proxy_port")
self.proxyLogin = kwargs.pop("proxy_login")
self.proxyPassword = kwargs.pop("proxy_password")
super(ProxyMixin, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(ProxyMixin, self).serialize(**result)
data = super().serialize(**result)
data["proxyType"] = self.proxyType
data["proxyAddress"] = self.proxyAddress
data["proxyPort"] = self.proxyPort
Expand Down Expand Up @@ -74,10 +74,10 @@ def __init__(
self.websiteSToken = website_s_token
self.recaptchaDataSValue = recaptcha_data_s_value
self.isInvisible = is_invisible
super(NoCaptchaTaskProxylessTask, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(NoCaptchaTaskProxylessTask, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["websiteKey"] = self.websiteKey
if self.websiteSToken is not None:
Expand Down Expand Up @@ -117,10 +117,10 @@ def __init__(
self.websiteKey = website_key
self.funcaptchaApiJSSubdomain = subdomain
self.data = data
super(FunCaptchaProxylessTask, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(FunCaptchaProxylessTask, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["websitePublicKey"] = self.websiteKey
if self.funcaptchaApiJSSubdomain:
Expand Down Expand Up @@ -157,7 +157,8 @@ def __init__(
max_length=None,
comment=None,
website_url=None,
*args, **kwargs
*args,
**kwargs
):
self.fp = fp
self.phrase = phrase
Expand All @@ -168,19 +169,27 @@ def __init__(
self.maxLength = max_length
self.comment = comment
self.websiteUrl = website_url
super(ImageToTextTask, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(ImageToTextTask, self).serialize(**result)
data = super().serialize(**result)
data["body"] = base64.b64encode(self.fp.read()).decode("utf-8")
data["phrase"] = self.phrase
data["case"] = self.case
data["numeric"] = self.numeric
data["math"] = self.math
data["minLength"] = self.minLength
data["maxLength"] = self.maxLength
data["comment"] = self.comment
data["websiteUrl"] = self.websiteUrl
if self.phrase is not None:
data["phrase"] = self.phrase
if self.case is not None:
data["case"] = self.case
if self.numeric is not None:
data["numeric"] = self.numeric
if self.math is not None:
data["math"] = self.math
if self.minLength is not None:
data["minLength"] = self.minLength
if self.maxLength is not None:
data["maxLength"] = self.maxLength
if self.comment is not None:
data["comment"] = self.comment
if self.websiteUrl is not None:
data["websiteUrl"] = self.websiteUrl
return data


Expand All @@ -200,10 +209,10 @@ def __init__(
self.minScore = min_score
self.pageAction = page_action
self.isEnterprise = is_enterprise
super(RecaptchaV3TaskProxyless, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(RecaptchaV3TaskProxyless, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["websiteKey"] = self.websiteKey
data["minScore"] = self.minScore
Expand All @@ -220,10 +229,10 @@ class HCaptchaTaskProxyless(BaseTask):
def __init__(self, website_url, website_key, *args, **kwargs):
self.websiteURL = website_url
self.websiteKey = website_key
super(HCaptchaTaskProxyless, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(HCaptchaTaskProxyless, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["websiteKey"] = self.websiteKey
return data
Expand All @@ -245,10 +254,10 @@ def __init__(self, website_url, website_key, enterprise_payload, api_domain, *ar
self.websiteKey = website_key
self.enterprisePayload = enterprise_payload
self.apiDomain = api_domain
super(RecaptchaV2EnterpriseTaskProxyless, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(RecaptchaV2EnterpriseTaskProxyless, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["websiteKey"] = self.websiteKey
if self.enterprisePayload:
Expand All @@ -258,7 +267,9 @@ def serialize(self, **result):
return data


class RecaptchaV2EnterpriseTask(ProxyMixin, UserAgentMixin, CookieMixin, BaseTask):
class RecaptchaV2EnterpriseTask(
ProxyMixin, UserAgentMixin, CookieMixin, RecaptchaV2EnterpriseTaskProxyless
):
type = "RecaptchaV2EnterpriseTask"


Expand All @@ -278,10 +289,10 @@ def __init__(
self.challenge = challenge
self.geetestApiServerSubdomain = subdomain
self.geetestGetLib = lib
super(GeeTestTaskProxyless, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(GeeTestTaskProxyless, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["gt"] = self.gt
data["challenge"] = self.challenge
Expand All @@ -306,10 +317,10 @@ def __init__(self, website_url, template_name, variables, *args, **kwargs):
self.websiteURL = website_url
self.templateName = template_name
self.variables = variables
super(AntiGateTaskProxyless).__init__(self, *args, **kwargs)
super().__init__(*args, **kwargs)

def serialize(self, **result):
data = super(AntiGateTaskProxyless, self).serialize(**result)
data = super().serialize(**result)
data["websiteURL"] = self.websiteURL
data["templateName"] = self.templateName
data["variables"] = self.variables
Expand Down
4 changes: 0 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,3 @@ tag_name = {new_version}

[nosetests]
process-timeout = 600

[bdist_wheel]
universal = 1

Loading
Loading