| import httpx
|
| from typing import Dict, Any, AsyncGenerator
|
| from config.constants import DEFAULT_HEADERS
|
|
|
|
|
| class HTTPClient:
|
| def __init__(self):
|
| self.client = httpx.AsyncClient(verify=False, http2=True)
|
|
|
| async def post(
|
| self, url: str, data: Any = None, headers: Dict = None, compress: bool = False, default_headers: bool = True, **kwargs
|
| ) -> httpx.Response:
|
| """
|
| Send POST request with optional compression
|
| """
|
| if default_headers:
|
| request_headers = {**DEFAULT_HEADERS, **(headers or {})}
|
| else:
|
| request_headers = headers or {}
|
|
|
| if compress:
|
| from .compression import compress_data
|
|
|
| data = compress_data(data)
|
| request_headers["Content-Encoding"] = "gzip"
|
| request_headers["Connect-Content-Encoding"] = "gzip"
|
| request_headers["Content-Length"] = str(len(data))
|
|
|
|
|
| for param in ['url', 'data', 'stream', 'headers', 'verify', 'timeout']:
|
| kwargs.pop(param, None)
|
|
|
| response = await self.client.post(
|
| url=url,
|
| content=data,
|
| headers=request_headers,
|
| timeout=60,
|
| **kwargs
|
| )
|
| return response
|
|
|
| async def stream_post(
|
| self, url: str, data: Any = None, headers: Dict = None, compress: bool = False, default_headers: bool = True, **kwargs
|
| ) -> AsyncGenerator[bytes, None]:
|
| """
|
| Send POST request with streaming response
|
| Yields chunks of response data as they arrive
|
| """
|
| if default_headers:
|
| request_headers = {**DEFAULT_HEADERS, **(headers or {})}
|
| else:
|
| request_headers = headers or {}
|
|
|
| if compress:
|
| from .compression import compress_data
|
| data = compress_data(data)
|
| request_headers["Content-Encoding"] = "gzip"
|
| request_headers["Connect-Content-Encoding"] = "gzip"
|
| request_headers["Content-Length"] = str(len(data))
|
|
|
|
|
| for param in ['url', 'data', 'stream', 'headers', 'verify', 'timeout']:
|
| kwargs.pop(param, None)
|
|
|
| async with self.client.stream(
|
| method="POST",
|
| url=url,
|
| content=data,
|
| headers=request_headers,
|
| timeout=60,
|
| **kwargs
|
| ) as response:
|
| async for chunk in response.aiter_bytes():
|
| yield chunk
|
|
|
| async def __aenter__(self):
|
| return self
|
|
|
| async def __aexit__(self, exc_type, exc_val, exc_tb):
|
| await self.client.aclose()
|
|
|