Skip to content

Commit 105801c

Browse files
feat(api): add health check endpoint for proxies
1 parent 99b8057 commit 105801c

File tree

6 files changed

+376
-6
lines changed

6 files changed

+376
-6
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 89
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2cf104c4b88159c6a50713b019188f83983748b9cacec598089cf9068dc5b1cd.yml
3-
openapi_spec_hash: 84ea30ae65ad7ebcc04d2f3907d1e73b
4-
config_hash: 179f33af31ece83563163d5b3d751d13
1+
configured_endpoints: 90
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-20fac779e9e13dc9421e467be31dbf274c39072ba0c01528ba451b48698d43c1.yml
3+
openapi_spec_hash: c3fc5784297ccc8f729326b62000d1f0
4+
config_hash: e47e015528251ee83e30367dbbb51044

api.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,12 @@ Methods:
228228
Types:
229229

230230
```python
231-
from kernel.types import ProxyCreateResponse, ProxyRetrieveResponse, ProxyListResponse
231+
from kernel.types import (
232+
ProxyCreateResponse,
233+
ProxyRetrieveResponse,
234+
ProxyListResponse,
235+
ProxyCheckResponse,
236+
)
232237
```
233238

234239
Methods:
@@ -237,6 +242,7 @@ Methods:
237242
- <code title="get /proxies/{id}">client.proxies.<a href="./src/kernel/resources/proxies.py">retrieve</a>(id) -> <a href="./src/kernel/types/proxy_retrieve_response.py">ProxyRetrieveResponse</a></code>
238243
- <code title="get /proxies">client.proxies.<a href="./src/kernel/resources/proxies.py">list</a>() -> <a href="./src/kernel/types/proxy_list_response.py">ProxyListResponse</a></code>
239244
- <code title="delete /proxies/{id}">client.proxies.<a href="./src/kernel/resources/proxies.py">delete</a>(id) -> None</code>
245+
- <code title="post /proxies/{id}/check">client.proxies.<a href="./src/kernel/resources/proxies.py">check</a>(id) -> <a href="./src/kernel/types/proxy_check_response.py">ProxyCheckResponse</a></code>
240246

241247
# Extensions
242248

src/kernel/resources/proxies.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
)
2020
from .._base_client import make_request_options
2121
from ..types.proxy_list_response import ProxyListResponse
22+
from ..types.proxy_check_response import ProxyCheckResponse
2223
from ..types.proxy_create_response import ProxyCreateResponse
2324
from ..types.proxy_retrieve_response import ProxyRetrieveResponse
2425

@@ -184,6 +185,39 @@ def delete(
184185
cast_to=NoneType,
185186
)
186187

188+
def check(
189+
self,
190+
id: str,
191+
*,
192+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
193+
# The extra values given here take precedence over values defined on the client or passed to this method.
194+
extra_headers: Headers | None = None,
195+
extra_query: Query | None = None,
196+
extra_body: Body | None = None,
197+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
198+
) -> ProxyCheckResponse:
199+
"""
200+
Run a health check on the proxy to verify it's working.
201+
202+
Args:
203+
extra_headers: Send extra headers
204+
205+
extra_query: Add additional query parameters to the request
206+
207+
extra_body: Add additional JSON properties to the request
208+
209+
timeout: Override the client-level default timeout for this request, in seconds
210+
"""
211+
if not id:
212+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
213+
return self._post(
214+
f"/proxies/{id}/check",
215+
options=make_request_options(
216+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
217+
),
218+
cast_to=ProxyCheckResponse,
219+
)
220+
187221

188222
class AsyncProxiesResource(AsyncAPIResource):
189223
@cached_property
@@ -344,6 +378,39 @@ async def delete(
344378
cast_to=NoneType,
345379
)
346380

