Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9530b67

Browse filesBrowse files
committed
Refactor imports, add tests, and clean up dependencies
- Replaced local `CaseInsensitiveDict` with `requests.structures.CaseInsensitiveDict` across multiple files - Added comprehensive test suite including: * Basic request tests (GET/POST) * Error handling tests * Session feature tests (cookies, headers, TLS) * Test configuration in `conftest.py` - Added `requests` as a dependency in `pyproject.toml` - Cleaned up `ClientIdentifiers` type formatting for better readability Cleanup notes: 1. The removal of `async_tls_client/structures.py` (commit 8283627) should have been part of this changeset since we're migrating to `requests.structures`. 2. The test-related `pyproject.toml` configuration (added in 9c38840) should have been included here instead, as it logically belongs with the new test suite. This change completes the transition away from internal structures while adding proper test coverage.
1 parent 9c38840 commit 9530b67
Copy full SHA for 9530b67

File tree

Expand file treeCollapse file tree

9 files changed

+125
-69
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+125
-69
lines changed

‎async_tls_client/cookies.py

Copy file name to clipboardExpand all lines: async_tls_client/cookies.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Any, MutableMapping, Union
55
from urllib.parse import urlparse, urlunparse
66

7-
from .structures import CaseInsensitiveDict
7+
from requests.structures import CaseInsensitiveDict
88

99
try:
1010
import threading

‎async_tls_client/response.py

Copy file name to clipboardExpand all lines: async_tls_client/response.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import json
33
from typing import Union
44

5+
from requests.structures import CaseInsensitiveDict
6+
57
from .cookies import RequestsCookieJar, cookiejar_from_dict
6-
from .structures import CaseInsensitiveDict
78

89

910
class Response:

‎async_tls_client/session/async_session.py

Copy file name to clipboardExpand all lines: async_tls_client/session/async_session.py
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
from json import dumps, loads
77
from typing import Any, Optional, Union
88

9+
from requests.structures import CaseInsensitiveDict
10+
911
from async_tls_client.cffi import destroySession, freeMemory, request
1012
from async_tls_client.cookies import cookiejar_from_dict, extract_cookies_to_jar, merge_cookies
1113
from async_tls_client.exceptions import TLSClientException
1214
from async_tls_client.response import Response, build_response
13-
from async_tls_client.structures import CaseInsensitiveDict
1415
from async_tls_client.types import ClientIdentifiers, Curves, DelegatedSignatureAlgorithms, H2Settings, \
1516
SignatureAlgorithms, \
1617
TLSVersions

‎async_tls_client/types.py

Copy file name to clipboardExpand all lines: async_tls_client/types.py
+41-66Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,78 +2,53 @@
22

