def test_init(self, monkeypatch): @dataclass class Client: timeout: object proxies: object limits: object monkeypatch.setattr(httpx, "AsyncClient", Client) request = HTTPXRequest() assert request._client.timeout == httpx.Timeout(connect=5.0, read=5.0, write=5.0, pool=1.0) assert request._client.proxies is None assert request._client.limits == httpx.Limits( max_connections=1, max_keepalive_connections=1 ) request = HTTPXRequest( connection_pool_size=42, proxy_url="proxy_url", connect_timeout=43, read_timeout=44, write_timeout=45, pool_timeout=46, ) assert request._client.proxies == "proxy_url" assert request._client.limits == httpx.Limits( max_connections=42, max_keepalive_connections=42 ) assert request._client.timeout == httpx.Timeout(connect=43, read=44, write=45, pool=46)
def test_slot_behaviour(self, mro_slots): inst = HTTPXRequest() for attr in inst.__slots__: if attr.startswith("__"): attr = f"_{inst.__class__.__name__}{attr}" assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
async def test_do_request_manual_timeouts(self, monkeypatch, httpx_request): default_timeouts = httpx.Timeout(connect=42, read=43, write=44, pool=45) manual_timeouts = httpx.Timeout(connect=52, read=53, write=54, pool=55) async def make_assertion(_, **kwargs): self.test_flag = kwargs.get("timeout") == manual_timeouts return httpx.Response(HTTPStatus.OK) async with HTTPXRequest( connect_timeout=default_timeouts.connect, read_timeout=default_timeouts.read, write_timeout=default_timeouts.write, pool_timeout=default_timeouts.pool, ) as httpx_request: monkeypatch.setattr(httpx.AsyncClient, "request", make_assertion) await httpx_request.do_request( method="GET", url="URL", connect_timeout=manual_timeouts.connect, read_timeout=manual_timeouts.read, write_timeout=manual_timeouts.write, pool_timeout=manual_timeouts.pool, ) assert self.test_flag
async def test_multiple_init_cycles(self): # nothing really to assert - this should just not fail httpx_request = HTTPXRequest() async with httpx_request: await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET") async with httpx_request: await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET")
async def test_multiple_inits_and_shutdowns(self, monkeypatch): self.test_flag = defaultdict(int) orig_init = httpx.AsyncClient.__init__ orig_aclose = httpx.AsyncClient.aclose class Client(httpx.AsyncClient): def __init__(*args, **kwargs): orig_init(*args, **kwargs) self.test_flag["init"] += 1 async def aclose(*args, **kwargs): await orig_aclose(*args, **kwargs) self.test_flag["shutdown"] += 1 monkeypatch.setattr(httpx, "AsyncClient", Client) # Create a new one instead of using the fixture so that the mocking can work httpx_request = HTTPXRequest() await httpx_request.initialize() await httpx_request.initialize() await httpx_request.initialize() await httpx_request.shutdown() await httpx_request.shutdown() await httpx_request.shutdown() assert self.test_flag["init"] == 1 assert self.test_flag["shutdown"] == 1
def _build_request(self, get_updates: bool) -> BaseRequest: prefix = "_get_updates_" if get_updates else "_" if not isinstance(getattr(self, f"{prefix}request"), DefaultValue): return getattr(self, f"{prefix}request") proxy_url = DefaultValue.get_value(getattr(self, f"{prefix}proxy_url")) if get_updates: connection_pool_size = (DefaultValue.get_value( getattr(self, f"{prefix}connection_pool_size")) or 1) else: connection_pool_size = (DefaultValue.get_value( getattr(self, f"{prefix}connection_pool_size")) or 256) timeouts = dict( connect_timeout=getattr(self, f"{prefix}connect_timeout"), read_timeout=getattr(self, f"{prefix}read_timeout"), write_timeout=getattr(self, f"{prefix}write_timeout"), pool_timeout=getattr(self, f"{prefix}pool_timeout"), ) # Get timeouts that were actually set- effective_timeouts = { key: value for key, value in timeouts.items() if not isinstance(value, DefaultValue) } return HTTPXRequest( connection_pool_size=connection_pool_size, proxy_url=proxy_url, **effective_timeouts, )
async def test_context_manager(self, monkeypatch): async def initialize(): self.test_flag = ["initialize"] async def shutdown(): self.test_flag.append("stop") httpx_request = HTTPXRequest() monkeypatch.setattr(httpx_request, "initialize", initialize) monkeypatch.setattr(httpx_request, "shutdown", shutdown) async with httpx_request: pass assert self.test_flag == ["initialize", "stop"]
async def test_do_request_pool_timeout(self, monkeypatch): async def request(_, **kwargs): if self.test_flag is None: self.test_flag = True else: raise httpx.PoolTimeout("pool timeout") return httpx.Response(HTTPStatus.OK) monkeypatch.setattr(httpx.AsyncClient, "request", request) with pytest.raises(TimedOut, match="Pool timeout"): async with HTTPXRequest(pool_timeout=0.02) as httpx_request: await asyncio.gather( httpx_request.do_request(method="GET", url="URL"), httpx_request.do_request(method="GET", url="URL"), )
async def test_context_manager(self, monkeypatch): async def initialize(): self.test_flag = ["initialize"] async def aclose(*args): self.test_flag.append("stop") httpx_request = HTTPXRequest() monkeypatch.setattr(httpx_request, "initialize", initialize) monkeypatch.setattr(httpx.AsyncClient, "aclose", aclose) async with httpx_request: pass assert self.test_flag == ["initialize", "stop"]
async def test_context_manager_exception_on_init(self, monkeypatch): async def initialize(): raise RuntimeError("initialize") async def aclose(*args): self.test_flag = "stop" httpx_request = HTTPXRequest() monkeypatch.setattr(httpx_request, "initialize", initialize) monkeypatch.setattr(httpx.AsyncClient, "aclose", aclose) with pytest.raises(RuntimeError, match="initialize"): async with httpx_request: pass assert self.test_flag == "stop"
async def httpx_request(): async with HTTPXRequest() as rq: yield rq