Skip to content

Commit 89fe99e

Browse files
chore: remove dependencies
1 parent aae2b74 commit 89fe99e

21 files changed

+440
-273
lines changed

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ repos:
1717
- id: check-docstring-first
1818
- id: detect-private-key
1919

20+
# run the autoflake.
21+
- repo: https://github.com/PyCQA/autoflake
22+
rev: v2.3.1
23+
hooks:
24+
- id: autoflake
25+
args: [--remove-all-unused-imports, --in-place, --ignore-init-module-imports]
26+
2027
# run the isort.
2128
- repo: https://github.com/PyCQA/isort
2229
rev: 6.1.0

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
init-actions:
33
python -m pip install --upgrade pip
44
python -m pip install -r requirements-dev.txt
5+
python -m autoflake --in-place --remove-all-unused-imports --ignore-init-module-imports .
56
python -m black tls_requests
67
python -m isort tls_requests
78
python -m flake8 tls_requests
89

10+
911
test:
1012
tox -p
1113
rm -rf *.egg-info

pyproject.toml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,47 @@ build-backend = 'setuptools.build_meta'
44

55
[tool.pytest.ini_options]
66
asyncio_mode = "auto"
7+
8+
[tool.black]
9+
line-length = 120
10+
target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
11+
unstable = true
12+
exclude = '''
13+
/(
14+
\.git
15+
| \.hg
16+
| \.mypy_cache
17+
| \.tox
18+
| \.venv
19+
| _build
20+
| buck-out
21+
| build
22+
| dist
23+
)/
24+
'''
25+
26+
27+
[tool.flake8]
28+
max-line-length = 120
29+
max-complexity = 10
30+
extend-ignore = [
31+
"E203", # Whitespace before ':', which black handles differently than flake8.
32+
"W503", # Line break before binary operator, black's preferred style.
33+
]
34+
35+
# Comma-separated list of directories to exclude from linting.
36+
exclude = [
37+
".git",
38+
"__pycache__",
39+
"docs/source/conf.py",
40+
"old",
41+
"build",
42+
"dist",
43+
".venv",
44+
]
45+
46+
# Per-file ignores are very useful for specific cases.
47+
# For example, __init__.py files often have unused imports on purpose.
48+
per-file-ignores = [
49+
"__init__.py:F401", # Ignore "unused import" in __init__.py files
50+
]

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ black==24.3.0
1717
coverage[toml]==7.6.1
1818
isort==5.13.2
1919
flake8==7.1.1
20+
autoflake==2.3.1
2021
mypy==1.11.2
2122
pytest==8.3.3
2223
pytest-asyncio==0.24.0

requirements.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
# Base
22
chardet~=5.2.0
3-
requests~=2.32.3
4-
tqdm~=4.67.1
53
idna~=3.10

setup.cfg

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ license_file = LICENSE
66
python_requires = >=3.8
77
install_requires =
88
chardet ~= 5.2.0
9-
requests ~= 2.32.3
10-
tqdm ~= 4.67.1
119
idna ~= 3.10
1210
classifiers =
1311
Development Status :: 5 - Production/Stable

tls_requests/__version__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
__title__ = "wrapper-tls-requests"
2-
__description__ = "A powerful and lightweight Python library for making secure and reliable HTTP/TLS Fingerprint requests."
2+
__description__ = (
3+
"A powerful and lightweight Python library for making secure and reliable HTTP/TLS Fingerprint requests."
4+
)
35
__url__ = "https://github.com/thewebscraping/tls-requests"
46
__author__ = "Tu Pham"
57
__author_email__ = "[email protected]"

tls_requests/client.py

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import (Any, Callable, Literal, Mapping, Optional, Sequence,
99
TypeVar, Union)
1010

