{
  "files": [
    "httpx_wrapper.py",
    "test_httpx_wrapper.py"
  ],
  "edits": [
    {
      "file": "httpx_wrapper.py",
      "content": "import httpx\nfrom typing import Any\n\nclass HTTPClientWrapper:\n    def __init__(self, default_timeout: float = 10.0):\n        self.default_timeout = default_timeout\n        self.client = httpx.Client()\n\n    def request(self, method: str, url: str, **kwargs: Any) -> httpx.Response:\n        # Preserve original signature; inject timeout internally\n        safe_kwargs = kwargs.copy()\n        if \"timeout\" not in safe_kwargs:\n            safe_kwargs[\"timeout\"] = self.default_timeout\n        elif isinstance(safe_kwargs[\"timeout\"], (int, float)):\n            safe_kwargs[\"timeout\"] = httpx.Timeout(safe_kwargs[\"timeout\"])\n        return self.client.request(method, url, **safe_kwargs)\n\n    def close(self):\n        self.client.close()\n"
    },
    {
      "file": "test_httpx_wrapper.py",
      "content": "import pytest\nimport httpx\nfrom unittest.mock import patch, MagicMock\nfrom httpx_wrapper import HTTPClientWrapper\n\n@pytest.fixture\ndef wrapper():\n    return HTTPClientWrapper(default_timeout=5.0)\n\ndef test_default_timeout_applied(wrapper):\n    with patch.object(wrapper.client, 'request', return_value=MagicMock()) as mock_req:\n        wrapper.request('GET', 'http://example.com')\n        call_kwargs = mock_req.call_args[1]\n        assert 'timeout' in call_kwargs\n        assert isinstance(call_kwargs['timeout'], httpx.Timeout)\n        assert call_kwargs['timeout'].connect == 5.0\n\ndef test_explicit_timeout_override(wrapper):\n    with patch.object(wrapper.client, 'request', return_value=MagicMock()) as mock_req:\n        wrapper.request('GET', 'http://example.com', timeout=15.0)\n        call_kwargs = mock_req.call_args[1]\n        assert isinstance(call_kwargs['timeout'], httpx.Timeout)\n        assert call_kwargs['timeout'].connect == 15.0\n\ndef test_signature_unchanged(wrapper):\n    import inspect\n    sig = inspect.signature(wrapper.request)\n    params = list(sig.parameters.keys())\n    assert params == ['method', 'url', 'kwargs']\n\ndef test_original_kwargs_unchanged(wrapper):\n    original_kwargs = {'headers': {'X-Test': '1'}}\n    with patch.object(wrapper.client, 'request', return_value=MagicMock()) as mock_req:\n        wrapper.request('GET', 'http://example.com', **original_kwargs)\n        assert 'timeout' not in original_kwargs\n"
    }
  ],
  "tests": [
    "pytest test_httpx_wrapper.py -v"
  ],
  "risks": [
    "Modifying kwargs in-place could leak the timeout into the caller's dictionary; using .copy() mitigates this but adds minor overhead.",
    "httpx.Timeout constructor with a single float sets connect/read/write/pool defaults; explicit timeout objects passed by callers are preserved, but type coercion might surprise users expecting raw floats to map differently.",
    "Synchronous client blocks the event loop; if the wrapper is used in async code, it will cause deadlocks. Consider providing an async variant or using httpx.AsyncClient with context managers.",
    "Missing context manager support (__enter__/__exit__) may lead to connection leaks if close() is forgotten. Adding context manager protocol is recommended for production use."
  ]
}