capskip 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. capskip-1.0.0/CHANGELOG.md +31 -0
  2. capskip-1.0.0/LICENSE +21 -0
  3. capskip-1.0.0/MANIFEST.in +10 -0
  4. capskip-1.0.0/PKG-INFO +301 -0
  5. capskip-1.0.0/README.md +268 -0
  6. capskip-1.0.0/SECURITY.md +35 -0
  7. capskip-1.0.0/capskip/__init__.py +29 -0
  8. capskip-1.0.0/capskip/_api_params.py +118 -0
  9. capskip-1.0.0/capskip/api.py +56 -0
  10. capskip-1.0.0/capskip/async_api.py +63 -0
  11. capskip-1.0.0/capskip/async_solver.py +123 -0
  12. capskip-1.0.0/capskip/exceptions.py +21 -0
  13. capskip-1.0.0/capskip/solver.py +163 -0
  14. capskip-1.0.0/capskip.egg-info/PKG-INFO +301 -0
  15. capskip-1.0.0/capskip.egg-info/SOURCES.txt +39 -0
  16. capskip-1.0.0/capskip.egg-info/dependency_links.txt +1 -0
  17. capskip-1.0.0/capskip.egg-info/requires.txt +8 -0
  18. capskip-1.0.0/capskip.egg-info/top_level.txt +1 -0
  19. capskip-1.0.0/docs/API_REFERENCE.md +306 -0
  20. capskip-1.0.0/docs/GETTING_STARTED.md +181 -0
  21. capskip-1.0.0/docs/TROUBLESHOOTING.md +203 -0
  22. capskip-1.0.0/docs/TUTORIAL.md +487 -0
  23. capskip-1.0.0/examples/async_example.py +32 -0
  24. capskip-1.0.0/examples/captcha.png +0 -0
  25. capskip-1.0.0/examples/image_captcha.py +18 -0
  26. capskip-1.0.0/examples/recaptcha.py +18 -0
  27. capskip-1.0.0/examples/turnstile.py +19 -0
  28. capskip-1.0.0/examples/verify_connection.py +41 -0
  29. capskip-1.0.0/pyproject.toml +63 -0
  30. capskip-1.0.0/setup.cfg +4 -0
  31. capskip-1.0.0/setup.py +9 -0
  32. capskip-1.0.0/tests/abstract.py +63 -0
  33. capskip-1.0.0/tests/abstract_async.py +47 -0
  34. capskip-1.0.0/tests/conftest.py +113 -0
  35. capskip-1.0.0/tests/test_async_normal.py +35 -0
  36. capskip-1.0.0/tests/test_async_recaptcha.py +76 -0
  37. capskip-1.0.0/tests/test_async_turnstile.py +62 -0
  38. capskip-1.0.0/tests/test_integration.py +185 -0
  39. capskip-1.0.0/tests/test_normal.py +55 -0
  40. capskip-1.0.0/tests/test_recaptcha.py +95 -0
  41. capskip-1.0.0/tests/test_turnstile.py +72 -0
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-07-14
9
+
10
+ ### Added
11
+
12
+ - Initial release of the CapSkip Python SDK
13
+ - `CapSkip` synchronous client for the local CapSkip API
14
+ - `AsyncCapSkip` asynchronous client (`httpx` + `aiofiles`)
15
+ - Image CAPTCHA solving via `normal()` (file, URL, base64, or data-URI)
16
+ - reCAPTCHA v2 / v3 solving via `recaptcha()` (invisible, enterprise, proxy)
17
+ - Cloudflare Turnstile solving via `turnstile()` (widget and challenge page)
18
+ - Turnstile automatically polls with `json=1` and returns `userAgent` when provided
19
+ - Manual workflow: `send()`, `get_result()`, `solve()`
20
+ - Adaptive result polling — starts at 0.25s and backs off (doubling) up to the
21
+ configured `pollingInterval`, so fast solves (e.g. image captchas) return in a
22
+ fraction of a second; `pollingInterval` also accepts sub-second (float) values
23
+ - Familiar parameter aliases (`url`→`pageurl`, `score`→`min_score`, etc.)
24
+ - Proxy support via dict format `{'type': '...', 'uri': '...'}`
25
+ - Strict per-captcha parameter validation — only documented parameters are accepted
26
+ - Exception hierarchy: `ValidationException`, `NetworkException`, `ApiException`, `TimeoutException`
27
+ - Example scripts for every supported captcha type
28
+ - Unit tests (sync + async) with a mocked API client
29
+ - Documentation: Tutorial, Getting Started, API Reference, Troubleshooting
30
+
31
+ [1.0.0]: https://github.com/capskip/capskip-python/releases/tag/v1.0.0
capskip-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CapSkip
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ include LICENSE
2
+ include README.md
3
+ include CHANGELOG.md
4
+ include SECURITY.md
5
+ recursive-include docs *.md
6
+ recursive-include examples *.py
7
+ recursive-include examples *.png
8
+ recursive-include tests *.py
9
+ global-exclude __pycache__
10
+ global-exclude *.py[cod]
capskip-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,301 @@
1
+ Metadata-Version: 2.4
2
+ Name: capskip
3
+ Version: 1.0.0
4
+ Summary: Python SDK for the CapSkip local captcha solver
5
+ Author-email: CapSkip <support@capskip.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://capskip.com
8
+ Project-URL: Documentation, https://github.com/capskip/capskip-python/blob/main/docs/GETTING_STARTED.md
9
+ Project-URL: Repository, https://github.com/capskip/capskip-python
10
+ Project-URL: Bug Tracker, https://github.com/capskip/capskip-python/issues
11
+ Project-URL: Changelog, https://github.com/capskip/capskip-python/blob/main/CHANGELOG.md
12
+ Keywords: captcha,captcha-solver,recaptcha,cloudflare,turnstile,capskip,automation
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Internet :: WWW/HTTP
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: requests>=2.28
26
+ Requires-Dist: httpx>=0.24
27
+ Requires-Dist: aiofiles>=23.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
31
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # CapSkip Python SDK
35
+
36
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
38
+ [![Tests](https://github.com/capskip/capskip-python/actions/workflows/ci.yml/badge.svg)](https://github.com/capskip/capskip-python/actions/workflows/ci.yml)
39
+
40
+ Official Python client for the [CapSkip](https://capskip.com) **local** captcha solver.
41
+
42
+ CapSkip runs on your machine and exposes a standard captcha-solver HTTP API (the familiar `in.php` / `res.php` endpoints). This SDK wraps that API with clean, familiar method names, so you can solve captchas locally — no cloud service and no per-solve API fees beyond your CapSkip license.
43
+
44
+ ---
45
+
46
+ ## Quick start (5 minutes)
47
+
48
+ ### 1. Install CapSkip
49
+
50
+ Download and run the CapSkip desktop app from [capskip.com](https://capskip.com). Leave it running in the background.
51
+
52
+ In CapSkip settings, note:
53
+
54
+ - **API port** (default: `8080`)
55
+ - **API key** (optional — if validation is disabled, any string works)
56
+
57
+ ### 2. Install the SDK
58
+
59
+ ```bash
60
+ pip install capskip
61
+ ```
62
+
63
+ Or from source:
64
+
65
+ ```bash
66
+ git clone https://github.com/capskip/capskip-python.git
67
+ cd capskip-python
68
+ pip install -e .
69
+ ```
70
+
71
+ ### 3. Solve your first captcha
72
+
73
+ ```python
74
+ from capskip import CapSkip
75
+
76
+ solver = CapSkip(host="127.0.0.1", port=8080)
77
+
78
+ result = solver.recaptcha(
79
+ sitekey="YOUR_SITEKEY",
80
+ url="https://example.com/page-with-recaptcha",
81
+ )
82
+
83
+ print(result["code"]) # g-recaptcha-response token
84
+ ```
85
+
86
+ > **Prerequisite:** CapSkip must be running before you call the SDK. If you see a connection error, see [Troubleshooting](docs/TROUBLESHOOTING.md).
87
+
88
+ ---
89
+
90
+ ## Supported captcha types
91
+
92
+ | Type | SDK method |
93
+ |---|---|
94
+ | Image CAPTCHA (distorted text) | `solver.normal(file)` |
95
+ | reCAPTCHA v2 (checkbox) | `solver.recaptcha(sitekey, url)` |
96
+ | reCAPTCHA v2 Invisible | `solver.recaptcha(..., invisible=1)` |
97
+ | reCAPTCHA v2 Enterprise | `solver.recaptcha(..., enterprise=1)` |
98
+ | reCAPTCHA v3 | `solver.recaptcha(..., version="v3")` |
99
+ | reCAPTCHA v3 Enterprise | `solver.recaptcha(..., version="v3", enterprise=1)` |
100
+ | Cloudflare Turnstile (widget) | `solver.turnstile(sitekey, url)` |
101
+ | Cloudflare Turnstile (challenge page) | `solver.turnstile(..., data=..., pagedata=...)` |
102
+
103
+ ---
104
+
105
+ ## Documentation
106
+
107
+ | Guide | Description |
108
+ |---|---|
109
+ | [Tutorial](docs/TUTORIAL.md) | Complete walkthrough of every captcha type, sync and async |
110
+ | [Getting Started](docs/GETTING_STARTED.md) | Full setup: CapSkip app, SDK install, first script |
111
+ | [API Reference](docs/API_REFERENCE.md) | All classes, methods, parameters, and return values |
112
+ | [Examples](examples/) | Ready-to-run scripts for every captcha type |
113
+ | [Troubleshooting](docs/TROUBLESHOOTING.md) | Connection errors, timeouts, proxy issues |
114
+ | [Contributing](CONTRIBUTING.md) | Development setup, tests, pull requests |
115
+ | [Changelog](CHANGELOG.md) | Release history |
116
+
117
+ ---
118
+
119
+ ## Configuration
120
+
121
+ ```python
122
+ from capskip import CapSkip
123
+
124
+ solver = CapSkip(
125
+ apiKey="capskip", # your CapSkip API key (or any string if validation is off)
126
+ host="127.0.0.1", # CapSkip host
127
+ port=8080, # CapSkip port from app settings
128
+ defaultTimeout=120, # seconds — image captcha polling timeout
129
+ recaptchaTimeout=300, # seconds — reCAPTCHA / Turnstile polling timeout
130
+ pollingInterval=5, # max seconds between res.php polls (starts at 0.25s, backs off to this)
131
+ )
132
+ ```
133
+
134
+ Use environment variables in production:
135
+
136
+ ```bash
137
+ # Linux / macOS
138
+ export CAPSKIP_API_KEY="your-key"
139
+ export CAPSKIP_HOST="127.0.0.1"
140
+ export CAPSKIP_PORT="8080"
141
+ ```
142
+
143
+ ```powershell
144
+ # Windows PowerShell
145
+ $env:CAPSKIP_API_KEY = "your-key"
146
+ $env:CAPSKIP_HOST = "127.0.0.1"
147
+ $env:CAPSKIP_PORT = "8080"
148
+ ```
149
+
150
+ ```python
151
+ import os
152
+ from capskip import CapSkip
153
+
154
+ solver = CapSkip(
155
+ apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
156
+ host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
157
+ port=int(os.getenv("CAPSKIP_PORT", "8080")),
158
+ )
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Usage examples
164
+
165
+ ### Image captcha
166
+
167
+ ```python
168
+ result = solver.normal("captcha.png")
169
+ result = solver.normal("https://example.com/captcha.jpg")
170
+ result = solver.normal("data:image/png;base64,iVBORw0KGgo...")
171
+ print(result["code"])
172
+ ```
173
+
174
+ ### reCAPTCHA v2 / v3
175
+
176
+ ```python
177
+ # reCAPTCHA v2
178
+ result = solver.recaptcha(sitekey="...", url="https://example.com")
179
+
180
+ # reCAPTCHA v3
181
+ result = solver.recaptcha(
182
+ sitekey="...",
183
+ url="https://example.com",
184
+ version="v3",
185
+ action="submit",
186
+ score=0.7,
187
+ )
188
+ ```
189
+
190
+ ### Cloudflare Turnstile
191
+
192
+ ```python
193
+ result = solver.turnstile(
194
+ sitekey="0x4AAAAAAA...",
195
+ url="https://example.com",
196
+ )
197
+ ```
198
+
199
+ ### With a proxy (reCAPTCHA & Turnstile only)
200
+
201
+ ```python
202
+ # Proxy is not supported for image captcha
203
+ result = solver.recaptcha(
204
+ sitekey="...",
205
+ url="https://example.com",
206
+ proxy={"type": "HTTPS", "uri": "user:pass@1.2.3.4:3128"},
207
+ )
208
+ result = solver.turnstile(
209
+ sitekey="...",
210
+ url="https://example.com",
211
+ proxy={"type": "HTTP", "uri": "1.2.3.4:3128"},
212
+ )
213
+ ```
214
+
215
+ ### Async (parallel solving)
216
+
217
+ ```python
218
+ import asyncio
219
+ from capskip import AsyncCapSkip
220
+
221
+ async def main():
222
+ solver = AsyncCapSkip()
223
+ r1, r2 = await asyncio.gather(
224
+ solver.recaptcha(sitekey="...", url="https://a.com"),
225
+ solver.turnstile(sitekey="...", url="https://b.com"),
226
+ )
227
+ print(r1["code"], r2["code"])
228
+
229
+ asyncio.run(main())
230
+ ```
231
+
232
+ More examples: [`examples/`](examples/)
233
+
234
+ ---
235
+
236
+ ## Return value
237
+
238
+ Every solve method returns:
239
+
240
+ ```python
241
+ {
242
+ "captchaId": "12345", # internal ID from CapSkip
243
+ "code": "TOKEN_OR_TEXT" # solution — text for image, token for reCAPTCHA/Turnstile
244
+ "userAgent": "..." # Turnstile only — use when submitting challenge-page tokens
245
+ }
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Error handling
251
+
252
+ ```python
253
+ from capskip import CapSkip, ValidationException, NetworkException, ApiException, TimeoutException
254
+
255
+ try:
256
+ result = solver.recaptcha(sitekey="...", url="...")
257
+ except ValidationException:
258
+ pass # invalid parameters
259
+ except NetworkException:
260
+ pass # CapSkip not running, or captcha not ready (manual polling)
261
+ except ApiException:
262
+ pass # API returned an error code
263
+ except TimeoutException:
264
+ pass # polling timeout exceeded
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Development
270
+
271
+ ```bash
272
+ git clone https://github.com/capskip/capskip-python.git
273
+ cd capskip-python
274
+ python -m venv .venv
275
+
276
+ # Windows
277
+ .venv\Scripts\activate
278
+
279
+ # Linux / macOS
280
+ source .venv/bin/activate
281
+
282
+ pip install -e ".[dev]"
283
+ pytest
284
+ ```
285
+
286
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow.
287
+
288
+ ---
289
+
290
+ ## Links
291
+
292
+ - [CapSkip website](https://capskip.com)
293
+ - [CapSkip API docs](https://capskip.com/api-docs/)
294
+ - [Report an issue](https://github.com/capskip/capskip-python/issues)
295
+ - [PyPI package](https://pypi.org/project/capskip/) *(when published)*
296
+
297
+ ---
298
+
299
+ ## License
300
+
301
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,268 @@
1
+ # CapSkip Python SDK
2
+
3
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
5
+ [![Tests](https://github.com/capskip/capskip-python/actions/workflows/ci.yml/badge.svg)](https://github.com/capskip/capskip-python/actions/workflows/ci.yml)
6
+
7
+ Official Python client for the [CapSkip](https://capskip.com) **local** captcha solver.
8
+
9
+ CapSkip runs on your machine and exposes a standard captcha-solver HTTP API (the familiar `in.php` / `res.php` endpoints). This SDK wraps that API with clean, familiar method names, so you can solve captchas locally — no cloud service and no per-solve API fees beyond your CapSkip license.
10
+
11
+ ---
12
+
13
+ ## Quick start (5 minutes)
14
+
15
+ ### 1. Install CapSkip
16
+
17
+ Download and run the CapSkip desktop app from [capskip.com](https://capskip.com). Leave it running in the background.
18
+
19
+ In CapSkip settings, note:
20
+
21
+ - **API port** (default: `8080`)
22
+ - **API key** (optional — if validation is disabled, any string works)
23
+
24
+ ### 2. Install the SDK
25
+
26
+ ```bash
27
+ pip install capskip
28
+ ```
29
+
30
+ Or from source:
31
+
32
+ ```bash
33
+ git clone https://github.com/capskip/capskip-python.git
34
+ cd capskip-python
35
+ pip install -e .
36
+ ```
37
+
38
+ ### 3. Solve your first captcha
39
+
40
+ ```python
41
+ from capskip import CapSkip
42
+
43
+ solver = CapSkip(host="127.0.0.1", port=8080)
44
+
45
+ result = solver.recaptcha(
46
+ sitekey="YOUR_SITEKEY",
47
+ url="https://example.com/page-with-recaptcha",
48
+ )
49
+
50
+ print(result["code"]) # g-recaptcha-response token
51
+ ```
52
+
53
+ > **Prerequisite:** CapSkip must be running before you call the SDK. If you see a connection error, see [Troubleshooting](docs/TROUBLESHOOTING.md).
54
+
55
+ ---
56
+
57
+ ## Supported captcha types
58
+
59
+ | Type | SDK method |
60
+ |---|---|
61
+ | Image CAPTCHA (distorted text) | `solver.normal(file)` |
62
+ | reCAPTCHA v2 (checkbox) | `solver.recaptcha(sitekey, url)` |
63
+ | reCAPTCHA v2 Invisible | `solver.recaptcha(..., invisible=1)` |
64
+ | reCAPTCHA v2 Enterprise | `solver.recaptcha(..., enterprise=1)` |
65
+ | reCAPTCHA v3 | `solver.recaptcha(..., version="v3")` |
66
+ | reCAPTCHA v3 Enterprise | `solver.recaptcha(..., version="v3", enterprise=1)` |
67
+ | Cloudflare Turnstile (widget) | `solver.turnstile(sitekey, url)` |
68
+ | Cloudflare Turnstile (challenge page) | `solver.turnstile(..., data=..., pagedata=...)` |
69
+
70
+ ---
71
+
72
+ ## Documentation
73
+
74
+ | Guide | Description |
75
+ |---|---|
76
+ | [Tutorial](docs/TUTORIAL.md) | Complete walkthrough of every captcha type, sync and async |
77
+ | [Getting Started](docs/GETTING_STARTED.md) | Full setup: CapSkip app, SDK install, first script |
78
+ | [API Reference](docs/API_REFERENCE.md) | All classes, methods, parameters, and return values |
79
+ | [Examples](examples/) | Ready-to-run scripts for every captcha type |
80
+ | [Troubleshooting](docs/TROUBLESHOOTING.md) | Connection errors, timeouts, proxy issues |
81
+ | [Contributing](CONTRIBUTING.md) | Development setup, tests, pull requests |
82
+ | [Changelog](CHANGELOG.md) | Release history |
83
+
84
+ ---
85
+
86
+ ## Configuration
87
+
88
+ ```python
89
+ from capskip import CapSkip
90
+
91
+ solver = CapSkip(
92
+ apiKey="capskip", # your CapSkip API key (or any string if validation is off)
93
+ host="127.0.0.1", # CapSkip host
94
+ port=8080, # CapSkip port from app settings
95
+ defaultTimeout=120, # seconds — image captcha polling timeout
96
+ recaptchaTimeout=300, # seconds — reCAPTCHA / Turnstile polling timeout
97
+ pollingInterval=5, # max seconds between res.php polls (starts at 0.25s, backs off to this)
98
+ )
99
+ ```
100
+
101
+ Use environment variables in production:
102
+
103
+ ```bash
104
+ # Linux / macOS
105
+ export CAPSKIP_API_KEY="your-key"
106
+ export CAPSKIP_HOST="127.0.0.1"
107
+ export CAPSKIP_PORT="8080"
108
+ ```
109
+
110
+ ```powershell
111
+ # Windows PowerShell
112
+ $env:CAPSKIP_API_KEY = "your-key"
113
+ $env:CAPSKIP_HOST = "127.0.0.1"
114
+ $env:CAPSKIP_PORT = "8080"
115
+ ```
116
+
117
+ ```python
118
+ import os
119
+ from capskip import CapSkip
120
+
121
+ solver = CapSkip(
122
+ apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
123
+ host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
124
+ port=int(os.getenv("CAPSKIP_PORT", "8080")),
125
+ )
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Usage examples
131
+
132
+ ### Image captcha
133
+
134
+ ```python
135
+ result = solver.normal("captcha.png")
136
+ result = solver.normal("https://example.com/captcha.jpg")
137
+ result = solver.normal("data:image/png;base64,iVBORw0KGgo...")
138
+ print(result["code"])
139
+ ```
140
+
141
+ ### reCAPTCHA v2 / v3
142
+
143
+ ```python
144
+ # reCAPTCHA v2
145
+ result = solver.recaptcha(sitekey="...", url="https://example.com")
146
+
147
+ # reCAPTCHA v3
148
+ result = solver.recaptcha(
149
+ sitekey="...",
150
+ url="https://example.com",
151
+ version="v3",
152
+ action="submit",
153
+ score=0.7,
154
+ )
155
+ ```
156
+
157
+ ### Cloudflare Turnstile
158
+
159
+ ```python
160
+ result = solver.turnstile(
161
+ sitekey="0x4AAAAAAA...",
162
+ url="https://example.com",
163
+ )
164
+ ```
165
+
166
+ ### With a proxy (reCAPTCHA & Turnstile only)
167
+
168
+ ```python
169
+ # Proxy is not supported for image captcha
170
+ result = solver.recaptcha(
171
+ sitekey="...",
172
+ url="https://example.com",
173
+ proxy={"type": "HTTPS", "uri": "user:pass@1.2.3.4:3128"},
174
+ )
175
+ result = solver.turnstile(
176
+ sitekey="...",
177
+ url="https://example.com",
178
+ proxy={"type": "HTTP", "uri": "1.2.3.4:3128"},
179
+ )
180
+ ```
181
+
182
+ ### Async (parallel solving)
183
+
184
+ ```python
185
+ import asyncio
186
+ from capskip import AsyncCapSkip
187
+
188
+ async def main():
189
+ solver = AsyncCapSkip()
190
+ r1, r2 = await asyncio.gather(
191
+ solver.recaptcha(sitekey="...", url="https://a.com"),
192
+ solver.turnstile(sitekey="...", url="https://b.com"),
193
+ )
194
+ print(r1["code"], r2["code"])
195
+
196
+ asyncio.run(main())
197
+ ```
198
+
199
+ More examples: [`examples/`](examples/)
200
+
201
+ ---
202
+
203
+ ## Return value
204
+
205
+ Every solve method returns:
206
+
207
+ ```python
208
+ {
209
+ "captchaId": "12345", # internal ID from CapSkip
210
+ "code": "TOKEN_OR_TEXT" # solution — text for image, token for reCAPTCHA/Turnstile
211
+ "userAgent": "..." # Turnstile only — use when submitting challenge-page tokens
212
+ }
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Error handling
218
+
219
+ ```python
220
+ from capskip import CapSkip, ValidationException, NetworkException, ApiException, TimeoutException
221
+
222
+ try:
223
+ result = solver.recaptcha(sitekey="...", url="...")
224
+ except ValidationException:
225
+ pass # invalid parameters
226
+ except NetworkException:
227
+ pass # CapSkip not running, or captcha not ready (manual polling)
228
+ except ApiException:
229
+ pass # API returned an error code
230
+ except TimeoutException:
231
+ pass # polling timeout exceeded
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Development
237
+
238
+ ```bash
239
+ git clone https://github.com/capskip/capskip-python.git
240
+ cd capskip-python
241
+ python -m venv .venv
242
+
243
+ # Windows
244
+ .venv\Scripts\activate
245
+
246
+ # Linux / macOS
247
+ source .venv/bin/activate
248
+
249
+ pip install -e ".[dev]"
250
+ pytest
251
+ ```
252
+
253
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow.
254
+
255
+ ---
256
+
257
+ ## Links
258
+
259
+ - [CapSkip website](https://capskip.com)
260
+ - [CapSkip API docs](https://capskip.com/api-docs/)
261
+ - [Report an issue](https://github.com/capskip/capskip-python/issues)
262
+ - [PyPI package](https://pypi.org/project/capskip/) *(when published)*
263
+
264
+ ---
265
+
266
+ ## License
267
+
268
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,35 @@
1
+ # Security Policy
2
+
3
+ ## Supported versions
4
+
5
+ | Version | Supported |
6
+ |---|---|
7
+ | 1.0.x | Yes |
8
+
9
+ ## Reporting a vulnerability
10
+
11
+ If you discover a security vulnerability in the CapSkip Python SDK, please report it responsibly.
12
+
13
+ **Do not** open a public GitHub issue for security vulnerabilities.
14
+
15
+ Instead, email **support@capskip.com** with:
16
+
17
+ - Description of the vulnerability
18
+ - Steps to reproduce
19
+ - Potential impact
20
+ - Suggested fix (if any)
21
+
22
+ We aim to acknowledge reports within 48 hours and provide a status update within 7 days.
23
+
24
+ ## Scope
25
+
26
+ This policy covers the `capskip` Python package in this repository.
27
+
28
+ The CapSkip desktop application itself is maintained separately — report app-level issues to CapSkip support.
29
+
30
+ ## Best practices for SDK users
31
+
32
+ - Do not commit API keys or captcha tokens to version control
33
+ - Use environment variables for `CAPSKIP_API_KEY`
34
+ - CapSkip runs locally — ensure your firewall rules match your security requirements
35
+ - When using proxies, avoid logging credentials in application logs
@@ -0,0 +1,29 @@
1
+ """CapSkip Python SDK — local captcha solver client."""
2
+
3
+ from .api import ApiClient
4
+ from .async_api import AsyncApiClient
5
+ from .async_solver import AsyncCapSkip
6
+ from .exceptions import (
7
+ ApiException,
8
+ CapSkipError,
9
+ NetworkException,
10
+ SolverExceptions,
11
+ TimeoutException,
12
+ ValidationException,
13
+ )
14
+ from .solver import CapSkip
15
+
16
+ __all__ = [
17
+ 'CapSkip',
18
+ 'AsyncCapSkip',
19
+ 'ApiClient',
20
+ 'AsyncApiClient',
21
+ 'CapSkipError',
22
+ 'SolverExceptions',
23
+ 'ValidationException',
24
+ 'NetworkException',
25
+ 'ApiException',
26
+ 'TimeoutException',
27
+ ]
28
+
29
+ __version__ = '1.0.0'