master
Raw Download raw file
 1import sys
 2
 3import asyncio
 4from asyncio.exceptions import TimeoutError
 5
 6import aiohttp
 7from aiohttp.client_exceptions import ClientConnectorError
 8
 9import logging
10
11from typing import List, Optional
12
13
14class BaseClient:
15    def __init__(
16        self,
17        *,
18        host,
19        path,
20        port="",
21        is_ssl=True,
22        timeout=5,
23        retries=6,
24        retry_wait=1,
25        max_timeout=300,
26        max_retry_wait=300,
27    ):
28        self.is_ssl = is_ssl
29        self.host = host
30        self.port = port
31        self.path = path
32        self.timeout = timeout
33        self.retries = retries
34        self.retry_wait = retry_wait
35        self.scheme = "https" if self.is_ssl else "http"
36        self.url = f"{self.scheme}://{self.host}:{self.port}{self.path}"
37        self.logger = logging.getLogger("aiohttp.internal")
38        self.max_timeout = max_timeout
39        self.max_retry_wait = max_retry_wait
40
41    async def retry_after_wait(self, err, func):
42        if self.retries > 0:
43
44            msg = f"Sleeping {self.retry_wait}s. {self.retries} retries remaining"
45            self.logger.warning(msg)
46            await asyncio.sleep(self.retry_wait)
47
48            self.retries = self.retries - 1
49            self.retry_wait = min(self.retry_wait * 2, self.max_retry_wait)
50            return await func()
51        else:
52            msg = f"Retries exhausted"
53            self.logger.error(msg)
54            return (err, None)
55
56    async def get_data(self):
57
58        msg = f"Fetching data from {self.url}"
59        self.logger.info(msg)
60        ct = aiohttp.ClientTimeout(total=self.timeout)
61        async with aiohttp.ClientSession(timeout=ct) as session:
62
63            try:
64                async with session.get(self.url) as resp:
65                    data = await resp.json()
66                    return (None, data)
67
68            except ClientConnectorError as err:
69                self.logger.error(err)
70                return await self.retry_after_wait(err, self.get_data)
71
72            except TimeoutError as err:
73                self.timeout = self.timeout * 2
74                self.logger.error(
75                    f"Request timed out. Retrying with {self.timeout}s timeout"
76                )
77                return await self.retry_after_wait(err, self.get_data)
78
79            except Exception as err:
80                self.logger.error(err)
81                return (err, None)