fleet-python 0.2.66b2__py3-none-any.whl → 0.2.105__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.
- examples/export_tasks.py +16 -5
- examples/export_tasks_filtered.py +245 -0
- examples/fetch_tasks.py +230 -0
- examples/import_tasks.py +140 -8
- examples/iterate_verifiers.py +725 -0
- fleet/__init__.py +128 -5
- fleet/_async/__init__.py +27 -3
- fleet/_async/base.py +24 -9
- fleet/_async/client.py +938 -41
- fleet/_async/env/client.py +60 -3
- fleet/_async/instance/client.py +52 -7
- fleet/_async/models.py +15 -0
- fleet/_async/resources/api.py +200 -0
- fleet/_async/resources/sqlite.py +1801 -46
- fleet/_async/tasks.py +122 -25
- fleet/_async/verifiers/bundler.py +22 -21
- fleet/_async/verifiers/verifier.py +25 -19
- fleet/agent/__init__.py +32 -0
- fleet/agent/gemini_cua/Dockerfile +45 -0
- fleet/agent/gemini_cua/__init__.py +10 -0
- fleet/agent/gemini_cua/agent.py +759 -0
- fleet/agent/gemini_cua/mcp/main.py +108 -0
- fleet/agent/gemini_cua/mcp_server/__init__.py +5 -0
- fleet/agent/gemini_cua/mcp_server/main.py +105 -0
- fleet/agent/gemini_cua/mcp_server/tools.py +178 -0
- fleet/agent/gemini_cua/requirements.txt +5 -0
- fleet/agent/gemini_cua/start.sh +30 -0
- fleet/agent/orchestrator.py +854 -0
- fleet/agent/types.py +49 -0
- fleet/agent/utils.py +34 -0
- fleet/base.py +34 -9
- fleet/cli.py +1061 -0
- fleet/client.py +1060 -48
- fleet/config.py +1 -1
- fleet/env/__init__.py +16 -0
- fleet/env/client.py +60 -3
- fleet/eval/__init__.py +15 -0
- fleet/eval/uploader.py +231 -0
- fleet/exceptions.py +8 -0
- fleet/instance/client.py +53 -8
- fleet/instance/models.py +1 -0
- fleet/models.py +303 -0
- fleet/proxy/__init__.py +25 -0
- fleet/proxy/proxy.py +453 -0
- fleet/proxy/whitelist.py +244 -0
- fleet/resources/api.py +200 -0
- fleet/resources/sqlite.py +1845 -46
- fleet/tasks.py +113 -20
- fleet/utils/__init__.py +7 -0
- fleet/utils/http_logging.py +178 -0
- fleet/utils/logging.py +13 -0
- fleet/utils/playwright.py +440 -0
- fleet/verifiers/bundler.py +22 -21
- fleet/verifiers/db.py +985 -1
- fleet/verifiers/decorator.py +1 -1
- fleet/verifiers/verifier.py +25 -19
- {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/METADATA +28 -1
- fleet_python-0.2.105.dist-info/RECORD +115 -0
- {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/WHEEL +1 -1
- fleet_python-0.2.105.dist-info/entry_points.txt +2 -0
- tests/test_app_method.py +85 -0
- tests/test_expect_exactly.py +4148 -0
- tests/test_expect_only.py +2593 -0
- tests/test_instance_dispatch.py +607 -0
- tests/test_sqlite_resource_dual_mode.py +263 -0
- tests/test_sqlite_shared_memory_behavior.py +117 -0
- fleet_python-0.2.66b2.dist-info/RECORD +0 -81
- tests/test_verifier_security.py +0 -427
- {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/licenses/LICENSE +0 -0
- {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/top_level.txt +0 -0
fleet/_async/env/client.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from ..client import AsyncFleet, AsyncEnv, Task
|
|
2
|
-
from ...models import Environment as EnvironmentModel, AccountResponse
|
|
2
|
+
from ...models import Environment as EnvironmentModel, AccountResponse, InstanceResponse, Run, HeartbeatResponse
|
|
3
3
|
from typing import List, Optional, Dict, Any
|
|
4
4
|
|
|
5
5
|
|
|
@@ -10,6 +10,8 @@ async def make_async(
|
|
|
10
10
|
env_variables: Optional[Dict[str, Any]] = None,
|
|
11
11
|
image_type: Optional[str] = None,
|
|
12
12
|
ttl_seconds: Optional[int] = None,
|
|
13
|
+
run_id: Optional[str] = None,
|
|
14
|
+
heartbeat_interval: Optional[int] = None,
|
|
13
15
|
) -> AsyncEnv:
|
|
14
16
|
return await AsyncFleet().make(
|
|
15
17
|
env_key,
|
|
@@ -18,6 +20,8 @@ async def make_async(
|
|
|
18
20
|
env_variables=env_variables,
|
|
19
21
|
image_type=image_type,
|
|
20
22
|
ttl_seconds=ttl_seconds,
|
|
23
|
+
run_id=run_id,
|
|
24
|
+
heartbeat_interval=heartbeat_interval,
|
|
21
25
|
)
|
|
22
26
|
|
|
23
27
|
|
|
@@ -34,14 +38,67 @@ async def list_regions_async() -> List[str]:
|
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
async def list_instances_async(
|
|
37
|
-
status: Optional[str] = None, region: Optional[str] = None
|
|
41
|
+
status: Optional[str] = None, region: Optional[str] = None, run_id: Optional[str] = None, profile_id: Optional[str] = None
|
|
38
42
|
) -> List[AsyncEnv]:
|
|
39
|
-
return await AsyncFleet().instances(status=status, region=region)
|
|
43
|
+
return await AsyncFleet().instances(status=status, region=region, run_id=run_id, profile_id=profile_id)
|
|
40
44
|
|
|
41
45
|
|
|
42
46
|
async def get_async(instance_id: str) -> AsyncEnv:
|
|
43
47
|
return await AsyncFleet().instance(instance_id)
|
|
44
48
|
|
|
45
49
|
|
|
50
|
+
async def close_async(instance_id: str) -> InstanceResponse:
|
|
51
|
+
"""Close (delete) a specific instance by ID.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
instance_id: The instance ID to close
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
InstanceResponse containing the deleted instance details
|
|
58
|
+
"""
|
|
59
|
+
return await AsyncFleet().close(instance_id)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def close_all_async(run_id: Optional[str] = None, profile_id: Optional[str] = None) -> List[InstanceResponse]:
|
|
63
|
+
"""Close (delete) instances using the batch delete endpoint.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
run_id: Optional run ID to filter instances by
|
|
67
|
+
profile_id: Optional profile ID to filter instances by (use "self" for your own profile)
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
List[InstanceResponse] containing the deleted instances
|
|
71
|
+
|
|
72
|
+
Note:
|
|
73
|
+
At least one of run_id or profile_id must be provided.
|
|
74
|
+
"""
|
|
75
|
+
return await AsyncFleet().close_all(run_id=run_id, profile_id=profile_id)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
async def list_runs_async(profile_id: Optional[str] = None, status: Optional[str] = "active") -> List[Run]:
|
|
79
|
+
"""List all runs (groups of instances by run_id) with aggregated statistics.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
profile_id: Optional profile ID to filter runs by (use "self" for your own profile)
|
|
83
|
+
status: Filter by run status - "active" (default), "inactive", or "all"
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
List[Run] containing run information with instance counts and timestamps
|
|
87
|
+
"""
|
|
88
|
+
return await AsyncFleet().list_runs(profile_id=profile_id, status=status)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def heartbeat_async(instance_id: str) -> HeartbeatResponse:
|
|
92
|
+
"""Send heartbeat to keep instance alive (if heartbeat monitoring is enabled).
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
instance_id: The instance ID to send heartbeat for
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
HeartbeatResponse containing heartbeat status and deadline information
|
|
99
|
+
"""
|
|
100
|
+
return await AsyncFleet().heartbeat(instance_id)
|
|
101
|
+
|
|
102
|
+
|
|
46
103
|
async def account_async() -> AccountResponse:
|
|
47
104
|
return await AsyncFleet().account()
|
fleet/_async/instance/client.py
CHANGED
|
@@ -9,6 +9,7 @@ from urllib.parse import urlparse
|
|
|
9
9
|
|
|
10
10
|
from ..resources.sqlite import AsyncSQLiteResource
|
|
11
11
|
from ..resources.browser import AsyncBrowserResource
|
|
12
|
+
from ..resources.api import AsyncAPIResource
|
|
12
13
|
from ..resources.base import Resource
|
|
13
14
|
|
|
14
15
|
from fleet.verifiers import DatabaseSnapshot
|
|
@@ -23,6 +24,7 @@ from ...instance.models import (
|
|
|
23
24
|
ResetResponse,
|
|
24
25
|
Resource as ResourceModel,
|
|
25
26
|
ResourceType,
|
|
27
|
+
ResourceMode,
|
|
26
28
|
HealthResponse,
|
|
27
29
|
ExecuteFunctionRequest,
|
|
28
30
|
ExecuteFunctionResponse,
|
|
@@ -35,6 +37,7 @@ logger = logging.getLogger(__name__)
|
|
|
35
37
|
RESOURCE_TYPES = {
|
|
36
38
|
ResourceType.db: AsyncSQLiteResource,
|
|
37
39
|
ResourceType.cdp: AsyncBrowserResource,
|
|
40
|
+
ResourceType.api: AsyncAPIResource,
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
ValidatorType = Callable[
|
|
@@ -85,15 +88,46 @@ class AsyncInstanceClient:
|
|
|
85
88
|
Returns:
|
|
86
89
|
An SQLite database resource for the given database name
|
|
87
90
|
"""
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
+
resource_info = self._resources_state[ResourceType.db.value][name]
|
|
92
|
+
# Local mode - resource_info is a dict with creation parameters
|
|
93
|
+
if isinstance(resource_info, dict) and resource_info.get('type') == 'local':
|
|
94
|
+
# Create new instance each time (matching HTTP mode behavior)
|
|
95
|
+
return AsyncSQLiteResource(
|
|
96
|
+
resource_info['resource_model'],
|
|
97
|
+
client=None,
|
|
98
|
+
db_path=resource_info['db_path']
|
|
99
|
+
)
|
|
100
|
+
# HTTP mode - resource_info is a ResourceModel, create new wrapper
|
|
101
|
+
return AsyncSQLiteResource(resource_info, self.client)
|
|
91
102
|
|
|
92
103
|
def browser(self, name: str) -> AsyncBrowserResource:
|
|
93
104
|
return AsyncBrowserResource(
|
|
94
105
|
self._resources_state[ResourceType.cdp.value][name], self.client
|
|
95
106
|
)
|
|
96
107
|
|
|
108
|
+
def api(self, name: str, base_url: str) -> AsyncAPIResource:
|
|
109
|
+
"""
|
|
110
|
+
Returns an API resource for making HTTP requests.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
name: The name of the API resource
|
|
114
|
+
base_url: The base URL for API requests
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
An AsyncAPIResource for making HTTP requests
|
|
118
|
+
"""
|
|
119
|
+
# Create a minimal resource model for API
|
|
120
|
+
resource_model = ResourceModel(
|
|
121
|
+
name=name,
|
|
122
|
+
type=ResourceType.api,
|
|
123
|
+
mode=ResourceMode.rw,
|
|
124
|
+
)
|
|
125
|
+
return AsyncAPIResource(
|
|
126
|
+
resource_model,
|
|
127
|
+
base_url=base_url,
|
|
128
|
+
client=self.client.httpx_client if self.client else None,
|
|
129
|
+
)
|
|
130
|
+
|
|
97
131
|
async def resources(self) -> List[Resource]:
|
|
98
132
|
await self._load_resources()
|
|
99
133
|
return [
|
|
@@ -130,10 +164,14 @@ class AsyncInstanceClient:
|
|
|
130
164
|
|
|
131
165
|
async def _load_resources(self) -> None:
|
|
132
166
|
if self._resources is None:
|
|
133
|
-
response = await self.client.request("GET", "/resources"
|
|
167
|
+
response = await self.client.request("GET", "/resources")
|
|
134
168
|
if response.status_code != 200:
|
|
135
|
-
|
|
136
|
-
|
|
169
|
+
response_body = response.text[:500] if response.text else "empty"
|
|
170
|
+
self._resources = [] # Mark as loaded (empty) to prevent retries
|
|
171
|
+
raise FleetEnvironmentError(
|
|
172
|
+
f"Failed to load instance resources: status_code={response.status_code} "
|
|
173
|
+
f"(url={self.base_url}, response={response_body})"
|
|
174
|
+
)
|
|
137
175
|
|
|
138
176
|
# Handle both old and new response formats
|
|
139
177
|
response_data = response.json()
|
|
@@ -177,10 +215,17 @@ class AsyncInstanceClient:
|
|
|
177
215
|
response = await self.client.request("GET", "/health")
|
|
178
216
|
return HealthResponse(**response.json())
|
|
179
217
|
|
|
218
|
+
def close(self):
|
|
219
|
+
"""Close anchor connections for in-memory databases."""
|
|
220
|
+
if hasattr(self, '_memory_anchors'):
|
|
221
|
+
for conn in self._memory_anchors.values():
|
|
222
|
+
conn.close()
|
|
223
|
+
self._memory_anchors.clear()
|
|
224
|
+
|
|
180
225
|
async def __aenter__(self):
|
|
181
226
|
"""Async context manager entry."""
|
|
182
227
|
return self
|
|
183
228
|
|
|
184
229
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
185
230
|
"""Async context manager exit."""
|
|
186
|
-
|
|
231
|
+
self.close()
|
fleet/_async/models.py
CHANGED
|
@@ -120,6 +120,7 @@ class ResourceMode(Enum):
|
|
|
120
120
|
class ResourceType(Enum):
|
|
121
121
|
sqlite = "sqlite"
|
|
122
122
|
cdp = "cdp"
|
|
123
|
+
api = "api"
|
|
123
124
|
|
|
124
125
|
|
|
125
126
|
class RestoreRequest(BaseModel):
|
|
@@ -155,12 +156,23 @@ class TaskRequest(BaseModel):
|
|
|
155
156
|
verifier_id: Optional[str] = Field(None, title="Verifier Id")
|
|
156
157
|
version: Optional[str] = Field(None, title="Version")
|
|
157
158
|
env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
|
|
159
|
+
metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
|
|
160
|
+
writer_metadata: Optional[Dict[str, Any]] = Field(
|
|
161
|
+
None, title="Writer Metadata", description="Metadata filled by task writer"
|
|
162
|
+
)
|
|
158
163
|
output_json_schema: Optional[Dict[str, Any]] = Field(None, title="Output Json Schema")
|
|
159
164
|
|
|
160
165
|
|
|
161
166
|
class TaskUpdateRequest(BaseModel):
|
|
162
167
|
prompt: Optional[str] = Field(None, title="Prompt")
|
|
163
168
|
verifier_code: Optional[str] = Field(None, title="Verifier Code")
|
|
169
|
+
metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
|
|
170
|
+
writer_metadata: Optional[Dict[str, Any]] = Field(
|
|
171
|
+
None, title="Writer Metadata", description="Metadata filled by task writer"
|
|
172
|
+
)
|
|
173
|
+
qa_metadata: Optional[Dict[str, Any]] = Field(
|
|
174
|
+
None, title="QA Metadata", description="Metadata filled by QA reviewer"
|
|
175
|
+
)
|
|
164
176
|
|
|
165
177
|
|
|
166
178
|
class VerifierData(BaseModel):
|
|
@@ -186,6 +198,9 @@ class TaskResponse(BaseModel):
|
|
|
186
198
|
data_version: Optional[str] = Field(None, title="Data Version")
|
|
187
199
|
env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
|
|
188
200
|
verifier: Optional[VerifierData] = Field(None, title="Verifier")
|
|
201
|
+
metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
|
|
202
|
+
writer_metadata: Optional[Dict[str, Any]] = Field(None, title="Writer Metadata")
|
|
203
|
+
qa_metadata: Optional[Dict[str, Any]] = Field(None, title="QA Metadata")
|
|
189
204
|
output_json_schema: Optional[Dict[str, Any]] = Field(None, title="Output Json Schema")
|
|
190
205
|
|
|
191
206
|
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""Async API Resource for making HTTP requests to the app's API endpoint."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from .base import Resource
|
|
7
|
+
from ...instance.models import Resource as ResourceModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AsyncAPIResponse:
|
|
11
|
+
"""Simple wrapper around httpx.Response with a requests-like interface."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, response: httpx.Response):
|
|
14
|
+
self._response = response
|
|
15
|
+
self.status_code: int = response.status_code
|
|
16
|
+
self.headers: httpx.Headers = response.headers
|
|
17
|
+
self.text: str = response.text
|
|
18
|
+
self.content: bytes = response.content
|
|
19
|
+
self.url: str = str(response.url)
|
|
20
|
+
self.ok: bool = response.is_success
|
|
21
|
+
|
|
22
|
+
def json(self) -> Any:
|
|
23
|
+
"""Parse response body as JSON."""
|
|
24
|
+
return self._response.json()
|
|
25
|
+
|
|
26
|
+
def raise_for_status(self) -> "AsyncAPIResponse":
|
|
27
|
+
"""Raise an HTTPStatusError if the response has an error status code."""
|
|
28
|
+
self._response.raise_for_status()
|
|
29
|
+
return self
|
|
30
|
+
|
|
31
|
+
def __repr__(self) -> str:
|
|
32
|
+
return f"<AsyncAPIResponse [{self.status_code}]>"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AsyncAPIResource(Resource):
|
|
36
|
+
"""Async HTTP client for making requests to the app's API endpoint.
|
|
37
|
+
|
|
38
|
+
Provides a requests-like interface for interacting with the app's REST API.
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
api = env.api()
|
|
42
|
+
response = await api.get("/users/1")
|
|
43
|
+
print(response.status_code) # 200
|
|
44
|
+
print(response.json()) # {"id": 1, "name": "John"}
|
|
45
|
+
|
|
46
|
+
# With headers/auth
|
|
47
|
+
response = await api.post(
|
|
48
|
+
"/users",
|
|
49
|
+
json={"name": "Jane"},
|
|
50
|
+
headers={"Authorization": "Bearer xxx"}
|
|
51
|
+
)
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
resource: ResourceModel,
|
|
57
|
+
base_url: str,
|
|
58
|
+
client: Optional[httpx.AsyncClient] = None,
|
|
59
|
+
):
|
|
60
|
+
super().__init__(resource)
|
|
61
|
+
self.base_url = base_url.rstrip("/")
|
|
62
|
+
self._client = client or httpx.AsyncClient()
|
|
63
|
+
|
|
64
|
+
def _build_url(self, path: str) -> str:
|
|
65
|
+
"""Build full URL from base_url and path."""
|
|
66
|
+
if path.startswith("/"):
|
|
67
|
+
return f"{self.base_url}{path}"
|
|
68
|
+
return f"{self.base_url}/{path}"
|
|
69
|
+
|
|
70
|
+
async def request(
|
|
71
|
+
self,
|
|
72
|
+
method: str,
|
|
73
|
+
path: str,
|
|
74
|
+
*,
|
|
75
|
+
params: Optional[Dict[str, Any]] = None,
|
|
76
|
+
json: Optional[Any] = None,
|
|
77
|
+
data: Optional[Dict[str, Any]] = None,
|
|
78
|
+
headers: Optional[Dict[str, str]] = None,
|
|
79
|
+
cookies: Optional[Dict[str, str]] = None,
|
|
80
|
+
timeout: Optional[float] = None,
|
|
81
|
+
**kwargs: Any,
|
|
82
|
+
) -> AsyncAPIResponse:
|
|
83
|
+
"""Make an HTTP request.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
method: HTTP method (GET, POST, PUT, PATCH, DELETE, etc.)
|
|
87
|
+
path: URL path (relative to base_url)
|
|
88
|
+
params: Query parameters
|
|
89
|
+
json: JSON body (will be serialized)
|
|
90
|
+
data: Form data
|
|
91
|
+
headers: Request headers
|
|
92
|
+
cookies: Request cookies
|
|
93
|
+
timeout: Request timeout in seconds
|
|
94
|
+
**kwargs: Additional arguments passed to httpx
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
AsyncAPIResponse with status_code, headers, text, content, json() method
|
|
98
|
+
"""
|
|
99
|
+
url = self._build_url(path)
|
|
100
|
+
response = await self._client.request(
|
|
101
|
+
method,
|
|
102
|
+
url,
|
|
103
|
+
params=params,
|
|
104
|
+
json=json,
|
|
105
|
+
data=data,
|
|
106
|
+
headers=headers,
|
|
107
|
+
cookies=cookies,
|
|
108
|
+
timeout=timeout,
|
|
109
|
+
**kwargs,
|
|
110
|
+
)
|
|
111
|
+
return AsyncAPIResponse(response)
|
|
112
|
+
|
|
113
|
+
async def get(
|
|
114
|
+
self,
|
|
115
|
+
path: str,
|
|
116
|
+
*,
|
|
117
|
+
params: Optional[Dict[str, Any]] = None,
|
|
118
|
+
headers: Optional[Dict[str, str]] = None,
|
|
119
|
+
**kwargs: Any,
|
|
120
|
+
) -> AsyncAPIResponse:
|
|
121
|
+
"""Make a GET request."""
|
|
122
|
+
return await self.request("GET", path, params=params, headers=headers, **kwargs)
|
|
123
|
+
|
|
124
|
+
async def post(
|
|
125
|
+
self,
|
|
126
|
+
path: str,
|
|
127
|
+
*,
|
|
128
|
+
json: Optional[Any] = None,
|
|
129
|
+
data: Optional[Dict[str, Any]] = None,
|
|
130
|
+
params: Optional[Dict[str, Any]] = None,
|
|
131
|
+
headers: Optional[Dict[str, str]] = None,
|
|
132
|
+
**kwargs: Any,
|
|
133
|
+
) -> AsyncAPIResponse:
|
|
134
|
+
"""Make a POST request."""
|
|
135
|
+
return await self.request(
|
|
136
|
+
"POST", path, json=json, data=data, params=params, headers=headers, **kwargs
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
async def put(
|
|
140
|
+
self,
|
|
141
|
+
path: str,
|
|
142
|
+
*,
|
|
143
|
+
json: Optional[Any] = None,
|
|
144
|
+
data: Optional[Dict[str, Any]] = None,
|
|
145
|
+
params: Optional[Dict[str, Any]] = None,
|
|
146
|
+
headers: Optional[Dict[str, str]] = None,
|
|
147
|
+
**kwargs: Any,
|
|
148
|
+
) -> AsyncAPIResponse:
|
|
149
|
+
"""Make a PUT request."""
|
|
150
|
+
return await self.request(
|
|
151
|
+
"PUT", path, json=json, data=data, params=params, headers=headers, **kwargs
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
async def patch(
|
|
155
|
+
self,
|
|
156
|
+
path: str,
|
|
157
|
+
*,
|
|
158
|
+
json: Optional[Any] = None,
|
|
159
|
+
data: Optional[Dict[str, Any]] = None,
|
|
160
|
+
params: Optional[Dict[str, Any]] = None,
|
|
161
|
+
headers: Optional[Dict[str, str]] = None,
|
|
162
|
+
**kwargs: Any,
|
|
163
|
+
) -> AsyncAPIResponse:
|
|
164
|
+
"""Make a PATCH request."""
|
|
165
|
+
return await self.request(
|
|
166
|
+
"PATCH", path, json=json, data=data, params=params, headers=headers, **kwargs
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
async def delete(
|
|
170
|
+
self,
|
|
171
|
+
path: str,
|
|
172
|
+
*,
|
|
173
|
+
params: Optional[Dict[str, Any]] = None,
|
|
174
|
+
headers: Optional[Dict[str, str]] = None,
|
|
175
|
+
**kwargs: Any,
|
|
176
|
+
) -> AsyncAPIResponse:
|
|
177
|
+
"""Make a DELETE request."""
|
|
178
|
+
return await self.request("DELETE", path, params=params, headers=headers, **kwargs)
|
|
179
|
+
|
|
180
|
+
async def head(
|
|
181
|
+
self,
|
|
182
|
+
path: str,
|
|
183
|
+
*,
|
|
184
|
+
params: Optional[Dict[str, Any]] = None,
|
|
185
|
+
headers: Optional[Dict[str, str]] = None,
|
|
186
|
+
**kwargs: Any,
|
|
187
|
+
) -> AsyncAPIResponse:
|
|
188
|
+
"""Make a HEAD request."""
|
|
189
|
+
return await self.request("HEAD", path, params=params, headers=headers, **kwargs)
|
|
190
|
+
|
|
191
|
+
async def options(
|
|
192
|
+
self,
|
|
193
|
+
path: str,
|
|
194
|
+
*,
|
|
195
|
+
params: Optional[Dict[str, Any]] = None,
|
|
196
|
+
headers: Optional[Dict[str, str]] = None,
|
|
197
|
+
**kwargs: Any,
|
|
198
|
+
) -> AsyncAPIResponse:
|
|
199
|
+
"""Make an OPTIONS request."""
|
|
200
|
+
return await self.request("OPTIONS", path, params=params, headers=headers, **kwargs)
|