manikandanj's picture
Prepare AI Time Machine hackathon Space
5862322 verified
Raw
History Blame Contribute Delete
2.09 kB
from __future__ import annotations
import json
import urllib.error
import urllib.request
from typing import Any
from time_machine.domain.errors import AdapterConfigurationError
class ModalEndpointClient:
def __init__(
self,
url: str,
timeout_seconds: float = 120.0,
bearer_token: str | None = None,
) -> None:
clean_url = url.strip()
if not clean_url:
raise AdapterConfigurationError("Modal endpoint URL must not be empty.")
self.url = clean_url
self.timeout_seconds = timeout_seconds
self.bearer_token = bearer_token.strip() if bearer_token else None
def post_json(self, payload: dict[str, Any]) -> dict[str, Any]:
body = json.dumps(payload).encode("utf-8")
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
if self.bearer_token:
headers["Authorization"] = f"Bearer {self.bearer_token}"
request = urllib.request.Request(
self.url,
data=body,
headers=headers,
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=self.timeout_seconds) as response:
response_body = response.read().decode("utf-8")
except urllib.error.HTTPError as exc:
detail = exc.read().decode("utf-8", errors="replace")
raise RuntimeError(
f"Modal endpoint {self.url} returned HTTP {exc.code}: {detail}"
) from exc
except urllib.error.URLError as exc:
raise RuntimeError(f"Modal endpoint {self.url} is not reachable: {exc}") from exc
try:
decoded = json.loads(response_body)
except json.JSONDecodeError as exc:
raise RuntimeError(
f"Modal endpoint {self.url} returned non-JSON response."
) from exc
if not isinstance(decoded, dict):
raise RuntimeError(f"Modal endpoint {self.url} returned a non-object JSON value.")
return decoded