captapi 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
captapi/_transport.py ADDED
@@ -0,0 +1,99 @@
1
+ """HTTP transports for the generated Captapi SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ import httpx
9
+
10
+ DEFAULT_BASE_URL = "https://api.captapi.com"
11
+
12
+
13
+ class CaptapiError(Exception):
14
+ """Raised for every failed request. Never fails silently."""
15
+
16
+ def __init__(self, message: str, status_code: int = 0, code: str | None = None, detail: Any = None) -> None:
17
+ super().__init__(message)
18
+ self.status_code = status_code
19
+ self.code = code
20
+ self.detail = detail
21
+
22
+
23
+ def _resolve_key(api_key: str | None) -> str:
24
+ key = api_key or os.environ.get("CAPTAPI_API_KEY")
25
+ if not key:
26
+ raise CaptapiError(
27
+ "Missing API key. Pass api_key= or set CAPTAPI_API_KEY. "
28
+ "Get one at https://captapi.com/dashboard/api-keys",
29
+ status_code=401,
30
+ code="missing_api_key",
31
+ )
32
+ return key
33
+
34
+
35
+ def _clean_params(params: dict[str, Any]) -> dict[str, Any]:
36
+ return {k: v for k, v in params.items() if v is not None}
37
+
38
+
39
+ def _check(response: httpx.Response, path: str) -> dict[str, Any]:
40
+ try:
41
+ body: Any = response.json()
42
+ except Exception:
43
+ body = None
44
+
45
+ ok = response.status_code < 400 and not (isinstance(body, dict) and body.get("success") is False)
46
+ if not ok:
47
+ detail = body.get("detail") or body.get("error") if isinstance(body, dict) else body
48
+ code = None
49
+ if isinstance(detail, dict) and detail.get("error"):
50
+ code = str(detail["error"])
51
+ elif isinstance(body, dict) and isinstance(body.get("error"), str):
52
+ code = body["error"]
53
+ raise CaptapiError(
54
+ f"Captapi {path} returned {response.status_code}: {detail!r}",
55
+ status_code=response.status_code,
56
+ code=code,
57
+ detail=detail,
58
+ )
59
+ if not isinstance(body, dict):
60
+ raise CaptapiError(f"Captapi {path} returned a non-JSON response", status_code=response.status_code)
61
+ return body
62
+
63
+
64
+ class SyncTransport:
65
+ def __init__(self, api_key: str | None = None, base_url: str | None = None, timeout: float = 120.0) -> None:
66
+ self._client = httpx.Client(
67
+ base_url=(base_url or DEFAULT_BASE_URL).rstrip("/"),
68
+ headers={"authorization": f"Bearer {_resolve_key(api_key)}", "accept": "application/json"},
69
+ timeout=timeout,
70
+ )
71
+
72
+ def get(self, path: str, params: dict[str, Any]) -> dict[str, Any]:
73
+ try:
74
+ response = self._client.get(path, params=_clean_params(params))
75
+ except httpx.HTTPError as exc:
76
+ raise CaptapiError(f"Request to {path} failed: {exc}", code="network_error") from exc
77
+ return _check(response, path)
78
+
79
+ def close(self) -> None:
80
+ self._client.close()
81
+
82
+
83
+ class AsyncTransport:
84
+ def __init__(self, api_key: str | None = None, base_url: str | None = None, timeout: float = 120.0) -> None:
85
+ self._client = httpx.AsyncClient(
86
+ base_url=(base_url or DEFAULT_BASE_URL).rstrip("/"),
87
+ headers={"authorization": f"Bearer {_resolve_key(api_key)}", "accept": "application/json"},
88
+ timeout=timeout,
89
+ )
90
+
91
+ async def get(self, path: str, params: dict[str, Any]) -> dict[str, Any]:
92
+ try:
93
+ response = await self._client.get(path, params=_clean_params(params))
94
+ except httpx.HTTPError as exc:
95
+ raise CaptapiError(f"Request to {path} failed: {exc}", code="network_error") from exc
96
+ return _check(response, path)
97
+
98
+ async def aclose(self) -> None:
99
+ await self._client.aclose()
Binary file
@@ -0,0 +1,6 @@
1
+ captapi/__init__.py,sha256=UVBOsOYW9gsjxn5rnjX5Sk_s_Ruhnv5WGDvDk3X4oX4,651
2
+ captapi/_generated.py,sha256=dPA8MDZBEyiuj_ju3aPbGaRVjeFmkdzSX1pgCmhfnwo,201758
3
+ captapi/_transport.py,sha256=7VMmJ3YqiDJXvbPrcvZpmM_JrhIe0eV1UAOv__LDFhU,3571
4
+ captapi-0.1.0.dist-info/METADATA,sha256=ZocKfyLHZnITUXB0Ofbf3i2EGu4CTcNpu6J-wxEqNHI,5299
5
+ captapi-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
6
+ captapi-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any