hyper-sdk 2.11.0__tar.gz → 2.11.1__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-2.11.0 → hyper_sdk-2.11.1}/PKG-INFO +1 -2
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/session.py +14 -20
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/session_async.py +14 -20
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk.egg-info/PKG-INFO +1 -2
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk.egg-info/requires.txt +0 -1
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/pyproject.toml +2 -3
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/LICENSE +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/README.md +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/__init__.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai/__init__.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai/pixel.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai/script_path.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai/sec_cpt.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai/stop_signal.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/akamai_input.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/datadome/__init__.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/datadome/parse.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/datadome_input.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/incapsula/__init__.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/incapsula/dynamic.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/incapsula/utmvc.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/incapsula_input.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/kasada/__init__.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/kasada/parse.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/kasada_input.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/shared.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk/trustdecision_input.py +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk.egg-info/SOURCES.txt +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk.egg-info/dependency_links.txt +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/hyper_sdk.egg-info/top_level.txt +0 -0
- {hyper_sdk-2.11.0 → hyper_sdk-2.11.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyper_sdk
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.1
|
|
4
4
|
Summary: Hyper Solutions Python SDK
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -39,7 +39,6 @@ Requires-Dist: idna>=3.6
|
|
|
39
39
|
Requires-Dist: jsonpickle>=3.0.3
|
|
40
40
|
Requires-Dist: PyJWT>=2.8.0
|
|
41
41
|
Requires-Dist: urllib3>=2.2.1
|
|
42
|
-
Requires-Dist: zstandard>=0.24.0
|
|
43
42
|
Dynamic: license-file
|
|
44
43
|
|
|
45
44
|
# Hyper Solutions SDK - Python Library for Bot Protection Bypass (Akamai, Incapsula, Kasada, DataDome)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"""Session class for Hyper Solutions API."""
|
|
2
2
|
|
|
3
3
|
from typing import Optional, Dict, Any, Tuple
|
|
4
|
-
from urllib.parse import quote
|
|
5
4
|
import httpx
|
|
6
5
|
import json
|
|
7
|
-
import
|
|
6
|
+
import gzip
|
|
8
7
|
|
|
9
8
|
from .shared import generate_signature, build_headers, validate_response
|
|
10
9
|
from .akamai_input import SensorInput, PixelInput, SbsdInput
|
|
@@ -24,12 +23,7 @@ class Session:
|
|
|
24
23
|
self.app_secret = app_secret
|
|
25
24
|
self.client = httpx.Client() if client is None else client
|
|
26
25
|
self._owns_client = client is None
|
|
27
|
-
self.compression = compression
|
|
28
|
-
|
|
29
|
-
# Initialize zstd compressor and decompressor if available
|
|
30
|
-
if self.compression:
|
|
31
|
-
self._compressor = zstd.ZstdCompressor(level=3)
|
|
32
|
-
self._decompressor = zstd.ZstdDecompressor()
|
|
26
|
+
self.compression = compression
|
|
33
27
|
|
|
34
28
|
def __enter__(self):
|
|
35
29
|
return self
|
|
@@ -74,7 +68,7 @@ class Session:
|
|
|
74
68
|
# Compress payload if large enough
|
|
75
69
|
payload, use_compression = self._compress_payload(payload)
|
|
76
70
|
if use_compression:
|
|
77
|
-
headers["content-encoding"] = "
|
|
71
|
+
headers["content-encoding"] = "gzip"
|
|
78
72
|
|
|
79
73
|
response = self.client.post(sensor_endpoint, headers=headers, content=payload)
|
|
80
74
|
|
|
@@ -179,7 +173,7 @@ class Session:
|
|
|
179
173
|
# Compress payload if large enough
|
|
180
174
|
payload, use_compression = self._compress_payload(payload)
|
|
181
175
|
if use_compression:
|
|
182
|
-
headers["content-encoding"] = "
|
|
176
|
+
headers["content-encoding"] = "gzip"
|
|
183
177
|
|
|
184
178
|
response = self.client.post("https://incapsula.hypersolutions.co/utmvc", headers=headers, content=payload)
|
|
185
179
|
|
|
@@ -221,7 +215,7 @@ class Session:
|
|
|
221
215
|
# Compress payload if large enough
|
|
222
216
|
payload, use_compression = self._compress_payload(payload)
|
|
223
217
|
if use_compression:
|
|
224
|
-
headers["content-encoding"] = "
|
|
218
|
+
headers["content-encoding"] = "gzip"
|
|
225
219
|
|
|
226
220
|
response = self.client.post("https://kasada.hypersolutions.co/payload", headers=headers, content=payload)
|
|
227
221
|
|
|
@@ -300,7 +294,7 @@ class Session:
|
|
|
300
294
|
# Compress payload if large enough
|
|
301
295
|
payload, use_compression = self._compress_payload(payload)
|
|
302
296
|
if use_compression:
|
|
303
|
-
headers["content-encoding"] = "
|
|
297
|
+
headers["content-encoding"] = "gzip"
|
|
304
298
|
|
|
305
299
|
response = self.client.post("https://trustdecision.hypersolutions.co/payload", headers=headers, content=payload)
|
|
306
300
|
|
|
@@ -366,12 +360,12 @@ class Session:
|
|
|
366
360
|
headers = build_headers(self.api_key, self.jwt_key, self.app_key, self.app_secret)
|
|
367
361
|
# Add compression headers
|
|
368
362
|
if self.compression:
|
|
369
|
-
headers["accept-encoding"] = "
|
|
363
|
+
headers["accept-encoding"] = "gzip"
|
|
370
364
|
return headers
|
|
371
365
|
|
|
372
366
|
def _compress_payload(self, payload: bytes) -> Tuple[bytes, bool]:
|
|
373
367
|
"""
|
|
374
|
-
Compresses the payload using
|
|
368
|
+
Compresses the payload using gzip if enabled and payload is large enough.
|
|
375
369
|
|
|
376
370
|
Args:
|
|
377
371
|
payload (bytes): The payload to potentially compress
|
|
@@ -383,7 +377,7 @@ class Session:
|
|
|
383
377
|
return payload, False
|
|
384
378
|
|
|
385
379
|
try:
|
|
386
|
-
compressed =
|
|
380
|
+
compressed = gzip.compress(payload, compresslevel=6)
|
|
387
381
|
return compressed, True
|
|
388
382
|
except Exception:
|
|
389
383
|
# Fall back to uncompressed if compression fails
|
|
@@ -391,7 +385,7 @@ class Session:
|
|
|
391
385
|
|
|
392
386
|
def _decompress_response(self, response: httpx.Response) -> bytes:
|
|
393
387
|
"""
|
|
394
|
-
Decompresses the response body if it's compressed with
|
|
388
|
+
Decompresses the response body if it's compressed with gzip.
|
|
395
389
|
|
|
396
390
|
Args:
|
|
397
391
|
response (httpx.Response): The HTTP response
|
|
@@ -402,9 +396,9 @@ class Session:
|
|
|
402
396
|
content = response.content
|
|
403
397
|
content_encoding = response.headers.get("content-encoding", "").lower()
|
|
404
398
|
|
|
405
|
-
if content_encoding == "
|
|
399
|
+
if content_encoding == "gzip" and self.compression:
|
|
406
400
|
try:
|
|
407
|
-
return
|
|
401
|
+
return gzip.decompress(content)
|
|
408
402
|
except Exception:
|
|
409
403
|
# Fall back to original content if decompression fails
|
|
410
404
|
pass
|
|
@@ -428,7 +422,7 @@ class Session:
|
|
|
428
422
|
# Compress payload if large enough
|
|
429
423
|
payload, use_compression = self._compress_payload(payload)
|
|
430
424
|
if use_compression:
|
|
431
|
-
headers["content-encoding"] = "
|
|
425
|
+
headers["content-encoding"] = "gzip"
|
|
432
426
|
|
|
433
427
|
response = self.client.post(url, headers=headers, content=payload)
|
|
434
428
|
|
|
@@ -455,7 +449,7 @@ class Session:
|
|
|
455
449
|
# Compress payload if large enough
|
|
456
450
|
payload, use_compression = self._compress_payload(payload)
|
|
457
451
|
if use_compression:
|
|
458
|
-
headers["content-encoding"] = "
|
|
452
|
+
headers["content-encoding"] = "gzip"
|
|
459
453
|
|
|
460
454
|
response = self.client.post(url, headers=headers, content=payload)
|
|
461
455
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"""Async version of the Session class for Hyper Solutions API."""
|
|
2
2
|
|
|
3
3
|
from typing import Optional, Dict, Any, Tuple
|
|
4
|
-
from urllib.parse import quote
|
|
5
4
|
import httpx
|
|
6
5
|
import json
|
|
7
|
-
import
|
|
6
|
+
import gzip
|
|
8
7
|
|
|
9
8
|
from .shared import generate_signature, build_headers, validate_response
|
|
10
9
|
from .akamai_input import SensorInput, PixelInput, SbsdInput
|
|
@@ -24,12 +23,7 @@ class SessionAsync:
|
|
|
24
23
|
self.app_secret = app_secret
|
|
25
24
|
self.client = client
|
|
26
25
|
self._owns_client = client is None
|
|
27
|
-
self.compression = compression
|
|
28
|
-
|
|
29
|
-
# Initialize zstd compressor and decompressor if available
|
|
30
|
-
if self.compression:
|
|
31
|
-
self._compressor = zstd.ZstdCompressor(level=3)
|
|
32
|
-
self._decompressor = zstd.ZstdDecompressor()
|
|
26
|
+
self.compression = compression
|
|
33
27
|
|
|
34
28
|
async def __aenter__(self):
|
|
35
29
|
if self._owns_client:
|
|
@@ -78,7 +72,7 @@ class SessionAsync:
|
|
|
78
72
|
# Compress payload if large enough
|
|
79
73
|
payload, use_compression = self._compress_payload(payload)
|
|
80
74
|
if use_compression:
|
|
81
|
-
headers["content-encoding"] = "
|
|
75
|
+
headers["content-encoding"] = "gzip"
|
|
82
76
|
|
|
83
77
|
response = await self.client.post(sensor_endpoint, headers=headers, content=payload)
|
|
84
78
|
|
|
@@ -184,7 +178,7 @@ class SessionAsync:
|
|
|
184
178
|
# Compress payload if large enough
|
|
185
179
|
payload, use_compression = self._compress_payload(payload)
|
|
186
180
|
if use_compression:
|
|
187
|
-
headers["content-encoding"] = "
|
|
181
|
+
headers["content-encoding"] = "gzip"
|
|
188
182
|
|
|
189
183
|
response = await self.client.post("https://incapsula.hypersolutions.co/utmvc", headers=headers, content=payload)
|
|
190
184
|
|
|
@@ -227,7 +221,7 @@ class SessionAsync:
|
|
|
227
221
|
# Compress payload if large enough
|
|
228
222
|
payload, use_compression = self._compress_payload(payload)
|
|
229
223
|
if use_compression:
|
|
230
|
-
headers["content-encoding"] = "
|
|
224
|
+
headers["content-encoding"] = "gzip"
|
|
231
225
|
|
|
232
226
|
response = await self.client.post("https://kasada.hypersolutions.co/payload", headers=headers, content=payload)
|
|
233
227
|
|
|
@@ -309,7 +303,7 @@ class SessionAsync:
|
|
|
309
303
|
# Compress payload if large enough
|
|
310
304
|
payload, use_compression = self._compress_payload(payload)
|
|
311
305
|
if use_compression:
|
|
312
|
-
headers["content-encoding"] = "
|
|
306
|
+
headers["content-encoding"] = "gzip"
|
|
313
307
|
|
|
314
308
|
response = await self.client.post("https://trustdecision.hypersolutions.co/payload", headers=headers, content=payload)
|
|
315
309
|
|
|
@@ -375,12 +369,12 @@ class SessionAsync:
|
|
|
375
369
|
headers = build_headers(self.api_key, self.jwt_key, self.app_key, self.app_secret)
|
|
376
370
|
# Add compression headers
|
|
377
371
|
if self.compression:
|
|
378
|
-
headers["accept-encoding"] = "
|
|
372
|
+
headers["accept-encoding"] = "gzip"
|
|
379
373
|
return headers
|
|
380
374
|
|
|
381
375
|
def _compress_payload(self, payload: bytes) -> Tuple[bytes, bool]:
|
|
382
376
|
"""
|
|
383
|
-
Compresses the payload using
|
|
377
|
+
Compresses the payload using gzip if enabled and payload is large enough.
|
|
384
378
|
|
|
385
379
|
Args:
|
|
386
380
|
payload (bytes): The payload to potentially compress
|
|
@@ -392,7 +386,7 @@ class SessionAsync:
|
|
|
392
386
|
return payload, False
|
|
393
387
|
|
|
394
388
|
try:
|
|
395
|
-
compressed =
|
|
389
|
+
compressed = gzip.compress(payload, compresslevel=6)
|
|
396
390
|
return compressed, True
|
|
397
391
|
except Exception:
|
|
398
392
|
# Fall back to uncompressed if compression fails
|
|
@@ -400,7 +394,7 @@ class SessionAsync:
|
|
|
400
394
|
|
|
401
395
|
def _decompress_response(self, response: httpx.Response) -> bytes:
|
|
402
396
|
"""
|
|
403
|
-
Decompresses the response body if it's compressed with
|
|
397
|
+
Decompresses the response body if it's compressed with gzip.
|
|
404
398
|
|
|
405
399
|
Args:
|
|
406
400
|
response (httpx.Response): The HTTP response
|
|
@@ -411,9 +405,9 @@ class SessionAsync:
|
|
|
411
405
|
content = response.content
|
|
412
406
|
content_encoding = response.headers.get("content-encoding", "").lower()
|
|
413
407
|
|
|
414
|
-
if content_encoding == "
|
|
408
|
+
if content_encoding == "gzip" and self.compression:
|
|
415
409
|
try:
|
|
416
|
-
return
|
|
410
|
+
return gzip.decompress(content)
|
|
417
411
|
except Exception:
|
|
418
412
|
# Fall back to original content if decompression fails
|
|
419
413
|
pass
|
|
@@ -438,7 +432,7 @@ class SessionAsync:
|
|
|
438
432
|
# Compress payload if large enough
|
|
439
433
|
payload, use_compression = self._compress_payload(payload)
|
|
440
434
|
if use_compression:
|
|
441
|
-
headers["content-encoding"] = "
|
|
435
|
+
headers["content-encoding"] = "gzip"
|
|
442
436
|
|
|
443
437
|
response = await self.client.post(url, headers=headers, content=payload)
|
|
444
438
|
|
|
@@ -466,7 +460,7 @@ class SessionAsync:
|
|
|
466
460
|
# Compress payload if large enough
|
|
467
461
|
payload, use_compression = self._compress_payload(payload)
|
|
468
462
|
if use_compression:
|
|
469
|
-
headers["content-encoding"] = "
|
|
463
|
+
headers["content-encoding"] = "gzip"
|
|
470
464
|
|
|
471
465
|
response = await self.client.post(url, headers=headers, content=payload)
|
|
472
466
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyper_sdk
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.1
|
|
4
4
|
Summary: Hyper Solutions Python SDK
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -39,7 +39,6 @@ Requires-Dist: idna>=3.6
|
|
|
39
39
|
Requires-Dist: jsonpickle>=3.0.3
|
|
40
40
|
Requires-Dist: PyJWT>=2.8.0
|
|
41
41
|
Requires-Dist: urllib3>=2.2.1
|
|
42
|
-
Requires-Dist: zstandard>=0.24.0
|
|
43
42
|
Dynamic: license-file
|
|
44
43
|
|
|
45
44
|
# Hyper Solutions SDK - Python Library for Bot Protection Bypass (Akamai, Incapsula, Kasada, DataDome)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hyper_sdk"
|
|
7
|
-
version = "2.11.
|
|
7
|
+
version = "2.11.1"
|
|
8
8
|
description = "Hyper Solutions Python SDK"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.7"
|
|
@@ -21,8 +21,7 @@ dependencies = [
|
|
|
21
21
|
"idna>=3.6",
|
|
22
22
|
"jsonpickle>=3.0.3",
|
|
23
23
|
"PyJWT>=2.8.0",
|
|
24
|
-
"urllib3>=2.2.1"
|
|
25
|
-
"zstandard>=0.24.0"
|
|
24
|
+
"urllib3>=2.2.1"
|
|
26
25
|
]
|
|
27
26
|
license = {file = "LICENSE"}
|
|
28
27
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|