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.
@@ -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
+ )
@@ -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
+ )
@@ -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
+ )