33
ClientIdentifiers: TypeAlias = Literal[
44
# Chrome
5-
"chrome_103",
6-
"chrome_104",
7-
"chrome_105",
8-
"chrome_106",
9-
"chrome_107",
10-
"chrome_108",
11-
"chrome_109",
12-
"chrome_110",
13-
"chrome_111",
14-
"chrome_112",
15-
"chrome_116_PSK",
16-
"chrome_116_PSK_PQ",
17-
"chrome_117",
18-
"chrome_120",
19-
"chrome_124",
20-
"chrome_131",
21-
"chrome_131_PSK",
22-
"chrome_133",
23-
"chrome_133_PSK",
5+
"chrome_103", "chrome_104", "chrome_105", "chrome_106", "chrome_107",
6+
"chrome_108", "chrome_109", "chrome_110", "chrome_111", "chrome_112",
7+
"chrome_116_PSK", "chrome_116_PSK_PQ", "chrome_117", "chrome_120",
8+
"chrome_124", "chrome_131", "chrome_131_PSK", "chrome_133", "chrome_133_PSK",
249
# Safari
25-
"safari_15_6_1",
26-
"safari_16_0",
10+
"safari_15_6_1", "safari_16_0",
2711
# iOS (Safari)
28-
"safari_ios_15_5",
29-
"safari_ios_15_6",
30-
"safari_ios_16_0",
31-
"safari_ios_17_0",
32-
"safari_ios_18_0",
12+
"safari_ios_15_5", "safari_ios_15_6", "safari_ios_16_0", "safari_ios_17_0", "safari_ios_18_0",
3313
# iPadOS (Safari)
3414
"safari_ipad_15_6",
3515
# FireFox
36-
"firefox_102",
37-
"firefox_104",
38-
"firefox_105",
39-
"firefox_106",
40-
"firefox_108",
41-
"firefox_110",
42-
"firefox_117",
43-
"firefox_120",
44-
"firefox_123",
45-
"firefox_132",
46-
"firefox_133",
47-
"firefox_135",
16+
"firefox_102", "firefox_104", "firefox_105", "firefox_106", "firefox_108",
17+
"firefox_110", "firefox_117", "firefox_120", "firefox_123", "firefox_132",
18+
"firefox_133", "firefox_135",
4819
# Opera
49-
"opera_89",
50-
"opera_90",
51-
"opera_91",
20+
"opera_89", "opera_90", "opera_91",
5221
# OkHttp4
53-
"okhttp4_android_7",
54-
"okhttp4_android_8",
55-
"okhttp4_android_9",
56-
"okhttp4_android_10",
57-
"okhttp4_android_11",
58-
"okhttp4_android_12",
59-
"okhttp4_android_13",
22+
"okhttp4_android_7", "okhttp4_android_8", "okhttp4_android_9", "okhttp4_android_10",
23+
"okhttp4_android_11", "okhttp4_android_12", "okhttp4_android_13",
6024
# Custom
61-
"zalando_ios_mobile",
62-
"zalando_android_mobile",
63-
"nike_ios_mobile",
64-
"nike_android_mobile",
65-
"cloudscraper",
66-
"mms_ios",
67-
"mms_ios_1",
68-
"mms_ios_2",
69-
"mms_ios_3",
70-
"mesh_ios",
71-
"mesh_ios_1",
72-
"mesh_ios_2",
73-
"mesh_android",
74-
"mesh_android_1",
75-
"mesh_android_2",
76-
"confirmed_ios",
77-
"confirmed_android",
78-
"confirmed_android_2",
25+
"zalando_ios_mobile", "zalando_android_mobile", "nike_ios_mobile", "nike_android_mobile",
26+
"cloudscraper", "mms_ios", "mms_ios_1", "mms_ios_2", "mms_ios_3", "mesh_ios", "mesh_ios_1",
27+
"mesh_ios_2", "mesh_android", "mesh_android_1", "mesh_android_2", "confirmed_ios", "confirmed_android",
28+
"confirmed_android_2"
29+
]
30+
31+
# https://github.com/bogdanfinn/tls-client/blob/7a71edbf6e05acd4ade8e910e4c29c968003e27b/mapper.go#L29
32+
SignatureAlgorithms: TypeAlias = Literal[
33+
"PKCS1WithSHA256", "PKCS1WithSHA384", "PKCS1WithSHA512", "PSSWithSHA256", "PSSWithSHA384",
34+
"PSSWithSHA512", "ECDSAWithP256AndSHA256", "ECDSAWithP384AndSHA384", "ECDSAWithP521AndSHA512",
35+
"PKCS1WithSHA1", "ECDSAWithSHA1", "Ed25519", "SHA224_RSA", "SHA224_ECDSA"
36+
]
37+
38+
DelegatedSignatureAlgorithms: TypeAlias = SignatureAlgorithms
39+
40+
41+
# https://github.com/bogdanfinn/tls-client/blob/7a71edbf6e05acd4ade8e910e4c29c968003e27b/mapper.go#L21
42+
TLSVersions: TypeAlias = Literal["GREASE", "1.3", "1.2", "1.1", "1.0"]
43+
44+
# https://github.com/bogdanfinn/tls-client/blob/7a71edbf6e05acd4ade8e910e4c29c968003e27b/mapper.go#L75
45+
Curves: TypeAlias = Literal[
46+
"GREASE", "P256", "P384", "P521", "X25519", "P256Kyber768", "X25519Kyber512D",
47+
"X25519Kyber768", "X25519Kyber768Old", "X25519MLKEM768"
48+
]
49+
50+
# https://github.com/bogdanfinn/tls-client/blob/7a71edbf6e05acd4ade8e910e4c29c968003e27b/mapper.go#L9
51+
H2Settings: TypeAlias = Literal[
52+
"HEADER_TABLE_SIZE", "ENABLE_PUSH", "MAX_CONCURRENT_STREAMS", "INITIAL_WINDOW_SIZE", "MAX_FRAME_SIZE",
53+
"MAX_HEADER_LIST_SIZE", "UNKNOWN_SETTING_7", "UNKNOWN_SETTING_8", "UNKNOWN_SETTING_9"
7954
]

