hyper-sdk 0.1.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.
- hyper_sdk-0.1.0/LICENSE +21 -0
- hyper_sdk-0.1.0/PKG-INFO +194 -0
- hyper_sdk-0.1.0/README.md +175 -0
- hyper_sdk-0.1.0/hyper_sdk/__init__.py +6 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai/__init__.py +4 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai/pixel.py +83 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai/script_path.py +28 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai/sec_cpt.py +115 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai/stop_signal.py +52 -0
- hyper_sdk-0.1.0/hyper_sdk/akamai_input.py +15 -0
- hyper_sdk-0.1.0/hyper_sdk/incapsula/__init__.py +1 -0
- hyper_sdk-0.1.0/hyper_sdk/incapsula/utmvc.py +42 -0
- hyper_sdk-0.1.0/hyper_sdk/incapsula_input.py +5 -0
- hyper_sdk-0.1.0/hyper_sdk/session.py +138 -0
- hyper_sdk-0.1.0/hyper_sdk.egg-info/PKG-INFO +194 -0
- hyper_sdk-0.1.0/hyper_sdk.egg-info/SOURCES.txt +19 -0
- hyper_sdk-0.1.0/hyper_sdk.egg-info/dependency_links.txt +1 -0
- hyper_sdk-0.1.0/hyper_sdk.egg-info/requires.txt +7 -0
- hyper_sdk-0.1.0/hyper_sdk.egg-info/top_level.txt +1 -0
- hyper_sdk-0.1.0/pyproject.toml +30 -0
- hyper_sdk-0.1.0/setup.cfg +4 -0
hyper_sdk-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Hyper Solutions
|
|
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.
|
hyper_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: hyper_sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Hyper Solutions Python SDK
|
|
5
|
+
Project-URL: homepage, https://github.com/Hyper-Solutions/hyper-sdk-py
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Requires-Python: >=3.6
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: certifi==2024.2.2
|
|
13
|
+
Requires-Dist: charset-normalizer==3.3.2
|
|
14
|
+
Requires-Dist: idna==3.6
|
|
15
|
+
Requires-Dist: jsonpickle==3.0.3
|
|
16
|
+
Requires-Dist: PyJWT==2.8.0
|
|
17
|
+
Requires-Dist: requests==2.31.0
|
|
18
|
+
Requires-Dist: urllib3==2.2.1
|
|
19
|
+
|
|
20
|
+
# Hyper Solutions SDK for Python
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
To use the Hyper Solutions SDK in your Python project, you need to install it using the following command:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pip install hyper-sdk
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Creating a Session
|
|
33
|
+
|
|
34
|
+
To start using the SDK, you need to create a new `Session` instance by providing your API key:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from hyper_sdk import Session
|
|
38
|
+
|
|
39
|
+
session = Session(api_key="your-api-key")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You can also optionally set a JWT key and a custom HTTP client:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from hyper_sdk import Session
|
|
46
|
+
|
|
47
|
+
session = Session(api_key="your-api-key", jwt_key="your-jwt-key", client=custom_http_client)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Akamai
|
|
51
|
+
|
|
52
|
+
The Akamai package provides functions for interacting with Akamai Bot Manager, including generating sensor data, parsing script path, parsing pixel challenges, and handling sec-cpt challenges.
|
|
53
|
+
|
|
54
|
+
### Generating Sensor Data
|
|
55
|
+
|
|
56
|
+
To generate sensor data required for generating valid Akamai cookies, use the `generate_sensor_data` method:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from hyper_sdk import SensorInput
|
|
60
|
+
|
|
61
|
+
sensor_input = SensorInput(
|
|
62
|
+
page_url="https://example.com/",
|
|
63
|
+
user_agent="your-user-agent",
|
|
64
|
+
abck="your-abck-cookie",
|
|
65
|
+
bmsz="your-bmsz-cookie",
|
|
66
|
+
version="2.0"
|
|
67
|
+
)
|
|
68
|
+
sensor_data = session.generate_sensor_data(sensor_input)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Parsing Script Path
|
|
72
|
+
|
|
73
|
+
To parse the Akamai Bot Manager script path from the given HTML code, use the `parse_script_path` function from the `script_path` module:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from hyper_sdk.akamai.script_path import parse_script_path
|
|
77
|
+
|
|
78
|
+
script_path = parse_script_path(html_source)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Handling Sec-Cpt Challenges
|
|
82
|
+
|
|
83
|
+
The Akamai package provides functions for handling sec-cpt challenges:
|
|
84
|
+
|
|
85
|
+
- `SecCptChallenge.parse`: Parses a sec-cpt challenge from an HTML source.
|
|
86
|
+
- `generate_sec_cpt_payload`: Generates a sec-cpt payload using the provided sec-cpt cookie.
|
|
87
|
+
- `update_sec_cpt_challenge_data`: Updates the challenge data of a `SecCptChallenge` instance from a response body.
|
|
88
|
+
|
|
89
|
+
Example usage:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from hyper_sdk.akamai.sec_cpt import SecCptChallenge
|
|
93
|
+
|
|
94
|
+
challenge = SecCptChallenge.parse(html_source)
|
|
95
|
+
payload = challenge.generate_sec_cpt_payload(sec_cpt_cookie)
|
|
96
|
+
challenge.update_sec_cpt_challenge_data(response_body)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Validating Cookies
|
|
100
|
+
|
|
101
|
+
The Akamai package provides functions for validating cookies:
|
|
102
|
+
|
|
103
|
+
- `is_cookie_valid`: Determines if the provided `_abck` cookie value is valid based on the given request count.
|
|
104
|
+
- `is_cookie_invalidated`: Determines if the current session requires more sensors to be sent.
|
|
105
|
+
|
|
106
|
+
Example usage:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from hyper_sdk.akamai.stop_signal import is_cookie_valid, is_cookie_invalidated
|
|
110
|
+
|
|
111
|
+
is_valid = is_cookie_valid(abck_cookie, request_count)
|
|
112
|
+
is_invalidated = is_cookie_invalidated(abck_cookie)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Generating Pixel Data
|
|
116
|
+
|
|
117
|
+
To generate pixel data, use the `generate_pixel_data` method:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from hyper_sdk import PixelInput
|
|
121
|
+
|
|
122
|
+
pixel_input = PixelInput(
|
|
123
|
+
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
|
|
124
|
+
html_var="your-html-var",
|
|
125
|
+
script_var="your-script-var"
|
|
126
|
+
)
|
|
127
|
+
pixel_data = session.generate_pixel_data(pixel_input)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Parsing Pixel Challenges
|
|
131
|
+
|
|
132
|
+
The Akamai package provides functions for parsing pixel challenges:
|
|
133
|
+
|
|
134
|
+
- `parse_pixel_html_var`: Parses the required pixel challenge variable from the given HTML code.
|
|
135
|
+
- `parse_pixel_script_url`: Parses the script URL of the pixel challenge script and the URL to post a generated payload to from the given HTML code.
|
|
136
|
+
- `parse_pixel_script_var`: Parses the dynamic value from the pixel script.
|
|
137
|
+
|
|
138
|
+
Example usage:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from hyper_sdk.akamai.pixel import parse_pixel_html_var, parse_pixel_script_url, parse_pixel_script_var
|
|
142
|
+
|
|
143
|
+
html_var = parse_pixel_html_var(html_source)
|
|
144
|
+
script_url, post_url = parse_pixel_script_url(html_source)
|
|
145
|
+
script_var = parse_pixel_script_var(script_source)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
## Incapsula
|
|
150
|
+
|
|
151
|
+
The Incapsula package provides functions for interacting with Imperva Incapsula, including generating Reese84 sensor data, UTMVC cookies, and parsing UTMVC script paths.
|
|
152
|
+
|
|
153
|
+
### Generating Reese84 Sensor
|
|
154
|
+
|
|
155
|
+
To generate sensor data required for generating valid Reese84 cookies, use the `generate_reese84_sensor` method:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
sensor_data = session.generate_reese84_sensor(site="example.com", user_agent="your-user-agent")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Generating UTMVC Cookie
|
|
162
|
+
|
|
163
|
+
To generate the UTMVC cookie using the Hyper Solutions API, use the `generate_utmvc_cookie` method:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from hyper_sdk import UtmvcInput
|
|
167
|
+
|
|
168
|
+
utmvc_input = UtmvcInput(
|
|
169
|
+
user_agent="your-user-agent",
|
|
170
|
+
session_ids=["session-id-1", "session-id-2"],
|
|
171
|
+
script="your-script"
|
|
172
|
+
)
|
|
173
|
+
utmvc_cookie = session.generate_utmvc_cookie(utmvc_input)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Parsing UTMVC Script Path
|
|
177
|
+
|
|
178
|
+
To parse the UTMVC script path from a given script content, use the `parse_utmvc_script_path` function from the `utmvc` module:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from hyper_sdk.incapsula.utmvc import parse_utmvc_script_path
|
|
182
|
+
|
|
183
|
+
script_path = parse_utmvc_script_path(script_content)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Generating UTMVC Submit Path
|
|
187
|
+
|
|
188
|
+
To generate a unique UTMVC submit path with a random query parameter, use the `get_utmvc_submit_path` function from the `utmvc` module:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from hyper_sdk.incapsula.utmvc import get_utmvc_submit_path
|
|
192
|
+
|
|
193
|
+
submit_path = get_utmvc_submit_path()
|
|
194
|
+
```
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Hyper Solutions SDK for Python
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
To use the Hyper Solutions SDK in your Python project, you need to install it using the following command:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pip install hyper-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Creating a Session
|
|
14
|
+
|
|
15
|
+
To start using the SDK, you need to create a new `Session` instance by providing your API key:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from hyper_sdk import Session
|
|
19
|
+
|
|
20
|
+
session = Session(api_key="your-api-key")
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
You can also optionally set a JWT key and a custom HTTP client:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from hyper_sdk import Session
|
|
27
|
+
|
|
28
|
+
session = Session(api_key="your-api-key", jwt_key="your-jwt-key", client=custom_http_client)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Akamai
|
|
32
|
+
|
|
33
|
+
The Akamai package provides functions for interacting with Akamai Bot Manager, including generating sensor data, parsing script path, parsing pixel challenges, and handling sec-cpt challenges.
|
|
34
|
+
|
|
35
|
+
### Generating Sensor Data
|
|
36
|
+
|
|
37
|
+
To generate sensor data required for generating valid Akamai cookies, use the `generate_sensor_data` method:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from hyper_sdk import SensorInput
|
|
41
|
+
|
|
42
|
+
sensor_input = SensorInput(
|
|
43
|
+
page_url="https://example.com/",
|
|
44
|
+
user_agent="your-user-agent",
|
|
45
|
+
abck="your-abck-cookie",
|
|
46
|
+
bmsz="your-bmsz-cookie",
|
|
47
|
+
version="2.0"
|
|
48
|
+
)
|
|
49
|
+
sensor_data = session.generate_sensor_data(sensor_input)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Parsing Script Path
|
|
53
|
+
|
|
54
|
+
To parse the Akamai Bot Manager script path from the given HTML code, use the `parse_script_path` function from the `script_path` module:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from hyper_sdk.akamai.script_path import parse_script_path
|
|
58
|
+
|
|
59
|
+
script_path = parse_script_path(html_source)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Handling Sec-Cpt Challenges
|
|
63
|
+
|
|
64
|
+
The Akamai package provides functions for handling sec-cpt challenges:
|
|
65
|
+
|
|
66
|
+
- `SecCptChallenge.parse`: Parses a sec-cpt challenge from an HTML source.
|
|
67
|
+
- `generate_sec_cpt_payload`: Generates a sec-cpt payload using the provided sec-cpt cookie.
|
|
68
|
+
- `update_sec_cpt_challenge_data`: Updates the challenge data of a `SecCptChallenge` instance from a response body.
|
|
69
|
+
|
|
70
|
+
Example usage:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from hyper_sdk.akamai.sec_cpt import SecCptChallenge
|
|
74
|
+
|
|
75
|
+
challenge = SecCptChallenge.parse(html_source)
|
|
76
|
+
payload = challenge.generate_sec_cpt_payload(sec_cpt_cookie)
|
|
77
|
+
challenge.update_sec_cpt_challenge_data(response_body)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Validating Cookies
|
|
81
|
+
|
|
82
|
+
The Akamai package provides functions for validating cookies:
|
|
83
|
+
|
|
84
|
+
- `is_cookie_valid`: Determines if the provided `_abck` cookie value is valid based on the given request count.
|
|
85
|
+
- `is_cookie_invalidated`: Determines if the current session requires more sensors to be sent.
|
|
86
|
+
|
|
87
|
+
Example usage:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from hyper_sdk.akamai.stop_signal import is_cookie_valid, is_cookie_invalidated
|
|
91
|
+
|
|
92
|
+
is_valid = is_cookie_valid(abck_cookie, request_count)
|
|
93
|
+
is_invalidated = is_cookie_invalidated(abck_cookie)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Generating Pixel Data
|
|
97
|
+
|
|
98
|
+
To generate pixel data, use the `generate_pixel_data` method:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from hyper_sdk import PixelInput
|
|
102
|
+
|
|
103
|
+
pixel_input = PixelInput(
|
|
104
|
+
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
|
|
105
|
+
html_var="your-html-var",
|
|
106
|
+
script_var="your-script-var"
|
|
107
|
+
)
|
|
108
|
+
pixel_data = session.generate_pixel_data(pixel_input)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Parsing Pixel Challenges
|
|
112
|
+
|
|
113
|
+
The Akamai package provides functions for parsing pixel challenges:
|
|
114
|
+
|
|
115
|
+
- `parse_pixel_html_var`: Parses the required pixel challenge variable from the given HTML code.
|
|
116
|
+
- `parse_pixel_script_url`: Parses the script URL of the pixel challenge script and the URL to post a generated payload to from the given HTML code.
|
|
117
|
+
- `parse_pixel_script_var`: Parses the dynamic value from the pixel script.
|
|
118
|
+
|
|
119
|
+
Example usage:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from hyper_sdk.akamai.pixel import parse_pixel_html_var, parse_pixel_script_url, parse_pixel_script_var
|
|
123
|
+
|
|
124
|
+
html_var = parse_pixel_html_var(html_source)
|
|
125
|
+
script_url, post_url = parse_pixel_script_url(html_source)
|
|
126
|
+
script_var = parse_pixel_script_var(script_source)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
## Incapsula
|
|
131
|
+
|
|
132
|
+
The Incapsula package provides functions for interacting with Imperva Incapsula, including generating Reese84 sensor data, UTMVC cookies, and parsing UTMVC script paths.
|
|
133
|
+
|
|
134
|
+
### Generating Reese84 Sensor
|
|
135
|
+
|
|
136
|
+
To generate sensor data required for generating valid Reese84 cookies, use the `generate_reese84_sensor` method:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
sensor_data = session.generate_reese84_sensor(site="example.com", user_agent="your-user-agent")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Generating UTMVC Cookie
|
|
143
|
+
|
|
144
|
+
To generate the UTMVC cookie using the Hyper Solutions API, use the `generate_utmvc_cookie` method:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from hyper_sdk import UtmvcInput
|
|
148
|
+
|
|
149
|
+
utmvc_input = UtmvcInput(
|
|
150
|
+
user_agent="your-user-agent",
|
|
151
|
+
session_ids=["session-id-1", "session-id-2"],
|
|
152
|
+
script="your-script"
|
|
153
|
+
)
|
|
154
|
+
utmvc_cookie = session.generate_utmvc_cookie(utmvc_input)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Parsing UTMVC Script Path
|
|
158
|
+
|
|
159
|
+
To parse the UTMVC script path from a given script content, use the `parse_utmvc_script_path` function from the `utmvc` module:
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
from hyper_sdk.incapsula.utmvc import parse_utmvc_script_path
|
|
163
|
+
|
|
164
|
+
script_path = parse_utmvc_script_path(script_content)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Generating UTMVC Submit Path
|
|
168
|
+
|
|
169
|
+
To generate a unique UTMVC submit path with a random query parameter, use the `get_utmvc_submit_path` function from the `utmvc` module:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from hyper_sdk.incapsula.utmvc import get_utmvc_submit_path
|
|
173
|
+
|
|
174
|
+
submit_path = get_utmvc_submit_path()
|
|
175
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
pixel_html_expr = re.compile(r'bazadebezolkohpepadr="(\d+)"')
|
|
4
|
+
pixel_script_url_expr = re.compile(r'src="(https?://.+/akam/\d+/\w+)"')
|
|
5
|
+
pixel_script_var_expr = re.compile(r'g=_\[(\d+)]')
|
|
6
|
+
pixel_script_string_array_expr = re.compile(r'var _=\[(.+?)];')
|
|
7
|
+
pixel_script_strings_expr = re.compile(r'("[^",]*")')
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def parse_pixel_html_var(src: str) -> int:
|
|
11
|
+
"""
|
|
12
|
+
ParsePixelHtmlVar gets the required pixel challenge variable from the given HTML code src.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
src (str): HTML source code as a string.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
int: The parsed pixel HTML variable.
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
Exception: If the pixel HTML var is not found in the source.
|
|
22
|
+
"""
|
|
23
|
+
match = pixel_html_expr.search(src)
|
|
24
|
+
if match:
|
|
25
|
+
return int(match.group(1))
|
|
26
|
+
else:
|
|
27
|
+
raise Exception("hyper-sdk: pixel HTML var not found")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def parse_pixel_script_url(src: str) -> tuple[str, str]:
|
|
31
|
+
"""
|
|
32
|
+
ParsePixelScriptURL gets the script URL of the pixel challenge script and the URL
|
|
33
|
+
to post a generated payload to from the given HTML code src.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
src (str): HTML source code as a string.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
tuple[str, str]: A tuple containing the script URL and the post URL.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
Exception: If the script URL is not found in the source.
|
|
43
|
+
"""
|
|
44
|
+
match = pixel_script_url_expr.search(src)
|
|
45
|
+
if match:
|
|
46
|
+
script_url = match.group(1)
|
|
47
|
+
# Create post_url
|
|
48
|
+
parts = script_url.split("/")
|
|
49
|
+
parts[-1] = "pixel_" + parts[-1]
|
|
50
|
+
post_url = "/".join(parts)
|
|
51
|
+
return script_url, post_url
|
|
52
|
+
else:
|
|
53
|
+
raise Exception("hyper-sdk: script URL not found")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def parse_pixel_script_var(src: str) -> str:
|
|
57
|
+
"""
|
|
58
|
+
Gets the dynamic value from the pixel script.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
src (str): HTML source code as a string.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
str: The dynamic value extracted from the pixel script.
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
Exception: If the script variable is not found or if there are issues extracting it.
|
|
68
|
+
"""
|
|
69
|
+
index_match = pixel_script_var_expr.search(src)
|
|
70
|
+
if not index_match:
|
|
71
|
+
raise Exception("hyper-sdk: script var not found")
|
|
72
|
+
string_index = int(index_match.group(1))
|
|
73
|
+
|
|
74
|
+
array_declaration_match = pixel_script_string_array_expr.search(src)
|
|
75
|
+
if not array_declaration_match:
|
|
76
|
+
raise Exception("hyper-sdk: script var not found")
|
|
77
|
+
|
|
78
|
+
raw_strings = pixel_script_strings_expr.findall(array_declaration_match.group(1))
|
|
79
|
+
if string_index >= len(raw_strings):
|
|
80
|
+
raise Exception("hyper-sdk: script var not found")
|
|
81
|
+
|
|
82
|
+
string_value = raw_strings[string_index].strip('"')
|
|
83
|
+
return string_value
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
# Precompiled regular expressions
|
|
4
|
+
script_path_expr = re.compile(r'<script type="text/javascript"\s+(?:nonce=".*?")?\s+src="([a-z\d/\-_]+)"></script>',
|
|
5
|
+
re.IGNORECASE)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def parse_script_path(src: str) -> str:
|
|
9
|
+
"""
|
|
10
|
+
Gets the Akamai Bot Manager web SDK path from the given HTML code src.
|
|
11
|
+
|
|
12
|
+
This function searches the provided HTML source code for the path of a JavaScript script tag that matches the
|
|
13
|
+
specified regular expression pattern.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
src (str): The HTML source code as a string.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
str: The path of the script extracted from the script tag.
|
|
20
|
+
|
|
21
|
+
Raises:
|
|
22
|
+
Exception: If the script path is not found in the source.
|
|
23
|
+
"""
|
|
24
|
+
match = script_path_expr.search(src)
|
|
25
|
+
if match:
|
|
26
|
+
return match.group(1)
|
|
27
|
+
else:
|
|
28
|
+
raise "hyper-sdk: script path not found"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import hashlib
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
from collections import OrderedDict
|
|
7
|
+
from typing import List
|
|
8
|
+
|
|
9
|
+
sec_duration_expr = re.compile(r'data-duration=(\d+)')
|
|
10
|
+
sec_challenge_expr = re.compile(r'challenge="(.*?)"')
|
|
11
|
+
sec_page_expr = re.compile(r'src="(/_sec/cp_challenge/ak-challenge-\d+-\d+.htm)"')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SecCptChallengeData:
|
|
15
|
+
def __init__(self, token: str, timestamp: int, nonce: str, difficulty: int):
|
|
16
|
+
self.token = token
|
|
17
|
+
self.timestamp = timestamp
|
|
18
|
+
self.nonce = nonce
|
|
19
|
+
self.difficulty = difficulty
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SecCptChallenge:
|
|
23
|
+
def __init__(self, duration: int, challenge_path: str, challenge_data: SecCptChallengeData):
|
|
24
|
+
self.duration = duration
|
|
25
|
+
self.challenge_path = challenge_path
|
|
26
|
+
self.challenge_data = challenge_data
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def parse(html: str) -> 'SecCptChallenge':
|
|
30
|
+
challenge_data = SecCptChallenge._parse_challenge_data(html)
|
|
31
|
+
duration = SecCptChallenge._parse_duration(html)
|
|
32
|
+
challenge_path = SecCptChallenge._parse_challenge_path(html)
|
|
33
|
+
|
|
34
|
+
return SecCptChallenge(duration, challenge_path, challenge_data)
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def _parse_challenge_data(src: str) -> SecCptChallengeData:
|
|
38
|
+
challenge_match = sec_challenge_expr.search(src)
|
|
39
|
+
if not challenge_match:
|
|
40
|
+
raise Exception("hyper-sdk: Challenge data not found.")
|
|
41
|
+
|
|
42
|
+
decoded_challenge = base64.b64decode(challenge_match.group(1))
|
|
43
|
+
challenge_data = json.loads(decoded_challenge)
|
|
44
|
+
|
|
45
|
+
return SecCptChallengeData(
|
|
46
|
+
challenge_data.get('token', ''),
|
|
47
|
+
challenge_data.get('timestamp', 0),
|
|
48
|
+
challenge_data.get('nonce', ''),
|
|
49
|
+
challenge_data.get('difficulty', 0)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def _parse_duration(src: str) -> int:
|
|
54
|
+
duration_match = sec_duration_expr.search(src)
|
|
55
|
+
if not duration_match:
|
|
56
|
+
raise Exception("hyper-sdk: Duration not found.")
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
duration = int(duration_match.group(1))
|
|
60
|
+
except ValueError as e:
|
|
61
|
+
raise Exception(f"hyper-sdk: Invalid duration value: {e}")
|
|
62
|
+
|
|
63
|
+
return duration
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def _parse_challenge_path(src: str) -> str:
|
|
67
|
+
page_match = sec_page_expr.search(src)
|
|
68
|
+
if not page_match:
|
|
69
|
+
raise Exception("hyper-sdk: Challenge path not found.")
|
|
70
|
+
|
|
71
|
+
return page_match.group(1)
|
|
72
|
+
|
|
73
|
+
def generate_sec_cpt_payload(self, sec_cpt_cookie: str) -> str:
|
|
74
|
+
sec, _, _ = sec_cpt_cookie.partition("~")
|
|
75
|
+
|
|
76
|
+
answers = self._generate_sec_cpt_answers(sec)
|
|
77
|
+
|
|
78
|
+
payload = OrderedDict([
|
|
79
|
+
("token", self.challenge_data.token),
|
|
80
|
+
("answers", answers)
|
|
81
|
+
])
|
|
82
|
+
|
|
83
|
+
return json.dumps(payload)
|
|
84
|
+
|
|
85
|
+
def update_sec_cpt_challenge_data(self, response_body: str):
|
|
86
|
+
challenge_data = json.loads(response_body)
|
|
87
|
+
self.challenge_data = SecCptChallengeData(
|
|
88
|
+
challenge_data.get('token', ''),
|
|
89
|
+
challenge_data.get('timestamp', 0),
|
|
90
|
+
challenge_data.get('nonce', ''),
|
|
91
|
+
challenge_data.get('difficulty', 0)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def _generate_sec_cpt_answers(self, sec: str) -> List[str]:
|
|
95
|
+
answers = []
|
|
96
|
+
difficulty = self.challenge_data.difficulty
|
|
97
|
+
|
|
98
|
+
while True:
|
|
99
|
+
answer = f"0.{os.urandom(8).hex()}"
|
|
100
|
+
hash_input = f"{sec}{self.challenge_data.timestamp}{self.challenge_data.nonce}{difficulty}{answer}"
|
|
101
|
+
|
|
102
|
+
output = 0
|
|
103
|
+
for byte in hashlib.sha256(hash_input.encode('ascii')).digest():
|
|
104
|
+
output = (output << 8) | byte
|
|
105
|
+
output %= difficulty
|
|
106
|
+
|
|
107
|
+
if output == 0:
|
|
108
|
+
difficulty += 1
|
|
109
|
+
answers.append(answer)
|
|
110
|
+
|
|
111
|
+
if len(answers) == 10:
|
|
112
|
+
break
|
|
113
|
+
continue
|
|
114
|
+
|
|
115
|
+
return answers
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
def is_cookie_valid(cookie: str, request_count: int) -> bool:
|
|
2
|
+
"""
|
|
3
|
+
Determines if the provided _abck cookie value is valid, based on Akamai Bot Manager's
|
|
4
|
+
client-side stop signal mechanism using the given request count. If the result is true, the client is ADVISED
|
|
5
|
+
to halt further sensor data submissions. Submitting further would still produce a valid cookie but is unnecessary.
|
|
6
|
+
|
|
7
|
+
The stop signal mechanism in the Akamai Bot Manager's client-side script informs a client that the cookie received is
|
|
8
|
+
valid and that any additional submissions are superfluous.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
cookie (str): The _abck cookie value.
|
|
12
|
+
request_count (int): The number of requests made.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
bool: True if the cookie is valid, False otherwise.
|
|
16
|
+
"""
|
|
17
|
+
parts = cookie.split("~")
|
|
18
|
+
if len(parts) < 2:
|
|
19
|
+
return False
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
request_threshold = int(parts[1])
|
|
23
|
+
except ValueError:
|
|
24
|
+
request_threshold = -1
|
|
25
|
+
|
|
26
|
+
return request_threshold != -1 and request_count >= request_threshold
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_cookie_invalidated(cookie: str) -> bool:
|
|
30
|
+
"""
|
|
31
|
+
Determines if the current session requires more sensors to be sent.
|
|
32
|
+
|
|
33
|
+
Protected endpoints can invalidate a session by setting a new _abck cookie that ends in '~0~-1~-1' or similar.
|
|
34
|
+
This function returns if such an invalidated cookie is present, if it is present you should be able to make the
|
|
35
|
+
cookie valid again with only 1 sensor post.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
cookie (str): The _abck cookie value.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
bool: True if the cookie has been invalidated, False otherwise.
|
|
42
|
+
"""
|
|
43
|
+
parts = cookie.split("~")
|
|
44
|
+
if len(parts) < 4:
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
signal = int(parts[3])
|
|
49
|
+
except ValueError:
|
|
50
|
+
signal = -1
|
|
51
|
+
|
|
52
|
+
return signal > -1
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class SensorInput:
|
|
2
|
+
def __init__(self, abck: str, bmsz: str, version: str, page_url: str, user_agent: str, script_hash=""):
|
|
3
|
+
self.abck = abck
|
|
4
|
+
self.bmsz = bmsz
|
|
5
|
+
self.version = version
|
|
6
|
+
self.page_url = page_url
|
|
7
|
+
self.user_agent = user_agent
|
|
8
|
+
self.script_hash = script_hash
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PixelInput:
|
|
12
|
+
def __init__(self, user_agent: str, html_var: str, script_var: str):
|
|
13
|
+
self.user_agent = user_agent
|
|
14
|
+
self.html_var = html_var
|
|
15
|
+
self.script_var = script_var
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .utmvc import *
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
# Precompiled regular expressions
|
|
5
|
+
script_regex = re.compile(r'src="(/_Incapsula_Resource\?[^"]*)"')
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def parse_utmvc_script_path(script_content: str) -> str:
|
|
9
|
+
"""
|
|
10
|
+
Parses the UTMVC script path from the given script content.
|
|
11
|
+
|
|
12
|
+
This function searches the provided script content for a specific pattern matching the UTMVC script path
|
|
13
|
+
using a precompiled regular expression. It extracts and returns the first match if found.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
script_content (str): The content of the script from which the UTMVC script path is to be extracted.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
str: The extracted UTMVC script path.
|
|
20
|
+
|
|
21
|
+
Raises:
|
|
22
|
+
Exception: If the UTMVC script path is not found in the script content.
|
|
23
|
+
"""
|
|
24
|
+
match = script_regex.search(script_content)
|
|
25
|
+
if match:
|
|
26
|
+
return match.group(1)
|
|
27
|
+
else:
|
|
28
|
+
raise Exception("hyper-sdk: utmvc script not found")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_utmvc_submit_path() -> str:
|
|
32
|
+
"""
|
|
33
|
+
Generates a UTMVC submit path with a unique random query parameter.
|
|
34
|
+
|
|
35
|
+
This function constructs a submit path for the UTMVC script by appending a random floating-point number as a query
|
|
36
|
+
parameter. The random number is used to ensure uniqueness of the request.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
str: A unique UTMVC submit path.
|
|
40
|
+
"""
|
|
41
|
+
random_float = random.random()
|
|
42
|
+
return f"/_Incapsula_Resource?SWKMTFSR=1&e={random_float:g}"
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from typing import Optional, Dict, Any
|
|
2
|
+
from urllib.parse import quote
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
import jwt
|
|
6
|
+
from datetime import datetime, timedelta, timezone
|
|
7
|
+
|
|
8
|
+
from .akamai_input import SensorInput, PixelInput
|
|
9
|
+
from .incapsula_input import UtmvcInput
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Session:
|
|
13
|
+
def __init__(self, api_key: str, jwt_key: Optional[str] = None, client: Optional[requests.Session] = None) -> None:
|
|
14
|
+
self.api_key = api_key
|
|
15
|
+
self.jwt_key = jwt_key
|
|
16
|
+
self.client = requests.Session() if client is None else client
|
|
17
|
+
|
|
18
|
+
def generate_sensor_data(self, input_data: SensorInput) -> str:
|
|
19
|
+
"""
|
|
20
|
+
Returns the sensor data required to generate valid akamai cookies using the Hyper Solutions API.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
input_data (SensorInput): An instance of SensorInput containing the necessary data for generating the sensor data.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
str: Sensor data as a string.
|
|
27
|
+
"""
|
|
28
|
+
sensor_endpoint = "https://akm.justhyped.dev/sensor"
|
|
29
|
+
return self._send_request(sensor_endpoint, {
|
|
30
|
+
'userAgent': input_data.user_agent,
|
|
31
|
+
'abck': input_data.abck,
|
|
32
|
+
'bmsz': input_data.bmsz,
|
|
33
|
+
'version': input_data.version,
|
|
34
|
+
'pageUrl': input_data.page_url,
|
|
35
|
+
'scriptHash': input_data.script_hash,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
def generate_pixel_data(self, input_data: PixelInput) -> str:
|
|
39
|
+
"""
|
|
40
|
+
Returns the pixel data using the Hyper Solutions API.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
session (Session): An instance of Session to handle the network request.
|
|
44
|
+
input_data (PixelInput): An instance of PixelInput containing the necessary data for generating the pixel data.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
str: Pixel data as a string.
|
|
48
|
+
"""
|
|
49
|
+
pixel_endpoint = "https://akm.justhyped.dev/pixel"
|
|
50
|
+
return self._send_request(pixel_endpoint, {
|
|
51
|
+
'userAgent': input_data.user_agent,
|
|
52
|
+
'htmlVar': input_data.html_var,
|
|
53
|
+
'scriptVar': input_data.script_var,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
def generate_reese84_sensor(self, site: str, user_agent: str) -> str:
|
|
57
|
+
"""
|
|
58
|
+
Returns the sensor data required to generate valid reese84 cookies using the Hyper Solutions API.
|
|
59
|
+
|
|
60
|
+
This function sends a request to the specified sensor endpoint with the necessary data to generate the reese84 sensor data.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
site (str): The name of the site that will be used to generate the sensor data.
|
|
64
|
+
user_agent (str): The user agent string used to generate the sensor data.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
str: Sensor data as a string.
|
|
68
|
+
|
|
69
|
+
Raises:
|
|
70
|
+
ValueError: If the script attribute in input_data is empty.
|
|
71
|
+
"""
|
|
72
|
+
return self._send_request("https://incapsula.justhyped.dev/reese84/" + quote(site),
|
|
73
|
+
{
|
|
74
|
+
'userAgent': user_agent,
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
def generate_utmvc_cookie(self, input_data: UtmvcInput) -> str:
|
|
78
|
+
"""
|
|
79
|
+
Returns the utmvc cookie using the Hyper Solutions API.
|
|
80
|
+
|
|
81
|
+
This function sends a request to the utmvc sensor endpoint with the necessary data to generate the utmvc cookie.
|
|
82
|
+
The input data must include a non-empty script and session IDs.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
session (Session): An instance of Session to handle the network request.
|
|
86
|
+
input_data (Input): An instance of Input containing the user agent, session IDs, and script.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
str: The utmvc cookie as a string.
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
ValueError: If the script attribute or session IDs in input_data are empty.
|
|
93
|
+
"""
|
|
94
|
+
if not input_data.script:
|
|
95
|
+
raise ValueError("script must be non empty")
|
|
96
|
+
|
|
97
|
+
if not input_data.session_ids:
|
|
98
|
+
raise ValueError("no session ids set")
|
|
99
|
+
|
|
100
|
+
return self._send_request("https://incapsula.justhyped.dev/utmvc", {
|
|
101
|
+
'userAgent': input_data.user_agent,
|
|
102
|
+
'sessionIds': input_data.session_ids,
|
|
103
|
+
'script': input_data.script,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
def generate_signature(self) -> str:
|
|
107
|
+
claims = {
|
|
108
|
+
"key": self.api_key,
|
|
109
|
+
"exp": datetime.now(timezone.utc) + timedelta(seconds=15)
|
|
110
|
+
}
|
|
111
|
+
token = jwt.encode(claims, self.jwt_key, algorithm='HS256')
|
|
112
|
+
return token.decode('utf-8')
|
|
113
|
+
|
|
114
|
+
def _send_request(self, url: str, input_data: Dict[str, Any]) -> str:
|
|
115
|
+
if not self.api_key:
|
|
116
|
+
raise ValueError("Missing API key")
|
|
117
|
+
|
|
118
|
+
headers = {
|
|
119
|
+
'Content-Type': 'application/json',
|
|
120
|
+
'Accept-Encoding': 'gzip',
|
|
121
|
+
'X-Api-Key': self.api_key
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if self.jwt_key:
|
|
125
|
+
signature = self.generate_signature()
|
|
126
|
+
headers['X-Signature'] = signature
|
|
127
|
+
|
|
128
|
+
response = self.client.post(url, headers=headers, json=input_data)
|
|
129
|
+
|
|
130
|
+
response_data = response.json()
|
|
131
|
+
|
|
132
|
+
if "error" in response_data and response_data["error"]:
|
|
133
|
+
raise Exception(f"API returned with error: {response_data['error']}")
|
|
134
|
+
|
|
135
|
+
if response.status_code != 200:
|
|
136
|
+
raise Exception(f"API returned with status code: {response.status_code}")
|
|
137
|
+
|
|
138
|
+
return response_data["payload"]
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: hyper_sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Hyper Solutions Python SDK
|
|
5
|
+
Project-URL: homepage, https://github.com/Hyper-Solutions/hyper-sdk-py
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Requires-Python: >=3.6
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: certifi==2024.2.2
|
|
13
|
+
Requires-Dist: charset-normalizer==3.3.2
|
|
14
|
+
Requires-Dist: idna==3.6
|
|
15
|
+
Requires-Dist: jsonpickle==3.0.3
|
|
16
|
+
Requires-Dist: PyJWT==2.8.0
|
|
17
|
+
Requires-Dist: requests==2.31.0
|
|
18
|
+
Requires-Dist: urllib3==2.2.1
|
|
19
|
+
|
|
20
|
+
# Hyper Solutions SDK for Python
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
To use the Hyper Solutions SDK in your Python project, you need to install it using the following command:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pip install hyper-sdk
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Creating a Session
|
|
33
|
+
|
|
34
|
+
To start using the SDK, you need to create a new `Session` instance by providing your API key:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from hyper_sdk import Session
|
|
38
|
+
|
|
39
|
+
session = Session(api_key="your-api-key")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You can also optionally set a JWT key and a custom HTTP client:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from hyper_sdk import Session
|
|
46
|
+
|
|
47
|
+
session = Session(api_key="your-api-key", jwt_key="your-jwt-key", client=custom_http_client)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Akamai
|
|
51
|
+
|
|
52
|
+
The Akamai package provides functions for interacting with Akamai Bot Manager, including generating sensor data, parsing script path, parsing pixel challenges, and handling sec-cpt challenges.
|
|
53
|
+
|
|
54
|
+
### Generating Sensor Data
|
|
55
|
+
|
|
56
|
+
To generate sensor data required for generating valid Akamai cookies, use the `generate_sensor_data` method:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from hyper_sdk import SensorInput
|
|
60
|
+
|
|
61
|
+
sensor_input = SensorInput(
|
|
62
|
+
page_url="https://example.com/",
|
|
63
|
+
user_agent="your-user-agent",
|
|
64
|
+
abck="your-abck-cookie",
|
|
65
|
+
bmsz="your-bmsz-cookie",
|
|
66
|
+
version="2.0"
|
|
67
|
+
)
|
|
68
|
+
sensor_data = session.generate_sensor_data(sensor_input)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Parsing Script Path
|
|
72
|
+
|
|
73
|
+
To parse the Akamai Bot Manager script path from the given HTML code, use the `parse_script_path` function from the `script_path` module:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from hyper_sdk.akamai.script_path import parse_script_path
|
|
77
|
+
|
|
78
|
+
script_path = parse_script_path(html_source)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Handling Sec-Cpt Challenges
|
|
82
|
+
|
|
83
|
+
The Akamai package provides functions for handling sec-cpt challenges:
|
|
84
|
+
|
|
85
|
+
- `SecCptChallenge.parse`: Parses a sec-cpt challenge from an HTML source.
|
|
86
|
+
- `generate_sec_cpt_payload`: Generates a sec-cpt payload using the provided sec-cpt cookie.
|
|
87
|
+
- `update_sec_cpt_challenge_data`: Updates the challenge data of a `SecCptChallenge` instance from a response body.
|
|
88
|
+
|
|
89
|
+
Example usage:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from hyper_sdk.akamai.sec_cpt import SecCptChallenge
|
|
93
|
+
|
|
94
|
+
challenge = SecCptChallenge.parse(html_source)
|
|
95
|
+
payload = challenge.generate_sec_cpt_payload(sec_cpt_cookie)
|
|
96
|
+
challenge.update_sec_cpt_challenge_data(response_body)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Validating Cookies
|
|
100
|
+
|
|
101
|
+
The Akamai package provides functions for validating cookies:
|
|
102
|
+
|
|
103
|
+
- `is_cookie_valid`: Determines if the provided `_abck` cookie value is valid based on the given request count.
|
|
104
|
+
- `is_cookie_invalidated`: Determines if the current session requires more sensors to be sent.
|
|
105
|
+
|
|
106
|
+
Example usage:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from hyper_sdk.akamai.stop_signal import is_cookie_valid, is_cookie_invalidated
|
|
110
|
+
|
|
111
|
+
is_valid = is_cookie_valid(abck_cookie, request_count)
|
|
112
|
+
is_invalidated = is_cookie_invalidated(abck_cookie)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Generating Pixel Data
|
|
116
|
+
|
|
117
|
+
To generate pixel data, use the `generate_pixel_data` method:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from hyper_sdk import PixelInput
|
|
121
|
+
|
|
122
|
+
pixel_input = PixelInput(
|
|
123
|
+
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
|
|
124
|
+
html_var="your-html-var",
|
|
125
|
+
script_var="your-script-var"
|
|
126
|
+
)
|
|
127
|
+
pixel_data = session.generate_pixel_data(pixel_input)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Parsing Pixel Challenges
|
|
131
|
+
|
|
132
|
+
The Akamai package provides functions for parsing pixel challenges:
|
|
133
|
+
|
|
134
|
+
- `parse_pixel_html_var`: Parses the required pixel challenge variable from the given HTML code.
|
|
135
|
+
- `parse_pixel_script_url`: Parses the script URL of the pixel challenge script and the URL to post a generated payload to from the given HTML code.
|
|
136
|
+
- `parse_pixel_script_var`: Parses the dynamic value from the pixel script.
|
|
137
|
+
|
|
138
|
+
Example usage:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from hyper_sdk.akamai.pixel import parse_pixel_html_var, parse_pixel_script_url, parse_pixel_script_var
|
|
142
|
+
|
|
143
|
+
html_var = parse_pixel_html_var(html_source)
|
|
144
|
+
script_url, post_url = parse_pixel_script_url(html_source)
|
|
145
|
+
script_var = parse_pixel_script_var(script_source)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
## Incapsula
|
|
150
|
+
|
|
151
|
+
The Incapsula package provides functions for interacting with Imperva Incapsula, including generating Reese84 sensor data, UTMVC cookies, and parsing UTMVC script paths.
|
|
152
|
+
|
|
153
|
+
### Generating Reese84 Sensor
|
|
154
|
+
|
|
155
|
+
To generate sensor data required for generating valid Reese84 cookies, use the `generate_reese84_sensor` method:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
sensor_data = session.generate_reese84_sensor(site="example.com", user_agent="your-user-agent")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Generating UTMVC Cookie
|
|
162
|
+
|
|
163
|
+
To generate the UTMVC cookie using the Hyper Solutions API, use the `generate_utmvc_cookie` method:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from hyper_sdk import UtmvcInput
|
|
167
|
+
|
|
168
|
+
utmvc_input = UtmvcInput(
|
|
169
|
+
user_agent="your-user-agent",
|
|
170
|
+
session_ids=["session-id-1", "session-id-2"],
|
|
171
|
+
script="your-script"
|
|
172
|
+
)
|
|
173
|
+
utmvc_cookie = session.generate_utmvc_cookie(utmvc_input)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Parsing UTMVC Script Path
|
|
177
|
+
|
|
178
|
+
To parse the UTMVC script path from a given script content, use the `parse_utmvc_script_path` function from the `utmvc` module:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from hyper_sdk.incapsula.utmvc import parse_utmvc_script_path
|
|
182
|
+
|
|
183
|
+
script_path = parse_utmvc_script_path(script_content)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Generating UTMVC Submit Path
|
|
187
|
+
|
|
188
|
+
To generate a unique UTMVC submit path with a random query parameter, use the `get_utmvc_submit_path` function from the `utmvc` module:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
from hyper_sdk.incapsula.utmvc import get_utmvc_submit_path
|
|
192
|
+
|
|
193
|
+
submit_path = get_utmvc_submit_path()
|
|
194
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
hyper_sdk/__init__.py
|
|
5
|
+
hyper_sdk/akamai_input.py
|
|
6
|
+
hyper_sdk/incapsula_input.py
|
|
7
|
+
hyper_sdk/session.py
|
|
8
|
+
hyper_sdk.egg-info/PKG-INFO
|
|
9
|
+
hyper_sdk.egg-info/SOURCES.txt
|
|
10
|
+
hyper_sdk.egg-info/dependency_links.txt
|
|
11
|
+
hyper_sdk.egg-info/requires.txt
|
|
12
|
+
hyper_sdk.egg-info/top_level.txt
|
|
13
|
+
hyper_sdk/akamai/__init__.py
|
|
14
|
+
hyper_sdk/akamai/pixel.py
|
|
15
|
+
hyper_sdk/akamai/script_path.py
|
|
16
|
+
hyper_sdk/akamai/sec_cpt.py
|
|
17
|
+
hyper_sdk/akamai/stop_signal.py
|
|
18
|
+
hyper_sdk/incapsula/__init__.py
|
|
19
|
+
hyper_sdk/incapsula/utmvc.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hyper_sdk
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hyper_sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Hyper Solutions Python SDK"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.6"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"certifi==2024.2.2",
|
|
18
|
+
"charset-normalizer==3.3.2",
|
|
19
|
+
"idna==3.6",
|
|
20
|
+
"jsonpickle==3.0.3",
|
|
21
|
+
"PyJWT==2.8.0",
|
|
22
|
+
"requests==2.31.0",
|
|
23
|
+
"urllib3==2.2.1",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
homepage = "https://github.com/Hyper-Solutions/hyper-sdk-py"
|
|
28
|
+
|
|
29
|
+
[tool.setuptools]
|
|
30
|
+
packages = ["hyper_sdk", "hyper_sdk.akamai", "hyper_sdk.incapsula"]
|