Skip to content

Commit

Permalink
[PR #9207/970c5d9 backport][3.11] add proxy and proxy_auth variables …
Browse files Browse the repository at this point in the history
…to ClientSession.__init__ (#9331)

Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Fixes #123'). -->
  • Loading branch information
meshya authored Oct 1, 2024
1 parent fbbe4ed commit e238777
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES/9207.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added ``proxy`` and ``proxy_auth`` parameters to ``ClientSession`` -- by :user:`meshya`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ Matthieu Hauglustaine
Matthieu Rigal
Matvey Tingaev
Meet Mangukiya
Meshya
Michael Ihnatenko
Michał Górny
Mikhail Burshteyn
Expand Down
12 changes: 12 additions & 0 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ class ClientSession:
"_max_line_size",
"_max_field_size",
"_resolve_charset",
"_default_proxy",
"_default_proxy_auth",
]
)

Expand All @@ -266,6 +268,8 @@ def __init__(
loop: Optional[asyncio.AbstractEventLoop] = None,
cookies: Optional[LooseCookies] = None,
headers: Optional[LooseHeaders] = None,
proxy: Optional[StrOrURL] = None,
proxy_auth: Optional[BasicAuth] = None,
skip_auto_headers: Optional[Iterable[str]] = None,
auth: Optional[BasicAuth] = None,
json_serialize: JSONEncoder = json.dumps,
Expand Down Expand Up @@ -396,6 +400,9 @@ def __init__(

self._resolve_charset = fallback_charset_resolver

self._default_proxy = proxy
self._default_proxy_auth = proxy_auth

def __init_subclass__(cls: Type["ClientSession"]) -> None:
warnings.warn(
"Inheritance class {} from ClientSession "
Expand Down Expand Up @@ -530,6 +537,11 @@ async def _request(
for i in skip_auto_headers:
skip_headers.add(istr(i))

if proxy is None:
proxy = self._default_proxy
if proxy_auth is None:
proxy_auth = self._default_proxy_auth

if proxy is None:
proxy_headers = None
else:
Expand Down
7 changes: 7 additions & 0 deletions docs/client_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,13 @@ Authentication credentials can be passed in proxy URL::
session.get("http://python.org",
proxy="http://user:pass@some.proxy.com")

And you may set default proxy::

proxy_auth = aiohttp.BasicAuth('user', 'pass')
async with aiohttp.ClientSession(proxy="http://proxy.com", proxy_auth=proxy_auth) as session:
async with session.get("http://python.org") as resp:
print(resp.status)

Contrary to the ``requests`` library, it won't read environment
variables by default. But you can do so by passing
``trust_env=True`` into :class:`aiohttp.ClientSession`
Expand Down
53 changes: 51 additions & 2 deletions tests/test_client_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,57 @@ def test_proxy_str(session, params) -> None:
]


async def test_request_tracing(loop, aiohttp_client) -> None:
async def handler(request):
async def test_default_proxy(loop: asyncio.AbstractEventLoop) -> None:
proxy_url = URL("http://proxy.example.com")
proxy_auth = mock.Mock()
proxy_url2 = URL("http://proxy.example2.com")
proxy_auth2 = mock.Mock()

class OnCall(Exception):
pass

request_class_mock = mock.Mock(side_effect=OnCall())
session = ClientSession(
proxy=proxy_url, proxy_auth=proxy_auth, request_class=request_class_mock
)

assert session._default_proxy == proxy_url, "`ClientSession._default_proxy` not set"
assert (
session._default_proxy_auth == proxy_auth
), "`ClientSession._default_proxy_auth` not set"

with pytest.raises(OnCall):
await session.get(
"http://example.com",
)

assert request_class_mock.called, "request class not called"
assert (
request_class_mock.call_args[1].get("proxy") == proxy_url
), "`ClientSession._request` uses default proxy not one used in ClientSession.get"
assert (
request_class_mock.call_args[1].get("proxy_auth") == proxy_auth
), "`ClientSession._request` uses default proxy_auth not one used in ClientSession.get"

request_class_mock.reset_mock()
with pytest.raises(OnCall):
await session.get(
"http://example.com", proxy=proxy_url2, proxy_auth=proxy_auth2
)

assert request_class_mock.called, "request class not called"
assert (
request_class_mock.call_args[1].get("proxy") == proxy_url2
), "`ClientSession._request` uses default proxy not one used in ClientSession.get"
assert (
request_class_mock.call_args[1].get("proxy_auth") == proxy_auth2
), "`ClientSession._request` uses default proxy_auth not one used in ClientSession.get"

await session.close()


async def test_request_tracing(loop: asyncio.AbstractEventLoop, aiohttp_client) -> None:
async def handler(request: web.Request) -> web.Response:
return web.json_response({"ok": True})

app = web.Application()
Expand Down

0 comments on commit e238777

Please sign in to comment.