firecrawl-py 3.3.1__py3-none-any.whl → 3.3.3__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.
Potentially problematic release.
This version of firecrawl-py might be problematic. Click here for more details.
- firecrawl/__init__.py +1 -1
- firecrawl/__tests__/e2e/v2/test_scrape.py +37 -1
- firecrawl/client.py +8 -4
- firecrawl/v2/types.py +19 -2
- {firecrawl_py-3.3.1.dist-info → firecrawl_py-3.3.3.dist-info}/METADATA +7 -3
- firecrawl_py-3.3.3.dist-info/RECORD +79 -0
- {firecrawl_py-3.3.1.dist-info → firecrawl_py-3.3.3.dist-info}/WHEEL +1 -1
- {firecrawl_py-3.3.1.dist-info → firecrawl_py-3.3.3.dist-info/licenses}/LICENSE +0 -0
- {firecrawl_py-3.3.1.dist-info → firecrawl_py-3.3.3.dist-info}/top_level.txt +0 -2
- build/lib/firecrawl/__init__.py +0 -87
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_batch_scrape.py +0 -79
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_crawl.py +0 -188
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_extract.py +0 -38
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_map.py +0 -40
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_scrape.py +0 -137
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_search.py +0 -248
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_usage.py +0 -35
- build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_watcher.py +0 -43
- build/lib/firecrawl/__tests__/e2e/v2/conftest.py +0 -73
- build/lib/firecrawl/__tests__/e2e/v2/test_async.py +0 -73
- build/lib/firecrawl/__tests__/e2e/v2/test_batch_scrape.py +0 -105
- build/lib/firecrawl/__tests__/e2e/v2/test_crawl.py +0 -276
- build/lib/firecrawl/__tests__/e2e/v2/test_extract.py +0 -54
- build/lib/firecrawl/__tests__/e2e/v2/test_map.py +0 -60
- build/lib/firecrawl/__tests__/e2e/v2/test_scrape.py +0 -154
- build/lib/firecrawl/__tests__/e2e/v2/test_search.py +0 -269
- build/lib/firecrawl/__tests__/e2e/v2/test_usage.py +0 -26
- build/lib/firecrawl/__tests__/e2e/v2/test_watcher.py +0 -65
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_params.py +0 -12
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_request_preparation.py +0 -61
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_validation.py +0 -12
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_map_request_preparation.py +0 -19
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_scrape_request_preparation.py +0 -50
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_search_request_preparation.py +0 -63
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_batch_request_preparation_async.py +0 -28
- build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_ensure_async.py +0 -117
- build/lib/firecrawl/__tests__/unit/v2/methods/test_batch_request_preparation.py +0 -90
- build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_params.py +0 -70
- build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_request_preparation.py +0 -240
- build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_validation.py +0 -107
- build/lib/firecrawl/__tests__/unit/v2/methods/test_map_request_preparation.py +0 -53
- build/lib/firecrawl/__tests__/unit/v2/methods/test_scrape_request_preparation.py +0 -92
- build/lib/firecrawl/__tests__/unit/v2/methods/test_search_request_preparation.py +0 -167
- build/lib/firecrawl/__tests__/unit/v2/methods/test_search_validation.py +0 -236
- build/lib/firecrawl/__tests__/unit/v2/methods/test_usage_types.py +0 -18
- build/lib/firecrawl/__tests__/unit/v2/methods/test_webhook.py +0 -123
- build/lib/firecrawl/__tests__/unit/v2/utils/test_validation.py +0 -290
- build/lib/firecrawl/__tests__/unit/v2/watcher/test_ws_watcher.py +0 -332
- build/lib/firecrawl/client.py +0 -242
- build/lib/firecrawl/firecrawl.backup.py +0 -4635
- build/lib/firecrawl/types.py +0 -161
- build/lib/firecrawl/v1/__init__.py +0 -14
- build/lib/firecrawl/v1/client.py +0 -4653
- build/lib/firecrawl/v2/__init__.py +0 -4
- build/lib/firecrawl/v2/client.py +0 -805
- build/lib/firecrawl/v2/client_async.py +0 -250
- build/lib/firecrawl/v2/methods/aio/__init__.py +0 -1
- build/lib/firecrawl/v2/methods/aio/batch.py +0 -85
- build/lib/firecrawl/v2/methods/aio/crawl.py +0 -171
- build/lib/firecrawl/v2/methods/aio/extract.py +0 -126
- build/lib/firecrawl/v2/methods/aio/map.py +0 -59
- build/lib/firecrawl/v2/methods/aio/scrape.py +0 -33
- build/lib/firecrawl/v2/methods/aio/search.py +0 -172
- build/lib/firecrawl/v2/methods/aio/usage.py +0 -42
- build/lib/firecrawl/v2/methods/batch.py +0 -417
- build/lib/firecrawl/v2/methods/crawl.py +0 -469
- build/lib/firecrawl/v2/methods/extract.py +0 -131
- build/lib/firecrawl/v2/methods/map.py +0 -77
- build/lib/firecrawl/v2/methods/scrape.py +0 -64
- build/lib/firecrawl/v2/methods/search.py +0 -197
- build/lib/firecrawl/v2/methods/usage.py +0 -41
- build/lib/firecrawl/v2/types.py +0 -665
- build/lib/firecrawl/v2/utils/__init__.py +0 -9
- build/lib/firecrawl/v2/utils/error_handler.py +0 -107
- build/lib/firecrawl/v2/utils/get_version.py +0 -15
- build/lib/firecrawl/v2/utils/http_client.py +0 -153
- build/lib/firecrawl/v2/utils/http_client_async.py +0 -65
- build/lib/firecrawl/v2/utils/normalize.py +0 -107
- build/lib/firecrawl/v2/utils/validation.py +0 -324
- build/lib/firecrawl/v2/watcher.py +0 -301
- build/lib/firecrawl/v2/watcher_async.py +0 -242
- build/lib/tests/test_change_tracking.py +0 -98
- build/lib/tests/test_timeout_conversion.py +0 -117
- firecrawl_py-3.3.1.dist-info/RECORD +0 -153
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Async WebSocket watcher with async iterator interface for v2 jobs.
|
|
3
|
-
|
|
4
|
-
Usage:
|
|
5
|
-
async for snapshot in AsyncWatcher(client, job_id, kind="crawl"):
|
|
6
|
-
print(snapshot.status)
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import asyncio
|
|
10
|
-
import inspect
|
|
11
|
-
import json
|
|
12
|
-
import time
|
|
13
|
-
from typing import AsyncIterator, Dict, List, Literal, Optional
|
|
14
|
-
|
|
15
|
-
import websockets
|
|
16
|
-
from websockets.exceptions import ConnectionClosed, ConnectionClosedOK, ConnectionClosedError
|
|
17
|
-
|
|
18
|
-
from .types import BatchScrapeJob, CrawlJob, Document
|
|
19
|
-
from .utils.normalize import normalize_document_input
|
|
20
|
-
|
|
21
|
-
JobKind = Literal["crawl", "batch"]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class AsyncWatcher:
|
|
25
|
-
def __init__(
|
|
26
|
-
self,
|
|
27
|
-
client: object,
|
|
28
|
-
job_id: str,
|
|
29
|
-
*,
|
|
30
|
-
kind: JobKind = "crawl",
|
|
31
|
-
timeout: Optional[int] = None,
|
|
32
|
-
) -> None:
|
|
33
|
-
self._client = client
|
|
34
|
-
self._job_id = job_id
|
|
35
|
-
self._kind = kind
|
|
36
|
-
self._timeout = timeout
|
|
37
|
-
self._poll_interval: float = 2.0
|
|
38
|
-
|
|
39
|
-
http_client = getattr(client, "http_client", None)
|
|
40
|
-
if http_client is not None:
|
|
41
|
-
self._api_url = getattr(http_client, "api_url", None)
|
|
42
|
-
self._api_key = getattr(http_client, "api_key", None)
|
|
43
|
-
else:
|
|
44
|
-
# Allow passing the top-level Firecrawl client directly
|
|
45
|
-
self._api_url = getattr(client, "api_url", None)
|
|
46
|
-
self._api_key = getattr(client, "api_key", None)
|
|
47
|
-
|
|
48
|
-
self._status: str = "scraping"
|
|
49
|
-
self._data: List[Dict] = []
|
|
50
|
-
|
|
51
|
-
def __aiter__(self) -> AsyncIterator[object]:
|
|
52
|
-
return self._iterate()
|
|
53
|
-
|
|
54
|
-
def _build_ws_url(self) -> str:
|
|
55
|
-
if not self._api_url:
|
|
56
|
-
raise ValueError("API URL is required for WebSocket watcher")
|
|
57
|
-
ws_base = self._api_url.replace("https://", "wss://").replace("http://", "ws://", 1)
|
|
58
|
-
if self._kind == "crawl":
|
|
59
|
-
return f"{ws_base}/v2/crawl/{self._job_id}"
|
|
60
|
-
return f"{ws_base}/v2/batch/scrape/{self._job_id}"
|
|
61
|
-
|
|
62
|
-
async def _iterate(self) -> AsyncIterator[object]:
|
|
63
|
-
uri = self._build_ws_url()
|
|
64
|
-
headers_list = []
|
|
65
|
-
if self._api_key:
|
|
66
|
-
headers_list.append(("Authorization", f"Bearer {self._api_key}"))
|
|
67
|
-
|
|
68
|
-
# Attempt to establish WS; on failure, fall back to HTTP polling immediately
|
|
69
|
-
try:
|
|
70
|
-
async with websockets.connect(uri, max_size=None, additional_headers=headers_list) as websocket:
|
|
71
|
-
deadline = asyncio.get_event_loop().time() + self._timeout if self._timeout else None
|
|
72
|
-
# Pre-yield a snapshot if available to ensure progress is visible
|
|
73
|
-
try:
|
|
74
|
-
pre = await self._fetch_job_status()
|
|
75
|
-
yield pre
|
|
76
|
-
if pre.status in ("completed", "failed", "cancelled"):
|
|
77
|
-
return
|
|
78
|
-
except Exception:
|
|
79
|
-
pass
|
|
80
|
-
|
|
81
|
-
while True:
|
|
82
|
-
try:
|
|
83
|
-
if deadline is not None:
|
|
84
|
-
remaining = max(0.0, deadline - asyncio.get_event_loop().time())
|
|
85
|
-
timeout = min(self._poll_interval, remaining) if remaining > 0 else 0.0
|
|
86
|
-
else:
|
|
87
|
-
timeout = self._poll_interval
|
|
88
|
-
msg = await asyncio.wait_for(websocket.recv(), timeout=timeout)
|
|
89
|
-
except asyncio.TimeoutError:
|
|
90
|
-
# Quiet period: poll HTTP once
|
|
91
|
-
job = await self._safe_fetch()
|
|
92
|
-
if job is not None:
|
|
93
|
-
yield job
|
|
94
|
-
if job.status in ("completed", "failed", "cancelled"):
|
|
95
|
-
return
|
|
96
|
-
if deadline is not None and asyncio.get_event_loop().time() >= deadline:
|
|
97
|
-
return
|
|
98
|
-
continue
|
|
99
|
-
except (ConnectionClosedOK, ConnectionClosed, ConnectionClosedError):
|
|
100
|
-
# Graceful/abrupt close: poll HTTP until terminal (bounded by timeout)
|
|
101
|
-
deadline = time.time() + (self._timeout or 30)
|
|
102
|
-
while True:
|
|
103
|
-
try:
|
|
104
|
-
job = await self._fetch_job_status()
|
|
105
|
-
yield job
|
|
106
|
-
if job.status in ("completed", "failed", "cancelled"):
|
|
107
|
-
return
|
|
108
|
-
except Exception:
|
|
109
|
-
return
|
|
110
|
-
if time.time() >= deadline:
|
|
111
|
-
return
|
|
112
|
-
await asyncio.sleep(1)
|
|
113
|
-
try:
|
|
114
|
-
body = json.loads(msg)
|
|
115
|
-
except Exception:
|
|
116
|
-
continue
|
|
117
|
-
|
|
118
|
-
msg_type = body.get("type")
|
|
119
|
-
if msg_type == "error":
|
|
120
|
-
self._status = "failed"
|
|
121
|
-
# Yield a terminal snapshot
|
|
122
|
-
if self._kind == "crawl":
|
|
123
|
-
yield CrawlJob(status="failed", completed=0, total=0, credits_used=0, expires_at=None, next=None, data=[])
|
|
124
|
-
else:
|
|
125
|
-
yield BatchScrapeJob(status="failed", completed=0, total=0, credits_used=0, expires_at=None, next=None, data=[])
|
|
126
|
-
return
|
|
127
|
-
elif msg_type == "catchup":
|
|
128
|
-
d = body.get("data", {})
|
|
129
|
-
self._status = d.get("status", self._status)
|
|
130
|
-
docs_in = d.get("data", []) or []
|
|
131
|
-
self._data.extend(docs_in)
|
|
132
|
-
# Fall through to emit a snapshot below
|
|
133
|
-
elif msg_type == "document":
|
|
134
|
-
doc = body.get("data")
|
|
135
|
-
if isinstance(doc, dict):
|
|
136
|
-
self._data.append(doc)
|
|
137
|
-
# Fall through to emit a snapshot below
|
|
138
|
-
elif msg_type == "done":
|
|
139
|
-
self._status = "completed"
|
|
140
|
-
raw_payload = body.get("data", {}) or {}
|
|
141
|
-
docs_in = raw_payload.get("data", []) or []
|
|
142
|
-
if isinstance(docs_in, list) and docs_in:
|
|
143
|
-
for doc in docs_in:
|
|
144
|
-
if isinstance(doc, dict):
|
|
145
|
-
self._data.append(doc)
|
|
146
|
-
# Emit final snapshot then end
|
|
147
|
-
yield self._make_snapshot(status="completed", payload=raw_payload, docs_override=self._data)
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
# Generic snapshot emit for status messages and periodic progress
|
|
151
|
-
payload = body.get("data", body)
|
|
152
|
-
status_str = payload.get("status", body.get("status", self._status))
|
|
153
|
-
snapshot = self._make_snapshot(status=status_str, payload=payload)
|
|
154
|
-
yield snapshot
|
|
155
|
-
if status_str in ("completed", "failed", "cancelled"):
|
|
156
|
-
return
|
|
157
|
-
except Exception:
|
|
158
|
-
# WS connect failure: fallback to HTTP polling loop until terminal/timeout
|
|
159
|
-
deadline = time.time() + (self._timeout or 30)
|
|
160
|
-
while True:
|
|
161
|
-
try:
|
|
162
|
-
job = await self._fetch_job_status()
|
|
163
|
-
yield job
|
|
164
|
-
if job.status in ("completed", "failed", "cancelled"):
|
|
165
|
-
return
|
|
166
|
-
except Exception:
|
|
167
|
-
return
|
|
168
|
-
if time.time() >= deadline:
|
|
169
|
-
return
|
|
170
|
-
await asyncio.sleep(1)
|
|
171
|
-
|
|
172
|
-
async def _fetch_job_status(self):
|
|
173
|
-
if self._kind == "crawl":
|
|
174
|
-
return await self._call_status_method("get_crawl_status")
|
|
175
|
-
return await self._call_status_method("get_batch_scrape_status")
|
|
176
|
-
|
|
177
|
-
async def _call_status_method(self, method_name: str):
|
|
178
|
-
# Try on client directly
|
|
179
|
-
meth = getattr(self._client, method_name, None)
|
|
180
|
-
if meth is not None:
|
|
181
|
-
try:
|
|
182
|
-
result = meth(self._job_id)
|
|
183
|
-
except TypeError:
|
|
184
|
-
result = None
|
|
185
|
-
if result is not None:
|
|
186
|
-
if inspect.isawaitable(result):
|
|
187
|
-
return await result
|
|
188
|
-
return result
|
|
189
|
-
# Fallback: if we couldn't call directly, try to_thread
|
|
190
|
-
return await asyncio.to_thread(meth, self._job_id)
|
|
191
|
-
|
|
192
|
-
# Try on client.v2
|
|
193
|
-
v2 = getattr(self._client, "v2", None)
|
|
194
|
-
if v2 is not None:
|
|
195
|
-
meth = getattr(v2, method_name, None)
|
|
196
|
-
if meth is not None:
|
|
197
|
-
try:
|
|
198
|
-
result = meth(self._job_id)
|
|
199
|
-
except TypeError:
|
|
200
|
-
result = None
|
|
201
|
-
if result is not None:
|
|
202
|
-
if inspect.isawaitable(result):
|
|
203
|
-
return await result
|
|
204
|
-
return result
|
|
205
|
-
return await asyncio.to_thread(meth, self._job_id)
|
|
206
|
-
|
|
207
|
-
raise RuntimeError(f"Client does not expose {method_name}")
|
|
208
|
-
|
|
209
|
-
async def _safe_fetch(self):
|
|
210
|
-
try:
|
|
211
|
-
return await self._fetch_job_status()
|
|
212
|
-
except Exception:
|
|
213
|
-
return None
|
|
214
|
-
|
|
215
|
-
def _make_snapshot(self, *, status: str, payload: Dict, docs_override: Optional[List[Dict]] = None):
|
|
216
|
-
docs = []
|
|
217
|
-
source_docs = docs_override if docs_override is not None else payload.get("data", []) or []
|
|
218
|
-
for doc in source_docs:
|
|
219
|
-
if isinstance(doc, dict):
|
|
220
|
-
d = normalize_document_input(doc)
|
|
221
|
-
docs.append(Document(**d))
|
|
222
|
-
|
|
223
|
-
if self._kind == "crawl":
|
|
224
|
-
return CrawlJob(
|
|
225
|
-
status=status,
|
|
226
|
-
completed=payload.get("completed", 0),
|
|
227
|
-
total=payload.get("total", 0),
|
|
228
|
-
credits_used=payload.get("creditsUsed", 0),
|
|
229
|
-
expires_at=payload.get("expiresAt"),
|
|
230
|
-
next=payload.get("next"),
|
|
231
|
-
data=docs,
|
|
232
|
-
)
|
|
233
|
-
return BatchScrapeJob(
|
|
234
|
-
status=status,
|
|
235
|
-
completed=payload.get("completed", 0),
|
|
236
|
-
total=payload.get("total", 0),
|
|
237
|
-
credits_used=payload.get("creditsUsed"),
|
|
238
|
-
expires_at=payload.get("expiresAt"),
|
|
239
|
-
next=payload.get("next"),
|
|
240
|
-
data=docs,
|
|
241
|
-
)
|
|
242
|
-
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from unittest.mock import patch, MagicMock
|
|
3
|
-
import json
|
|
4
|
-
import os
|
|
5
|
-
from firecrawl import FirecrawlApp
|
|
6
|
-
|
|
7
|
-
class TestChangeTracking(unittest.TestCase):
|
|
8
|
-
@patch('requests.post')
|
|
9
|
-
def test_change_tracking_format(self, mock_post):
|
|
10
|
-
mock_response = MagicMock()
|
|
11
|
-
mock_response.status_code = 200
|
|
12
|
-
mock_response.json.return_value = {
|
|
13
|
-
'success': True,
|
|
14
|
-
'data': {
|
|
15
|
-
'markdown': 'Test markdown content',
|
|
16
|
-
'changeTracking': {
|
|
17
|
-
'previousScrapeAt': '2023-01-01T00:00:00Z',
|
|
18
|
-
'changeStatus': 'changed',
|
|
19
|
-
'visibility': 'visible'
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
mock_post.return_value = mock_response
|
|
24
|
-
|
|
25
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
26
|
-
result = app.scrape_url('https://example.com', {
|
|
27
|
-
'formats': ['markdown', 'changeTracking']
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
args, kwargs = mock_post.call_args
|
|
31
|
-
self.assertEqual(kwargs['json']['formats'], ['markdown', 'changeTracking'])
|
|
32
|
-
|
|
33
|
-
self.assertEqual(result['changeTracking']['previousScrapeAt'], '2023-01-01T00:00:00Z')
|
|
34
|
-
self.assertEqual(result['changeTracking']['changeStatus'], 'changed')
|
|
35
|
-
self.assertEqual(result['changeTracking']['visibility'], 'visible')
|
|
36
|
-
|
|
37
|
-
@patch('requests.post')
|
|
38
|
-
def test_change_tracking_options(self, mock_post):
|
|
39
|
-
mock_response = MagicMock()
|
|
40
|
-
mock_response.status_code = 200
|
|
41
|
-
mock_response.json.return_value = {
|
|
42
|
-
'success': True,
|
|
43
|
-
'data': {
|
|
44
|
-
'markdown': 'Test markdown content',
|
|
45
|
-
'changeTracking': {
|
|
46
|
-
'previousScrapeAt': '2023-01-01T00:00:00Z',
|
|
47
|
-
'changeStatus': 'changed',
|
|
48
|
-
'visibility': 'visible',
|
|
49
|
-
'diff': {
|
|
50
|
-
'text': '@@ -1,1 +1,1 @@\n-old content\n+new content',
|
|
51
|
-
'json': {
|
|
52
|
-
'files': [{
|
|
53
|
-
'from': None,
|
|
54
|
-
'to': None,
|
|
55
|
-
'chunks': [{
|
|
56
|
-
'content': '@@ -1,1 +1,1 @@',
|
|
57
|
-
'changes': [{
|
|
58
|
-
'type': 'del',
|
|
59
|
-
'content': '-old content',
|
|
60
|
-
'del': True,
|
|
61
|
-
'ln': 1
|
|
62
|
-
}, {
|
|
63
|
-
'type': 'add',
|
|
64
|
-
'content': '+new content',
|
|
65
|
-
'add': True,
|
|
66
|
-
'ln': 1
|
|
67
|
-
}]
|
|
68
|
-
}]
|
|
69
|
-
}]
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
'json': {
|
|
73
|
-
'title': {
|
|
74
|
-
'previous': 'Old Title',
|
|
75
|
-
'current': 'New Title'
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
mock_post.return_value = mock_response
|
|
82
|
-
|
|
83
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
84
|
-
result = app.scrape_url('https://example.com', {
|
|
85
|
-
'formats': ['markdown', 'changeTracking'],
|
|
86
|
-
'changeTrackingOptions': {
|
|
87
|
-
'modes': ['git-diff', 'json'],
|
|
88
|
-
'schema': {'type': 'object', 'properties': {'title': {'type': 'string'}}}
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
args, kwargs = mock_post.call_args
|
|
93
|
-
self.assertEqual(kwargs['json']['formats'], ['markdown', 'changeTracking'])
|
|
94
|
-
self.assertEqual(kwargs['json']['changeTrackingOptions']['modes'], ['git-diff', 'json'])
|
|
95
|
-
|
|
96
|
-
self.assertEqual(result['changeTracking']['diff']['text'], '@@ -1,1 +1,1 @@\n-old content\n+new content')
|
|
97
|
-
self.assertEqual(result['changeTracking']['json']['title']['previous'], 'Old Title')
|
|
98
|
-
self.assertEqual(result['changeTracking']['json']['title']['current'], 'New Title')
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from unittest.mock import patch, MagicMock
|
|
3
|
-
import os
|
|
4
|
-
from firecrawl import FirecrawlApp
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class TestTimeoutConversion(unittest.TestCase):
|
|
8
|
-
|
|
9
|
-
@patch('requests.post')
|
|
10
|
-
def test_scrape_url_timeout_conversion(self, mock_post):
|
|
11
|
-
mock_response = MagicMock()
|
|
12
|
-
mock_response.status_code = 200
|
|
13
|
-
mock_response.json.return_value = {
|
|
14
|
-
'success': True,
|
|
15
|
-
'data': {
|
|
16
|
-
'markdown': 'Test content'
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
mock_post.return_value = mock_response
|
|
20
|
-
|
|
21
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
22
|
-
app.scrape_url('https://example.com', timeout=60000)
|
|
23
|
-
|
|
24
|
-
args, kwargs = mock_post.call_args
|
|
25
|
-
self.assertEqual(kwargs['timeout'], 65.0)
|
|
26
|
-
|
|
27
|
-
@patch('requests.post')
|
|
28
|
-
def test_scrape_url_default_timeout(self, mock_post):
|
|
29
|
-
mock_response = MagicMock()
|
|
30
|
-
mock_response.status_code = 200
|
|
31
|
-
mock_response.json.return_value = {
|
|
32
|
-
'success': True,
|
|
33
|
-
'data': {
|
|
34
|
-
'markdown': 'Test content'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
mock_post.return_value = mock_response
|
|
38
|
-
|
|
39
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
40
|
-
app.scrape_url('https://example.com')
|
|
41
|
-
|
|
42
|
-
args, kwargs = mock_post.call_args
|
|
43
|
-
self.assertEqual(kwargs['timeout'], 35.0)
|
|
44
|
-
|
|
45
|
-
@patch('requests.post')
|
|
46
|
-
def test_post_request_timeout_conversion(self, mock_post):
|
|
47
|
-
mock_response = MagicMock()
|
|
48
|
-
mock_response.status_code = 200
|
|
49
|
-
mock_post.return_value = mock_response
|
|
50
|
-
|
|
51
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
52
|
-
|
|
53
|
-
data = {'timeout': 30000}
|
|
54
|
-
headers = {'Content-Type': 'application/json'}
|
|
55
|
-
|
|
56
|
-
app._post_request('https://example.com/api', data, headers)
|
|
57
|
-
|
|
58
|
-
args, kwargs = mock_post.call_args
|
|
59
|
-
self.assertEqual(kwargs['timeout'], 35.0)
|
|
60
|
-
|
|
61
|
-
@patch('requests.post')
|
|
62
|
-
def test_post_request_default_timeout(self, mock_post):
|
|
63
|
-
mock_response = MagicMock()
|
|
64
|
-
mock_response.status_code = 200
|
|
65
|
-
mock_post.return_value = mock_response
|
|
66
|
-
|
|
67
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
68
|
-
|
|
69
|
-
data = {'timeout': 30000, 'url': 'https://example.com'}
|
|
70
|
-
headers = {'Content-Type': 'application/json'}
|
|
71
|
-
|
|
72
|
-
app._post_request('https://example.com/api', data, headers)
|
|
73
|
-
|
|
74
|
-
args, kwargs = mock_post.call_args
|
|
75
|
-
self.assertEqual(kwargs['timeout'], 35.0)
|
|
76
|
-
|
|
77
|
-
@patch('requests.post')
|
|
78
|
-
def test_timeout_edge_cases(self, mock_post):
|
|
79
|
-
mock_response = MagicMock()
|
|
80
|
-
mock_response.status_code = 200
|
|
81
|
-
mock_response.json.return_value = {
|
|
82
|
-
'success': True,
|
|
83
|
-
'data': {
|
|
84
|
-
'markdown': 'Test content'
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
mock_post.return_value = mock_response
|
|
88
|
-
|
|
89
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
90
|
-
|
|
91
|
-
app.scrape_url('https://example.com', timeout=1000)
|
|
92
|
-
args, kwargs = mock_post.call_args
|
|
93
|
-
self.assertEqual(kwargs['timeout'], 6.0)
|
|
94
|
-
|
|
95
|
-
app.scrape_url('https://example.com', timeout=0)
|
|
96
|
-
args, kwargs = mock_post.call_args
|
|
97
|
-
self.assertEqual(kwargs['timeout'], 5.0)
|
|
98
|
-
|
|
99
|
-
@patch('requests.post')
|
|
100
|
-
def test_post_request_no_timeout_key(self, mock_post):
|
|
101
|
-
mock_response = MagicMock()
|
|
102
|
-
mock_response.status_code = 200
|
|
103
|
-
mock_post.return_value = mock_response
|
|
104
|
-
|
|
105
|
-
app = FirecrawlApp(api_key=os.environ.get('TEST_API_KEY', 'dummy-api-key-for-testing'))
|
|
106
|
-
|
|
107
|
-
data = {'url': 'https://example.com'}
|
|
108
|
-
headers = {'Content-Type': 'application/json'}
|
|
109
|
-
|
|
110
|
-
app._post_request('https://example.com/api', data, headers)
|
|
111
|
-
|
|
112
|
-
args, kwargs = mock_post.call_args
|
|
113
|
-
self.assertIsNone(kwargs['timeout'])
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if __name__ == '__main__':
|
|
117
|
-
unittest.main()
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
build/lib/firecrawl/__init__.py,sha256=q6Qr0IrjAPt6TZgTs8CfgMyp0luoj3Sz8mA9220BPOw,2192
|
|
2
|
-
build/lib/firecrawl/client.py,sha256=2BGIRTiW2eR6q3wu_g2s3VTQtrHYauoDeNF1YklQpHo,11089
|
|
3
|
-
build/lib/firecrawl/firecrawl.backup.py,sha256=v1FEN3jR4g5Aupg4xp6SLkuFvYMQuUKND2YELbYjE6c,200430
|
|
4
|
-
build/lib/firecrawl/types.py,sha256=W9N2pqQuevEIIjYHN9rbDf31E-nwdCECqIn11Foz2T8,2836
|
|
5
|
-
build/lib/firecrawl/__tests__/e2e/v2/conftest.py,sha256=I28TUpN5j0-9gM79NlbrDS8Jlsheao657od2f-2xK0Y,2587
|
|
6
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_async.py,sha256=ZXpf1FVOJgNclITglrxIyFwP4cOiqzWLicGaxIm70BQ,2526
|
|
7
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_batch_scrape.py,sha256=H9GtuwHIFdOQ958SOVThi_kvDDxcXAK_ECRh95ogonQ,3265
|
|
8
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_crawl.py,sha256=cOssZvIwtghAtLiM1QdNLhPEwAxZ9j9umTrBUPtJjpU,9951
|
|
9
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_extract.py,sha256=HgvGiDlyWtFygiPo5EP44Dem1oWrwgRF-hfc1LfeVSU,1670
|
|
10
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_map.py,sha256=9sT-Yq8V_8c9esl_bv5hnTA9WXb2Dg81kj6M-s0484c,1618
|
|
11
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_scrape.py,sha256=psW2nfcA_hMFpZ4msL_VJWJTMa3Sidp11ubhftbm52g,5759
|
|
12
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_search.py,sha256=tvU9_eg_3H5em0fhIwPPjuYe9BRAQ5St-BLM0l_FfVs,9079
|
|
13
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_usage.py,sha256=JlBkYblhThua5qF2crRjsPpq4Ja0cBsdzxZ5zxXnQ_Y,805
|
|
14
|
-
build/lib/firecrawl/__tests__/e2e/v2/test_watcher.py,sha256=OPTKLhVAKWqXl2Tieo6zCN1xpEwZDsz-B977CVJgLMA,1932
|
|
15
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_batch_scrape.py,sha256=gJv_mLzzoAYftETB2TLkrpSfB5c04kaYgkD4hQTYsIg,2639
|
|
16
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_crawl.py,sha256=X-nk5tkYUYIkM6kTYl7GDjvxh2JT9GxJqk2KlO8xpWw,7282
|
|
17
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_extract.py,sha256=3CNRIFzgBMcOYOLhnKcK1k5a3Gy--u08EGDkL31uieM,1199
|
|
18
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_map.py,sha256=nckl1kbiEaaTdu5lm__tOoTDG-txTYwwSH3KZEvyKzc,1199
|
|
19
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_scrape.py,sha256=b17A7advBEjxrjdait2w8GHztZeKy_P3zZ3ixm5H7xw,4453
|
|
20
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_search.py,sha256=ehV0Ai_hknAkaoE551j2lbktV4bi_J0h3FKzC7G15Iw,8246
|
|
21
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_usage.py,sha256=Dh9BVo48NKSZOKgLbO7n8fpMjvYmeMXDFzbIhnCTMhE,1014
|
|
22
|
-
build/lib/firecrawl/__tests__/e2e/v2/aio/test_aio_watcher.py,sha256=hwES4Nu5c0hniZ9heIPDfvh_2JmJ2wPoX9ULTZ0Asjs,1471
|
|
23
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_batch_request_preparation.py,sha256=HeOxN-sPYSssytcIRAEicJSZsFt_Oa5qGXAtdumR54c,4040
|
|
24
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_params.py,sha256=p9hzg14uAs1iHKXPDSXhGU6hEzPBF_Ae34RAf5XYa10,2387
|
|
25
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_request_preparation.py,sha256=PEKbooNXfQwPpvcPHXABJnveztgAA-RFBhtlSs8uPro,8780
|
|
26
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_crawl_validation.py,sha256=kErOmHSD01eMjXiMd4rgsMVGd_aU2G9uVymBjbAFoGw,3918
|
|
27
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_map_request_preparation.py,sha256=toVcgnMp_cFeYsIUuyKGEWZGp0nAAkzaeFGUbY0zY0o,1868
|
|
28
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_scrape_request_preparation.py,sha256=wDOslsA5BN4kyezlaT5GeMv_Ifn8f461EaA7i5ujnaQ,3482
|
|
29
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_search_request_preparation.py,sha256=14lUgFpQsiosgMKjDustBRVE0zXnHujBI76F8BC5PZ4,6072
|
|
30
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_search_validation.py,sha256=7UGcNHpQzCpZbAPYjthfdPFWmAPcoApY-ED-khtuANs,9498
|
|
31
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_usage_types.py,sha256=cCHHfa6agSjD0brQ9rcAcw2kaI9riUH5C0dXV-fqktg,591
|
|
32
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/test_webhook.py,sha256=AvvW-bKpUA--Lvtif2bmUIp-AxiaMJ29ie1i9dk8WbI,4586
|
|
33
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_params.py,sha256=9azJxVvDOBqUevLp-wBF9gF7Ptj-7nN6LOkPQncFX2M,456
|
|
34
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_request_preparation.py,sha256=RkIKt7uxBzVhAkrLQwXYjmC-9sj32SUNQrJZgF2WEMs,2565
|
|
35
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_validation.py,sha256=WMgltdrrT2HOflqGyahC4v-Wb29_8sypN0hwS9lYXe8,403
|
|
36
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_map_request_preparation.py,sha256=PdUJrR0JLWqrithAnRXwuRrnsIN2h_DTu6-xvTOn_UU,725
|
|
37
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_scrape_request_preparation.py,sha256=A5DT4wpH4vrIPvFxKVHrtDH5A3bgJ_ad4fmVQ8LN1t0,1993
|
|
38
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_aio_search_request_preparation.py,sha256=hFk4XgqF3aFPGFJe0ikB1uwf_0FsppNGA088OrWUXvg,2091
|
|
39
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_batch_request_preparation_async.py,sha256=E26UnUhpbjG-EG0ab4WRD94AxA5IBWmIHq8ZLBOWoAA,1202
|
|
40
|
-
build/lib/firecrawl/__tests__/unit/v2/methods/aio/test_ensure_async.py,sha256=pUwuWhRbVUTbgsZn4hgZesMkTMesTv_NPmvFW--ls-Y,3815
|
|
41
|
-
build/lib/firecrawl/__tests__/unit/v2/utils/test_validation.py,sha256=E4n4jpBhH_W7E0ikI5r8KMAKiOhbfGD3i_B8-dv3PlI,10803
|
|
42
|
-
build/lib/firecrawl/__tests__/unit/v2/watcher/test_ws_watcher.py,sha256=87w47n0iOihtu4jTR4-4rw1-xVKWmLg2BOBGxjQPnUk,9517
|
|
43
|
-
build/lib/firecrawl/v1/__init__.py,sha256=aP1oisPeZVGGZynvENc07JySMOZfv_4zAlxQ0ecMJXA,481
|
|
44
|
-
build/lib/firecrawl/v1/client.py,sha256=sydurfEFTsXyowyaGryA1lkPxN_r9Nf6iQpM43OwJyM,201672
|
|
45
|
-
build/lib/firecrawl/v2/__init__.py,sha256=Jc6a8tBjYG5OPkjDM5pl-notyys-7DEj7PLEfepv3fc,137
|
|
46
|
-
build/lib/firecrawl/v2/client.py,sha256=_DZFZO1aWvODzznK0g2Svcd2-xxXgWGR0d9vniNlk1w,30621
|
|
47
|
-
build/lib/firecrawl/v2/client_async.py,sha256=zwxHis1bSh0tSF1480ze-4XDQEDJ5yDur1ZqtL94dwc,10127
|
|
48
|
-
build/lib/firecrawl/v2/types.py,sha256=rBdTaTQmb1SmdR8O0GvA_gCfBG-QCtBOrMsFgA9Usms,22114
|
|
49
|
-
build/lib/firecrawl/v2/watcher.py,sha256=FOU71tqSKxgeuGycu4ye0SLc2dw7clIcoQjPsi-4Csc,14229
|
|
50
|
-
build/lib/firecrawl/v2/watcher_async.py,sha256=AVjW2mgABniolSsauK4u0FW8ya6WzRUdyEg2R-8vGCw,10278
|
|
51
|
-
build/lib/firecrawl/v2/methods/batch.py,sha256=us7zUGl7u9ZDIEk2J3rNqj87bkaNjXU27SMFW_fdcg8,11932
|
|
52
|
-
build/lib/firecrawl/v2/methods/crawl.py,sha256=4ZUmanHNuNtq9wbKMAZ3lenuPcNdOaV0kYXqMI5XJJ8,15485
|
|
53
|
-
build/lib/firecrawl/v2/methods/extract.py,sha256=-Jr4BtraU3b7hd3JIY73V-S69rUclxyXyUpoQb6DCQk,4274
|
|
54
|
-
build/lib/firecrawl/v2/methods/map.py,sha256=4SADb0-lkbdOWDmO6k8_TzK0yRti5xsN40N45nUl9uA,2592
|
|
55
|
-
build/lib/firecrawl/v2/methods/scrape.py,sha256=CSHBwC-P91UfrW3zHirjNAs2h899FKcWvd1DY_4fJdo,1921
|
|
56
|
-
build/lib/firecrawl/v2/methods/search.py,sha256=6BKiQ1aKJjWBKm9BBtKxFKGD74kCKBeMIp_OgjcDFAw,7673
|
|
57
|
-
build/lib/firecrawl/v2/methods/usage.py,sha256=OJlkxwaB-AAtgO3WLr9QiqBRmjdh6GVhroCgleegupQ,1460
|
|
58
|
-
build/lib/firecrawl/v2/methods/aio/__init__.py,sha256=RocMJnGwnLIvGu3G8ZvY8INkipC7WHZiu2bE31eSyJs,35
|
|
59
|
-
build/lib/firecrawl/v2/methods/aio/batch.py,sha256=GS_xsd_Uib1fxFITBK1sH88VGzFMrIcqJVQqOvMQ540,3735
|
|
60
|
-
build/lib/firecrawl/v2/methods/aio/crawl.py,sha256=pC6bHVk30Hj1EJdAChxpMOg0Xx_GVqq4tIlvU2e5RQ4,6688
|
|
61
|
-
build/lib/firecrawl/v2/methods/aio/extract.py,sha256=IfNr2ETqt4dR73JFzrEYI4kk5vpKnJOG0BmPEjGEoO4,4217
|
|
62
|
-
build/lib/firecrawl/v2/methods/aio/map.py,sha256=EuT-5A0cQr_e5SBfEZ6pnl8u0JUwEEvSwhyT2N-QoKU,2326
|
|
63
|
-
build/lib/firecrawl/v2/methods/aio/scrape.py,sha256=ilA9qco8YGwCFpE0PN1XBQUyuHPQwH2QioZ-xsfxhgU,1386
|
|
64
|
-
build/lib/firecrawl/v2/methods/aio/search.py,sha256=_TqTFGQLlOCCLNdWcOvakTqPGD2r9AOlBg8RasOgmvw,6177
|
|
65
|
-
build/lib/firecrawl/v2/methods/aio/usage.py,sha256=OtBi6X-aT09MMR2dpm3vBCm9JrJZIJLCQ8jJ3L7vie4,1606
|
|
66
|
-
build/lib/firecrawl/v2/utils/__init__.py,sha256=i1GgxySmqEXpWSBQCu3iZBPIJG7fXj0QXCDWGwerWNs,338
|
|
67
|
-
build/lib/firecrawl/v2/utils/error_handler.py,sha256=Iuf916dHphDY8ObNNlWy75628DFeJ0Rv8ljRp4LttLE,4199
|
|
68
|
-
build/lib/firecrawl/v2/utils/get_version.py,sha256=0CxW_41q2hlzIxEWOivUCaYw3GFiSIH32RPUMcIgwAY,492
|
|
69
|
-
build/lib/firecrawl/v2/utils/http_client.py,sha256=_n8mp4xi6GGihg662Lsv6TSlvw9zykyADwEk0fg8mYA,4873
|
|
70
|
-
build/lib/firecrawl/v2/utils/http_client_async.py,sha256=iy89_bk2HS3afSRHZ8016eMCa9Fk-5MFTntcOHfbPgE,1936
|
|
71
|
-
build/lib/firecrawl/v2/utils/normalize.py,sha256=nlTU6QRghT1YKZzNZlIQj4STSRuSUGrS9cCErZIcY5w,3636
|
|
72
|
-
build/lib/firecrawl/v2/utils/validation.py,sha256=L8by7z-t6GuMGIYkK7il1BM8d-4_-sAdG9hDMF_LeG4,14518
|
|
73
|
-
build/lib/tests/test_change_tracking.py,sha256=_IJ5ShLcoj2fHDBaw-nE4I4lHdmDB617ocK_XMHhXps,4177
|
|
74
|
-
build/lib/tests/test_timeout_conversion.py,sha256=PWlIEMASQNhu4cp1OW_ebklnE9NCiigPnEFCtI5N3w0,3996
|
|
75
|
-
firecrawl/__init__.py,sha256=q6Qr0IrjAPt6TZgTs8CfgMyp0luoj3Sz8mA9220BPOw,2192
|
|
76
|
-
firecrawl/client.py,sha256=2BGIRTiW2eR6q3wu_g2s3VTQtrHYauoDeNF1YklQpHo,11089
|
|
77
|
-
firecrawl/firecrawl.backup.py,sha256=v1FEN3jR4g5Aupg4xp6SLkuFvYMQuUKND2YELbYjE6c,200430
|
|
78
|
-
firecrawl/types.py,sha256=W9N2pqQuevEIIjYHN9rbDf31E-nwdCECqIn11Foz2T8,2836
|
|
79
|
-
firecrawl/__tests__/e2e/v2/conftest.py,sha256=I28TUpN5j0-9gM79NlbrDS8Jlsheao657od2f-2xK0Y,2587
|
|
80
|
-
firecrawl/__tests__/e2e/v2/test_async.py,sha256=ZXpf1FVOJgNclITglrxIyFwP4cOiqzWLicGaxIm70BQ,2526
|
|
81
|
-
firecrawl/__tests__/e2e/v2/test_batch_scrape.py,sha256=H9GtuwHIFdOQ958SOVThi_kvDDxcXAK_ECRh95ogonQ,3265
|
|
82
|
-
firecrawl/__tests__/e2e/v2/test_crawl.py,sha256=cOssZvIwtghAtLiM1QdNLhPEwAxZ9j9umTrBUPtJjpU,9951
|
|
83
|
-
firecrawl/__tests__/e2e/v2/test_extract.py,sha256=HgvGiDlyWtFygiPo5EP44Dem1oWrwgRF-hfc1LfeVSU,1670
|
|
84
|
-
firecrawl/__tests__/e2e/v2/test_map.py,sha256=9sT-Yq8V_8c9esl_bv5hnTA9WXb2Dg81kj6M-s0484c,1618
|
|
85
|
-
firecrawl/__tests__/e2e/v2/test_scrape.py,sha256=psW2nfcA_hMFpZ4msL_VJWJTMa3Sidp11ubhftbm52g,5759
|
|
86
|
-
firecrawl/__tests__/e2e/v2/test_search.py,sha256=tvU9_eg_3H5em0fhIwPPjuYe9BRAQ5St-BLM0l_FfVs,9079
|
|
87
|
-
firecrawl/__tests__/e2e/v2/test_usage.py,sha256=JlBkYblhThua5qF2crRjsPpq4Ja0cBsdzxZ5zxXnQ_Y,805
|
|
88
|
-
firecrawl/__tests__/e2e/v2/test_watcher.py,sha256=OPTKLhVAKWqXl2Tieo6zCN1xpEwZDsz-B977CVJgLMA,1932
|
|
89
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_batch_scrape.py,sha256=gJv_mLzzoAYftETB2TLkrpSfB5c04kaYgkD4hQTYsIg,2639
|
|
90
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_crawl.py,sha256=X-nk5tkYUYIkM6kTYl7GDjvxh2JT9GxJqk2KlO8xpWw,7282
|
|
91
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_extract.py,sha256=3CNRIFzgBMcOYOLhnKcK1k5a3Gy--u08EGDkL31uieM,1199
|
|
92
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_map.py,sha256=nckl1kbiEaaTdu5lm__tOoTDG-txTYwwSH3KZEvyKzc,1199
|
|
93
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_scrape.py,sha256=b17A7advBEjxrjdait2w8GHztZeKy_P3zZ3ixm5H7xw,4453
|
|
94
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_search.py,sha256=ehV0Ai_hknAkaoE551j2lbktV4bi_J0h3FKzC7G15Iw,8246
|
|
95
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_usage.py,sha256=Dh9BVo48NKSZOKgLbO7n8fpMjvYmeMXDFzbIhnCTMhE,1014
|
|
96
|
-
firecrawl/__tests__/e2e/v2/aio/test_aio_watcher.py,sha256=hwES4Nu5c0hniZ9heIPDfvh_2JmJ2wPoX9ULTZ0Asjs,1471
|
|
97
|
-
firecrawl/__tests__/unit/v2/methods/test_batch_request_preparation.py,sha256=HeOxN-sPYSssytcIRAEicJSZsFt_Oa5qGXAtdumR54c,4040
|
|
98
|
-
firecrawl/__tests__/unit/v2/methods/test_crawl_params.py,sha256=p9hzg14uAs1iHKXPDSXhGU6hEzPBF_Ae34RAf5XYa10,2387
|
|
99
|
-
firecrawl/__tests__/unit/v2/methods/test_crawl_request_preparation.py,sha256=PEKbooNXfQwPpvcPHXABJnveztgAA-RFBhtlSs8uPro,8780
|
|
100
|
-
firecrawl/__tests__/unit/v2/methods/test_crawl_validation.py,sha256=kErOmHSD01eMjXiMd4rgsMVGd_aU2G9uVymBjbAFoGw,3918
|
|
101
|
-
firecrawl/__tests__/unit/v2/methods/test_map_request_preparation.py,sha256=toVcgnMp_cFeYsIUuyKGEWZGp0nAAkzaeFGUbY0zY0o,1868
|
|
102
|
-
firecrawl/__tests__/unit/v2/methods/test_scrape_request_preparation.py,sha256=wDOslsA5BN4kyezlaT5GeMv_Ifn8f461EaA7i5ujnaQ,3482
|
|
103
|
-
firecrawl/__tests__/unit/v2/methods/test_search_request_preparation.py,sha256=14lUgFpQsiosgMKjDustBRVE0zXnHujBI76F8BC5PZ4,6072
|
|
104
|
-
firecrawl/__tests__/unit/v2/methods/test_search_validation.py,sha256=7UGcNHpQzCpZbAPYjthfdPFWmAPcoApY-ED-khtuANs,9498
|
|
105
|
-
firecrawl/__tests__/unit/v2/methods/test_usage_types.py,sha256=cCHHfa6agSjD0brQ9rcAcw2kaI9riUH5C0dXV-fqktg,591
|
|
106
|
-
firecrawl/__tests__/unit/v2/methods/test_webhook.py,sha256=AvvW-bKpUA--Lvtif2bmUIp-AxiaMJ29ie1i9dk8WbI,4586
|
|
107
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_params.py,sha256=9azJxVvDOBqUevLp-wBF9gF7Ptj-7nN6LOkPQncFX2M,456
|
|
108
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_request_preparation.py,sha256=RkIKt7uxBzVhAkrLQwXYjmC-9sj32SUNQrJZgF2WEMs,2565
|
|
109
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_crawl_validation.py,sha256=WMgltdrrT2HOflqGyahC4v-Wb29_8sypN0hwS9lYXe8,403
|
|
110
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_map_request_preparation.py,sha256=PdUJrR0JLWqrithAnRXwuRrnsIN2h_DTu6-xvTOn_UU,725
|
|
111
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_scrape_request_preparation.py,sha256=A5DT4wpH4vrIPvFxKVHrtDH5A3bgJ_ad4fmVQ8LN1t0,1993
|
|
112
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_aio_search_request_preparation.py,sha256=hFk4XgqF3aFPGFJe0ikB1uwf_0FsppNGA088OrWUXvg,2091
|
|
113
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_batch_request_preparation_async.py,sha256=E26UnUhpbjG-EG0ab4WRD94AxA5IBWmIHq8ZLBOWoAA,1202
|
|
114
|
-
firecrawl/__tests__/unit/v2/methods/aio/test_ensure_async.py,sha256=pUwuWhRbVUTbgsZn4hgZesMkTMesTv_NPmvFW--ls-Y,3815
|
|
115
|
-
firecrawl/__tests__/unit/v2/utils/test_validation.py,sha256=E4n4jpBhH_W7E0ikI5r8KMAKiOhbfGD3i_B8-dv3PlI,10803
|
|
116
|
-
firecrawl/__tests__/unit/v2/watcher/test_ws_watcher.py,sha256=87w47n0iOihtu4jTR4-4rw1-xVKWmLg2BOBGxjQPnUk,9517
|
|
117
|
-
firecrawl/v1/__init__.py,sha256=aP1oisPeZVGGZynvENc07JySMOZfv_4zAlxQ0ecMJXA,481
|
|
118
|
-
firecrawl/v1/client.py,sha256=sydurfEFTsXyowyaGryA1lkPxN_r9Nf6iQpM43OwJyM,201672
|
|
119
|
-
firecrawl/v2/__init__.py,sha256=Jc6a8tBjYG5OPkjDM5pl-notyys-7DEj7PLEfepv3fc,137
|
|
120
|
-
firecrawl/v2/client.py,sha256=_DZFZO1aWvODzznK0g2Svcd2-xxXgWGR0d9vniNlk1w,30621
|
|
121
|
-
firecrawl/v2/client_async.py,sha256=zwxHis1bSh0tSF1480ze-4XDQEDJ5yDur1ZqtL94dwc,10127
|
|
122
|
-
firecrawl/v2/types.py,sha256=rBdTaTQmb1SmdR8O0GvA_gCfBG-QCtBOrMsFgA9Usms,22114
|
|
123
|
-
firecrawl/v2/watcher.py,sha256=FOU71tqSKxgeuGycu4ye0SLc2dw7clIcoQjPsi-4Csc,14229
|
|
124
|
-
firecrawl/v2/watcher_async.py,sha256=AVjW2mgABniolSsauK4u0FW8ya6WzRUdyEg2R-8vGCw,10278
|
|
125
|
-
firecrawl/v2/methods/batch.py,sha256=us7zUGl7u9ZDIEk2J3rNqj87bkaNjXU27SMFW_fdcg8,11932
|
|
126
|
-
firecrawl/v2/methods/crawl.py,sha256=4ZUmanHNuNtq9wbKMAZ3lenuPcNdOaV0kYXqMI5XJJ8,15485
|
|
127
|
-
firecrawl/v2/methods/extract.py,sha256=-Jr4BtraU3b7hd3JIY73V-S69rUclxyXyUpoQb6DCQk,4274
|
|
128
|
-
firecrawl/v2/methods/map.py,sha256=4SADb0-lkbdOWDmO6k8_TzK0yRti5xsN40N45nUl9uA,2592
|
|
129
|
-
firecrawl/v2/methods/scrape.py,sha256=CSHBwC-P91UfrW3zHirjNAs2h899FKcWvd1DY_4fJdo,1921
|
|
130
|
-
firecrawl/v2/methods/search.py,sha256=6BKiQ1aKJjWBKm9BBtKxFKGD74kCKBeMIp_OgjcDFAw,7673
|
|
131
|
-
firecrawl/v2/methods/usage.py,sha256=OJlkxwaB-AAtgO3WLr9QiqBRmjdh6GVhroCgleegupQ,1460
|
|
132
|
-
firecrawl/v2/methods/aio/__init__.py,sha256=RocMJnGwnLIvGu3G8ZvY8INkipC7WHZiu2bE31eSyJs,35
|
|
133
|
-
firecrawl/v2/methods/aio/batch.py,sha256=GS_xsd_Uib1fxFITBK1sH88VGzFMrIcqJVQqOvMQ540,3735
|
|
134
|
-
firecrawl/v2/methods/aio/crawl.py,sha256=pC6bHVk30Hj1EJdAChxpMOg0Xx_GVqq4tIlvU2e5RQ4,6688
|
|
135
|
-
firecrawl/v2/methods/aio/extract.py,sha256=IfNr2ETqt4dR73JFzrEYI4kk5vpKnJOG0BmPEjGEoO4,4217
|
|
136
|
-
firecrawl/v2/methods/aio/map.py,sha256=EuT-5A0cQr_e5SBfEZ6pnl8u0JUwEEvSwhyT2N-QoKU,2326
|
|
137
|
-
firecrawl/v2/methods/aio/scrape.py,sha256=ilA9qco8YGwCFpE0PN1XBQUyuHPQwH2QioZ-xsfxhgU,1386
|
|
138
|
-
firecrawl/v2/methods/aio/search.py,sha256=_TqTFGQLlOCCLNdWcOvakTqPGD2r9AOlBg8RasOgmvw,6177
|
|
139
|
-
firecrawl/v2/methods/aio/usage.py,sha256=OtBi6X-aT09MMR2dpm3vBCm9JrJZIJLCQ8jJ3L7vie4,1606
|
|
140
|
-
firecrawl/v2/utils/__init__.py,sha256=i1GgxySmqEXpWSBQCu3iZBPIJG7fXj0QXCDWGwerWNs,338
|
|
141
|
-
firecrawl/v2/utils/error_handler.py,sha256=Iuf916dHphDY8ObNNlWy75628DFeJ0Rv8ljRp4LttLE,4199
|
|
142
|
-
firecrawl/v2/utils/get_version.py,sha256=0CxW_41q2hlzIxEWOivUCaYw3GFiSIH32RPUMcIgwAY,492
|
|
143
|
-
firecrawl/v2/utils/http_client.py,sha256=_n8mp4xi6GGihg662Lsv6TSlvw9zykyADwEk0fg8mYA,4873
|
|
144
|
-
firecrawl/v2/utils/http_client_async.py,sha256=iy89_bk2HS3afSRHZ8016eMCa9Fk-5MFTntcOHfbPgE,1936
|
|
145
|
-
firecrawl/v2/utils/normalize.py,sha256=nlTU6QRghT1YKZzNZlIQj4STSRuSUGrS9cCErZIcY5w,3636
|
|
146
|
-
firecrawl/v2/utils/validation.py,sha256=L8by7z-t6GuMGIYkK7il1BM8d-4_-sAdG9hDMF_LeG4,14518
|
|
147
|
-
tests/test_change_tracking.py,sha256=_IJ5ShLcoj2fHDBaw-nE4I4lHdmDB617ocK_XMHhXps,4177
|
|
148
|
-
tests/test_timeout_conversion.py,sha256=PWlIEMASQNhu4cp1OW_ebklnE9NCiigPnEFCtI5N3w0,3996
|
|
149
|
-
firecrawl_py-3.3.1.dist-info/LICENSE,sha256=nPCunEDwjRGHlmjvsiDUyIWbkqqyj3Ej84ntnh0g0zA,1084
|
|
150
|
-
firecrawl_py-3.3.1.dist-info/METADATA,sha256=SPUwqXjAcBRw9lV09sA-4JNWVa7EvU3_M7FjyvlvGTc,7316
|
|
151
|
-
firecrawl_py-3.3.1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
|
152
|
-
firecrawl_py-3.3.1.dist-info/top_level.txt,sha256=ytN_R30g2U2qZYFyIm710Z8QeK9FO1Uwa-WPGHXyqjE,27
|
|
153
|
-
firecrawl_py-3.3.1.dist-info/RECORD,,
|