‎pyproject.toml

Copy file name to clipboardExpand all lines: pyproject.toml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ classifiers = [
2828
requires-python = ">=3.9"
2929
dependencies = [
3030
"typing-extensions>=4.0",
31+
"requests" # tested with 2.32.2
3132
]
3233

3334
[project.urls]

‎tests/conftest.py

Copy file name to clipboard
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import pytest
2+
from async_tls_client import AsyncSession
3+
4+
@pytest.fixture
5+
async def session():
6+
async with AsyncSession(client_identifier="chrome120") as sess:
7+
yield sess

‎tests/test_basic_requests.py

Copy file name to clipboard
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pytest
2+
3+
@pytest.mark.asyncio
4+
async def test_get_request(session):
5+
response = await session.get("https://httpbin.org/get")
6+
assert response.status_code == 200
7+
assert response.url == "https://httpbin.org/get"
8+
assert "headers" in response.json()
9+
10+
@pytest.mark.asyncio
11+
async def test_post_with_data(session):
12+
response = await session.post(
13+
"https://httpbin.org/post",
14+
data={"key": "value"}
15+
)
16+
assert response.status_code == 200
17+
assert response.json()["form"] == {"key": "value"}
18+
19+
@pytest.mark.asyncio
20+
async def test_post_with_json(session):
21+
response = await session.post(
22+
"https://httpbin.org/post",
23+
json={"key": "value"}
24+
)
25+
assert response.status_code == 200
26+
assert response.json()["json"] == {"key": "value"}

‎tests/test_errors.py

Copy file name to clipboard
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pytest
2+
from async_tls_client.exceptions import TLSClientException
3+
4+
@pytest.mark.asyncio
5+
async def test_invalid_url(session):
6+
with pytest.raises(TLSClientException):
7+
await session.get("invalid://invalid-url")
8+
9+
@pytest.mark.asyncio
10+
async def test_timeout(session):
11+
with pytest.raises(TLSClientException):
12+
await session.get(
13+
"https://httpbin.org/delay/5",
14+
timeout_seconds=1
15+
)
16+
17+
@pytest.mark.asyncio
18+
async def test_nonexistent_domain(session):
19+
with pytest.raises(TLSClientException):
20+
await session.get("https://nonexistent-domain-12345.com")

‎tests/test_session_features.py

Copy file name to clipboard
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import pytest
2+
3+
@pytest.mark.asyncio
4+
async def test_cookie_handling(session):
5+
# Set cookie
6+
await session.get("https://httpbin.org/cookies/set/sessioncookie/12345")
7+
# Verify persistence
8+
response = await session.get("https://httpbin.org/cookies")
9+
assert response.json()["cookies"] == {"sessioncookie": "12345"}
10+
11+
@pytest.mark.asyncio
12+
async def test_custom_headers(session):
13+
response = await session.get(
14+
"https://httpbin.org/headers",
15+
headers={"X-Test-Header": "value"}
16+
)
17+
assert response.json()["headers"]["X-Test-Header"] == "value"
18+
19+
@pytest.mark.asyncio
20+
async def test_tls_fingerprinting(session):
21+
response = await session.get("https://tls.peet.ws/api/all")
22+
data = response.json()
23+
assert "tls" in data
24+
assert "ja3_hash" in data["tls"]
25+
assert len(data["tls"]["ja3_hash"]) == 32 # MD5 hash length

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.