11-
from .exceptions import RemoteProtocolError, TooManyRedirects
11+
from .exceptions import ProxyError, RemoteProtocolError, TooManyRedirects
1212
from .models import (URL, Auth, BasicAuth, Cookies, HeaderRotator, Headers,
1313
Proxy, ProxyRotator, Request, Response, StatusCodes,
1414
TLSClient, TLSConfig, TLSIdentifierRotator, URLParams)
@@ -119,7 +119,11 @@ def __init__(
119119
self.max_redirects = max_redirects
120120
self.http2 = http2
121121
self.verify = verify
122-
self.client_identifier = TLSIdentifierRotator.from_file(client_identifier) if isinstance(client_identifier, list) else client_identifier
122+
self.client_identifier = (
123+
TLSIdentifierRotator.from_file(client_identifier)
124+
if isinstance(client_identifier, list)
125+
else client_identifier
126+
)
123127
self.encoding = encoding
124128

125129
@property
@@ -174,9 +178,7 @@ def hooks(self) -> Mapping[Literal["request", "response"], list[Callable]]:
174178
def hooks(self, hooks: HookTypes) -> None:
175179
self._hooks = self._rebuild_hooks(hooks)
176180

177-
def prepare_auth(
178-
self, request: Request, auth: AuthTypes, *args, **kwargs
179-
) -> Union[Request, Any]:
181+
def prepare_auth(self, request: Request, auth: AuthTypes, *args, **kwargs) -> Union[Request, Any]:
180182
"""Build Auth Request instance"""
181183

182184
if isinstance(auth, tuple) and len(auth) == 2:
@@ -222,7 +224,7 @@ def prepare_proxy(self, proxy: ProxyTypes | None) -> Optional[Proxy]:
222224
return proxy
223225
if isinstance(proxy, URL):
224226
return Proxy(str(proxy))
225-
raise TypeError(f"Unsupported proxy type: {type(proxy)}")
227+
raise ProxyError(f"Unsupported proxy type: {type(proxy)}")
226228

227229
def prepare_tls_identifier(self, identifier: Optional[str, TLSIdentifierRotator]) -> str:
228230
if isinstance(identifier, str):
@@ -279,19 +281,15 @@ def build_request(
279281
timeout=timeout or self.timeout,
280282
)
281283

282-
def build_hook_request(
283-
self, request: Request, *args, **kwargs
284-
) -> Union[Request, Any]:
284+
def build_hook_request(self, request: Request, *args, **kwargs) -> Union[Request, Any]:
285285
request_hooks = self._rebuild_hooks(self.hooks).get("request")
286286
if isinstance(request_hooks, Sequence):
287287
for hook in request_hooks:
288288
if callable(hook):
289289
return hook(request)
290290
return None
291291

292-
def build_hook_response(
293-
self, response: Response, *args, **kwargs
294-
) -> Union[Response, Any]:
292+
def build_hook_response(self, response: Response, *args, **kwargs) -> Union[Response, Any]:
295293
request_hooks = self._rebuild_hooks(self.hooks).get("response")
296294
if isinstance(request_hooks, Sequence):
297295
for hook in request_hooks:
@@ -308,9 +306,7 @@ def _rebuild_hooks(self, hooks: HookTypes):
308306
}
309307
return None
310308

311-
def _rebuild_redirect_request(
312-
self, request: Request, response: Response
313-
) -> Request:
309+
def _rebuild_redirect_request(self, request: Request, response: Response) -> Request:
314310
"""Rebuild Redirect Request"""
315311

