peakfo 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.
- peakfo-1.0.0/LICENSE +21 -0
- peakfo-1.0.0/PKG-INFO +165 -0
- peakfo-1.0.0/README.md +134 -0
- peakfo-1.0.0/peakfo/__init__.py +10 -0
- peakfo-1.0.0/peakfo/client.py +193 -0
- peakfo-1.0.0/peakfo/exceptions.py +26 -0
- peakfo-1.0.0/peakfo.egg-info/PKG-INFO +165 -0
- peakfo-1.0.0/peakfo.egg-info/SOURCES.txt +12 -0
- peakfo-1.0.0/peakfo.egg-info/dependency_links.txt +1 -0
- peakfo-1.0.0/peakfo.egg-info/requires.txt +1 -0
- peakfo-1.0.0/peakfo.egg-info/top_level.txt +1 -0
- peakfo-1.0.0/pyproject.toml +35 -0
- peakfo-1.0.0/setup.cfg +4 -0
- peakfo-1.0.0/setup.py +33 -0
peakfo-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peak.fo
|
|
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.
|
peakfo-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: peakfo
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Peak.fo API Client - Solve Turnstile, CloudFlare WAF, and AWS WAF challenges
|
|
5
|
+
Home-page: https://github.com/peakfo/peakfo-python
|
|
6
|
+
Author: Peak.fo
|
|
7
|
+
Author-email: "Peak.fo" <support@peak.fo>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://peak.fo
|
|
10
|
+
Project-URL: Documentation, https://peak.fo/docs
|
|
11
|
+
Project-URL: Repository, https://github.com/peakfo/peakfo-python
|
|
12
|
+
Keywords: captcha,turnstile,cloudflare,aws,waf,solver
|
|
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.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.25.0
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
|
|
32
|
+
# Peak.fo Python SDK
|
|
33
|
+
|
|
34
|
+
Official Python client library for [Peak.fo](https://peak.fo) - the fastest captcha solving API for Turnstile, CloudFlare WAF, and AWS WAF challenges.
|
|
35
|
+
|
|
36
|
+
## 🚀 Features
|
|
37
|
+
|
|
38
|
+
- **Turnstile Solver** - Solve CloudFlare Turnstile challenges
|
|
39
|
+
- **CloudFlare WAF Solver** - Bypass CloudFlare 5-second challenges
|
|
40
|
+
- **AWS WAF Solver** - Solve AWS WAF challenges for iOS/Android mobile apps
|
|
41
|
+
|
|
42
|
+
## 📦 Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install peakfo
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 🎁 Free Trial
|
|
49
|
+
|
|
50
|
+
New users receive **$0.50 free trial credits** when signing up at [peak.fo](https://peak.fo)!
|
|
51
|
+
|
|
52
|
+
## 🔧 Quick Start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from peakfo import PeakClient
|
|
56
|
+
|
|
57
|
+
# Initialize client with your API key
|
|
58
|
+
client = PeakClient("pk_your_api_key_here")
|
|
59
|
+
|
|
60
|
+
# Check your balance
|
|
61
|
+
balance = client.get_balance()
|
|
62
|
+
print(f"Balance: ${balance['balance']}")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 📖 Usage Examples
|
|
66
|
+
|
|
67
|
+
### Solve Turnstile
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from peakfo import PeakClient
|
|
71
|
+
|
|
72
|
+
client = PeakClient("pk_your_api_key")
|
|
73
|
+
|
|
74
|
+
result = client.solve_turnstile(
|
|
75
|
+
sitekey="0x4AAAAAAXXXXXXXXXXXXXXX",
|
|
76
|
+
url="https://example.com/login",
|
|
77
|
+
proxy="http://user:pass@ip:port"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
print(f"Token: {result['token']}")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Solve CloudFlare WAF (5-second challenge)
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from peakfo import PeakClient
|
|
87
|
+
|
|
88
|
+
client = PeakClient("pk_your_api_key")
|
|
89
|
+
|
|
90
|
+
result = client.solve_cloudflare_waf(
|
|
91
|
+
url="https://example.com/", # Must end with /
|
|
92
|
+
proxy="http://user:pass@ip:port"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
print(f"Cookies: {result['cookies']}")
|
|
96
|
+
print(f"User-Agent: {result['user_agent']}")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> ⚠️ **Note:** URL must end with trailing slash. Only Windows Chrome user agents are supported.
|
|
100
|
+
|
|
101
|
+
### Solve AWS WAF (Mobile SDK)
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from peakfo import PeakClient
|
|
105
|
+
|
|
106
|
+
client = PeakClient("pk_your_api_key")
|
|
107
|
+
|
|
108
|
+
result = client.solve_aws_waf(
|
|
109
|
+
url="https://app.example.com/",
|
|
110
|
+
sdk_url="https://xxx.edge.sdk.awswaf.com/xxx/xxx",
|
|
111
|
+
proxy="http://user:pass@ip:port",
|
|
112
|
+
user_agent="ExampleApp/1.0 (iOS 17.0)",
|
|
113
|
+
os="ios" # or "android"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
print(f"Token: {result['token']}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> ⚠️ **Note:** AWS WAF solver is for mobile apps only (iOS/Android SDK), not web browsers.
|
|
120
|
+
|
|
121
|
+
## 🔑 Finding AWS WAF SDK URL
|
|
122
|
+
|
|
123
|
+
The SDK URL can be found by:
|
|
124
|
+
1. Intercepting your app's network traffic (using Charles, mitmproxy, etc.)
|
|
125
|
+
2. Looking for requests to `*.edge.sdk.awswaf.com`
|
|
126
|
+
3. The URL format is: `https://{id}.edge.sdk.awswaf.com/{id}/{token}`
|
|
127
|
+
|
|
128
|
+
## ⚠️ Error Handling
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from peakfo import PeakClient, AuthenticationError, InsufficientBalanceError, SolveError
|
|
132
|
+
|
|
133
|
+
client = PeakClient("pk_your_api_key")
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
result = client.solve_turnstile(
|
|
137
|
+
sitekey="0x4AAAAAAXXXXXXX",
|
|
138
|
+
url="https://example.com/",
|
|
139
|
+
proxy="http://user:pass@ip:port"
|
|
140
|
+
)
|
|
141
|
+
except AuthenticationError:
|
|
142
|
+
print("Invalid API key")
|
|
143
|
+
except InsufficientBalanceError:
|
|
144
|
+
print("Please top up your balance")
|
|
145
|
+
except SolveError as e:
|
|
146
|
+
print(f"Solve failed: {e}")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 💰 Pricing
|
|
150
|
+
|
|
151
|
+
| Task Type | Price per 1K |
|
|
152
|
+
|-----------|-------------|
|
|
153
|
+
| Turnstile | $1.00 |
|
|
154
|
+
| CloudFlare WAF | $1.20 |
|
|
155
|
+
| AWS WAF | $1.00 |
|
|
156
|
+
|
|
157
|
+
## 📞 Support
|
|
158
|
+
|
|
159
|
+
- **Website:** [peak.fo](https://peak.fo)
|
|
160
|
+
- **Live Chat:** Available on website
|
|
161
|
+
- **Telegram:** [@jujucodings](https://t.me/jujucodings)
|
|
162
|
+
|
|
163
|
+
## 📄 License
|
|
164
|
+
|
|
165
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
peakfo-1.0.0/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Peak.fo Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python client library for [Peak.fo](https://peak.fo) - the fastest captcha solving API for Turnstile, CloudFlare WAF, and AWS WAF challenges.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **Turnstile Solver** - Solve CloudFlare Turnstile challenges
|
|
8
|
+
- **CloudFlare WAF Solver** - Bypass CloudFlare 5-second challenges
|
|
9
|
+
- **AWS WAF Solver** - Solve AWS WAF challenges for iOS/Android mobile apps
|
|
10
|
+
|
|
11
|
+
## 📦 Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install peakfo
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 🎁 Free Trial
|
|
18
|
+
|
|
19
|
+
New users receive **$0.50 free trial credits** when signing up at [peak.fo](https://peak.fo)!
|
|
20
|
+
|
|
21
|
+
## 🔧 Quick Start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from peakfo import PeakClient
|
|
25
|
+
|
|
26
|
+
# Initialize client with your API key
|
|
27
|
+
client = PeakClient("pk_your_api_key_here")
|
|
28
|
+
|
|
29
|
+
# Check your balance
|
|
30
|
+
balance = client.get_balance()
|
|
31
|
+
print(f"Balance: ${balance['balance']}")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 📖 Usage Examples
|
|
35
|
+
|
|
36
|
+
### Solve Turnstile
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from peakfo import PeakClient
|
|
40
|
+
|
|
41
|
+
client = PeakClient("pk_your_api_key")
|
|
42
|
+
|
|
43
|
+
result = client.solve_turnstile(
|
|
44
|
+
sitekey="0x4AAAAAAXXXXXXXXXXXXXXX",
|
|
45
|
+
url="https://example.com/login",
|
|
46
|
+
proxy="http://user:pass@ip:port"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
print(f"Token: {result['token']}")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Solve CloudFlare WAF (5-second challenge)
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from peakfo import PeakClient
|
|
56
|
+
|
|
57
|
+
client = PeakClient("pk_your_api_key")
|
|
58
|
+
|
|
59
|
+
result = client.solve_cloudflare_waf(
|
|
60
|
+
url="https://example.com/", # Must end with /
|
|
61
|
+
proxy="http://user:pass@ip:port"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
print(f"Cookies: {result['cookies']}")
|
|
65
|
+
print(f"User-Agent: {result['user_agent']}")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
> ⚠️ **Note:** URL must end with trailing slash. Only Windows Chrome user agents are supported.
|
|
69
|
+
|
|
70
|
+
### Solve AWS WAF (Mobile SDK)
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from peakfo import PeakClient
|
|
74
|
+
|
|
75
|
+
client = PeakClient("pk_your_api_key")
|
|
76
|
+
|
|
77
|
+
result = client.solve_aws_waf(
|
|
78
|
+
url="https://app.example.com/",
|
|
79
|
+
sdk_url="https://xxx.edge.sdk.awswaf.com/xxx/xxx",
|
|
80
|
+
proxy="http://user:pass@ip:port",
|
|
81
|
+
user_agent="ExampleApp/1.0 (iOS 17.0)",
|
|
82
|
+
os="ios" # or "android"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
print(f"Token: {result['token']}")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> ⚠️ **Note:** AWS WAF solver is for mobile apps only (iOS/Android SDK), not web browsers.
|
|
89
|
+
|
|
90
|
+
## 🔑 Finding AWS WAF SDK URL
|
|
91
|
+
|
|
92
|
+
The SDK URL can be found by:
|
|
93
|
+
1. Intercepting your app's network traffic (using Charles, mitmproxy, etc.)
|
|
94
|
+
2. Looking for requests to `*.edge.sdk.awswaf.com`
|
|
95
|
+
3. The URL format is: `https://{id}.edge.sdk.awswaf.com/{id}/{token}`
|
|
96
|
+
|
|
97
|
+
## ⚠️ Error Handling
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from peakfo import PeakClient, AuthenticationError, InsufficientBalanceError, SolveError
|
|
101
|
+
|
|
102
|
+
client = PeakClient("pk_your_api_key")
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
result = client.solve_turnstile(
|
|
106
|
+
sitekey="0x4AAAAAAXXXXXXX",
|
|
107
|
+
url="https://example.com/",
|
|
108
|
+
proxy="http://user:pass@ip:port"
|
|
109
|
+
)
|
|
110
|
+
except AuthenticationError:
|
|
111
|
+
print("Invalid API key")
|
|
112
|
+
except InsufficientBalanceError:
|
|
113
|
+
print("Please top up your balance")
|
|
114
|
+
except SolveError as e:
|
|
115
|
+
print(f"Solve failed: {e}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 💰 Pricing
|
|
119
|
+
|
|
120
|
+
| Task Type | Price per 1K |
|
|
121
|
+
|-----------|-------------|
|
|
122
|
+
| Turnstile | $1.00 |
|
|
123
|
+
| CloudFlare WAF | $1.20 |
|
|
124
|
+
| AWS WAF | $1.00 |
|
|
125
|
+
|
|
126
|
+
## 📞 Support
|
|
127
|
+
|
|
128
|
+
- **Website:** [peak.fo](https://peak.fo)
|
|
129
|
+
- **Live Chat:** Available on website
|
|
130
|
+
- **Telegram:** [@jujucodings](https://t.me/jujucodings)
|
|
131
|
+
|
|
132
|
+
## 📄 License
|
|
133
|
+
|
|
134
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Peak.fo API Client Library for Python
|
|
3
|
+
Solve Turnstile, CloudFlare WAF, and AWS WAF challenges
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .client import PeakClient
|
|
7
|
+
from .exceptions import PeakError, AuthenticationError, InsufficientBalanceError, SolveError
|
|
8
|
+
|
|
9
|
+
__version__ = "1.0.0"
|
|
10
|
+
__all__ = ["PeakClient", "PeakError", "AuthenticationError", "InsufficientBalanceError", "SolveError"]
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""Peak.fo API Client"""
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from typing import Optional, Dict, Any
|
|
5
|
+
from .exceptions import PeakError, AuthenticationError, InsufficientBalanceError, SolveError, TaskDisabledError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PeakClient:
|
|
9
|
+
"""
|
|
10
|
+
Peak.fo API Client for solving captcha challenges.
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
client = PeakClient("pk_your_api_key")
|
|
14
|
+
|
|
15
|
+
# Solve Turnstile
|
|
16
|
+
result = client.solve_turnstile(
|
|
17
|
+
sitekey="0x4AAAAAAXXXXXXX",
|
|
18
|
+
url="https://example.com/",
|
|
19
|
+
proxy="http://user:pass@ip:port"
|
|
20
|
+
)
|
|
21
|
+
print(result["token"])
|
|
22
|
+
|
|
23
|
+
# Solve CloudFlare WAF
|
|
24
|
+
result = client.solve_cloudflare_waf(
|
|
25
|
+
url="https://example.com/",
|
|
26
|
+
proxy="http://user:pass@ip:port"
|
|
27
|
+
)
|
|
28
|
+
print(result["cookies"])
|
|
29
|
+
|
|
30
|
+
# Solve AWS WAF
|
|
31
|
+
result = client.solve_aws_waf(
|
|
32
|
+
url="https://example.com/",
|
|
33
|
+
sdk_url="https://xxx.edge.sdk.awswaf.com/xxx/xxx",
|
|
34
|
+
proxy="http://user:pass@ip:port",
|
|
35
|
+
user_agent="App/1.0 (iOS 17.0)",
|
|
36
|
+
os="ios"
|
|
37
|
+
)
|
|
38
|
+
print(result["token"])
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
BASE_URL = "https://api.peak.fo"
|
|
42
|
+
|
|
43
|
+
def __init__(self, api_key: str, base_url: Optional[str] = None):
|
|
44
|
+
"""
|
|
45
|
+
Initialize Peak.fo client.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
api_key: Your Peak.fo API key (starts with pk_)
|
|
49
|
+
base_url: Optional custom base URL
|
|
50
|
+
"""
|
|
51
|
+
self.api_key = api_key
|
|
52
|
+
self.base_url = base_url or self.BASE_URL
|
|
53
|
+
self.session = requests.Session()
|
|
54
|
+
self.session.headers.update({
|
|
55
|
+
"X-API-Key": api_key,
|
|
56
|
+
"Content-Type": "application/json"
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
def _request(self, method: str, endpoint: str, data: Optional[Dict] = None) -> Dict[str, Any]:
|
|
60
|
+
"""Make API request and handle errors."""
|
|
61
|
+
url = f"{self.base_url}{endpoint}"
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
if method == "GET":
|
|
65
|
+
response = self.session.get(url, timeout=120)
|
|
66
|
+
else:
|
|
67
|
+
response = self.session.post(url, json=data, timeout=120)
|
|
68
|
+
|
|
69
|
+
result = response.json()
|
|
70
|
+
|
|
71
|
+
if not result.get("success", False):
|
|
72
|
+
error = result.get("error", "Unknown error")
|
|
73
|
+
|
|
74
|
+
if "authentication" in error.lower() or "invalid api key" in error.lower():
|
|
75
|
+
raise AuthenticationError(error)
|
|
76
|
+
elif "insufficient balance" in error.lower():
|
|
77
|
+
raise InsufficientBalanceError(error)
|
|
78
|
+
elif "disabled" in error.lower():
|
|
79
|
+
raise TaskDisabledError(error)
|
|
80
|
+
else:
|
|
81
|
+
raise SolveError(error)
|
|
82
|
+
|
|
83
|
+
return result.get("data", result)
|
|
84
|
+
|
|
85
|
+
except requests.exceptions.RequestException as e:
|
|
86
|
+
raise PeakError(f"Request failed: {e}")
|
|
87
|
+
|
|
88
|
+
def get_balance(self) -> Dict[str, Any]:
|
|
89
|
+
"""
|
|
90
|
+
Get account balance information.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
dict: Balance info with 'type' and 'balance' or package details
|
|
94
|
+
"""
|
|
95
|
+
return self._request("GET", "/balance")
|
|
96
|
+
|
|
97
|
+
def solve_turnstile(
|
|
98
|
+
self,
|
|
99
|
+
sitekey: str,
|
|
100
|
+
url: str,
|
|
101
|
+
proxy: str,
|
|
102
|
+
action: Optional[str] = None,
|
|
103
|
+
cdata: Optional[str] = None
|
|
104
|
+
) -> Dict[str, str]:
|
|
105
|
+
"""
|
|
106
|
+
Solve CloudFlare Turnstile challenge.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
sitekey: Turnstile sitekey (0x4AAAAA...)
|
|
110
|
+
url: Page URL where Turnstile appears
|
|
111
|
+
proxy: Proxy in format http://user:pass@ip:port
|
|
112
|
+
action: Optional Turnstile action parameter
|
|
113
|
+
cdata: Optional Turnstile cdata parameter
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
dict: {"token": "turnstile_token_here"}
|
|
117
|
+
"""
|
|
118
|
+
data = {
|
|
119
|
+
"task_type": "turnstiletask",
|
|
120
|
+
"sitekey": sitekey,
|
|
121
|
+
"url": url,
|
|
122
|
+
"proxy": proxy
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if action:
|
|
126
|
+
data["action"] = action
|
|
127
|
+
if cdata:
|
|
128
|
+
data["cdata"] = cdata
|
|
129
|
+
|
|
130
|
+
return self._request("POST", "/solve", data)
|
|
131
|
+
|
|
132
|
+
def solve_cloudflare_waf(
|
|
133
|
+
self,
|
|
134
|
+
url: str,
|
|
135
|
+
proxy: str
|
|
136
|
+
) -> Dict[str, Any]:
|
|
137
|
+
"""
|
|
138
|
+
Solve CloudFlare WAF 5-second challenge.
|
|
139
|
+
|
|
140
|
+
Note: URL must end with trailing slash. Only Windows Chrome user agents supported.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
url: Target URL (must end with /)
|
|
144
|
+
proxy: Proxy in format http://user:pass@ip:port
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
dict: {"cookies": {...}, "user_agent": "..."}
|
|
148
|
+
"""
|
|
149
|
+
# Ensure trailing slash
|
|
150
|
+
if not url.endswith("/"):
|
|
151
|
+
url += "/"
|
|
152
|
+
|
|
153
|
+
data = {
|
|
154
|
+
"task_type": "cloudflare5stask",
|
|
155
|
+
"url": url,
|
|
156
|
+
"proxy": proxy
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return self._request("POST", "/solve", data)
|
|
160
|
+
|
|
161
|
+
def solve_aws_waf(
|
|
162
|
+
self,
|
|
163
|
+
url: str,
|
|
164
|
+
sdk_url: str,
|
|
165
|
+
proxy: str,
|
|
166
|
+
user_agent: str,
|
|
167
|
+
os: str = "ios"
|
|
168
|
+
) -> Dict[str, str]:
|
|
169
|
+
"""
|
|
170
|
+
Solve AWS WAF challenge for mobile SDK.
|
|
171
|
+
|
|
172
|
+
Note: This is for iOS/Android mobile apps only, not web browsers.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
url: App's base URL (e.g., https://app.example.com/)
|
|
176
|
+
sdk_url: AWS WAF SDK endpoint (https://xxx.edge.sdk.awswaf.com/xxx/xxx)
|
|
177
|
+
proxy: Proxy in format http://user:pass@ip:port
|
|
178
|
+
user_agent: Mobile app user agent (e.g., "AppName/1.0 (iOS 17.0)")
|
|
179
|
+
os: Operating system - "ios" or "android"
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
dict: {"token": "aws_waf_token_here"}
|
|
183
|
+
"""
|
|
184
|
+
data = {
|
|
185
|
+
"task_type": "awswaftask",
|
|
186
|
+
"url": url,
|
|
187
|
+
"sdk_url": sdk_url,
|
|
188
|
+
"proxy": proxy,
|
|
189
|
+
"user_agent": user_agent,
|
|
190
|
+
"os": os
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return self._request("POST", "/solve", data)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Peak.fo API Exceptions"""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PeakError(Exception):
|
|
5
|
+
"""Base exception for Peak.fo API errors"""
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AuthenticationError(PeakError):
|
|
10
|
+
"""Raised when API key is invalid or missing"""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InsufficientBalanceError(PeakError):
|
|
15
|
+
"""Raised when account balance is insufficient"""
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SolveError(PeakError):
|
|
20
|
+
"""Raised when solve operation fails"""
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TaskDisabledError(PeakError):
|
|
25
|
+
"""Raised when task type is currently disabled"""
|
|
26
|
+
pass
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: peakfo
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Peak.fo API Client - Solve Turnstile, CloudFlare WAF, and AWS WAF challenges
|
|
5
|
+
Home-page: https://github.com/peakfo/peakfo-python
|
|
6
|
+
Author: Peak.fo
|
|
7
|
+
Author-email: "Peak.fo" <support@peak.fo>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://peak.fo
|
|
10
|
+
Project-URL: Documentation, https://peak.fo/docs
|
|
11
|
+
Project-URL: Repository, https://github.com/peakfo/peakfo-python
|
|
12
|
+
Keywords: captcha,turnstile,cloudflare,aws,waf,solver
|
|
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.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Requires-Python: >=3.7
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.25.0
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: home-page
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
|
|
32
|
+
# Peak.fo Python SDK
|
|
33
|
+
|
|
34
|
+
Official Python client library for [Peak.fo](https://peak.fo) - the fastest captcha solving API for Turnstile, CloudFlare WAF, and AWS WAF challenges.
|
|
35
|
+
|
|
36
|
+
## 🚀 Features
|
|
37
|
+
|
|
38
|
+
- **Turnstile Solver** - Solve CloudFlare Turnstile challenges
|
|
39
|
+
- **CloudFlare WAF Solver** - Bypass CloudFlare 5-second challenges
|
|
40
|
+
- **AWS WAF Solver** - Solve AWS WAF challenges for iOS/Android mobile apps
|
|
41
|
+
|
|
42
|
+
## 📦 Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install peakfo
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 🎁 Free Trial
|
|
49
|
+
|
|
50
|
+
New users receive **$0.50 free trial credits** when signing up at [peak.fo](https://peak.fo)!
|
|
51
|
+
|
|
52
|
+
## 🔧 Quick Start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from peakfo import PeakClient
|
|
56
|
+
|
|
57
|
+
# Initialize client with your API key
|
|
58
|
+
client = PeakClient("pk_your_api_key_here")
|
|
59
|
+
|
|
60
|
+
# Check your balance
|
|
61
|
+
balance = client.get_balance()
|
|
62
|
+
print(f"Balance: ${balance['balance']}")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 📖 Usage Examples
|
|
66
|
+
|
|
67
|
+
### Solve Turnstile
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from peakfo import PeakClient
|
|
71
|
+
|
|
72
|
+
client = PeakClient("pk_your_api_key")
|
|
73
|
+
|
|
74
|
+
result = client.solve_turnstile(
|
|
75
|
+
sitekey="0x4AAAAAAXXXXXXXXXXXXXXX",
|
|
76
|
+
url="https://example.com/login",
|
|
77
|
+
proxy="http://user:pass@ip:port"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
print(f"Token: {result['token']}")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Solve CloudFlare WAF (5-second challenge)
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from peakfo import PeakClient
|
|
87
|
+
|
|
88
|
+
client = PeakClient("pk_your_api_key")
|
|
89
|
+
|
|
90
|
+
result = client.solve_cloudflare_waf(
|
|
91
|
+
url="https://example.com/", # Must end with /
|
|
92
|
+
proxy="http://user:pass@ip:port"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
print(f"Cookies: {result['cookies']}")
|
|
96
|
+
print(f"User-Agent: {result['user_agent']}")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> ⚠️ **Note:** URL must end with trailing slash. Only Windows Chrome user agents are supported.
|
|
100
|
+
|
|
101
|
+
### Solve AWS WAF (Mobile SDK)
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from peakfo import PeakClient
|
|
105
|
+
|
|
106
|
+
client = PeakClient("pk_your_api_key")
|
|
107
|
+
|
|
108
|
+
result = client.solve_aws_waf(
|
|
109
|
+
url="https://app.example.com/",
|
|
110
|
+
sdk_url="https://xxx.edge.sdk.awswaf.com/xxx/xxx",
|
|
111
|
+
proxy="http://user:pass@ip:port",
|
|
112
|
+
user_agent="ExampleApp/1.0 (iOS 17.0)",
|
|
113
|
+
os="ios" # or "android"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
print(f"Token: {result['token']}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> ⚠️ **Note:** AWS WAF solver is for mobile apps only (iOS/Android SDK), not web browsers.
|
|
120
|
+
|
|
121
|
+
## 🔑 Finding AWS WAF SDK URL
|
|
122
|
+
|
|
123
|
+
The SDK URL can be found by:
|
|
124
|
+
1. Intercepting your app's network traffic (using Charles, mitmproxy, etc.)
|
|
125
|
+
2. Looking for requests to `*.edge.sdk.awswaf.com`
|
|
126
|
+
3. The URL format is: `https://{id}.edge.sdk.awswaf.com/{id}/{token}`
|
|
127
|
+
|
|
128
|
+
## ⚠️ Error Handling
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from peakfo import PeakClient, AuthenticationError, InsufficientBalanceError, SolveError
|
|
132
|
+
|
|
133
|
+
client = PeakClient("pk_your_api_key")
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
result = client.solve_turnstile(
|
|
137
|
+
sitekey="0x4AAAAAAXXXXXXX",
|
|
138
|
+
url="https://example.com/",
|
|
139
|
+
proxy="http://user:pass@ip:port"
|
|
140
|
+
)
|
|
141
|
+
except AuthenticationError:
|
|
142
|
+
print("Invalid API key")
|
|
143
|
+
except InsufficientBalanceError:
|
|
144
|
+
print("Please top up your balance")
|
|
145
|
+
except SolveError as e:
|
|
146
|
+
print(f"Solve failed: {e}")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 💰 Pricing
|
|
150
|
+
|
|
151
|
+
| Task Type | Price per 1K |
|
|
152
|
+
|-----------|-------------|
|
|
153
|
+
| Turnstile | $1.00 |
|
|
154
|
+
| CloudFlare WAF | $1.20 |
|
|
155
|
+
| AWS WAF | $1.00 |
|
|
156
|
+
|
|
157
|
+
## 📞 Support
|
|
158
|
+
|
|
159
|
+
- **Website:** [peak.fo](https://peak.fo)
|
|
160
|
+
- **Live Chat:** Available on website
|
|
161
|
+
- **Telegram:** [@jujucodings](https://t.me/jujucodings)
|
|
162
|
+
|
|
163
|
+
## 📄 License
|
|
164
|
+
|
|
165
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
peakfo/__init__.py
|
|
6
|
+
peakfo/client.py
|
|
7
|
+
peakfo/exceptions.py
|
|
8
|
+
peakfo.egg-info/PKG-INFO
|
|
9
|
+
peakfo.egg-info/SOURCES.txt
|
|
10
|
+
peakfo.egg-info/dependency_links.txt
|
|
11
|
+
peakfo.egg-info/requires.txt
|
|
12
|
+
peakfo.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.25.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
peakfo
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "peakfo"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Peak.fo API Client - Solve Turnstile, CloudFlare WAF, and AWS WAF challenges"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.7"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Peak.fo", email = "support@peak.fo"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["captcha", "turnstile", "cloudflare", "aws", "waf", "solver"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.7",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"requests>=2.25.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://peak.fo"
|
|
34
|
+
Documentation = "https://peak.fo/docs"
|
|
35
|
+
Repository = "https://github.com/peakfo/peakfo-python"
|
peakfo-1.0.0/setup.cfg
ADDED
peakfo-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as f:
|
|
4
|
+
long_description = f.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="peakfo",
|
|
8
|
+
version="1.0.0",
|
|
9
|
+
description="Peak.fo API Client - Solve Turnstile, CloudFlare WAF, and AWS WAF challenges",
|
|
10
|
+
long_description=long_description,
|
|
11
|
+
long_description_content_type="text/markdown",
|
|
12
|
+
author="Peak.fo",
|
|
13
|
+
author_email="support@peak.fo",
|
|
14
|
+
url="https://github.com/peakfo/peakfo-python",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
install_requires=[
|
|
17
|
+
"requests>=2.25.0",
|
|
18
|
+
],
|
|
19
|
+
python_requires=">=3.7",
|
|
20
|
+
classifiers=[
|
|
21
|
+
"Development Status :: 5 - Production/Stable",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.7",
|
|
26
|
+
"Programming Language :: Python :: 3.8",
|
|
27
|
+
"Programming Language :: Python :: 3.9",
|
|
28
|
+
"Programming Language :: Python :: 3.10",
|
|
29
|
+
"Programming Language :: Python :: 3.11",
|
|
30
|
+
"Programming Language :: Python :: 3.12",
|
|
31
|
+
],
|
|
32
|
+
keywords="captcha turnstile cloudflare aws waf solver",
|
|
33
|
+
)
|