tinyfish 0.2.5__tar.gz → 0.2.6__tar.gz
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.
- {tinyfish-0.2.5 → tinyfish-0.2.6}/PKG-INFO +33 -1
- {tinyfish-0.2.5 → tinyfish-0.2.6}/README.md +32 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/pyproject.toml +8 -3
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/__init__.py +27 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/client/async_.py +10 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/client/sync.py +10 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/resource.py +2 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/agent/__init__.py +146 -6
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/client.py +5 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/fetch/__init__.py +59 -4
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/runs/types.py +4 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/search/__init__.py +36 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/search/types.py +1 -0
- tinyfish-0.2.6/src/tinyfish/vault/__init__.py +208 -0
- tinyfish-0.2.6/src/tinyfish/vault/types.py +106 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_agent.py +249 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_fetch.py +62 -1
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_runs.py +159 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_search.py +26 -3
- tinyfish-0.2.6/tests/test_vault.py +438 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/uv.lock +15 -12
- {tinyfish-0.2.5 → tinyfish-0.2.6}/.gitignore +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/.pre-commit-config.yaml +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/AGENTS.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/CLAUDE.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/RELEASE.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/exceptions-and-errors-guide.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/internal/api-integration-header.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/internal/exceptions-and-errors-guide.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/internal/publishing-private-guide.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/pagination-guide.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/proxy-and-browser-profiles.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/docs/streaming-guide.md +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/__init__.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/client/__init__.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/client/_base.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/exceptions.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/_utils/sse_parser.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/agent/types.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/browser/__init__.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/browser/types.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/fetch/types.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/py.typed +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/src/tinyfish/runs/__init__.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/__init__.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/conftest.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_browser.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_client.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/test_errors.py +0 -0
- {tinyfish-0.2.5 → tinyfish-0.2.6}/tests/testing_guide.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinyfish
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Official Python SDK for the TinyFish API
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Requires-Dist: httpx>=0.27.0
|
|
@@ -75,6 +75,14 @@ response = client.agent.run(
|
|
|
75
75
|
enabled=True,
|
|
76
76
|
country_code=ProxyCountryCode.US, # optional — US, GB, CA, DE, FR, JP, AU
|
|
77
77
|
),
|
|
78
|
+
output_schema={ # require structured output
|
|
79
|
+
"type": "object",
|
|
80
|
+
"properties": {
|
|
81
|
+
"headline_count": {"type": "integer"},
|
|
82
|
+
"top_headline": {"type": "string"},
|
|
83
|
+
},
|
|
84
|
+
"required": ["headline_count", "top_headline"],
|
|
85
|
+
},
|
|
78
86
|
)
|
|
79
87
|
|
|
80
88
|
if response.status == RunStatus.COMPLETED:
|
|
@@ -83,6 +91,12 @@ else:
|
|
|
83
91
|
print(f"Failed: {response.error.message}")
|
|
84
92
|
```
|
|
85
93
|
|
|
94
|
+
`output_schema` must be a top-level object. The SDK sends the schema to the API as-is; invalid schemas are rejected by
|
|
95
|
+
the API before execution.
|
|
96
|
+
|
|
97
|
+
The same `output_schema=` keyword is available on `client.agent.queue()` and `client.agent.stream()`.
|
|
98
|
+
Persisted runs return the requested contract back as `run.output_schema`.
|
|
99
|
+
|
|
86
100
|
**Returns `AgentRunResponse`:**
|
|
87
101
|
|
|
88
102
|
| Field | Type | Description |
|
|
@@ -101,6 +115,8 @@ else:
|
|
|
101
115
|
|
|
102
116
|
Starts the automation in the background and returns a `run_id` immediately. Poll with `runs.get()` when you're ready for the result.
|
|
103
117
|
|
|
118
|
+
`queue()` accepts the same structured-output parameters as `run()`, including `output_schema=...`.
|
|
119
|
+
|
|
104
120
|
```python
|
|
105
121
|
import time
|
|
106
122
|
from tinyfish import TinyFish, RunStatus
|
|
@@ -179,6 +195,7 @@ run = client.runs.get(
|
|
|
179
195
|
print(run.status) # PENDING, RUNNING, COMPLETED, FAILED, CANCELLED
|
|
180
196
|
print(run.result)
|
|
181
197
|
print(run.goal)
|
|
198
|
+
print(run.output_schema) # requested structured-output contract, if one was provided
|
|
182
199
|
print(run.streaming_url) # live browser URL (while RUNNING)
|
|
183
200
|
print(run.browser_config) # proxy/browser settings that were used
|
|
184
201
|
```
|
|
@@ -191,6 +208,7 @@ print(run.browser_config) # proxy/browser settings that were used
|
|
|
191
208
|
| `status` | `RunStatus` | `PENDING`, `RUNNING`, `COMPLETED`, `FAILED`, `CANCELLED` |
|
|
192
209
|
| `goal` | `str` | The goal that was given |
|
|
193
210
|
| `result` | `dict \| None` | Extracted data (`None` if not completed) |
|
|
211
|
+
| `output_schema` | `dict \| None` | JSON Schema contract originally requested for the run |
|
|
194
212
|
| `error` | `RunError \| None` | Error details (`None` if succeeded) |
|
|
195
213
|
| `streaming_url` | `str \| None` | Live browser URL (available while running) |
|
|
196
214
|
| `browser_config` | `BrowserConfig \| None` | Proxy/browser settings used |
|
|
@@ -296,6 +314,20 @@ response = client.agent.run(
|
|
|
296
314
|
)
|
|
297
315
|
```
|
|
298
316
|
|
|
317
|
+
### Browser Context Profiles
|
|
318
|
+
|
|
319
|
+
Use Browser Context Profiles when a run should start from saved logged-in state. Pass `use_profile=True` for your default profile, or add `profile_id` for a specific profile. Pair with `use_vault=True` when TinyFish should repair stale sessions with saved credentials.
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
response = client.agent.run(
|
|
323
|
+
goal="Summarize the dashboard",
|
|
324
|
+
url="https://app.example.com/dashboard",
|
|
325
|
+
use_profile=True,
|
|
326
|
+
profile_id="prof_abc123def4567890",
|
|
327
|
+
use_vault=True,
|
|
328
|
+
)
|
|
329
|
+
```
|
|
330
|
+
|
|
299
331
|
### Proxy configuration
|
|
300
332
|
|
|
301
333
|
Route requests through a proxy, optionally pinned to a country:
|
|
@@ -65,6 +65,14 @@ response = client.agent.run(
|
|
|
65
65
|
enabled=True,
|
|
66
66
|
country_code=ProxyCountryCode.US, # optional — US, GB, CA, DE, FR, JP, AU
|
|
67
67
|
),
|
|
68
|
+
output_schema={ # require structured output
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"headline_count": {"type": "integer"},
|
|
72
|
+
"top_headline": {"type": "string"},
|
|
73
|
+
},
|
|
74
|
+
"required": ["headline_count", "top_headline"],
|
|
75
|
+
},
|
|
68
76
|
)
|
|
69
77
|
|
|
70
78
|
if response.status == RunStatus.COMPLETED:
|
|
@@ -73,6 +81,12 @@ else:
|
|
|
73
81
|
print(f"Failed: {response.error.message}")
|
|
74
82
|
```
|
|
75
83
|
|
|
84
|
+
`output_schema` must be a top-level object. The SDK sends the schema to the API as-is; invalid schemas are rejected by
|
|
85
|
+
the API before execution.
|
|
86
|
+
|
|
87
|
+
The same `output_schema=` keyword is available on `client.agent.queue()` and `client.agent.stream()`.
|
|
88
|
+
Persisted runs return the requested contract back as `run.output_schema`.
|
|
89
|
+
|
|
76
90
|
**Returns `AgentRunResponse`:**
|
|
77
91
|
|
|
78
92
|
| Field | Type | Description |
|
|
@@ -91,6 +105,8 @@ else:
|
|
|
91
105
|
|
|
92
106
|
Starts the automation in the background and returns a `run_id` immediately. Poll with `runs.get()` when you're ready for the result.
|
|
93
107
|
|
|
108
|
+
`queue()` accepts the same structured-output parameters as `run()`, including `output_schema=...`.
|
|
109
|
+
|
|
94
110
|
```python
|
|
95
111
|
import time
|
|
96
112
|
from tinyfish import TinyFish, RunStatus
|
|
@@ -169,6 +185,7 @@ run = client.runs.get(
|
|
|
169
185
|
print(run.status) # PENDING, RUNNING, COMPLETED, FAILED, CANCELLED
|
|
170
186
|
print(run.result)
|
|
171
187
|
print(run.goal)
|
|
188
|
+
print(run.output_schema) # requested structured-output contract, if one was provided
|
|
172
189
|
print(run.streaming_url) # live browser URL (while RUNNING)
|
|
173
190
|
print(run.browser_config) # proxy/browser settings that were used
|
|
174
191
|
```
|
|
@@ -181,6 +198,7 @@ print(run.browser_config) # proxy/browser settings that were used
|
|
|
181
198
|
| `status` | `RunStatus` | `PENDING`, `RUNNING`, `COMPLETED`, `FAILED`, `CANCELLED` |
|
|
182
199
|
| `goal` | `str` | The goal that was given |
|
|
183
200
|
| `result` | `dict \| None` | Extracted data (`None` if not completed) |
|
|
201
|
+
| `output_schema` | `dict \| None` | JSON Schema contract originally requested for the run |
|
|
184
202
|
| `error` | `RunError \| None` | Error details (`None` if succeeded) |
|
|
185
203
|
| `streaming_url` | `str \| None` | Live browser URL (available while running) |
|
|
186
204
|
| `browser_config` | `BrowserConfig \| None` | Proxy/browser settings used |
|
|
@@ -286,6 +304,20 @@ response = client.agent.run(
|
|
|
286
304
|
)
|
|
287
305
|
```
|
|
288
306
|
|
|
307
|
+
### Browser Context Profiles
|
|
308
|
+
|
|
309
|
+
Use Browser Context Profiles when a run should start from saved logged-in state. Pass `use_profile=True` for your default profile, or add `profile_id` for a specific profile. Pair with `use_vault=True` when TinyFish should repair stale sessions with saved credentials.
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
response = client.agent.run(
|
|
313
|
+
goal="Summarize the dashboard",
|
|
314
|
+
url="https://app.example.com/dashboard",
|
|
315
|
+
use_profile=True,
|
|
316
|
+
profile_id="prof_abc123def4567890",
|
|
317
|
+
use_vault=True,
|
|
318
|
+
)
|
|
319
|
+
```
|
|
320
|
+
|
|
289
321
|
### Proxy configuration
|
|
290
322
|
|
|
291
323
|
Route requests through a proxy, optionally pinned to a country:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tinyfish"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.6"
|
|
4
4
|
description = "Official Python SDK for the TinyFish API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -10,6 +10,11 @@ dependencies = [
|
|
|
10
10
|
"tenacity>=8.0.0",
|
|
11
11
|
]
|
|
12
12
|
|
|
13
|
+
[tool.uv]
|
|
14
|
+
constraint-dependencies = [
|
|
15
|
+
"pygments>=2.20.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
13
18
|
[build-system]
|
|
14
19
|
requires = ["hatchling"]
|
|
15
20
|
build-backend = "hatchling.build"
|
|
@@ -20,8 +25,8 @@ packages = ["src/tinyfish"]
|
|
|
20
25
|
[dependency-groups]
|
|
21
26
|
dev = [
|
|
22
27
|
"ruff>=0.15.2",
|
|
23
|
-
"pytest>=
|
|
24
|
-
"pytest-asyncio>=
|
|
28
|
+
"pytest>=9.0.3",
|
|
29
|
+
"pytest-asyncio>=1.3.0",
|
|
25
30
|
"respx>=0.22.0",
|
|
26
31
|
"python-dotenv>=1.2.2",
|
|
27
32
|
]
|
|
@@ -65,6 +65,21 @@ from .runs.types import (
|
|
|
65
65
|
# Search types
|
|
66
66
|
from .search.types import SearchQueryResponse, SearchResult
|
|
67
67
|
|
|
68
|
+
# Vault types
|
|
69
|
+
from .vault.types import (
|
|
70
|
+
FieldMetadata,
|
|
71
|
+
SyncSummary,
|
|
72
|
+
VaultConnection,
|
|
73
|
+
VaultConnectResponse,
|
|
74
|
+
VaultDisconnectResponse,
|
|
75
|
+
VaultFieldType,
|
|
76
|
+
VaultItem,
|
|
77
|
+
VaultListConnectionsResponse,
|
|
78
|
+
VaultListItemsResponse,
|
|
79
|
+
VaultProvider,
|
|
80
|
+
VaultSyncItemsResponse,
|
|
81
|
+
)
|
|
82
|
+
|
|
68
83
|
__version__ = version("tinyfish")
|
|
69
84
|
|
|
70
85
|
__all__ = [
|
|
@@ -122,4 +137,16 @@ __all__ = [
|
|
|
122
137
|
"RunStatus",
|
|
123
138
|
"RunListResponse",
|
|
124
139
|
"PaginationInfo",
|
|
140
|
+
# Vault types
|
|
141
|
+
"VaultProvider",
|
|
142
|
+
"VaultFieldType",
|
|
143
|
+
"FieldMetadata",
|
|
144
|
+
"VaultItem",
|
|
145
|
+
"VaultConnection",
|
|
146
|
+
"SyncSummary",
|
|
147
|
+
"VaultConnectResponse",
|
|
148
|
+
"VaultListConnectionsResponse",
|
|
149
|
+
"VaultDisconnectResponse",
|
|
150
|
+
"VaultListItemsResponse",
|
|
151
|
+
"VaultSyncItemsResponse",
|
|
125
152
|
]
|
|
@@ -131,6 +131,16 @@ class BaseAsyncAPIClient(_BaseClient):
|
|
|
131
131
|
response = await self._request("POST", path, json=json)
|
|
132
132
|
return self._parse_response(response, cast_to)
|
|
133
133
|
|
|
134
|
+
async def _delete(
|
|
135
|
+
self,
|
|
136
|
+
path: str,
|
|
137
|
+
*,
|
|
138
|
+
cast_to: type[ResponseT],
|
|
139
|
+
) -> ResponseT:
|
|
140
|
+
"""Make DELETE request and parse the response into cast_to."""
|
|
141
|
+
response = await self._request("DELETE", path)
|
|
142
|
+
return self._parse_response(response, cast_to)
|
|
143
|
+
|
|
134
144
|
async def _post_stream(
|
|
135
145
|
self,
|
|
136
146
|
path: str,
|
|
@@ -131,6 +131,16 @@ class BaseSyncAPIClient(_BaseClient):
|
|
|
131
131
|
response = self._request("POST", path, json=json)
|
|
132
132
|
return self._parse_response(response, cast_to)
|
|
133
133
|
|
|
134
|
+
def _delete(
|
|
135
|
+
self,
|
|
136
|
+
path: str,
|
|
137
|
+
*,
|
|
138
|
+
cast_to: type[ResponseT],
|
|
139
|
+
) -> ResponseT:
|
|
140
|
+
"""Make DELETE request and parse the response into cast_to."""
|
|
141
|
+
response = self._request("DELETE", path)
|
|
142
|
+
return self._parse_response(response, cast_to)
|
|
143
|
+
|
|
134
144
|
def _post_stream(
|
|
135
145
|
self,
|
|
136
146
|
path: str,
|
|
@@ -10,6 +10,7 @@ class BaseSyncAPIResource:
|
|
|
10
10
|
self._client = client
|
|
11
11
|
self._get = client._get
|
|
12
12
|
self._post = client._post
|
|
13
|
+
self._delete = client._delete
|
|
13
14
|
self._post_stream = client._post_stream
|
|
14
15
|
|
|
15
16
|
|
|
@@ -20,4 +21,5 @@ class BaseAsyncAPIResource:
|
|
|
20
21
|
self._client = client
|
|
21
22
|
self._get = client._get
|
|
22
23
|
self._post = client._post
|
|
24
|
+
self._delete = client._delete
|
|
23
25
|
self._post_stream = client._post_stream
|
|
@@ -27,12 +27,32 @@ def _build_run_body(
|
|
|
27
27
|
url: str,
|
|
28
28
|
browser_profile: BrowserProfile | None,
|
|
29
29
|
proxy_config: ProxyConfig | None,
|
|
30
|
+
output_schema: dict[str, Any] | None,
|
|
31
|
+
use_profile: bool | None = None,
|
|
32
|
+
profile_id: str | None = None,
|
|
33
|
+
use_vault: bool | None = None,
|
|
34
|
+
credential_item_ids: list[str] | None = None,
|
|
30
35
|
) -> dict[str, Any]:
|
|
31
36
|
body: dict[str, Any] = {"goal": goal, "url": url}
|
|
32
37
|
if browser_profile is not None:
|
|
33
38
|
body["browser_profile"] = browser_profile
|
|
34
39
|
if proxy_config is not None:
|
|
35
40
|
body["proxy_config"] = proxy_config.model_dump(exclude_none=True)
|
|
41
|
+
if output_schema is not None:
|
|
42
|
+
body["output_schema"] = output_schema
|
|
43
|
+
if use_profile is not None:
|
|
44
|
+
body["use_profile"] = use_profile
|
|
45
|
+
if profile_id is not None:
|
|
46
|
+
profile_id = profile_id.strip()
|
|
47
|
+
if not profile_id:
|
|
48
|
+
raise ValueError("profile_id must be a non-empty string")
|
|
49
|
+
if use_profile is not True:
|
|
50
|
+
raise ValueError("profile_id requires use_profile=True")
|
|
51
|
+
body["profile_id"] = profile_id
|
|
52
|
+
if use_vault is not None:
|
|
53
|
+
body["use_vault"] = use_vault
|
|
54
|
+
if credential_item_ids is not None:
|
|
55
|
+
body["credential_item_ids"] = credential_item_ids
|
|
36
56
|
return body
|
|
37
57
|
|
|
38
58
|
|
|
@@ -106,6 +126,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
106
126
|
url: str,
|
|
107
127
|
browser_profile: BrowserProfile | None = None,
|
|
108
128
|
proxy_config: ProxyConfig | None = None,
|
|
129
|
+
output_schema: dict[str, Any] | None = None,
|
|
130
|
+
use_profile: bool | None = None,
|
|
131
|
+
profile_id: str | None = None,
|
|
132
|
+
use_vault: bool | None = None,
|
|
133
|
+
credential_item_ids: list[str] | None = None,
|
|
109
134
|
) -> AgentRunResponse:
|
|
110
135
|
"""Run a browser automation and wait for it to finish.
|
|
111
136
|
|
|
@@ -117,6 +142,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
117
142
|
url: The URL to open the browser on.
|
|
118
143
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
119
144
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
145
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
146
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
147
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
148
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
149
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
120
150
|
|
|
121
151
|
Returns:
|
|
122
152
|
AgentRunResponse with status, result, and timing info.
|
|
@@ -126,7 +156,17 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
126
156
|
RateLimitError: Too many requests.
|
|
127
157
|
InternalServerError: Something went wrong on the server.
|
|
128
158
|
"""
|
|
129
|
-
body = _build_run_body(
|
|
159
|
+
body = _build_run_body(
|
|
160
|
+
goal,
|
|
161
|
+
url,
|
|
162
|
+
browser_profile,
|
|
163
|
+
proxy_config,
|
|
164
|
+
output_schema,
|
|
165
|
+
use_profile,
|
|
166
|
+
profile_id,
|
|
167
|
+
use_vault,
|
|
168
|
+
credential_item_ids,
|
|
169
|
+
)
|
|
130
170
|
return self._post("/v1/automation/run", json=body, cast_to=AgentRunResponse)
|
|
131
171
|
|
|
132
172
|
def queue(
|
|
@@ -136,6 +176,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
136
176
|
url: str,
|
|
137
177
|
browser_profile: BrowserProfile | None = None,
|
|
138
178
|
proxy_config: ProxyConfig | None = None,
|
|
179
|
+
output_schema: dict[str, Any] | None = None,
|
|
180
|
+
use_profile: bool | None = None,
|
|
181
|
+
profile_id: str | None = None,
|
|
182
|
+
use_vault: bool | None = None,
|
|
183
|
+
credential_item_ids: list[str] | None = None,
|
|
139
184
|
) -> AgentRunAsyncResponse:
|
|
140
185
|
"""Queue a browser automation and return immediately.
|
|
141
186
|
|
|
@@ -147,6 +192,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
147
192
|
url: The URL to open the browser on.
|
|
148
193
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
149
194
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
195
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
196
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
197
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
198
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
199
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
150
200
|
|
|
151
201
|
Returns:
|
|
152
202
|
AgentRunAsyncResponse with the run_id to poll later.
|
|
@@ -156,7 +206,17 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
156
206
|
RateLimitError: Too many requests.
|
|
157
207
|
InternalServerError: Something went wrong on the server.
|
|
158
208
|
"""
|
|
159
|
-
body = _build_run_body(
|
|
209
|
+
body = _build_run_body(
|
|
210
|
+
goal,
|
|
211
|
+
url,
|
|
212
|
+
browser_profile,
|
|
213
|
+
proxy_config,
|
|
214
|
+
output_schema,
|
|
215
|
+
use_profile,
|
|
216
|
+
profile_id,
|
|
217
|
+
use_vault,
|
|
218
|
+
credential_item_ids,
|
|
219
|
+
)
|
|
160
220
|
return self._post("/v1/automation/run-async", json=body, cast_to=AgentRunAsyncResponse)
|
|
161
221
|
|
|
162
222
|
def stream(
|
|
@@ -166,6 +226,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
166
226
|
url: str,
|
|
167
227
|
browser_profile: BrowserProfile | None = None,
|
|
168
228
|
proxy_config: ProxyConfig | None = None,
|
|
229
|
+
output_schema: dict[str, Any] | None = None,
|
|
230
|
+
use_profile: bool | None = None,
|
|
231
|
+
profile_id: str | None = None,
|
|
232
|
+
use_vault: bool | None = None,
|
|
233
|
+
credential_item_ids: list[str] | None = None,
|
|
169
234
|
on_started: Callable[[StartedEvent], None] | None = None,
|
|
170
235
|
on_streaming_url: Callable[[StreamingUrlEvent], None] | None = None,
|
|
171
236
|
on_progress: Callable[[ProgressEvent], None] | None = None,
|
|
@@ -202,6 +267,11 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
202
267
|
url: The URL to open the browser on.
|
|
203
268
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
204
269
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
270
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
271
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
272
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
273
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
274
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
205
275
|
on_started: Called when the run starts (receives StartedEvent).
|
|
206
276
|
on_streaming_url: Called with the live browser stream URL (receives StreamingUrlEvent).
|
|
207
277
|
on_progress: Called on each automation step (receives ProgressEvent).
|
|
@@ -216,7 +286,17 @@ class AgentResource(BaseSyncAPIResource):
|
|
|
216
286
|
RateLimitError: Too many requests.
|
|
217
287
|
InternalServerError: Something went wrong on the server.
|
|
218
288
|
"""
|
|
219
|
-
body = _build_run_body(
|
|
289
|
+
body = _build_run_body(
|
|
290
|
+
goal,
|
|
291
|
+
url,
|
|
292
|
+
browser_profile,
|
|
293
|
+
proxy_config,
|
|
294
|
+
output_schema,
|
|
295
|
+
use_profile,
|
|
296
|
+
profile_id,
|
|
297
|
+
use_vault,
|
|
298
|
+
credential_item_ids,
|
|
299
|
+
)
|
|
220
300
|
|
|
221
301
|
def _generate() -> Iterator[AgentRunWithStreamingResponse]:
|
|
222
302
|
lines = self._post_stream("/v1/automation/run-sse", json=body)
|
|
@@ -261,6 +341,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
261
341
|
url: str,
|
|
262
342
|
browser_profile: BrowserProfile | None = None,
|
|
263
343
|
proxy_config: ProxyConfig | None = None,
|
|
344
|
+
output_schema: dict[str, Any] | None = None,
|
|
345
|
+
use_profile: bool | None = None,
|
|
346
|
+
profile_id: str | None = None,
|
|
347
|
+
use_vault: bool | None = None,
|
|
348
|
+
credential_item_ids: list[str] | None = None,
|
|
264
349
|
) -> AgentRunResponse:
|
|
265
350
|
"""Run a browser automation and wait for it to finish.
|
|
266
351
|
|
|
@@ -272,6 +357,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
272
357
|
url: The URL to open the browser on.
|
|
273
358
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
274
359
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
360
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
361
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
362
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
363
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
364
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
275
365
|
|
|
276
366
|
Returns:
|
|
277
367
|
AgentRunResponse with status, result, and timing info.
|
|
@@ -281,7 +371,17 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
281
371
|
RateLimitError: Too many requests.
|
|
282
372
|
InternalServerError: Something went wrong on the server.
|
|
283
373
|
"""
|
|
284
|
-
body = _build_run_body(
|
|
374
|
+
body = _build_run_body(
|
|
375
|
+
goal,
|
|
376
|
+
url,
|
|
377
|
+
browser_profile,
|
|
378
|
+
proxy_config,
|
|
379
|
+
output_schema,
|
|
380
|
+
use_profile,
|
|
381
|
+
profile_id,
|
|
382
|
+
use_vault,
|
|
383
|
+
credential_item_ids,
|
|
384
|
+
)
|
|
285
385
|
return await self._post("/v1/automation/run", json=body, cast_to=AgentRunResponse)
|
|
286
386
|
|
|
287
387
|
async def queue(
|
|
@@ -291,6 +391,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
291
391
|
url: str,
|
|
292
392
|
browser_profile: BrowserProfile | None = None,
|
|
293
393
|
proxy_config: ProxyConfig | None = None,
|
|
394
|
+
output_schema: dict[str, Any] | None = None,
|
|
395
|
+
use_profile: bool | None = None,
|
|
396
|
+
profile_id: str | None = None,
|
|
397
|
+
use_vault: bool | None = None,
|
|
398
|
+
credential_item_ids: list[str] | None = None,
|
|
294
399
|
) -> AgentRunAsyncResponse:
|
|
295
400
|
"""Queue a browser automation and return immediately.
|
|
296
401
|
|
|
@@ -302,6 +407,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
302
407
|
url: The URL to open the browser on.
|
|
303
408
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
304
409
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
410
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
411
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
412
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
413
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
414
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
305
415
|
|
|
306
416
|
Returns:
|
|
307
417
|
AgentRunAsyncResponse with the run_id to poll later.
|
|
@@ -311,7 +421,17 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
311
421
|
RateLimitError: Too many requests.
|
|
312
422
|
InternalServerError: Something went wrong on the server.
|
|
313
423
|
"""
|
|
314
|
-
body = _build_run_body(
|
|
424
|
+
body = _build_run_body(
|
|
425
|
+
goal,
|
|
426
|
+
url,
|
|
427
|
+
browser_profile,
|
|
428
|
+
proxy_config,
|
|
429
|
+
output_schema,
|
|
430
|
+
use_profile,
|
|
431
|
+
profile_id,
|
|
432
|
+
use_vault,
|
|
433
|
+
credential_item_ids,
|
|
434
|
+
)
|
|
315
435
|
return await self._post("/v1/automation/run-async", json=body, cast_to=AgentRunAsyncResponse)
|
|
316
436
|
|
|
317
437
|
def stream(
|
|
@@ -321,6 +441,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
321
441
|
url: str,
|
|
322
442
|
browser_profile: BrowserProfile | None = None,
|
|
323
443
|
proxy_config: ProxyConfig | None = None,
|
|
444
|
+
output_schema: dict[str, Any] | None = None,
|
|
445
|
+
use_profile: bool | None = None,
|
|
446
|
+
profile_id: str | None = None,
|
|
447
|
+
use_vault: bool | None = None,
|
|
448
|
+
credential_item_ids: list[str] | None = None,
|
|
324
449
|
on_started: Callable[[StartedEvent], None] | None = None,
|
|
325
450
|
on_streaming_url: Callable[[StreamingUrlEvent], None] | None = None,
|
|
326
451
|
on_progress: Callable[[ProgressEvent], None] | None = None,
|
|
@@ -357,6 +482,11 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
357
482
|
url: The URL to open the browser on.
|
|
358
483
|
browser_profile: "lite" (default) or "stealth" (anti-detection).
|
|
359
484
|
proxy_config: Optional proxy settings (enabled, country_code).
|
|
485
|
+
output_schema: Optional JSON Schema object describing the expected final result.
|
|
486
|
+
use_profile: Whether to start from a saved Browser Context Profile.
|
|
487
|
+
profile_id: Specific Browser Context Profile ID. Requires use_profile=True.
|
|
488
|
+
use_vault: Whether to use stored vault credentials for authentication.
|
|
489
|
+
credential_item_ids: Specific vault item IDs to use. When omitted, all matching credentials are available.
|
|
360
490
|
on_started: Called when the run starts (receives StartedEvent).
|
|
361
491
|
on_streaming_url: Called with the live browser stream URL (receives StreamingUrlEvent).
|
|
362
492
|
on_progress: Called on each automation step (receives ProgressEvent).
|
|
@@ -371,7 +501,17 @@ class AsyncAgentResource(BaseAsyncAPIResource):
|
|
|
371
501
|
RateLimitError: Too many requests.
|
|
372
502
|
InternalServerError: Something went wrong on the server.
|
|
373
503
|
"""
|
|
374
|
-
body = _build_run_body(
|
|
504
|
+
body = _build_run_body(
|
|
505
|
+
goal,
|
|
506
|
+
url,
|
|
507
|
+
browser_profile,
|
|
508
|
+
proxy_config,
|
|
509
|
+
output_schema,
|
|
510
|
+
use_profile,
|
|
511
|
+
profile_id,
|
|
512
|
+
use_vault,
|
|
513
|
+
credential_item_ids,
|
|
514
|
+
)
|
|
375
515
|
|
|
376
516
|
async def _generate() -> AsyncIterator[AgentRunWithStreamingResponse]:
|
|
377
517
|
lines = self._post_stream("/v1/automation/run-sse", json=body)
|
|
@@ -8,6 +8,7 @@ from .browser import AsyncBrowserResource, BrowserResource
|
|
|
8
8
|
from .fetch import AsyncFetchResource, FetchResource
|
|
9
9
|
from .runs import AsyncRunsResource, RunsResource
|
|
10
10
|
from .search import AsyncSearchResource, SearchResource
|
|
11
|
+
from .vault import AsyncVaultResource, VaultResource
|
|
11
12
|
|
|
12
13
|
__all__ = ["TinyFish", "AsyncTinyFish"]
|
|
13
14
|
|
|
@@ -28,6 +29,7 @@ class TinyFish(BaseSyncAPIClient):
|
|
|
28
29
|
fetch: FetchResource
|
|
29
30
|
runs: RunsResource
|
|
30
31
|
search: SearchResource
|
|
32
|
+
vault: VaultResource
|
|
31
33
|
|
|
32
34
|
def __init__(
|
|
33
35
|
self,
|
|
@@ -52,6 +54,7 @@ class TinyFish(BaseSyncAPIClient):
|
|
|
52
54
|
self.fetch = FetchResource(self)
|
|
53
55
|
self.runs = RunsResource(self)
|
|
54
56
|
self.search = SearchResource(self)
|
|
57
|
+
self.vault = VaultResource(self)
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
class AsyncTinyFish(BaseAsyncAPIClient):
|
|
@@ -65,6 +68,7 @@ class AsyncTinyFish(BaseAsyncAPIClient):
|
|
|
65
68
|
fetch: AsyncFetchResource
|
|
66
69
|
runs: AsyncRunsResource
|
|
67
70
|
search: AsyncSearchResource
|
|
71
|
+
vault: AsyncVaultResource
|
|
68
72
|
|
|
69
73
|
def __init__(
|
|
70
74
|
self,
|
|
@@ -89,3 +93,4 @@ class AsyncTinyFish(BaseAsyncAPIClient):
|
|
|
89
93
|
self.fetch = AsyncFetchResource(self)
|
|
90
94
|
self.runs = AsyncRunsResource(self)
|
|
91
95
|
self.search = AsyncSearchResource(self)
|
|
96
|
+
self.vault = AsyncVaultResource(self)
|