async def _get_request_side_effect(url, *args, **kwargs):
     nonlocal retry_count
     retry_count += 1
     if retry_count <= len(proxies):
         raise ProxyError(response=Response(status_code=429))
     else:
         return Response(status_code=429)
    async def test_receive_error_no_retries_configured(self, client_mock):
        client_mock.return_value.__aenter__.return_value = client_mock
        client_mock.get = CoroutineMock(return_value=Response(status_code=429))

        pytrends = TrendReq(retries=0, backoff_factor=0)
        pytrends.cookies = {'NID': '12eqf98hnf8032r54'}

        with pytest.raises(ResponseError):
            await pytrends.top_charts(date=2018)
        assert client_mock.get.call_count == 1
 async def _get_request_side_effect(url, *args, **kwargs):
     nonlocal retry_count
     retry_count += 1
     #Make fail in a few different ways. On last attempt, return response
     if retry_count == pytrend.retries - 1:
         raise ConnectionRefusedError()
     elif retry_count != pytrend.retries:
         return Response(status_code=429)
     else:
         return trending_searches_200_response
    async def test_all_retries_fail(self, client_mock):
        client_mock.return_value.__aenter__.return_value = client_mock
        client_mock.get = CoroutineMock(return_value=Response(status_code=429))

        pytrend = TrendReq(timeout=TIMEOUT, retries=3, backoff_factor=0.1)
        with pytest.raises(ResponseError):
            await pytrend.build_payload(kw_list=['pizza', 'bagel'])

        calls = [
            call('https://trends.google.com/?geo=US', timeout=ANY)
            for _ in range(pytrend.retries)
        ]
        client_mock.get.assert_has_calls(calls)
    async def send(self,
                   request: Request,
                   timeout: Timeout = None) -> Response:
        stream_id = self._quic.get_next_available_stream_id()

        # prepare request
        self._http.send_headers(
            stream_id=stream_id,
            headers=[
                (b":method", request.method.encode()),
                (b":scheme", request.url.scheme.encode()),
                (b":authority", str(request.url.authority).encode()),
                (b":path", request.url.full_path.encode()),
            ] + [(k.encode(), v.encode())
                 for (k, v) in request.headers.items()
                 if k not in ("connection", "host")],
        )
        self._http.send_data(stream_id=stream_id,
                             data=request.read(),
                             end_stream=True)

        # transmit request
        waiter = self._loop.create_future()
        self._request_events[stream_id] = deque()
        self._request_waiter[stream_id] = waiter
        self.transmit()

        # process response
        events: Deque[H3Event] = await asyncio.shield(waiter)
        content = b""
        headers = []
        status_code = None
        for event in events:
            if isinstance(event, HeadersReceived):
                for header, value in event.headers:
                    if header == b":status":
                        status_code = int(value.decode())
                    elif header[0:1] != b":":
                        headers.append((header.decode(), value.decode()))
            elif isinstance(event, DataReceived):
                content += event.data

        return Response(
            status_code=status_code,
            http_version="HTTP/3",
            headers=headers,
            content=content,
            request=request,
        )
Example #6
0
    async def send(self,
                   request: Request,
                   timeout: TimeoutTypes = None) -> Response:
        scope = {
            "type": "http",
            "asgi": {
                "version": "3.0"
            },
            "http_version": "1.1",
            "method": request.method,
            "headers": request.headers.raw,
            "scheme": request.url.scheme,
            "path": request.url.path,
            "query_string": request.url.query.encode("ascii"),
            "server": request.url.host,
            "client": self.client,
            "root_path": self.root_path,
            "extensions": ["http.response.template"],
        }
        status_code = None
        headers = None
        body_parts = []
        response_started = False
        response_complete = False
        template = None
        context = None

        request_body_chunks = request.stream.__aiter__()

        async def receive() -> dict:
            try:
                body = await request_body_chunks.__anext__()
            except StopAsyncIteration:
                return {
                    "type": "http.request",
                    "body": b"",
                    "more_body": False
                }
            return {"type": "http.request", "body": body, "more_body": True}

        async def send(message: dict) -> None:
            nonlocal status_code, headers, body_parts
            nonlocal response_started, response_complete
            nonlocal template, context

            if message["type"] == "http.response.start":
                assert not response_started

                status_code = message["status"]
                headers = message.get("headers", [])
                response_started = True

            elif message["type"] == "http.response.body":
                assert not response_complete
                body = message.get("body", b"")
                more_body = message.get("more_body", False)

                if body and request.method != "HEAD":
                    body_parts.append(body)

                if not more_body:
                    response_complete = True

            elif message["type"] == "http.response.template":
                template = message["template"]
                context = message["context"]

        try:
            await self.app(scope, receive, send)
        except Exception:
            if self.raise_app_exceptions or not response_complete:
                raise

        assert response_complete
        assert status_code is not None
        assert headers is not None

        stream = ByteStream(b"".join(body_parts))

        response = Response(
            status_code=status_code,
            http_version="HTTP/1.1",
            headers=headers,
            stream=stream,
            request=request,
        )
        response.template = template
        response.context = context
        return response