import typing from httpx import Response, URL, AsyncClient, HTTPStatusError from httpx._client import UseClientDefault, USE_CLIENT_DEFAULT from httpx._types import ( RequestContent, RequestData, RequestFiles, QueryParamTypes, HeaderTypes, CookieTypes, AuthTypes, TimeoutTypes, RequestExtensions, ) from loguru import logger from mcp.server.fastmcp.exceptions import ToolError async def call_get( client: AsyncClient, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: logger.debug(f"Calling GET '{url}' params: '{params}'") try: response = await client.get( url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) response.raise_for_status() return response except HTTPStatusError as e: logger.error(f"Error calling GET {url}: {e}") raise ToolError(f"Error calling tool: {e}.") from e async def call_put( client: AsyncClient, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: try: response = await client.put( url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) response.raise_for_status() return response except HTTPStatusError as e: logger.error(f"Error calling PUT {url}: {e}") raise ToolError(f"Error calling tool: {e}") from e async def call_post( client: AsyncClient, url: URL | str, *, content: RequestContent | None = None, data: RequestData | None = None, files: RequestFiles | None = None, json: typing.Any | None = None, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: try: response = await client.post( url=url, content=content, data=data, files=files, json=json, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) response.raise_for_status() return response except HTTPStatusError as e: logger.error(f"Error calling POST {url}: {e}") raise ToolError(f"Error calling tool: {e}") from e async def call_delete( client: AsyncClient, url: URL | str, *, params: QueryParamTypes | None = None, headers: HeaderTypes | None = None, cookies: CookieTypes | None = None, auth: AuthTypes | UseClientDefault = USE_CLIENT_DEFAULT, follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT, timeout: TimeoutTypes | UseClientDefault = USE_CLIENT_DEFAULT, extensions: RequestExtensions | None = None, ) -> Response: try: response = await client.delete( url=url, params=params, headers=headers, cookies=cookies, auth=auth, follow_redirects=follow_redirects, timeout=timeout, extensions=extensions, ) response.raise_for_status() return response except HTTPStatusError as e: logger.error(f"Error calling DELETE {url}: {e}") raise ToolError(f"Error calling tool: {e}") from e