import asyncio from aiohttp import ( ClientSession, ClientConnectorError, ClientProxyConnectionError, ServerDisconnectedError, ) from aiohttp_socks import ProxyConnector, ProxyError, SocksError import time from asyncio import TimeoutError from typing import Any, Optional, Tuple, List, Coroutine TIMEOUT: float = 10. # sec FILENAME: str = 'proxy.txt' def read(file: str) -> Optional[List[str]]: try: with open(file, 'r') as f: return f.readlines() except (OSError, FileNotFoundError) as exc: raise exc async def fetch(proxy: str) -> Optional[Tuple[str, float]]: """ Fetch url with proxy :param proxy: :return: proxy string, elapsed time """ start: float = time.perf_counter() connector: ProxyConnector = ProxyConnector.from_url(f'socks5://{proxy}') async with ClientSession(connector=connector) as session: try: async with session.get('https://api.telegram.org:443') as resp: if resp.status == 200: return proxy, time.perf_counter() - start except ( ClientProxyConnectionError, ClientConnectorError, ServerDisconnectedError, SocksError, ProxyError, OSError, ) as exc: # print(exc.__class__.__name__) pass return None async def main(filename: str): lines = read(filename) if not lines: raise ValueError(f'File `{filename}` is empty, shutdown') results: List[Tuple[str, float]] = [] # can be omitted tasks: List[Coroutine[Any, Any, Optional[Tuple[str, float]]]] = [fetch(proxy.strip()) for proxy in lines] try: for future in asyncio.as_completed(tasks, timeout=TIMEOUT): result: Any = await future if result: results.append(result) proxy, request_time = result print(f"socks5://{proxy: <20} answered in {request_time:.2f} seconds") # TODO: Save result except TimeoutError as ext: print(f"Reached {ext.__class__.__name__} ({TIMEOUT} sec)") if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(main(FILENAME))