381+
async def check(
382+
self,
383+
id: str,
384+
*,
385+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
386+
# The extra values given here take precedence over values defined on the client or passed to this method.
387+
extra_headers: Headers | None = None,
388+
extra_query: Query | None = None,
389+
extra_body: Body | None = None,
390+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
391+
) -> ProxyCheckResponse:
392+
"""
393+
Run a health check on the proxy to verify it's working.
394+
395+
Args:
396+
extra_headers: Send extra headers
397+
398+
extra_query: Add additional query parameters to the request
399+
400+
extra_body: Add additional JSON properties to the request
401+
402+
timeout: Override the client-level default timeout for this request, in seconds
403+
"""
404+
if not id:
405+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
406+
return await self._post(
407+
f"/proxies/{id}/check",
408+
options=make_request_options(
409+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
410+
),
411+
cast_to=ProxyCheckResponse,
412+
)
413+
347414

348415
class ProxiesResourceWithRawResponse:
349416
def __init__(self, proxies: ProxiesResource) -> None:
@@ -361,6 +428,9 @@ def __init__(self, proxies: ProxiesResource) -> None:
361428
self.delete = to_raw_response_wrapper(
362429
proxies.delete,
363430
)
431+
self.check = to_raw_response_wrapper(
432+
proxies.check,
433+
)
364434

365435

366436
class AsyncProxiesResourceWithRawResponse:
@@ -379,6 +449,9 @@ def __init__(self, proxies: AsyncProxiesResource) -> None:
379449
self.delete = async_to_raw_response_wrapper(
380450
proxies.delete,
381451
)
452+
self.check = async_to_raw_response_wrapper(
453+
proxies.check,
454+
)
382455

383456

384457
class ProxiesResourceWithStreamingResponse:
@@ -397,6 +470,9 @@ def __init__(self, proxies: ProxiesResource) -> None:
397470
self.delete = to_streamed_response_wrapper(
398471
proxies.delete,
399472
)
473+
self.check = to_streamed_response_wrapper(
474+
proxies.check,
475+
)
400476

401477

402478
class AsyncProxiesResourceWithStreamingResponse:
@@ -415,3 +491,6 @@ def __init__(self, proxies: AsyncProxiesResource) -> None:
415491
self.delete = async_to_streamed_response_wrapper(
416492
proxies.delete,
417493
)
494+
self.check = async_to_streamed_response_wrapper(
495+
proxies.check,
496+
)

