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,140 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.analytics import DomainBreakdownResponse, TimeSeriesResponse, TotalResponse
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _analytics_body(
|
|
13
|
+
period: str = "24h",
|
|
14
|
+
start_date: str | None = None,
|
|
15
|
+
end_date: str | None = None,
|
|
16
|
+
) -> dict[str, Any]:
|
|
17
|
+
body: dict[str, Any] = {"period": period}
|
|
18
|
+
body["start_date"] = start_date
|
|
19
|
+
body["end_date"] = end_date
|
|
20
|
+
return body
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AnalyticsResource:
|
|
24
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
25
|
+
self._client = client
|
|
26
|
+
|
|
27
|
+
def traffic(
|
|
28
|
+
self,
|
|
29
|
+
*,
|
|
30
|
+
period: str = "24h",
|
|
31
|
+
start_date: str | None = None,
|
|
32
|
+
end_date: str | None = None,
|
|
33
|
+
) -> TimeSeriesResponse:
|
|
34
|
+
body = _analytics_body(period, start_date, end_date)
|
|
35
|
+
data = self._client.request("POST", "/traffic", json=body)
|
|
36
|
+
return TimeSeriesResponse.from_dict(data)
|
|
37
|
+
|
|
38
|
+
def traffic_total(
|
|
39
|
+
self,
|
|
40
|
+
*,
|
|
41
|
+
period: str = "24h",
|
|
42
|
+
start_date: str | None = None,
|
|
43
|
+
end_date: str | None = None,
|
|
44
|
+
) -> TotalResponse:
|
|
45
|
+
body = _analytics_body(period, start_date, end_date)
|
|
46
|
+
data = self._client.request("POST", "/traffic/period-total", json=body)
|
|
47
|
+
return TotalResponse.from_dict(data)
|
|
48
|
+
|
|
49
|
+
def requests(
|
|
50
|
+
self,
|
|
51
|
+
*,
|
|
52
|
+
period: str = "24h",
|
|
53
|
+
start_date: str | None = None,
|
|
54
|
+
end_date: str | None = None,
|
|
55
|
+
) -> TimeSeriesResponse:
|
|
56
|
+
body = _analytics_body(period, start_date, end_date)
|
|
57
|
+
data = self._client.request("POST", "/requests", json=body)
|
|
58
|
+
return TimeSeriesResponse.from_dict(data)
|
|
59
|
+
|
|
60
|
+
def requests_total(
|
|
61
|
+
self,
|
|
62
|
+
*,
|
|
63
|
+
period: str = "24h",
|
|
64
|
+
start_date: str | None = None,
|
|
65
|
+
end_date: str | None = None,
|
|
66
|
+
) -> TotalResponse:
|
|
67
|
+
body = _analytics_body(period, start_date, end_date)
|
|
68
|
+
data = self._client.request("POST", "/requests/period-total", json=body)
|
|
69
|
+
return TotalResponse.from_dict(data)
|
|
70
|
+
|
|
71
|
+
def domain_breakdown(
|
|
72
|
+
self,
|
|
73
|
+
*,
|
|
74
|
+
period: str = "24h",
|
|
75
|
+
start_date: str | None = None,
|
|
76
|
+
end_date: str | None = None,
|
|
77
|
+
) -> DomainBreakdownResponse:
|
|
78
|
+
body = _analytics_body(period, start_date, end_date)
|
|
79
|
+
data = self._client.request("POST", "/domain-breakdown", json=body)
|
|
80
|
+
return DomainBreakdownResponse.from_dict(data)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class AsyncAnalyticsResource:
|
|
84
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
85
|
+
self._client = client
|
|
86
|
+
|
|
87
|
+
async def traffic(
|
|
88
|
+
self,
|
|
89
|
+
*,
|
|
90
|
+
period: str = "24h",
|
|
91
|
+
start_date: str | None = None,
|
|
92
|
+
end_date: str | None = None,
|
|
93
|
+
) -> TimeSeriesResponse:
|
|
94
|
+
body = _analytics_body(period, start_date, end_date)
|
|
95
|
+
data = await self._client.request("POST", "/traffic", json=body)
|
|
96
|
+
return TimeSeriesResponse.from_dict(data)
|
|
97
|
+
|
|
98
|
+
async def traffic_total(
|
|
99
|
+
self,
|
|
100
|
+
*,
|
|
101
|
+
period: str = "24h",
|
|
102
|
+
start_date: str | None = None,
|
|
103
|
+
end_date: str | None = None,
|
|
104
|
+
) -> TotalResponse:
|
|
105
|
+
body = _analytics_body(period, start_date, end_date)
|
|
106
|
+
data = await self._client.request("POST", "/traffic/period-total", json=body)
|
|
107
|
+
return TotalResponse.from_dict(data)
|
|
108
|
+
|
|
109
|
+
async def requests(
|
|
110
|
+
self,
|
|
111
|
+
*,
|
|
112
|
+
period: str = "24h",
|
|
113
|
+
start_date: str | None = None,
|
|
114
|
+
end_date: str | None = None,
|
|
115
|
+
) -> TimeSeriesResponse:
|
|
116
|
+
body = _analytics_body(period, start_date, end_date)
|
|
117
|
+
data = await self._client.request("POST", "/requests", json=body)
|
|
118
|
+
return TimeSeriesResponse.from_dict(data)
|
|
119
|
+
|
|
120
|
+
async def requests_total(
|
|
121
|
+
self,
|
|
122
|
+
*,
|
|
123
|
+
period: str = "24h",
|
|
124
|
+
start_date: str | None = None,
|
|
125
|
+
end_date: str | None = None,
|
|
126
|
+
) -> TotalResponse:
|
|
127
|
+
body = _analytics_body(period, start_date, end_date)
|
|
128
|
+
data = await self._client.request("POST", "/requests/period-total", json=body)
|
|
129
|
+
return TotalResponse.from_dict(data)
|
|
130
|
+
|
|
131
|
+
async def domain_breakdown(
|
|
132
|
+
self,
|
|
133
|
+
*,
|
|
134
|
+
period: str = "24h",
|
|
135
|
+
start_date: str | None = None,
|
|
136
|
+
end_date: str | None = None,
|
|
137
|
+
) -> DomainBreakdownResponse:
|
|
138
|
+
body = _analytics_body(period, start_date, end_date)
|
|
139
|
+
data = await self._client.request("POST", "/domain-breakdown", json=body)
|
|
140
|
+
return DomainBreakdownResponse.from_dict(data)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.auth import LoginResponse, RegisterResponse, SocialAccount, SupportedProvider, User
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AuthResource:
|
|
13
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
def register(
|
|
17
|
+
self,
|
|
18
|
+
*,
|
|
19
|
+
name: str,
|
|
20
|
+
email: str,
|
|
21
|
+
password: str,
|
|
22
|
+
password_confirmation: str,
|
|
23
|
+
referral_code: str | None = None,
|
|
24
|
+
utm_source: str | None = None,
|
|
25
|
+
utm_medium: str | None = None,
|
|
26
|
+
utm_campaign: str | None = None,
|
|
27
|
+
) -> RegisterResponse:
|
|
28
|
+
body: dict[str, Any] = {
|
|
29
|
+
"name": name,
|
|
30
|
+
"email": email,
|
|
31
|
+
"password": password,
|
|
32
|
+
"password_confirmation": password_confirmation,
|
|
33
|
+
}
|
|
34
|
+
if referral_code is not None:
|
|
35
|
+
body["referral_code"] = referral_code
|
|
36
|
+
if utm_source is not None:
|
|
37
|
+
body["utm_source"] = utm_source
|
|
38
|
+
if utm_medium is not None:
|
|
39
|
+
body["utm_medium"] = utm_medium
|
|
40
|
+
if utm_campaign is not None:
|
|
41
|
+
body["utm_campaign"] = utm_campaign
|
|
42
|
+
|
|
43
|
+
data = self._client.request("POST", "/auth/register", json=body)
|
|
44
|
+
return RegisterResponse.from_dict(data)
|
|
45
|
+
|
|
46
|
+
def login(
|
|
47
|
+
self,
|
|
48
|
+
*,
|
|
49
|
+
email: str,
|
|
50
|
+
password: str,
|
|
51
|
+
twofa_code: str | None = None,
|
|
52
|
+
) -> LoginResponse:
|
|
53
|
+
body: dict[str, Any] = {"email": email, "password": password}
|
|
54
|
+
if twofa_code is not None:
|
|
55
|
+
body["twofa_code"] = twofa_code
|
|
56
|
+
data = self._client.request("POST", "/auth/login", json=body)
|
|
57
|
+
return LoginResponse.from_dict(data)
|
|
58
|
+
|
|
59
|
+
def user(self) -> User:
|
|
60
|
+
data = self._client.request("GET", "/auth/user")
|
|
61
|
+
return User.from_dict(data)
|
|
62
|
+
|
|
63
|
+
def logout(self) -> None:
|
|
64
|
+
self._client.request("POST", "/auth/logout")
|
|
65
|
+
|
|
66
|
+
def supported_providers(self) -> list[SupportedProvider]:
|
|
67
|
+
data = self._client.request("GET", "/auth/supported-providers")
|
|
68
|
+
if isinstance(data, list):
|
|
69
|
+
return [SupportedProvider.from_dict(item) for item in data]
|
|
70
|
+
return []
|
|
71
|
+
|
|
72
|
+
def social_accounts(self) -> list[SocialAccount]:
|
|
73
|
+
data = self._client.request("GET", "/auth/social-accounts")
|
|
74
|
+
if isinstance(data, list):
|
|
75
|
+
return [SocialAccount.from_dict(item) for item in data]
|
|
76
|
+
return []
|
|
77
|
+
|
|
78
|
+
def disconnect_social(self, provider: str) -> None:
|
|
79
|
+
self._client.request("DELETE", f"/auth/social-accounts/{provider}")
|
|
80
|
+
|
|
81
|
+
def oauth_redirect(self, provider: str) -> Any:
|
|
82
|
+
return self._client.request("GET", f"/auth/{provider}/redirect")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class AsyncAuthResource:
|
|
86
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
87
|
+
self._client = client
|
|
88
|
+
|
|
89
|
+
async def register(
|
|
90
|
+
self,
|
|
91
|
+
*,
|
|
92
|
+
name: str,
|
|
93
|
+
email: str,
|
|
94
|
+
password: str,
|
|
95
|
+
password_confirmation: str,
|
|
96
|
+
referral_code: str | None = None,
|
|
97
|
+
utm_source: str | None = None,
|
|
98
|
+
utm_medium: str | None = None,
|
|
99
|
+
utm_campaign: str | None = None,
|
|
100
|
+
) -> RegisterResponse:
|
|
101
|
+
body: dict[str, Any] = {
|
|
102
|
+
"name": name,
|
|
103
|
+
"email": email,
|
|
104
|
+
"password": password,
|
|
105
|
+
"password_confirmation": password_confirmation,
|
|
106
|
+
}
|
|
107
|
+
if referral_code is not None:
|
|
108
|
+
body["referral_code"] = referral_code
|
|
109
|
+
if utm_source is not None:
|
|
110
|
+
body["utm_source"] = utm_source
|
|
111
|
+
if utm_medium is not None:
|
|
112
|
+
body["utm_medium"] = utm_medium
|
|
113
|
+
if utm_campaign is not None:
|
|
114
|
+
body["utm_campaign"] = utm_campaign
|
|
115
|
+
|
|
116
|
+
data = await self._client.request("POST", "/auth/register", json=body)
|
|
117
|
+
return RegisterResponse.from_dict(data)
|
|
118
|
+
|
|
119
|
+
async def login(
|
|
120
|
+
self,
|
|
121
|
+
*,
|
|
122
|
+
email: str,
|
|
123
|
+
password: str,
|
|
124
|
+
twofa_code: str | None = None,
|
|
125
|
+
) -> LoginResponse:
|
|
126
|
+
body: dict[str, Any] = {"email": email, "password": password}
|
|
127
|
+
if twofa_code is not None:
|
|
128
|
+
body["twofa_code"] = twofa_code
|
|
129
|
+
data = await self._client.request("POST", "/auth/login", json=body)
|
|
130
|
+
return LoginResponse.from_dict(data)
|
|
131
|
+
|
|
132
|
+
async def user(self) -> User:
|
|
133
|
+
data = await self._client.request("GET", "/auth/user")
|
|
134
|
+
return User.from_dict(data)
|
|
135
|
+
|
|
136
|
+
async def logout(self) -> None:
|
|
137
|
+
await self._client.request("POST", "/auth/logout")
|
|
138
|
+
|
|
139
|
+
async def supported_providers(self) -> list[SupportedProvider]:
|
|
140
|
+
data = await self._client.request("GET", "/auth/supported-providers")
|
|
141
|
+
if isinstance(data, list):
|
|
142
|
+
return [SupportedProvider.from_dict(item) for item in data]
|
|
143
|
+
return []
|
|
144
|
+
|
|
145
|
+
async def social_accounts(self) -> list[SocialAccount]:
|
|
146
|
+
data = await self._client.request("GET", "/auth/social-accounts")
|
|
147
|
+
if isinstance(data, list):
|
|
148
|
+
return [SocialAccount.from_dict(item) for item in data]
|
|
149
|
+
return []
|
|
150
|
+
|
|
151
|
+
async def disconnect_social(self, provider: str) -> None:
|
|
152
|
+
await self._client.request("DELETE", f"/auth/social-accounts/{provider}")
|
|
153
|
+
|
|
154
|
+
async def oauth_redirect(self, provider: str) -> Any:
|
|
155
|
+
return await self._client.request("GET", f"/auth/{provider}/redirect")
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.coupons import CouponResponse
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CouponsResource:
|
|
13
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
def validate(
|
|
17
|
+
self,
|
|
18
|
+
*,
|
|
19
|
+
code: str,
|
|
20
|
+
plan_id: str | None = None,
|
|
21
|
+
order_sum: float | None = None,
|
|
22
|
+
currency: str | None = None,
|
|
23
|
+
) -> CouponResponse:
|
|
24
|
+
body: dict[str, Any] = {"code": code}
|
|
25
|
+
if plan_id is not None:
|
|
26
|
+
body["plan_id"] = plan_id
|
|
27
|
+
if order_sum is not None:
|
|
28
|
+
body["order_sum"] = order_sum
|
|
29
|
+
if currency is not None:
|
|
30
|
+
body["currency"] = currency
|
|
31
|
+
data = self._client.request("POST", "/coupon/validate", json=body)
|
|
32
|
+
return CouponResponse.from_dict(data)
|
|
33
|
+
|
|
34
|
+
def apply(
|
|
35
|
+
self,
|
|
36
|
+
*,
|
|
37
|
+
code: str,
|
|
38
|
+
plan_id: str | None = None,
|
|
39
|
+
order_sum: float | None = None,
|
|
40
|
+
currency: str | None = None,
|
|
41
|
+
) -> CouponResponse:
|
|
42
|
+
body: dict[str, Any] = {"code": code}
|
|
43
|
+
if plan_id is not None:
|
|
44
|
+
body["plan_id"] = plan_id
|
|
45
|
+
if order_sum is not None:
|
|
46
|
+
body["order_sum"] = order_sum
|
|
47
|
+
if currency is not None:
|
|
48
|
+
body["currency"] = currency
|
|
49
|
+
data = self._client.request("POST", "/coupon/apply", json=body)
|
|
50
|
+
return CouponResponse.from_dict(data)
|
|
51
|
+
|
|
52
|
+
def redeem(self, *, code: str) -> CouponResponse:
|
|
53
|
+
data = self._client.request("POST", "/coupon/redeem", json={"code": code})
|
|
54
|
+
return CouponResponse.from_dict(data)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class AsyncCouponsResource:
|
|
58
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
59
|
+
self._client = client
|
|
60
|
+
|
|
61
|
+
async def validate(
|
|
62
|
+
self,
|
|
63
|
+
*,
|
|
64
|
+
code: str,
|
|
65
|
+
plan_id: str | None = None,
|
|
66
|
+
order_sum: float | None = None,
|
|
67
|
+
currency: str | None = None,
|
|
68
|
+
) -> CouponResponse:
|
|
69
|
+
body: dict[str, Any] = {"code": code}
|
|
70
|
+
if plan_id is not None:
|
|
71
|
+
body["plan_id"] = plan_id
|
|
72
|
+
if order_sum is not None:
|
|
73
|
+
body["order_sum"] = order_sum
|
|
74
|
+
if currency is not None:
|
|
75
|
+
body["currency"] = currency
|
|
76
|
+
data = await self._client.request("POST", "/coupon/validate", json=body)
|
|
77
|
+
return CouponResponse.from_dict(data)
|
|
78
|
+
|
|
79
|
+
async def apply(
|
|
80
|
+
self,
|
|
81
|
+
*,
|
|
82
|
+
code: str,
|
|
83
|
+
plan_id: str | None = None,
|
|
84
|
+
order_sum: float | None = None,
|
|
85
|
+
currency: str | None = None,
|
|
86
|
+
) -> CouponResponse:
|
|
87
|
+
body: dict[str, Any] = {"code": code}
|
|
88
|
+
if plan_id is not None:
|
|
89
|
+
body["plan_id"] = plan_id
|
|
90
|
+
if order_sum is not None:
|
|
91
|
+
body["order_sum"] = order_sum
|
|
92
|
+
if currency is not None:
|
|
93
|
+
body["currency"] = currency
|
|
94
|
+
data = await self._client.request("POST", "/coupon/apply", json=body)
|
|
95
|
+
return CouponResponse.from_dict(data)
|
|
96
|
+
|
|
97
|
+
async def redeem(self, *, code: str) -> CouponResponse:
|
|
98
|
+
data = await self._client.request("POST", "/coupon/redeem", json={"code": code})
|
|
99
|
+
return CouponResponse.from_dict(data)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.email import EmailChangeResponse
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EmailResource:
|
|
13
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
14
|
+
self._client = client
|
|
15
|
+
|
|
16
|
+
def request_change(self, *, email: str, twofa_code: str | None = None) -> EmailChangeResponse:
|
|
17
|
+
body: dict[str, Any] = {"email": email}
|
|
18
|
+
if twofa_code is not None:
|
|
19
|
+
body["twofa_code"] = twofa_code
|
|
20
|
+
data = self._client.request("POST", "/profile/email/request-change", json=body)
|
|
21
|
+
return EmailChangeResponse.from_dict(data)
|
|
22
|
+
|
|
23
|
+
def confirm_change(self, *, token: str) -> EmailChangeResponse:
|
|
24
|
+
data = self._client.request("POST", "/profile/email/confirm-change", json={"token": token})
|
|
25
|
+
return EmailChangeResponse.from_dict(data)
|
|
26
|
+
|
|
27
|
+
def cancel_change(self) -> EmailChangeResponse:
|
|
28
|
+
data = self._client.request("POST", "/profile/email/cancel-change")
|
|
29
|
+
return EmailChangeResponse.from_dict(data)
|
|
30
|
+
|
|
31
|
+
def resend_verification(self) -> EmailChangeResponse:
|
|
32
|
+
data = self._client.request("POST", "/profile/email/resend-verification")
|
|
33
|
+
return EmailChangeResponse.from_dict(data)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AsyncEmailResource:
|
|
37
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
38
|
+
self._client = client
|
|
39
|
+
|
|
40
|
+
async def request_change(self, *, email: str, twofa_code: str | None = None) -> EmailChangeResponse:
|
|
41
|
+
body: dict[str, Any] = {"email": email}
|
|
42
|
+
if twofa_code is not None:
|
|
43
|
+
body["twofa_code"] = twofa_code
|
|
44
|
+
data = await self._client.request("POST", "/profile/email/request-change", json=body)
|
|
45
|
+
return EmailChangeResponse.from_dict(data)
|
|
46
|
+
|
|
47
|
+
async def confirm_change(self, *, token: str) -> EmailChangeResponse:
|
|
48
|
+
data = await self._client.request("POST", "/profile/email/confirm-change", json={"token": token})
|
|
49
|
+
return EmailChangeResponse.from_dict(data)
|
|
50
|
+
|
|
51
|
+
async def cancel_change(self) -> EmailChangeResponse:
|
|
52
|
+
data = await self._client.request("POST", "/profile/email/cancel-change")
|
|
53
|
+
return EmailChangeResponse.from_dict(data)
|
|
54
|
+
|
|
55
|
+
async def resend_verification(self) -> EmailChangeResponse:
|
|
56
|
+
data = await self._client.request("POST", "/profile/email/resend-verification")
|
|
57
|
+
return EmailChangeResponse.from_dict(data)
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from proxyhat.types.locations import ISP, City, Country, Region, Zipcode
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from proxyhat.async_client import AsyncProxyHat
|
|
9
|
+
from proxyhat.client import ProxyHat
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _location_params(
|
|
13
|
+
limit: int | None = None,
|
|
14
|
+
offset: int | None = None,
|
|
15
|
+
name: str | None = None,
|
|
16
|
+
connection_type: str | None = None,
|
|
17
|
+
**kwargs: Any,
|
|
18
|
+
) -> dict[str, Any]:
|
|
19
|
+
params: dict[str, Any] = {}
|
|
20
|
+
if limit is not None:
|
|
21
|
+
params["limit"] = limit
|
|
22
|
+
if offset is not None:
|
|
23
|
+
params["offset"] = offset
|
|
24
|
+
if name is not None:
|
|
25
|
+
params["name"] = name
|
|
26
|
+
if connection_type is not None:
|
|
27
|
+
params["connection_type"] = connection_type
|
|
28
|
+
params.update({k: v for k, v in kwargs.items() if v is not None})
|
|
29
|
+
return params
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LocationsResource:
|
|
33
|
+
def __init__(self, client: ProxyHat) -> None:
|
|
34
|
+
self._client = client
|
|
35
|
+
|
|
36
|
+
def countries(
|
|
37
|
+
self,
|
|
38
|
+
*,
|
|
39
|
+
limit: int | None = None,
|
|
40
|
+
offset: int | None = None,
|
|
41
|
+
name: str | None = None,
|
|
42
|
+
connection_type: str | None = None,
|
|
43
|
+
) -> list[Country]:
|
|
44
|
+
params = _location_params(limit=limit, offset=offset, name=name, connection_type=connection_type)
|
|
45
|
+
data = self._client.request("GET", "/locations/countries", params=params)
|
|
46
|
+
if isinstance(data, list):
|
|
47
|
+
return [Country.from_dict(item) for item in data]
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
def regions(
|
|
51
|
+
self,
|
|
52
|
+
*,
|
|
53
|
+
limit: int | None = None,
|
|
54
|
+
offset: int | None = None,
|
|
55
|
+
name: str | None = None,
|
|
56
|
+
connection_type: str | None = None,
|
|
57
|
+
country__code: str | None = None,
|
|
58
|
+
) -> list[Region]:
|
|
59
|
+
params = _location_params(
|
|
60
|
+
limit=limit, offset=offset, name=name, connection_type=connection_type, country__code=country__code
|
|
61
|
+
)
|
|
62
|
+
data = self._client.request("GET", "/locations/regions", params=params)
|
|
63
|
+
if isinstance(data, list):
|
|
64
|
+
return [Region.from_dict(item) for item in data]
|
|
65
|
+
return []
|
|
66
|
+
|
|
67
|
+
def cities(
|
|
68
|
+
self,
|
|
69
|
+
*,
|
|
70
|
+
limit: int | None = None,
|
|
71
|
+
offset: int | None = None,
|
|
72
|
+
name: str | None = None,
|
|
73
|
+
connection_type: str | None = None,
|
|
74
|
+
country__code: str | None = None,
|
|
75
|
+
region__code: str | None = None,
|
|
76
|
+
) -> list[City]:
|
|
77
|
+
params = _location_params(
|
|
78
|
+
limit=limit,
|
|
79
|
+
offset=offset,
|
|
80
|
+
name=name,
|
|
81
|
+
connection_type=connection_type,
|
|
82
|
+
country__code=country__code,
|
|
83
|
+
region__code=region__code,
|
|
84
|
+
)
|
|
85
|
+
data = self._client.request("GET", "/locations/cities", params=params)
|
|
86
|
+
if isinstance(data, list):
|
|
87
|
+
return [City.from_dict(item) for item in data]
|
|
88
|
+
return []
|
|
89
|
+
|
|
90
|
+
def isps(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
limit: int | None = None,
|
|
94
|
+
offset: int | None = None,
|
|
95
|
+
name: str | None = None,
|
|
96
|
+
connection_type: str | None = None,
|
|
97
|
+
country__code: str | None = None,
|
|
98
|
+
) -> list[ISP]:
|
|
99
|
+
params = _location_params(
|
|
100
|
+
limit=limit, offset=offset, name=name, connection_type=connection_type, country__code=country__code
|
|
101
|
+
)
|
|
102
|
+
data = self._client.request("GET", "/locations/isps", params=params)
|
|
103
|
+
if isinstance(data, list):
|
|
104
|
+
return [ISP.from_dict(item) for item in data]
|
|
105
|
+
return []
|
|
106
|
+
|
|
107
|
+
def zipcodes(
|
|
108
|
+
self,
|
|
109
|
+
*,
|
|
110
|
+
limit: int | None = None,
|
|
111
|
+
offset: int | None = None,
|
|
112
|
+
name: str | None = None,
|
|
113
|
+
connection_type: str | None = None,
|
|
114
|
+
country__code: str | None = None,
|
|
115
|
+
city__code: str | None = None,
|
|
116
|
+
) -> list[Zipcode]:
|
|
117
|
+
params = _location_params(
|
|
118
|
+
limit=limit,
|
|
119
|
+
offset=offset,
|
|
120
|
+
name=name,
|
|
121
|
+
connection_type=connection_type,
|
|
122
|
+
country__code=country__code,
|
|
123
|
+
city__code=city__code,
|
|
124
|
+
)
|
|
125
|
+
data = self._client.request("GET", "/locations/zipcodes", params=params)
|
|
126
|
+
if isinstance(data, list):
|
|
127
|
+
return [Zipcode.from_dict(item) for item in data]
|
|
128
|
+
return []
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class AsyncLocationsResource:
|
|
132
|
+
def __init__(self, client: AsyncProxyHat) -> None:
|
|
133
|
+
self._client = client
|
|
134
|
+
|
|
135
|
+
async def countries(
|
|
136
|
+
self,
|
|
137
|
+
*,
|
|
138
|
+
limit: int | None = None,
|
|
139
|
+
offset: int | None = None,
|
|
140
|
+
name: str | None = None,
|
|
141
|
+
connection_type: str | None = None,
|
|
142
|
+
) -> list[Country]:
|
|
143
|
+
params = _location_params(limit=limit, offset=offset, name=name, connection_type=connection_type)
|
|
144
|
+
data = await self._client.request("GET", "/locations/countries", params=params)
|
|
145
|
+
if isinstance(data, list):
|
|
146
|
+
return [Country.from_dict(item) for item in data]
|
|
147
|
+
return []
|
|
148
|
+
|
|
149
|
+
async def regions(
|
|
150
|
+
self,
|
|
151
|
+
*,
|
|
152
|
+
limit: int | None = None,
|
|
153
|
+
offset: int | None = None,
|
|
154
|
+
name: str | None = None,
|
|
155
|
+
connection_type: str | None = None,
|
|
156
|
+
country__code: str | None = None,
|
|
157
|
+
) -> list[Region]:
|
|
158
|
+
params = _location_params(
|
|
159
|
+
limit=limit, offset=offset, name=name, connection_type=connection_type, country__code=country__code
|
|
160
|
+
)
|
|
161
|
+
data = await self._client.request("GET", "/locations/regions", params=params)
|
|
162
|
+
if isinstance(data, list):
|
|
163
|
+
return [Region.from_dict(item) for item in data]
|
|
164
|
+
return []
|
|
165
|
+
|
|
166
|
+
async def cities(
|
|
167
|
+
self,
|
|
168
|
+
*,
|
|
169
|
+
limit: int | None = None,
|
|
170
|
+
offset: int | None = None,
|
|
171
|
+
name: str | None = None,
|
|
172
|
+
connection_type: str | None = None,
|
|
173
|
+
country__code: str | None = None,
|
|
174
|
+
region__code: str | None = None,
|
|
175
|
+
) -> list[City]:
|
|
176
|
+
params = _location_params(
|
|
177
|
+
limit=limit,
|
|
178
|
+
offset=offset,
|
|
179
|
+
name=name,
|
|
180
|
+
connection_type=connection_type,
|
|
181
|
+
country__code=country__code,
|
|
182
|
+
region__code=region__code,
|
|
183
|
+
)
|
|
184
|
+
data = await self._client.request("GET", "/locations/cities", params=params)
|
|
185
|
+
if isinstance(data, list):
|
|
186
|
+
return [City.from_dict(item) for item in data]
|
|
187
|
+
return []
|
|
188
|
+
|
|
189
|
+
async def isps(
|
|
190
|
+
self,
|
|
191
|
+
*,
|
|
192
|
+
limit: int | None = None,
|
|
193
|
+
offset: int | None = None,
|
|
194
|
+
name: str | None = None,
|
|
195
|
+
connection_type: str | None = None,
|
|
196
|
+
country__code: str | None = None,
|
|
197
|
+
) -> list[ISP]:
|
|
198
|
+
params = _location_params(
|
|
199
|
+
limit=limit, offset=offset, name=name, connection_type=connection_type, country__code=country__code
|
|
200
|
+
)
|
|
201
|
+
data = await self._client.request("GET", "/locations/isps", params=params)
|
|
202
|
+
if isinstance(data, list):
|
|
203
|
+
return [ISP.from_dict(item) for item in data]
|
|
204
|
+
return []
|
|
205
|
+
|
|
206
|
+
async def zipcodes(
|
|
207
|
+
self,
|
|
208
|
+
*,
|
|
209
|
+
limit: int | None = None,
|
|
210
|
+
offset: int | None = None,
|
|
211
|
+
name: str | None = None,
|
|
212
|
+
connection_type: str | None = None,
|
|
213
|
+
country__code: str | None = None,
|
|
214
|
+
city__code: str | None = None,
|
|
215
|
+
) -> list[Zipcode]:
|
|
216
|
+
params = _location_params(
|
|
217
|
+
limit=limit,
|
|
218
|
+
offset=offset,
|
|
219
|
+
name=name,
|
|
220
|
+
connection_type=connection_type,
|
|
221
|
+
country__code=country__code,
|
|
222
|
+
city__code=city__code,
|
|
223
|
+
)
|
|
224
|
+
data = await self._client.request("GET", "/locations/zipcodes", params=params)
|
|
225
|
+
if isinstance(data, list):
|
|
226
|
+
return [Zipcode.from_dict(item) for item in data]
|
|
227
|
+
return []
|