316312
return Request(
@@ -357,7 +353,8 @@ def _rebuild_redirect_url(self, request: Request, response: Response) -> URL:
357353
self.config.sessionId = str(uuid.uuid4())
358354
else:
359355
raise RemoteProtocolError(
360-
"Switching remote scheme from HTTP/2 to HTTP/1 is not supported. Please initialize Client with parameter `http2` to `auto`."
356+
"Switching remote scheme from HTTP/2 to HTTP/1 is not supported. Please initialize Client with"
357+
" parameter `http2` to `auto`."
361358
)
362359

363360
setattr(url, "_url", None) # reset url
@@ -366,9 +363,7 @@ def _rebuild_redirect_url(self, request: Request, response: Response) -> URL:
366363

367364
return url
368365

369-
def _send(
370-
self, request: Request, *, history: list = None, start: float = None
371-
) -> Response:
366+
def _send(self, request: Request, *, history: list = None, start: float = None) -> Response:
372367
start = start or time.perf_counter()
373368
tls_identifier = self.prepare_tls_identifier(self.client_identifier)
374369
config = self.prepare_config(request, tls_identifier=tls_identifier)
@@ -401,14 +396,10 @@ def close(self) -> None:
401396

402397
def __enter__(self: T) -> T:
403398
if self._state == ClientState.OPENED:
404-
raise RuntimeError(
405-
"It is not possible to open a client instance more than once."
406-
)
399+
raise RuntimeError("It is not possible to open a client instance more than once.")
407400

408401
if self._state == ClientState.CLOSED:
409-
raise RuntimeError(
410-
"The client instance cannot be reopened after it has been closed."
411-
)
402+
raise RuntimeError("The client instance cannot be reopened after it has been closed.")
412403

413404
self._state = ClientState.OPENED
414405
return self
@@ -518,7 +509,9 @@ def send(
518509
if isinstance(self.proxy, ProxyRotator) and response.request.proxy:
519510
proxy_success = 200 <= response.status_code < 500 and response.status_code not in [407]
520511
self.proxy.mark_result(
521-
proxy=response.request.proxy, success=proxy_success, latency=response.elapsed
512+
proxy=response.request.proxy,
513+
success=proxy_success,
514+
latency=response.elapsed,
522515
)
523516

524517
if self.hooks.get("response"):
@@ -780,7 +773,7 @@ async def aprepare_proxy(self, proxy: ProxyTypes | None) -> Optional[Proxy]:
780773
return proxy
781774
if isinstance(proxy, URL):
782775
return Proxy(str(proxy))
783-
raise TypeError(f"Unsupported proxy type: {type(proxy)}")
776+
raise ProxyError(f"Unsupported proxy type: {type(proxy)}")
784777

785778
async def aprepare_tls_identifier(self, identifier) -> str:
786779
if isinstance(identifier, str):
@@ -1078,7 +1071,9 @@ async def send(
10781071
if isinstance(self.proxy, ProxyRotator) and response.request.proxy:
10791072
proxy_success = 200 <= response.status_code < 500 and response.status_code not in [407]
10801073
await self.proxy.amark_result(
1081-
proxy=response.request.proxy, success=proxy_success, latency=response.elapsed
1074+
proxy=response.request.proxy,
1075+
success=proxy_success,
1076+
latency=response.elapsed,
10821077
)
10831078

10841079
if self.hooks.get("response"):
@@ -1091,9 +1086,7 @@ async def send(
10911086
await response.aclose()
10921087
return response
10931088

1094-
async def _send(
1095-
self, request: Request, *, history: list = None, start: float = None
1096-
) -> Response:
1089+
async def _send(self, request: Request, *, history: list = None, start: float = None) -> Response:
10971090
start = start or time.perf_counter()
10981091
tls_identifier = await self.aprepare_tls_identifier(self.client_identifier)
10991092
config = self.prepare_config(request, tls_identifier=tls_identifier)
@@ -1123,14 +1116,10 @@ async def aclose(self) -> None:
11231116

11241117
async def __aenter__(self: A) -> A:
11251118
if self._state == ClientState.OPENED:
1126-
raise RuntimeError(
1127-
"It is not possible to open a client instance more than once."
1128-
)
1119+
raise RuntimeError("It is not possible to open a client instance more than once.")
11291120

11301121
if self._state == ClientState.CLOSED:
1131-
raise RuntimeError(
1132-
"The client instance cannot be reopened after it has been closed."
1133-
)
1122+
raise RuntimeError("The client instance cannot be reopened after it has been closed.")
11341123

11351124
self._state = ClientState.OPENED
11361125
return self

tls_requests/exceptions.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66
pass
77

88
__all__ = [
9+
"AuthenticationError",
910
"CookieConflictError",
1011
"HTTPError",
11-
"URLError",
12-
"RemoteProtocolError",
12+
"HeaderError",
1313
"ProtocolError",
14+
"RemoteProtocolError",
1415
"StreamConsumed",
1516
"StreamError",
16-
"TooManyRedirects",
1717
"TLSError",
18+
"RotatorError",
19+
"TooManyRedirects",
20+
"URLError",
1821
]
1922

2023

@@ -31,6 +34,14 @@ def __init__(self, message: str, **kwargs) -> None:
3134
super().__init__(message)
3235

3336

37+
class AuthenticationError(HTTPError):
38+
"""Authentication Error"""
39+
40+
41+
class HeaderError(HTTPError):
42+
"""Header Error"""
43+
44+
3445
class ProtocolError(HTTPError):
3546
"""Protocol Error"""
3647

@@ -81,3 +92,7 @@ class StreamConsumed(StreamError):
8192

8293
class StreamClosed(StreamError):
8394
pass
95+
96+
97+
class RotatorError(HTTPError):
98+
pass

tls_requests/models/auth.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from base64 import b64encode
22
from typing import Any, Union
33

4-
from tls_requests.models.request import Request
4+
from ..exceptions import AuthenticationError
5+
from .request import Request
56

67

78
class Auth:
@@ -22,16 +23,14 @@ def build_auth(self, request: Request):
2223
return self._build_auth_headers(request)
2324

2425
def _build_auth_headers(self, request: Request):
25-
auth_token = b64encode(
26-
b":".join([self._encode(self.username), self._encode(self.password)])
27-
).decode()
26+
auth_token = b64encode(b":".join([self._encode(self.username), self._encode(self.password)])).decode()
2827
request.headers["Authorization"] = "Basic %s" % auth_token
2928

3029
def _encode(self, value: Union[str, bytes]) -> bytes:
3130
if isinstance(self.username, str):
3231
value = value.encode("latin1")
3332

3433
if not isinstance(value, bytes):
35-
raise TypeError("`username` or `password` parameter must be str or byte.")
34+
raise AuthenticationError("`username` or `password` parameter must be str or byte.")
3635

3736
return value

0 commit comments

Comments
 (0)