Skip to content

Commit 7eac6c5

Browse files
chore: remove dependencies
1 parent aae2b74 commit 7eac6c5

File tree

18 files changed

+429
-294
lines changed

18 files changed

+429
-294
lines changed

pyproject.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,46 @@ 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+
exclude = '''
12+
/(
13+
\.git
14+
| \.hg
15+
| \.mypy_cache
16+
| \.tox
17+
| \.venv
18+
| _build
19+
| buck-out
20+
| build
21+
| dist
22+
)/
23+
'''
24+
25+
26+
[tool.flake8]
27+
max-line-length = 120
28+
max-complexity = 10
29+
extend-ignore = [
30+
"E203", # Whitespace before ':', which black handles differently than flake8.
31+
"W503", # Line break before binary operator, black's preferred style.
32+
]
33+
34+
# Comma-separated list of directories to exclude from linting.
35+
exclude = [
36+
".git",
37+
"__pycache__",
38+
"docs/source/conf.py",
39+
"old",
40+
"build",
41+
"dist",
42+
".venv",
43+
]
44+
45+
# Per-file ignores are very useful for specific cases.
46+
# For example, __init__.py files often have unused imports on purpose.
47+
per-file-ignores = [
48+
"__init__.py:F401", # Ignore "unused import" in __init__.py files
49+
]

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 & 23 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
@@ -46,24 +44,3 @@ exclude =
4644
examples*
4745
tools*
4846
docs*
49-
50-
[flake8]
51-
max-line-length = 120
52-
ignore = F821, E203, W503, E501, E231
53-
per-file-ignores =
54-
__init__.py: F405, F403, E402, F401
55-
56-
[tool.black]
57-
line-length = 120
58-
include = '\.pyi?$'
59-
unstable = true
60-
61-
62-
[tool.isort]
63-
atomic = true
64-
profile = "black"
65-
line_length = 120
66-
skip_gitignore = true
67-
skip_glob = ["tests/data", "profiling"]
68-
known_first_party = ["black", "blib2to3", "blackd", "_black_version"]
69-
add_imports = "from __future__ import annotations"

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)