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
38 changes: 38 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
Changelog
=========

Unreleased
----------

Added
#####

- Add context manager support to ``AnticaptchaClient`` (``__enter__``, ``__exit__``, ``close``)
- Add ``ANTICAPTCHA_API_KEY`` environment variable fallback for ``AnticaptchaClient``
- Add ``Proxy`` frozen dataclass with ``parse_url()`` and ``to_kwargs()`` methods
- Add snake_case aliases: ``create_task``, ``create_task_smee``, ``get_balance``, ``get_app_stats``
- Add ``py.typed`` marker and complete type annotations (`#124 <https://github.com/ad-m/python-anticaptcha/pull/124>`_)
- Add ``__repr__`` to ``Job``, ``AnticaptchaClient``, and ``BaseTask`` (`#123 <https://github.com/ad-m/python-anticaptcha/pull/123>`_)
- Add optional ``on_check`` callback to ``Job.join()`` (`#125 <https://github.com/ad-m/python-anticaptcha/pull/125>`_)
- ``ImageToTextTask`` now accepts file paths (``str``/``Path``), raw bytes, or file-like objects

Changed
#######

- **Breaking:** Minimum Python version increased from 2.7+ to 3.9+
- Migrate from ``setup.py`` / ``setup.cfg`` to ``pyproject.toml`` (PEP 621) (`#122 <https://github.com/ad-m/python-anticaptcha/pull/122>`_)
- Switch README from RST to Markdown (`#126 <https://github.com/ad-m/python-anticaptcha/pull/126>`_)
- Switch test runner from nose2 to pytest
- Switch PyPI publishing to trusted publishing via GitHub Actions (`#114 <https://github.com/ad-m/python-anticaptcha/pull/114>`_)
- Fix ``RecaptchaV2EnterpriseTask`` missing proxyless base class inheritance
- Fix ``ImageToTextTask.serialize()`` sending ``None`` values
- Fix ``GeeTestTask`` incorrect inheritance
- Fix ``AntiGateTaskProxyless`` super() call
- Remove redundant cookies serialization in ``ProxyMixin``
- Use Python 3 ``super()`` without arguments throughout codebase

Removed
#######

- Drop Python 2.7 and Python 3.4-3.8 support
- Remove ``six`` dependency (replaced with stdlib ``urllib.parse``)
- Remove ``compat.py`` module
- Remove legacy ``setup.py`` and ``setup.cfg``

1.0.0 - 2022-03-28
------------------

Expand Down
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at naczelnik@jawnosc.tk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at naczelnik@jawne.info.pl. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
CHROMEDRIVER_VERSION=99.0.4844.17
CHROMEDRIVER_DIR=${PWD}/geckodriver
CHROMEDRIVER_DIR=${PWD}/chromedriver

.PHONY: lint fmt build docs install test test_e2e gecko
.PHONY: lint fmt build docs install test test_e2e chromedriver

build:
python setup.py sdist bdist_wheel
python -m build

install: install_test install_docs install_pkg

Expand All @@ -18,7 +18,7 @@ install_pkg:
python -m pip install --upgrade pip wheel
pip install .

gecko:
chromedriver:
mkdir -p ${CHROMEDRIVER_DIR}
wget -q -P ${CHROMEDRIVER_DIR} "http://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip"
unzip ${CHROMEDRIVER_DIR}/chromedriver* -d ${CHROMEDRIVER_DIR}
Expand All @@ -28,10 +28,10 @@ test:
pytest

test_e2e:
PATH=$$PWD/geckodriver:$$PATH pytest -m e2e --override-ini="addopts="
PATH=$$PWD/chromedriver:$$PATH pytest -m e2e --override-ini="addopts="

clean:
rm -r build geckodriver
rm -r build chromedriver

