async ip address calls

This commit is contained in:
SimplifiedPrivacy 2026-10-22 13:37:27 -04:00
parent af368db8b7
commit 587c72f4c3

View file

@ -11,6 +11,7 @@ from essentials.observers.ConnectionObserver import ConnectionObserver
# generic
import time
import random
import asyncio
import httpx
from httpx_socks import AsyncProxyTransport
import httpx_socks
@ -31,50 +32,63 @@ API_ENDPOINT_FORMATS = {
MAX_ATTEMPTS = 3
def test(connection_observer: Optional[ConnectionObserver], port: Optional[int] = None) -> Result:
"""
Cycles through 3 possible endpoints,
to attempt to get an IP address for the systemwide connection.
"""
attempt = 0
endpoint_index = 0
endpoint_list = list(API_ENDPOINT_FORMATS.keys())
return asyncio.run(_test(connection_observer, port))
async def _test(connection_observer: Optional[ConnectionObserver], port: Optional[int] = None) -> Result:
endpoint_list = list(API_ENDPOINT_FORMATS.keys())[:MAX_ATTEMPTS]
if port:
transport = httpx_socks.SyncProxyTransport(
transport = httpx_socks.AsyncProxyTransport(
proxy_type=ProxyType.SOCKS5,
proxy_host="127.0.0.1",
proxy_port=port,
)
_ip_test_client = httpx.Client(transport=transport, http2=True, timeout=6)
client = httpx.AsyncClient(transport=transport, http2=True, timeout=6)
else:
_ip_test_client = httpx.Client(http2=True, timeout=6)
client = httpx.AsyncClient(http2=True, timeout=6)
while attempt < MAX_ATTEMPTS:
endpoint_url = endpoint_list[attempt]
attempt += 1
logger.info(f"Attempt {attempt}: Trying {endpoint_url}")
async def attempt_request(url: str, index: int):
logger.info(f"Attempt {index + 1}: Trying {url}")
if connection_observer:
connection_observer.notify("connecting", f"Testing IP. Attempt {attempt}")
connection_observer.notify("connecting", f"Testing IP. Attempt {index + 1}")
try:
raw_response = _ip_test_client.get(endpoint_url)
raw_response = await client.get(url)
filtered_response = classify_response(raw_response)
if filtered_response.valid:
ip_address = extract_ip_from_response(
response=filtered_response.data,
api_url=endpoint_url
api_url=url
)
if ip_address is not None:
return Result(valid=True, data=ip_address)
else:
logger.error(f"Skipping {endpoint_url}")
logger.error(f"Skipping {url}")
except Exception as e:
logger.error(f"We are NOT error handling this. Skipping {endpoint_url}. Invalid API reply or failed connection {str(e)}")
logger.error(f"Skipping {url}. Invalid API reply or failed connection {str(e)}")
return Result(valid=False)
logger.error(f"We went through {MAX_ATTEMPTS} attempts and could not get a reply.")
try:
# Create tasks for all endpoints to run them concurrently
tasks = [asyncio.create_task(attempt_request(url, i)) for i, url in enumerate(endpoint_list)]
# Process tasks as they complete
for future in asyncio.as_completed(tasks):
result = await future
if result.valid:
# Cancel all other pending tasks immediately
for t in tasks:
if not t.done():
t.cancel()
return result
finally:
await client.aclose()
logger.error(f"We went through {len(endpoint_list)} attempts and could not get a reply.")
return Result(valid=False, error_type=ResultError.CONNECTION, message="Could not connect.")
@ -84,9 +98,6 @@ def extract_ip_from_response(response: dict, api_url: str) -> str | bool:
Extract the IP address from the API's response,
based on which keys that API uses.
Rank:
Helper
On Success:
Returns String of IP address