photonhq-api 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.
- photon_api/__init__.py +18 -0
- photon_api/_model_base.py +62 -0
- photon_api/client.py +79 -0
- photon_api/config_generated.py +2 -0
- photon_api/errors.py +62 -0
- photon_api/generated/__init__.py +1 -0
- photon_api/generated/models.py +29622 -0
- photon_api/py.typed +0 -0
- photon_api/rpc_generated.py +7128 -0
- photon_api/transport.py +344 -0
- photonhq_api-0.1.0.dist-info/METADATA +234 -0
- photonhq_api-0.1.0.dist-info/RECORD +14 -0
- photonhq_api-0.1.0.dist-info/WHEEL +4 -0
- photonhq_api-0.1.0.dist-info/licenses/LICENSE +22 -0
photon_api/__init__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .client import AsyncPhoton, Photon
|
|
2
|
+
from .errors import (
|
|
3
|
+
ApiError,
|
|
4
|
+
PhotonError,
|
|
5
|
+
ResponseValidationError,
|
|
6
|
+
TransportError,
|
|
7
|
+
)
|
|
8
|
+
from .transport import RawResponse
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ApiError",
|
|
12
|
+
"AsyncPhoton",
|
|
13
|
+
"Photon",
|
|
14
|
+
"PhotonError",
|
|
15
|
+
"RawResponse",
|
|
16
|
+
"ResponseValidationError",
|
|
17
|
+
"TransportError",
|
|
18
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Base classes and helpers of the generated models (tools/python-codegen).
|
|
2
|
+
|
|
3
|
+
The models carry the contract's types; values the contract restricts only by
|
|
4
|
+
validation keywords (patterns, lengths, bounds, sizes) are left to the service.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Annotated, Any, Generic, TypeVar
|
|
8
|
+
|
|
9
|
+
from pydantic import AfterValidator, ConfigDict, TypeAdapter
|
|
10
|
+
from pydantic import BaseModel as PydanticBaseModel
|
|
11
|
+
from pydantic import RootModel as PydanticRootModel
|
|
12
|
+
|
|
13
|
+
T = TypeVar("T")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseModel(PydanticBaseModel):
|
|
17
|
+
# Members the SDK does not know are kept (a response may gain fields).
|
|
18
|
+
model_config = ConfigDict(extra="allow", defer_build=True)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RootModel(PydanticRootModel[T], Generic[T]):
|
|
22
|
+
model_config = ConfigDict(defer_build=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def validate_all_of(data: Any, *constraints: type[PydanticBaseModel]) -> Any:
|
|
26
|
+
"""Check the input of a union narrowed by object constraints against each constraint.
|
|
27
|
+
|
|
28
|
+
Generated (tools/python-codegen/intersections.py) as a `mode="before"`
|
|
29
|
+
validator: every constraint model validates the value as given, and the
|
|
30
|
+
root type validates the union; the value is valid only if all accept it.
|
|
31
|
+
A model instance is checked through its JSON form.
|
|
32
|
+
"""
|
|
33
|
+
raw = (
|
|
34
|
+
data.model_dump(mode="json", by_alias=True) if isinstance(data, PydanticBaseModel) else data
|
|
35
|
+
)
|
|
36
|
+
for constraint in constraints:
|
|
37
|
+
constraint.model_validate(raw)
|
|
38
|
+
return data
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class PrefixItems:
|
|
42
|
+
"""`PrefixItems[T1, ..., Tn]`: a JSON Schema `prefixItems` array without `items`.
|
|
43
|
+
|
|
44
|
+
Item i, when present, validates as Ti; later items are unconstrained, and
|
|
45
|
+
the array may be shorter than n. Generated for arrays whose positional
|
|
46
|
+
items the model generator would otherwise drop
|
|
47
|
+
(tools/python-codegen/prefix_items.py). The value is a `list`.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __class_getitem__(cls, params: Any) -> Any:
|
|
51
|
+
types = params if isinstance(params, tuple) else (params,)
|
|
52
|
+
adapters: list[TypeAdapter[Any]] = []
|
|
53
|
+
|
|
54
|
+
def validate(value: list[Any]) -> list[Any]:
|
|
55
|
+
if not adapters:
|
|
56
|
+
adapters.extend(TypeAdapter(item) for item in types)
|
|
57
|
+
return [
|
|
58
|
+
adapters[index].validate_python(item) if index < len(adapters) else item
|
|
59
|
+
for index, item in enumerate(value)
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
return Annotated[list[Any], AfterValidator(validate)]
|
photon_api/client.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from .config_generated import DEFAULT_BASE_URL
|
|
8
|
+
from .rpc_generated import AsyncRoot, SyncRoot
|
|
9
|
+
from .transport import (
|
|
10
|
+
DEFAULT_MAX_RETRY_AFTER,
|
|
11
|
+
AsyncHeaderProvider,
|
|
12
|
+
AsyncTransport,
|
|
13
|
+
SyncHeaderProvider,
|
|
14
|
+
SyncTransport,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Photon(SyncRoot):
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
23
|
+
headers: SyncHeaderProvider | None = None,
|
|
24
|
+
timeout: float = 30.0,
|
|
25
|
+
max_attempts: int = 3,
|
|
26
|
+
client: httpx.Client | None = None,
|
|
27
|
+
max_retry_after: float = DEFAULT_MAX_RETRY_AFTER,
|
|
28
|
+
) -> None:
|
|
29
|
+
self._transport = SyncTransport(
|
|
30
|
+
base_url=base_url,
|
|
31
|
+
headers=headers,
|
|
32
|
+
timeout=timeout,
|
|
33
|
+
max_attempts=max_attempts,
|
|
34
|
+
client=client,
|
|
35
|
+
max_retry_after=max_retry_after,
|
|
36
|
+
)
|
|
37
|
+
super().__init__(self._transport)
|
|
38
|
+
self.raw = SyncRoot(self._transport, raw=True)
|
|
39
|
+
|
|
40
|
+
def close(self) -> None:
|
|
41
|
+
self._transport.close()
|
|
42
|
+
|
|
43
|
+
def __enter__(self) -> Photon:
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
def __exit__(self, *_: Any) -> None:
|
|
47
|
+
self.close()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AsyncPhoton(AsyncRoot):
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
*,
|
|
54
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
55
|
+
headers: AsyncHeaderProvider | None = None,
|
|
56
|
+
timeout: float = 30.0,
|
|
57
|
+
max_attempts: int = 3,
|
|
58
|
+
client: httpx.AsyncClient | None = None,
|
|
59
|
+
max_retry_after: float = DEFAULT_MAX_RETRY_AFTER,
|
|
60
|
+
) -> None:
|
|
61
|
+
self._transport = AsyncTransport(
|
|
62
|
+
base_url=base_url,
|
|
63
|
+
headers=headers,
|
|
64
|
+
timeout=timeout,
|
|
65
|
+
max_attempts=max_attempts,
|
|
66
|
+
client=client,
|
|
67
|
+
max_retry_after=max_retry_after,
|
|
68
|
+
)
|
|
69
|
+
super().__init__(self._transport)
|
|
70
|
+
self.raw = AsyncRoot(self._transport, raw=True)
|
|
71
|
+
|
|
72
|
+
async def close(self) -> None:
|
|
73
|
+
await self._transport.close()
|
|
74
|
+
|
|
75
|
+
async def __aenter__(self) -> AsyncPhoton:
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
async def __aexit__(self, *_: Any) -> None:
|
|
79
|
+
await self.close()
|
photon_api/errors.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PhotonError(Exception):
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
message: str,
|
|
10
|
+
*,
|
|
11
|
+
operation_id: str | None = None,
|
|
12
|
+
request_id: str | None = None,
|
|
13
|
+
) -> None:
|
|
14
|
+
super().__init__(message)
|
|
15
|
+
self.operation_id = operation_id
|
|
16
|
+
self.request_id = request_id
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ResponseValidationError(PhotonError):
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
message: str,
|
|
23
|
+
*,
|
|
24
|
+
status: int,
|
|
25
|
+
raw_body: str,
|
|
26
|
+
operation_id: str,
|
|
27
|
+
request_id: str | None,
|
|
28
|
+
) -> None:
|
|
29
|
+
super().__init__(
|
|
30
|
+
message,
|
|
31
|
+
operation_id=operation_id,
|
|
32
|
+
request_id=request_id,
|
|
33
|
+
)
|
|
34
|
+
self.status = status
|
|
35
|
+
self.raw_body = raw_body
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TransportError(PhotonError):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ApiError(PhotonError):
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
message: str,
|
|
46
|
+
*,
|
|
47
|
+
status: int,
|
|
48
|
+
headers: dict[str, str],
|
|
49
|
+
body: Any,
|
|
50
|
+
raw_body: str,
|
|
51
|
+
operation_id: str,
|
|
52
|
+
request_id: str | None,
|
|
53
|
+
) -> None:
|
|
54
|
+
super().__init__(
|
|
55
|
+
message,
|
|
56
|
+
operation_id=operation_id,
|
|
57
|
+
request_id=request_id,
|
|
58
|
+
)
|
|
59
|
+
self.status = status
|
|
60
|
+
self.headers = headers
|
|
61
|
+
self.body = body
|
|
62
|
+
self.raw_body = raw_body
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .models import *
|