proxyhat 0.2.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.
- proxyhat/__init__.py +39 -0
- proxyhat/_base_client.py +104 -0
- proxyhat/async_client.py +124 -0
- proxyhat/client.py +129 -0
- proxyhat/connection.py +90 -0
- proxyhat/errors.py +72 -0
- proxyhat/py.typed +0 -0
- proxyhat/resources/__init__.py +0 -0
- proxyhat/resources/analytics.py +140 -0
- proxyhat/resources/auth.py +155 -0
- proxyhat/resources/coupons.py +99 -0
- proxyhat/resources/email.py +57 -0
- proxyhat/resources/locations.py +227 -0
- proxyhat/resources/payments.py +107 -0
- proxyhat/resources/plans.py +83 -0
- proxyhat/resources/profile.py +75 -0
- proxyhat/resources/proxy_descriptors.py +64 -0
- proxyhat/resources/proxy_presets.py +71 -0
- proxyhat/resources/sub_user_groups.py +77 -0
- proxyhat/resources/sub_users.py +171 -0
- proxyhat/resources/two_factor.py +107 -0
- proxyhat/types/__init__.py +49 -0
- proxyhat/types/analytics.py +52 -0
- proxyhat/types/auth.py +106 -0
- proxyhat/types/coupons.py +39 -0
- proxyhat/types/email.py +13 -0
- proxyhat/types/locations.py +101 -0
- proxyhat/types/payments.py +101 -0
- proxyhat/types/plans.py +59 -0
- proxyhat/types/profile.py +30 -0
- proxyhat/types/proxy_descriptor.py +33 -0
- proxyhat/types/proxy_presets.py +21 -0
- proxyhat/types/sub_user.py +69 -0
- proxyhat/types/sub_user_groups.py +25 -0
- proxyhat/types/two_factor.py +37 -0
- proxyhat-0.2.0.dist-info/METADATA +195 -0
- proxyhat-0.2.0.dist-info/RECORD +39 -0
- proxyhat-0.2.0.dist-info/WHEEL +4 -0
- proxyhat-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.two_factor import RecoveryCodes, TwoFactorEnableResponse, TwoFactorStatus
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TwoFactorResource:
|
|
13
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
def status(self) -> TwoFactorStatus:
|
|
17
|
+
data = self._client.request("GET", "/profile/2fa/status")
|
|
18
|
+
return TwoFactorStatus.from_dict(data)
|
|
19
|
+
|
|
20
|
+
def enable(self) -> TwoFactorEnableResponse:
|
|
21
|
+
data = self._client.request("POST", "/profile/2fa/enable")
|
|
22
|
+
return TwoFactorEnableResponse.from_dict(data)
|
|
23
|
+
|
|
24
|
+
def confirm(self, *, code: str) -> Any:
|
|
25
|
+
return self._client.request("POST", "/profile/2fa/confirm", json={"code": code})
|
|
26
|
+
|
|
27
|
+
def disable(self, *, twofa_code: str) -> Any:
|
|
28
|
+
return self._client.request("POST", "/profile/2fa/disable", json={"twofa_code": twofa_code})
|
|
29
|
+
|
|
30
|
+
def qr_code(self) -> TwoFactorEnableResponse:
|
|
31
|
+
data = self._client.request("GET", "/profile/2fa/qr-code")
|
|
32
|
+
return TwoFactorEnableResponse.from_dict(data)
|
|
33
|
+
|
|
34
|
+
def recovery_codes(self) -> RecoveryCodes:
|
|
35
|
+
data = self._client.request("GET", "/profile/2fa/recovery-codes")
|
|
36
|
+
return RecoveryCodes.from_dict(data)
|
|
37
|
+
|
|
38
|
+
def disable_by_recovery(self, *, recovery_code: str) -> Any:
|
|
39
|
+
return self._client.request(
|
|
40
|
+
"POST", "/profile/2fa/disable-by-recovery-code", json={"recovery_code": recovery_code}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def change_password(
|
|
44
|
+
self,
|
|
45
|
+
*,
|
|
46
|
+
current_password: str,
|
|
47
|
+
password: str,
|
|
48
|
+
password_confirmation: str,
|
|
49
|
+
twofa_code: str | None = None,
|
|
50
|
+
) -> Any:
|
|
51
|
+
body: dict[str, Any] = {
|
|
52
|
+
"current_password": current_password,
|
|
53
|
+
"password": password,
|
|
54
|
+
"password_confirmation": password_confirmation,
|
|
55
|
+
}
|
|
56
|
+
if twofa_code is not None:
|
|
57
|
+
body["twofa_code"] = twofa_code
|
|
58
|
+
return self._client.request("POST", "/profile/password", json=body)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class AsyncTwoFactorResource:
|
|
62
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
63
|
+
self._client = client
|
|
64
|
+
|
|
65
|
+
async def status(self) -> TwoFactorStatus:
|
|
66
|
+
data = await self._client.request("GET", "/profile/2fa/status")
|
|
67
|
+
return TwoFactorStatus.from_dict(data)
|
|
68
|
+
|
|
69
|
+
async def enable(self) -> TwoFactorEnableResponse:
|
|
70
|
+
data = await self._client.request("POST", "/profile/2fa/enable")
|
|
71
|
+
return TwoFactorEnableResponse.from_dict(data)
|
|
72
|
+
|
|
73
|
+
async def confirm(self, *, code: str) -> Any:
|
|
74
|
+
return await self._client.request("POST", "/profile/2fa/confirm", json={"code": code})
|
|
75
|
+
|
|
76
|
+
async def disable(self, *, twofa_code: str) -> Any:
|
|
77
|
+
return await self._client.request("POST", "/profile/2fa/disable", json={"twofa_code": twofa_code})
|
|
78
|
+
|
|
79
|
+
async def qr_code(self) -> TwoFactorEnableResponse:
|
|
80
|
+
data = await self._client.request("GET", "/profile/2fa/qr-code")
|
|
81
|
+
return TwoFactorEnableResponse.from_dict(data)
|
|
82
|
+
|
|
83
|
+
async def recovery_codes(self) -> RecoveryCodes:
|
|
84
|
+
data = await self._client.request("GET", "/profile/2fa/recovery-codes")
|
|
85
|
+
return RecoveryCodes.from_dict(data)
|
|
86
|
+
|
|
87
|
+
async def disable_by_recovery(self, *, recovery_code: str) -> Any:
|
|
88
|
+
return await self._client.request(
|
|
89
|
+
"POST", "/profile/2fa/disable-by-recovery-code", json={"recovery_code": recovery_code}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
async def change_password(
|
|
93
|
+
self,
|
|
94
|
+
*,
|
|
95
|
+
current_password: str,
|
|
96
|
+
password: str,
|
|
97
|
+
password_confirmation: str,
|
|
98
|
+
twofa_code: str | None = None,
|
|
99
|
+
) -> Any:
|
|
100
|
+
body: dict[str, Any] = {
|
|
101
|
+
"current_password": current_password,
|
|
102
|
+
"password": password,
|
|
103
|
+
"password_confirmation": password_confirmation,
|
|
104
|
+
}
|
|
105
|
+
if twofa_code is not None:
|
|
106
|
+
body["twofa_code"] = twofa_code
|
|
107
|
+
return await self._client.request("POST", "/profile/password", json=body)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from proxyhat.types.analytics import DomainBreakdownItem, DomainBreakdownResponse, TimeSeriesResponse, TotalResponse
|
|
2
|
+
from proxyhat.types.auth import LoginResponse, RegisterResponse, SocialAccount, SupportedProvider, TrafficInfo, User
|
|
3
|
+
from proxyhat.types.coupons import Coupon, CouponResponse
|
|
4
|
+
from proxyhat.types.email import EmailChangeResponse
|
|
5
|
+
from proxyhat.types.locations import ISP, City, Country, Region, Zipcode
|
|
6
|
+
from proxyhat.types.payments import Cryptocurrency, Payment, PaymentCreateResponse, PaymentDetails
|
|
7
|
+
from proxyhat.types.plans import RegularPlan, SubscriptionPlan
|
|
8
|
+
from proxyhat.types.profile import APIKey, Preferences
|
|
9
|
+
from proxyhat.types.proxy_presets import ProxyPreset
|
|
10
|
+
from proxyhat.types.sub_user import BulkDeleteResponse, ResetUsageResponse, SubUser
|
|
11
|
+
from proxyhat.types.sub_user_groups import SubUserGroup
|
|
12
|
+
from proxyhat.types.two_factor import RecoveryCodes, TwoFactorEnableResponse, TwoFactorStatus
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"APIKey",
|
|
16
|
+
"BulkDeleteResponse",
|
|
17
|
+
"City",
|
|
18
|
+
"Country",
|
|
19
|
+
"Coupon",
|
|
20
|
+
"CouponResponse",
|
|
21
|
+
"Cryptocurrency",
|
|
22
|
+
"DomainBreakdownItem",
|
|
23
|
+
"DomainBreakdownResponse",
|
|
24
|
+
"EmailChangeResponse",
|
|
25
|
+
"ISP",
|
|
26
|
+
"LoginResponse",
|
|
27
|
+
"Payment",
|
|
28
|
+
"PaymentCreateResponse",
|
|
29
|
+
"PaymentDetails",
|
|
30
|
+
"Preferences",
|
|
31
|
+
"ProxyPreset",
|
|
32
|
+
"RecoveryCodes",
|
|
33
|
+
"Region",
|
|
34
|
+
"RegularPlan",
|
|
35
|
+
"RegisterResponse",
|
|
36
|
+
"ResetUsageResponse",
|
|
37
|
+
"SocialAccount",
|
|
38
|
+
"SubUser",
|
|
39
|
+
"SubUserGroup",
|
|
40
|
+
"SubscriptionPlan",
|
|
41
|
+
"SupportedProvider",
|
|
42
|
+
"TimeSeriesResponse",
|
|
43
|
+
"TotalResponse",
|
|
44
|
+
"TrafficInfo",
|
|
45
|
+
"TwoFactorEnableResponse",
|
|
46
|
+
"TwoFactorStatus",
|
|
47
|
+
"User",
|
|
48
|
+
"Zipcode",
|
|
49
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class TimeSeriesResponse:
|
|
9
|
+
labels: list[str] = field(default_factory=list)
|
|
10
|
+
data: list[int] = field(default_factory=list)
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def from_dict(cls, data: dict[str, Any]) -> TimeSeriesResponse:
|
|
14
|
+
return cls(
|
|
15
|
+
labels=data.get("labels", []),
|
|
16
|
+
data=data.get("data", []),
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class TotalResponse:
|
|
22
|
+
total: int = 0
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def from_dict(cls, data: dict[str, Any]) -> TotalResponse:
|
|
26
|
+
return cls(total=data.get("total", 0))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class DomainBreakdownItem:
|
|
31
|
+
domain: str
|
|
32
|
+
bandwidth: int
|
|
33
|
+
requests: int
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_dict(cls, data: dict[str, Any]) -> DomainBreakdownItem:
|
|
37
|
+
return cls(
|
|
38
|
+
domain=data.get("domain", ""),
|
|
39
|
+
bandwidth=data.get("bandwidth", 0),
|
|
40
|
+
requests=data.get("requests", 0),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class DomainBreakdownResponse:
|
|
46
|
+
items: list[DomainBreakdownItem] = field(default_factory=list)
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_dict(cls, data: dict[str, Any]) -> DomainBreakdownResponse:
|
|
50
|
+
return cls(
|
|
51
|
+
items=[DomainBreakdownItem.from_dict(item) for item in data.get("items", [])],
|
|
52
|
+
)
|
proxyhat/types/auth.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class RegisterResponse:
|
|
9
|
+
message: str
|
|
10
|
+
access_token: str
|
|
11
|
+
token_type: str
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def from_dict(cls, data: dict[str, Any]) -> RegisterResponse:
|
|
15
|
+
return cls(
|
|
16
|
+
message=data.get("message", ""),
|
|
17
|
+
access_token=data.get("accessToken", ""),
|
|
18
|
+
token_type=data.get("tokenType", ""),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class LoginResponse:
|
|
24
|
+
access_token: str
|
|
25
|
+
token_type: str
|
|
26
|
+
requires_2fa: bool = False
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def from_dict(cls, data: dict[str, Any]) -> LoginResponse:
|
|
30
|
+
return cls(
|
|
31
|
+
access_token=data.get("accessToken", ""),
|
|
32
|
+
token_type=data.get("tokenType", ""),
|
|
33
|
+
requires_2fa=data.get("requires_2fa", False),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class TrafficInfo:
|
|
39
|
+
subscription: str | None
|
|
40
|
+
subscription_starts_at: str | None
|
|
41
|
+
subscription_expires_at: str | None
|
|
42
|
+
regular_bytes: int
|
|
43
|
+
regular_human: str
|
|
44
|
+
subscription_bytes: int
|
|
45
|
+
subscription_human: str
|
|
46
|
+
total_bytes: int
|
|
47
|
+
total_human: str
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def from_dict(cls, data: dict[str, Any]) -> TrafficInfo:
|
|
51
|
+
return cls(
|
|
52
|
+
subscription=data.get("subscription"),
|
|
53
|
+
subscription_starts_at=data.get("subscription_starts_at"),
|
|
54
|
+
subscription_expires_at=data.get("subscription_expires_at"),
|
|
55
|
+
regular_bytes=data.get("regular_bytes", 0),
|
|
56
|
+
regular_human=data.get("regular_human", ""),
|
|
57
|
+
subscription_bytes=data.get("subscription_bytes", 0),
|
|
58
|
+
subscription_human=data.get("subscription_human", ""),
|
|
59
|
+
total_bytes=data.get("total_bytes", 0),
|
|
60
|
+
total_human=data.get("total_human", ""),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class User:
|
|
66
|
+
uuid: str
|
|
67
|
+
name: str
|
|
68
|
+
email: str
|
|
69
|
+
traffic: TrafficInfo
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_dict(cls, data: dict[str, Any]) -> User:
|
|
73
|
+
return cls(
|
|
74
|
+
uuid=data.get("uuid", ""),
|
|
75
|
+
name=data.get("name", ""),
|
|
76
|
+
email=data.get("email", ""),
|
|
77
|
+
traffic=TrafficInfo.from_dict(data.get("traffic", {})),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class SupportedProvider:
|
|
83
|
+
name: str
|
|
84
|
+
slug: str
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def from_dict(cls, data: dict[str, Any]) -> SupportedProvider:
|
|
88
|
+
return cls(
|
|
89
|
+
name=data.get("name", ""),
|
|
90
|
+
slug=data.get("slug", ""),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class SocialAccount:
|
|
96
|
+
provider: str
|
|
97
|
+
email: str | None
|
|
98
|
+
connected_at: str | None
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def from_dict(cls, data: dict[str, Any]) -> SocialAccount:
|
|
102
|
+
return cls(
|
|
103
|
+
provider=data.get("provider", ""),
|
|
104
|
+
email=data.get("email"),
|
|
105
|
+
connected_at=data.get("connected_at"),
|
|
106
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class Coupon:
|
|
9
|
+
id: str
|
|
10
|
+
code: str
|
|
11
|
+
type: str
|
|
12
|
+
data: Any
|
|
13
|
+
discount: float | None = None
|
|
14
|
+
final_amount: float | None = None
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_dict(cls, data: dict[str, Any]) -> Coupon:
|
|
18
|
+
return cls(
|
|
19
|
+
id=data.get("id", ""),
|
|
20
|
+
code=data.get("code", ""),
|
|
21
|
+
type=data.get("type", ""),
|
|
22
|
+
data=data.get("data"),
|
|
23
|
+
discount=data.get("discount"),
|
|
24
|
+
final_amount=data.get("final_amount"),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class CouponResponse:
|
|
30
|
+
success: bool
|
|
31
|
+
coupon: Coupon | None = None
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def from_dict(cls, data: dict[str, Any]) -> CouponResponse:
|
|
35
|
+
coupon_data = data.get("coupon")
|
|
36
|
+
return cls(
|
|
37
|
+
success=data.get("success", False),
|
|
38
|
+
coupon=Coupon.from_dict(coupon_data) if coupon_data else None,
|
|
39
|
+
)
|
proxyhat/types/email.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class EmailChangeResponse:
|
|
9
|
+
message: str
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def from_dict(cls, data: dict[str, Any]) -> EmailChangeResponse:
|
|
13
|
+
return cls(message=data.get("message", ""))
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class Country:
|
|
9
|
+
code: str
|
|
10
|
+
name: str
|
|
11
|
+
availability: str
|
|
12
|
+
connection_type: str
|
|
13
|
+
|
|
14
|
+
@classmethod
|
|
15
|
+
def from_dict(cls, data: dict[str, Any]) -> Country:
|
|
16
|
+
return cls(
|
|
17
|
+
code=data.get("code", ""),
|
|
18
|
+
name=data.get("name", ""),
|
|
19
|
+
availability=data.get("availability", ""),
|
|
20
|
+
connection_type=data.get("connection_type", ""),
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class Region:
|
|
26
|
+
code: str
|
|
27
|
+
name: str
|
|
28
|
+
country_code: str
|
|
29
|
+
availability: str | None = None
|
|
30
|
+
connection_type: str | None = None
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def from_dict(cls, data: dict[str, Any]) -> Region:
|
|
34
|
+
return cls(
|
|
35
|
+
code=data.get("code", ""),
|
|
36
|
+
name=data.get("name", ""),
|
|
37
|
+
country_code=data.get("country_code", ""),
|
|
38
|
+
availability=data.get("availability"),
|
|
39
|
+
connection_type=data.get("connection_type"),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class City:
|
|
45
|
+
code: str
|
|
46
|
+
name: str
|
|
47
|
+
country_code: str
|
|
48
|
+
region_code: str | None = None
|
|
49
|
+
availability: str | None = None
|
|
50
|
+
connection_type: str | None = None
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_dict(cls, data: dict[str, Any]) -> City:
|
|
54
|
+
return cls(
|
|
55
|
+
code=data.get("code", ""),
|
|
56
|
+
name=data.get("name", ""),
|
|
57
|
+
country_code=data.get("country_code", ""),
|
|
58
|
+
region_code=data.get("region_code"),
|
|
59
|
+
availability=data.get("availability"),
|
|
60
|
+
connection_type=data.get("connection_type"),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class ISP:
|
|
66
|
+
code: str
|
|
67
|
+
name: str
|
|
68
|
+
country_code: str
|
|
69
|
+
availability: str | None = None
|
|
70
|
+
connection_type: str | None = None
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def from_dict(cls, data: dict[str, Any]) -> ISP:
|
|
74
|
+
return cls(
|
|
75
|
+
code=data.get("code", ""),
|
|
76
|
+
name=data.get("name", ""),
|
|
77
|
+
country_code=data.get("country_code", ""),
|
|
78
|
+
availability=data.get("availability"),
|
|
79
|
+
connection_type=data.get("connection_type"),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class Zipcode:
|
|
85
|
+
code: str
|
|
86
|
+
name: str
|
|
87
|
+
country_code: str
|
|
88
|
+
city_code: str | None = None
|
|
89
|
+
availability: str | None = None
|
|
90
|
+
connection_type: str | None = None
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def from_dict(cls, data: dict[str, Any]) -> Zipcode:
|
|
94
|
+
return cls(
|
|
95
|
+
code=data.get("code", ""),
|
|
96
|
+
name=data.get("name", ""),
|
|
97
|
+
country_code=data.get("country_code", ""),
|
|
98
|
+
city_code=data.get("city_code"),
|
|
99
|
+
availability=data.get("availability"),
|
|
100
|
+
connection_type=data.get("connection_type"),
|
|
101
|
+
)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class PaymentCreateResponse:
|
|
9
|
+
success: bool
|
|
10
|
+
payment_id: str
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def from_dict(cls, data: dict[str, Any]) -> PaymentCreateResponse:
|
|
14
|
+
return cls(
|
|
15
|
+
success=data.get("success", False),
|
|
16
|
+
payment_id=data.get("payment_id", ""),
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class CryptoInfo:
|
|
22
|
+
code: str
|
|
23
|
+
currency: str
|
|
24
|
+
network: str
|
|
25
|
+
icon: str | None = None
|
|
26
|
+
label: str | None = None
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def from_dict(cls, data: dict[str, Any]) -> CryptoInfo:
|
|
30
|
+
return cls(
|
|
31
|
+
code=data.get("code", ""),
|
|
32
|
+
currency=data.get("currency", ""),
|
|
33
|
+
network=data.get("network", ""),
|
|
34
|
+
icon=data.get("icon"),
|
|
35
|
+
label=data.get("label"),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class PaymentDetails:
|
|
41
|
+
pay_address: str
|
|
42
|
+
crypto_amount: float
|
|
43
|
+
amount_usd: float
|
|
44
|
+
crypto: CryptoInfo
|
|
45
|
+
status: str
|
|
46
|
+
tx_hash: str | None = None
|
|
47
|
+
expires_at: str | None = None
|
|
48
|
+
completed_at: str | None = None
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def from_dict(cls, data: dict[str, Any]) -> PaymentDetails:
|
|
52
|
+
return cls(
|
|
53
|
+
pay_address=data.get("pay_address", ""),
|
|
54
|
+
crypto_amount=data.get("crypto_amount", 0.0),
|
|
55
|
+
amount_usd=data.get("amount_usd", 0.0),
|
|
56
|
+
crypto=CryptoInfo.from_dict(data.get("crypto", {})),
|
|
57
|
+
status=data.get("status", ""),
|
|
58
|
+
tx_hash=data.get("tx_hash"),
|
|
59
|
+
expires_at=data.get("expires_at"),
|
|
60
|
+
completed_at=data.get("completed_at"),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class Payment:
|
|
66
|
+
id: str
|
|
67
|
+
type: str
|
|
68
|
+
status: str
|
|
69
|
+
amount: float | None = None
|
|
70
|
+
currency: str | None = None
|
|
71
|
+
created_at: str | None = None
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def from_dict(cls, data: dict[str, Any]) -> Payment:
|
|
75
|
+
return cls(
|
|
76
|
+
id=data.get("id", ""),
|
|
77
|
+
type=data.get("type", ""),
|
|
78
|
+
status=data.get("status", ""),
|
|
79
|
+
amount=data.get("amount"),
|
|
80
|
+
currency=data.get("currency"),
|
|
81
|
+
created_at=data.get("created_at"),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class Cryptocurrency:
|
|
87
|
+
code: str
|
|
88
|
+
currency: str
|
|
89
|
+
network: str
|
|
90
|
+
icon: str | None = None
|
|
91
|
+
label: str | None = None
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def from_dict(cls, data: dict[str, Any]) -> Cryptocurrency:
|
|
95
|
+
return cls(
|
|
96
|
+
code=data.get("code", ""),
|
|
97
|
+
currency=data.get("currency", ""),
|
|
98
|
+
network=data.get("network", ""),
|
|
99
|
+
icon=data.get("icon"),
|
|
100
|
+
label=data.get("label"),
|
|
101
|
+
)
|
proxyhat/types/plans.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class RegularPlan:
|
|
9
|
+
id: str
|
|
10
|
+
name: str
|
|
11
|
+
gb: int
|
|
12
|
+
price_per_gb: float
|
|
13
|
+
price_total: float
|
|
14
|
+
currency: str
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_dict(cls, data: dict[str, Any]) -> RegularPlan:
|
|
18
|
+
return cls(
|
|
19
|
+
id=data.get("id", ""),
|
|
20
|
+
name=data.get("name", ""),
|
|
21
|
+
gb=data.get("gb", 0),
|
|
22
|
+
price_per_gb=data.get("price_per_gb", 0.0),
|
|
23
|
+
price_total=data.get("price_total", 0.0),
|
|
24
|
+
currency=data.get("currency", "USD"),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class SubscriptionPlan:
|
|
30
|
+
id: str
|
|
31
|
+
name: str
|
|
32
|
+
gb: int
|
|
33
|
+
price_per_gb: float
|
|
34
|
+
price_total: float
|
|
35
|
+
period: str
|
|
36
|
+
rollover_enabled: bool = False
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_dict(cls, data: dict[str, Any]) -> SubscriptionPlan:
|
|
40
|
+
return cls(
|
|
41
|
+
id=data.get("id", ""),
|
|
42
|
+
name=data.get("name", ""),
|
|
43
|
+
gb=data.get("gb", 0),
|
|
44
|
+
price_per_gb=data.get("price_per_gb", 0.0),
|
|
45
|
+
price_total=data.get("price_total", 0.0),
|
|
46
|
+
period=data.get("period", ""),
|
|
47
|
+
rollover_enabled=data.get("rollover_enabled", False),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class PublicPricing:
|
|
53
|
+
plans: list[Any]
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def from_dict(cls, data: Any) -> PublicPricing:
|
|
57
|
+
if isinstance(data, list):
|
|
58
|
+
return cls(plans=data)
|
|
59
|
+
return cls(plans=data.get("plans", []))
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class Preferences:
|
|
9
|
+
data: dict[str, Any]
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def from_dict(cls, data: dict[str, Any]) -> Preferences:
|
|
13
|
+
return cls(data=data)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class APIKey:
|
|
18
|
+
id: str
|
|
19
|
+
name: str | None
|
|
20
|
+
plain_text_token: str | None = None
|
|
21
|
+
created_at: str | None = None
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def from_dict(cls, data: dict[str, Any]) -> APIKey:
|
|
25
|
+
return cls(
|
|
26
|
+
id=data.get("id", ""),
|
|
27
|
+
name=data.get("name"),
|
|
28
|
+
plain_text_token=data.get("plain_text_token"),
|
|
29
|
+
created_at=data.get("created_at"),
|
|
30
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class ProxyDescriptor:
|
|
9
|
+
"""Server-built connection descriptor (POST /v1/proxy-descriptors)."""
|
|
10
|
+
|
|
11
|
+
provider_id: str
|
|
12
|
+
sub_user_uuid: str
|
|
13
|
+
protocol: str
|
|
14
|
+
filter: str
|
|
15
|
+
host: str
|
|
16
|
+
port: int
|
|
17
|
+
username: str
|
|
18
|
+
password: str
|
|
19
|
+
url: str
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_dict(cls, data: dict[str, Any]) -> ProxyDescriptor:
|
|
23
|
+
return cls(
|
|
24
|
+
provider_id=data.get("provider_id", ""),
|
|
25
|
+
sub_user_uuid=data.get("sub_user_uuid", ""),
|
|
26
|
+
protocol=data.get("protocol", ""),
|
|
27
|
+
filter=data.get("filter", ""),
|
|
28
|
+
host=data.get("host", ""),
|
|
29
|
+
port=data.get("port", 0),
|
|
30
|
+
username=data.get("username", ""),
|
|
31
|
+
password=data.get("password", ""),
|
|
32
|
+
url=data.get("url", ""),
|
|
33
|
+
)
|