89 lines
3.0 KiB
Python

"""HTTP client utilities for making requests to the backend API"""
import aiohttp
from typing import Optional
import ssl
import os
def get_windows_host_ip() -> Optional[str]:
"""
Get the Windows host IP address when running in WSL.
In WSL2, the Windows host IP is typically the first nameserver in /etc/resolv.conf.
"""
try:
if os.path.exists("/etc/resolv.conf"):
with open("/etc/resolv.conf", "r") as f:
for line in f:
if line.startswith("nameserver"):
ip = line.split()[1]
if ip not in ["127.0.0.1", "127.0.0.53"] and not ip.startswith("fe80"):
return ip
except Exception:
pass
return None
def normalize_backend_url(url: str) -> str:
"""
Normalize backend URL for better compatibility, especially on WSL and Docker.
"""
if not ("localhost" in url or "127.0.0.1" in url):
return url
if os.path.exists("/.dockerenv"):
print(f"Warning: Running in Docker but URL contains localhost: {url}")
print("Please set BACKEND_URL environment variable in docker-compose.yml to use Docker service name (e.g., http://backend:8000/api/v1)")
return url.replace("localhost", "127.0.0.1")
try:
if os.path.exists("/proc/version"):
with open("/proc/version", "r") as f:
version_content = f.read().lower()
if "microsoft" in version_content:
windows_ip = get_windows_host_ip()
if windows_ip:
if "localhost" in url or "127.0.0.1" in url:
url = url.replace("localhost", windows_ip).replace("127.0.0.1", windows_ip)
print(f"WSL detected: Using Windows host IP {windows_ip} for backend connection")
return url
except Exception as e:
print(f"Warning: Could not detect WSL environment: {e}")
if url.startswith("http://localhost") or url.startswith("https://localhost"):
return url.replace("localhost", "127.0.0.1")
return url
def create_http_session(timeout: Optional[aiohttp.ClientTimeout] = None) -> aiohttp.ClientSession:
"""
Create a configured aiohttp ClientSession for backend API requests.
Args:
timeout: Optional timeout configuration. Defaults to 30 seconds total timeout.
Returns:
Configured aiohttp.ClientSession
"""
if timeout is None:
timeout = aiohttp.ClientTimeout(total=30, connect=10)
connector = aiohttp.TCPConnector(
ssl=False,
limit=100,
limit_per_host=30,
force_close=True,
enable_cleanup_closed=True
)
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
return aiohttp.ClientSession(
connector=connector,
timeout=timeout,
headers={
"Content-Type": "application/json",
"Accept": "application/json"
}
)