src/kernel/types/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .browser_persistence import BrowserPersistence as BrowserPersistence
2323
from .proxy_create_params import ProxyCreateParams as ProxyCreateParams
2424
from .proxy_list_response import ProxyListResponse as ProxyListResponse
25+
from .proxy_check_response import ProxyCheckResponse as ProxyCheckResponse
2526
from .browser_create_params import BrowserCreateParams as BrowserCreateParams
2627
from .browser_delete_params import BrowserDeleteParams as BrowserDeleteParams
2728
from .browser_list_response import BrowserListResponse as BrowserListResponse
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Union, Optional
4+
from datetime import datetime
5+
from typing_extensions import Literal, TypeAlias
6+
7+
from .._models import BaseModel
8+
9+
__all__ = [
10+
"ProxyCheckResponse",
11+
"Config",
12+
"ConfigDatacenterProxyConfig",
13+
"ConfigIspProxyConfig",
14+
"ConfigResidentialProxyConfig",
15+
"ConfigMobileProxyConfig",
16+
"ConfigCustomProxyConfig",
17+
]
18+
19+
20+
class ConfigDatacenterProxyConfig(BaseModel):
21+
"""Configuration for a datacenter proxy."""
22+
23+
country: Optional[str] = None
24+
"""ISO 3166 country code. Defaults to US if not provided."""
25+
26+
27+
class ConfigIspProxyConfig(BaseModel):
28+
"""Configuration for an ISP proxy."""
29+
30+
country: Optional[str] = None
31+
"""ISO 3166 country code. Defaults to US if not provided."""
32+
33+
34+
class ConfigResidentialProxyConfig(BaseModel):
35+
"""Configuration for residential proxies."""
36+
37+
asn: Optional[str] = None
38+
"""Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html"""
39+
40+
city: Optional[str] = None
41+
"""City name (no spaces, e.g.
42+
43+
`sanfrancisco`). If provided, `country` must also be provided.
44+
"""
45+
46+
country: Optional[str] = None
47+
"""ISO 3166 country code."""
48+
49+
os: Optional[Literal["windows", "macos", "android"]] = None
50+
"""Operating system of the residential device."""
51+
52+
state: Optional[str] = None
53+
"""Two-letter state code."""
54+
55+
zip: Optional[str] = None
56+
"""US ZIP code."""
57+
58+
59+
class ConfigMobileProxyConfig(BaseModel):
60+
"""Configuration for mobile proxies."""
61+
62+
asn: Optional[str] = None
63+
"""Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html"""
64+
65+
carrier: Optional[
66+
Literal[
67+
"a1",
68+
"aircel",
69+
"airtel",
70+
"att",
71+
"celcom",
72+
"chinamobile",
73+
"claro",
74+
"comcast",
75+
"cox",
76+
"digi",
77+
"dt",
78+
"docomo",
79+
"dtac",
80+
"etisalat",
81+
"idea",
82+
"kyivstar",
83+
"meo",
84+
"megafon",
85+
"mtn",
86+
"mtnza",
87+
"mts",
88+
"optus",
89+
"orange",
90+
"qwest",
91+
"reliance_jio",
92+
"robi",
93+
"sprint",
94+
"telefonica",
95+
"telstra",
96+
"tmobile",
97+
"tigo",
98+
"tim",
99+
"verizon",
100+
"vimpelcom",
101+
"vodacomza",
102+
"vodafone",
103+
"vivo",
104+
"zain",
105+
"vivabo",
106+
"telenormyanmar",
107+
"kcelljsc",
108+
"swisscom",
109+
"singtel",
110+
"asiacell",
111+
"windit",
112+
"cellc",
113+
"ooredoo",
114+
"drei",
115+
"umobile",
116+
"cableone",
117+
"proximus",
118+
"tele2",
119+
"mobitel",
120+
"o2",
121+
"bouygues",
122+
"free",
123+
"sfr",
124+
"digicel",
125+
]
126+
] = None
127+
"""Mobile carrier."""
128+
129+
city: Optional[str] = None
130+
"""City name (no spaces, e.g.
131+
132+
`sanfrancisco`). If provided, `country` must also be provided.
133+
"""
134+
135+
country: Optional[str] = None
136+
"""ISO 3166 country code"""
137+
138+
state: Optional[str] = None
139+
"""Two-letter state code."""
140+
141+
zip: Optional[str] = None
142+
"""US ZIP code."""
143+
144+
145+
class ConfigCustomProxyConfig(BaseModel):
146+
"""Configuration for a custom proxy (e.g., private proxy server)."""
147+
148+
host: str
149+
"""Proxy host address or IP."""
150+
151+
port: int
152+
"""Proxy port."""
153+
154+
has_password: Optional[bool] = None
155+
"""Whether the proxy has a password."""
156+
157+
username: Optional[str] = None
158+
"""Username for proxy authentication."""
159+
160+
161+
Config: TypeAlias = Union[
162+
ConfigDatacenterProxyConfig,
163+
ConfigIspProxyConfig,
164+
ConfigResidentialProxyConfig,
165+
ConfigMobileProxyConfig,
166+
ConfigCustomProxyConfig,
167+
]
168+
169+
170+
class ProxyCheckResponse(BaseModel):
171+
"""Configuration for routing traffic through a proxy."""
172+
173+
type: Literal["datacenter", "isp", "residential", "mobile", "custom"]
174+
"""Proxy type to use.
175+
176+
In terms of quality for avoiding bot-detection, from best to worst: `mobile` >
177+
`residential` > `isp` > `datacenter`.
178+
"""
179+
180+
id: Optional[str] = None
181+
182+
config: Optional[Config] = None
183+
"""Configuration specific to the selected proxy `type`."""
184+
185+
last_checked: Optional[datetime] = None
186+
"""Timestamp of the last health check performed on this proxy."""
187+
188+
name: Optional[str] = None
189+
"""Readable name of the proxy."""
190+
191+
protocol: Optional[Literal["http", "https"]] = None
192+
"""Protocol to use for the proxy connection."""
193+
194+
status: Optional[Literal["available", "unavailable"]] = None
195+
"""Current health status of the proxy."""

0 commit comments

Comments
 (0)