lint:
docker run --rm -v /$$(pwd):/apps alpine/flake8 ./
Expand Down
49 changes: 38 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
[![Build Status](https://github.com/ad-m/python-anticaptcha/workflows/Python%20package/badge.svg)](https://github.com/ad-m/python-anticaptcha/actions?workflow=Python+package)
[![PyPI](https://img.shields.io/pypi/v/python-anticaptcha.svg)](https://pypi.org/project/python-anticaptcha/)
[![Chat](https://badges.gitter.im/python-anticaptcha/Lobby.svg)](https://gitter.im/python-anticaptcha/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
[![Python compatibility](https://img.shields.io/pypi/pyversions/python-anticaptcha.svg)](https://github.com/ad-m/python-anticaptcha/blob/master/setup.py)
[![Python compatibility](https://img.shields.io/pypi/pyversions/python-anticaptcha.svg)](https://github.com/ad-m/python-anticaptcha/blob/master/pyproject.toml)

Client library for solve captchas with [Anticaptcha.com support](http://getcaptchasolution.com/i1hvnzdymd).
Client library for solving captchas with [Anticaptcha.com support](http://getcaptchasolution.com/i1hvnzdymd).
The library requires Python >= 3.9.

The library is cyclically and automatically tested for proper operation. We are constantly making the best efforts for its effective operation.
Expand All @@ -22,7 +22,7 @@ pip install python-anticaptcha

## Usage

To use this library do you need [Anticaptcha.com](http://getcaptchasolution.com/p9bwplkicx) API key.
To use this library you need [Anticaptcha.com](http://getcaptchasolution.com/p9bwplkicx) API key.

You can pass the key explicitly or set the `ANTICAPTCHA_API_KEY` environment variable:

Expand All @@ -34,6 +34,14 @@ client = AnticaptchaClient("my-api-key")
client = AnticaptchaClient()
```

The client can be used as a context manager to ensure the underlying session is closed:

```python
with AnticaptchaClient(api_key) as client:
job = client.create_task(task)
job.join()
```

### Solve recaptcha

Example snippet for Recaptcha:
Expand All @@ -52,12 +60,11 @@ job.join()
print(job.get_solution_response())
```

The full integration example is available in file `examples/recaptcha.py`.
The full integration example is available in file `examples/recaptcha_request.py`.

If you only process few page many times to increase reliability, you can specify
whether the captcha is visible or not. This parameter is not required, as is the
system detects invisible sitekeys automatically, and needs several recursive
measures for automated training and analysis. For provide that pass
If you process the same page many times, to increase reliability you can specify
whether the captcha is visible or not. This parameter is not required, as the
system detects invisible sitekeys automatically. To provide that, pass
`is_invisible` parameter to `NoCaptchaTaskProxylessTask` or `NoCaptchaTask` eg.:

```python
Expand All @@ -82,9 +89,17 @@ Example snippet for text captcha:
from python_anticaptcha import AnticaptchaClient, ImageToTextTask

api_key = '174faff8fbc769e94a5862391ecfd010'
captcha_fp = open('examples/captcha_ms.jpeg', 'rb')
client = AnticaptchaClient(api_key)
task = ImageToTextTask(captcha_fp)

# From a file path:
task = ImageToTextTask('examples/captcha_ms.jpeg')

# Or from raw bytes:
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb').read())

# Or from a file object:
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb'))

job = client.create_task(task)
job.join()
print(job.get_captcha_text())
Expand All @@ -111,6 +126,18 @@ job.join()
print(job.get_token_response())
```

### Monitor solve progress

You can pass an `on_check` callback to `job.join()` to monitor progress:

```python
def progress(elapsed, status):
print(f"Elapsed: {elapsed}s, status: {status}")

job = client.create_task(task)
job.join(on_check=progress)
```

### Report incorrect image

Example snippet for reporting an incorrect image task:
Expand Down Expand Up @@ -138,7 +165,7 @@ pip install mitmproxy
mitmweb -p 9190 -b 0.0.0.0 --ignore '.' --socks
```

Next to in your application use something like:
Then in your application use something like:

```python
proxy = Proxy.parse_url("socks5://123.123.123.123:9190")
Expand Down
12 changes: 5 additions & 7 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/stable/config
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Path setup --------------------------------------------------------------

Expand All @@ -21,13 +21,12 @@
# -- Project information -----------------------------------------------------

project = u"python-anticaptcha"
copyright = u"2018, Adam Dobrawy"
copyright = u"2018-2026, Adam Dobrawy"
author = u"Adam Dobrawy"

# The short X.Y version
# Version is managed by setuptools-scm; leave empty for Sphinx
version = u""
# The full version, including alpha/beta/rc tags
release = u"0.2.0"
release = u""


# -- General configuration ---------------------------------------------------
Expand Down Expand Up @@ -84,10 +83,9 @@
html_theme = "alabaster"

try:
import sphinx_rtd_theme
import sphinx_rtd_theme # noqa: F401

html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
except ImportError:
pass

Expand Down
9 changes: 4 additions & 5 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ The project is open-source.

Changes are managed through GitHub. Pull requests are particularly welcome.

All changes are automatically tested using TravisCI.
All changes are automatically tested using GitHub Actions.

New release
-----------

Follow these steps to publish the new release:

* update changelog - use any text editor
* bump version - use ```bumpversion {major,minor,patch}```
* build package - use ```python setup.py sdist bdist_wheel --universal```
* upload release to PyPI - use ```twine upload dist/*```
* push changes to GitHub - ```git push origin && git push --tags```
* tag version - use ``git tag vX.Y.Z`` (versions are managed by ``setuptools-scm``)
* push changes to GitHub - ``git push origin && git push --tags``
* PyPI upload is handled automatically via GitHub Actions using `trusted publishing <https://docs.pypi.org/trusted-publishers/>`_
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Welcome to python-anticaptcha's documentation!
==============================================

Client library for solve captchas with `Anticaptcha.com support`_.
Client library for solving captchas with `Anticaptcha.com support`_.
The library requires Python >= 3.9.

The library is cyclically and automatically tested for proper operation. We are constantly making the best efforts for its effective operation.
Expand Down
46 changes: 37 additions & 9 deletions docs/usage.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Usage
=====

To use this library do you need `Anticaptcha.com`_ API key.
To use this library you need `Anticaptcha.com`_ API key.

You can pass the key explicitly or set the ``ANTICAPTCHA_API_KEY`` environment variable:

Expand All @@ -13,6 +13,14 @@ You can pass the key explicitly or set the ``ANTICAPTCHA_API_KEY`` environment v
# Or set ANTICAPTCHA_API_KEY environment variable
client = AnticaptchaClient()

The client can be used as a context manager to ensure the underlying session is closed:

.. code:: python

with AnticaptchaClient(api_key) as client:
job = client.create_task(task)
job.join()

Solve recaptcha
###############

Expand All @@ -32,12 +40,11 @@ Example snippet for Recaptcha:
job.join()
print(job.get_solution_response())

The full integration example is available in file ``examples/recaptcha.py``.
The full integration example is available in file ``examples/recaptcha_request.py``.

If you only process few page many times to increase reliability, you can specify
whether the captcha is visible or not. This parameter is not required, as is the
system detects invisible sitekeys automatically, and needs several recursive
measures for automated training and analysis. For provide that pass
If you process the same page many times, to increase reliability you can specify
whether the captcha is visible or not. This parameter is not required, as the
system detects invisible sitekeys automatically. To provide that, pass
``is_invisible`` parameter to ``NoCaptchaTaskProxylessTask`` or ``NoCaptchaTask`` eg.:

.. code:: python
Expand Down Expand Up @@ -65,9 +72,17 @@ Example snippet for text captcha:
from python_anticaptcha import AnticaptchaClient, ImageToTextTask

api_key = '174faff8fbc769e94a5862391ecfd010'
captcha_fp = open('examples/captcha_ms.jpeg', 'rb')
client = AnticaptchaClient(api_key)
task = ImageToTextTask(captcha_fp)

# From a file path:
task = ImageToTextTask('examples/captcha_ms.jpeg')

# Or from raw bytes:
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb').read())

# Or from a file object:
# task = ImageToTextTask(open('examples/captcha_ms.jpeg', 'rb'))

job = client.create_task(task)
job.join()
print(job.get_captcha_text())
Expand All @@ -94,6 +109,19 @@ Example snippet for funcaptcha:
job.join()
print(job.get_token_response())

Monitor solve progress
######################

You can pass an ``on_check`` callback to ``job.join()`` to monitor progress:

.. code:: python

def progress(elapsed, status):
print(f"Elapsed: {elapsed}s, status: {status}")

job = client.create_task(task)
job.join(on_check=progress)

Report incorrect image
######################

Expand Down Expand Up @@ -123,7 +151,7 @@ the possibility of simply launching such a server by:
pip install mitmproxy
mitmweb -p 9190 -b 0.0.0.0 --ignore '.' --socks

Next to in your application use something like:
Then in your application use something like:

.. code:: python

Expand Down
Loading