Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR #9207/970c5d9 backport][3.11] add proxy and proxy_auth variables to ClientSession.__init__ #9331

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -531,6 +538,11 @@ async def _request(
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 not None:
bdraco marked this conversation as resolved.
Show resolved Hide resolved
proxy_headers = None
else:
proxy_headers = self._prepare_headers(proxy_headers)
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
55 changes: 53 additions & 2 deletions tests/test_client_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,59 @@ 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()
github-advanced-security[bot] marked this conversation as resolved.
Dismissed
Show resolved Hide resolved

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: AiohttpClient
bdraco marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
async def handler(request: web.Request) -> web.Response:
return web.json_response({"ok": True})

app = web.Application()
Expand Down
Loading