scrapelyserp 0.1.0__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.
- scrapelyserp-0.1.0/.gitignore +61 -0
- scrapelyserp-0.1.0/LICENSE +21 -0
- scrapelyserp-0.1.0/PKG-INFO +151 -0
- scrapelyserp-0.1.0/README.md +135 -0
- scrapelyserp-0.1.0/pyproject.toml +26 -0
- scrapelyserp-0.1.0/src/scrapelyserp/__init__.py +50 -0
- scrapelyserp-0.1.0/src/scrapelyserp/_base.py +272 -0
- scrapelyserp-0.1.0/src/scrapelyserp/_errors.py +92 -0
- scrapelyserp-0.1.0/src/scrapelyserp/_resources.py +8412 -0
- scrapelyserp-0.1.0/src/scrapelyserp/_routes.py +303 -0
- scrapelyserp-0.1.0/src/scrapelyserp/_version.py +1 -0
- scrapelyserp-0.1.0/src/scrapelyserp/py.typed +0 -0
- scrapelyserp-0.1.0/src/scrapelyserp/types.py +3991 -0
- scrapelyserp-0.1.0/tests/test_client.py +172 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# dependencies
|
|
4
|
+
/node_modules
|
|
5
|
+
/.pnp
|
|
6
|
+
.pnp.*
|
|
7
|
+
.yarn/*
|
|
8
|
+
!.yarn/patches
|
|
9
|
+
!.yarn/plugins
|
|
10
|
+
!.yarn/releases
|
|
11
|
+
!.yarn/versions
|
|
12
|
+
|
|
13
|
+
# testing
|
|
14
|
+
/coverage
|
|
15
|
+
|
|
16
|
+
# next.js
|
|
17
|
+
/.next/
|
|
18
|
+
/out/
|
|
19
|
+
|
|
20
|
+
# production
|
|
21
|
+
/build
|
|
22
|
+
|
|
23
|
+
# misc
|
|
24
|
+
.DS_Store
|
|
25
|
+
*.pem
|
|
26
|
+
|
|
27
|
+
# debug
|
|
28
|
+
npm-debug.log*
|
|
29
|
+
yarn-debug.log*
|
|
30
|
+
yarn-error.log*
|
|
31
|
+
.pnpm-debug.log*
|
|
32
|
+
|
|
33
|
+
# env files (can opt-in for committing if needed)
|
|
34
|
+
.env*
|
|
35
|
+
|
|
36
|
+
# vercel
|
|
37
|
+
.vercel
|
|
38
|
+
|
|
39
|
+
# typescript
|
|
40
|
+
*.tsbuildinfo
|
|
41
|
+
next-env.d.ts
|
|
42
|
+
|
|
43
|
+
.data/
|
|
44
|
+
.env*
|
|
45
|
+
!.env.example
|
|
46
|
+
|
|
47
|
+
# tls-client shared libraries: only the Linux build ships (native/tls-client-linux-amd64.so).
|
|
48
|
+
# Point TLS_CLIENT_LIB_PATH at a Windows/macOS build for local live testing.
|
|
49
|
+
native/*.dll
|
|
50
|
+
native/*.dylib
|
|
51
|
+
.live/
|
|
52
|
+
|
|
53
|
+
# ForgeDeck local artifacts (run prompts, captured transcripts)
|
|
54
|
+
.forgedeck/
|
|
55
|
+
.forgememory/transcripts/
|
|
56
|
+
|
|
57
|
+
# SDK / CLI / MCP package builds (packages/)
|
|
58
|
+
packages/*/dist/
|
|
59
|
+
packages/*/node_modules/
|
|
60
|
+
__pycache__/
|
|
61
|
+
*.egg-info/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scrapely
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: scrapelyserp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for the Scrapely API: product, price and stock data, structured search results, and watchlists that alert on change.
|
|
5
|
+
Project-URL: Homepage, https://scrapelyserp.com
|
|
6
|
+
Project-URL: Documentation, https://scrapelyserp.com/docs
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: api,price monitoring,product data,scrapely,scrapelyserp,sdk
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.9
|
|
14
|
+
Requires-Dist: httpx<1,>=0.24
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# scrapelyserp
|
|
18
|
+
|
|
19
|
+
The official Python SDK for the [Scrapely API](https://scrapelyserp.com/docs): product, price and stock data from
|
|
20
|
+
the retailers you sell on, structured search results, and watchlists that alert you when something changes.
|
|
21
|
+
|
|
22
|
+
- Every API operation, generated from the API's OpenAPI document, grouped by resource.
|
|
23
|
+
- Sync (`Scrapely`) and asyncio (`AsyncScrapely`) clients over [httpx](https://www.python-httpx.org/), the only
|
|
24
|
+
dependency. Python 3.9+.
|
|
25
|
+
- Typed: request and response bodies are `TypedDict`s (`scrapelyserp.types`), methods have typed signatures.
|
|
26
|
+
- Retries with backoff on 429 and 5xx, honouring `Retry-After`; idempotency keys generated for you.
|
|
27
|
+
- Typed errors carrying the API's error `code` and `param`.
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
pip install scrapelyserp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from scrapelyserp import Scrapely
|
|
37
|
+
|
|
38
|
+
client = Scrapely() # reads SCRAPELY_API_KEY
|
|
39
|
+
|
|
40
|
+
account = client.account.get()
|
|
41
|
+
print(account["balance"], "credits")
|
|
42
|
+
|
|
43
|
+
products = client.products.fetch(platform="amazon", ids=["B0009KNLV6"], tier="lite")
|
|
44
|
+
for item in products["results"]:
|
|
45
|
+
print(item["id"], item["status"], item.get("price"))
|
|
46
|
+
|
|
47
|
+
# Structured endpoints are grouped by platform.
|
|
48
|
+
results = client.structured.amazon.search(query="wireless earbuds")
|
|
49
|
+
posts = client.structured.reddit.posts(subreddit="deals")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Async:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import asyncio
|
|
56
|
+
from scrapelyserp import AsyncScrapely
|
|
57
|
+
|
|
58
|
+
async def main() -> None:
|
|
59
|
+
async with AsyncScrapely() as client:
|
|
60
|
+
account = await client.account.get()
|
|
61
|
+
async for item in client.watchlists.list_items_iter("wl_…"):
|
|
62
|
+
print(item["id"])
|
|
63
|
+
|
|
64
|
+
asyncio.run(main())
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
client = Scrapely(
|
|
71
|
+
api_key="sk_live_…", # default: SCRAPELY_API_KEY
|
|
72
|
+
base_url="https://scrapelyserp.com", # default: SCRAPELY_BASE_URL, then this
|
|
73
|
+
max_retries=2, # 429, 5xx (except 501) and network errors
|
|
74
|
+
timeout=360.0, # seconds per attempt
|
|
75
|
+
headers={"x-my-header": "1"},
|
|
76
|
+
http_client=httpx.Client(...), # your own httpx client (proxies, transports, tests)
|
|
77
|
+
)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Use it as a context manager (`with Scrapely() as client:`) or call `client.close()`.
|
|
81
|
+
|
|
82
|
+
## Resources
|
|
83
|
+
|
|
84
|
+
`client.products`, `client.offers`, `client.platforms`, `client.structured` (one sub-resource per platform:
|
|
85
|
+
`client.structured.ebay.image_search(...)`), `client.watchlists`, `client.destinations`,
|
|
86
|
+
`client.webhook_endpoints`, `client.s3_export`, `client.account`, `client.meta`.
|
|
87
|
+
|
|
88
|
+
Path parameters are positional; query parameters are keyword arguments; a body is a dict, keyword arguments, or both
|
|
89
|
+
(keywords win):
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
wl = client.watchlists.create(name="Consoles", platform="target", ids=["83887639"], every="15m")
|
|
93
|
+
client.watchlists.update(wl["id"], status="paused")
|
|
94
|
+
page = client.watchlists.list_items(wl["id"], state="active", limit=100)
|
|
95
|
+
client.destinations.set_for_watchlist(wl["id"], destinations=[])
|
|
96
|
+
|
|
97
|
+
# Any operation by its OpenAPI operationId:
|
|
98
|
+
client.request("getWatchlist", path={"id": wl["id"]})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Every method also takes `options={"headers": ..., "timeout": ..., "max_retries": ...}`.
|
|
102
|
+
|
|
103
|
+
## Pagination
|
|
104
|
+
|
|
105
|
+
List operations with a `starting_after` cursor have an `..._iter` twin that walks every page:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
for item in client.watchlists.list_items_iter("wl_…", changed_since="2026-11-01T00:00:00Z"):
|
|
109
|
+
print(item["id"], item.get("snapshot"))
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Errors
|
|
113
|
+
|
|
114
|
+
Every error is a `ScrapelyError`. API answers are an `APIError` subclass with `status`, `code` (stable: branch on
|
|
115
|
+
it), `message`, `param`, `docs` and `request_id`:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from scrapelyserp import APIError, InsufficientCreditsError
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
client.products.fetch(platform="walmart", ids=["5689919121"])
|
|
122
|
+
except InsufficientCreditsError:
|
|
123
|
+
print("Top up first")
|
|
124
|
+
except APIError as e:
|
|
125
|
+
print(e.code, e.param, e.request_id)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`BadRequestError` (400), `AuthenticationError` (401), `InsufficientCreditsError` (402), `PermissionDeniedError`
|
|
129
|
+
(403), `NotFoundError` (404), `ConflictError` (409), `RateLimitError` (429), `InternalServerError` (5xx),
|
|
130
|
+
`ComingSoonError` (501: announced, not live yet; nothing charged), `APIConnectionError` / `APITimeoutError`
|
|
131
|
+
(no answer).
|
|
132
|
+
|
|
133
|
+
## Retries and idempotency
|
|
134
|
+
|
|
135
|
+
429 and 5xx answers (except 501) and network errors are retried `max_retries` times, waiting for `Retry-After` when
|
|
136
|
+
the API sends it, else 0.5 s, 1 s, 2 s... Operations that accept an `Idempotency-Key` (creating a watchlist) get one
|
|
137
|
+
generated per call and reused across its retries; pass `idempotency_key=` to choose your own.
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
`types.py`, `_routes.py` and `_resources.py` are generated from the API's OpenAPI document by
|
|
142
|
+
`scripts/sdk/generate.ts` in the Scrapely repository; do not edit them by hand.
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
python -m unittest discover -s tests # offline, against httpx.MockTransport
|
|
146
|
+
python -m build # sdist + wheel
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
MIT
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# scrapelyserp
|
|
2
|
+
|
|
3
|
+
The official Python SDK for the [Scrapely API](https://scrapelyserp.com/docs): product, price and stock data from
|
|
4
|
+
the retailers you sell on, structured search results, and watchlists that alert you when something changes.
|
|
5
|
+
|
|
6
|
+
- Every API operation, generated from the API's OpenAPI document, grouped by resource.
|
|
7
|
+
- Sync (`Scrapely`) and asyncio (`AsyncScrapely`) clients over [httpx](https://www.python-httpx.org/), the only
|
|
8
|
+
dependency. Python 3.9+.
|
|
9
|
+
- Typed: request and response bodies are `TypedDict`s (`scrapelyserp.types`), methods have typed signatures.
|
|
10
|
+
- Retries with backoff on 429 and 5xx, honouring `Retry-After`; idempotency keys generated for you.
|
|
11
|
+
- Typed errors carrying the API's error `code` and `param`.
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install scrapelyserp
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from scrapelyserp import Scrapely
|
|
21
|
+
|
|
22
|
+
client = Scrapely() # reads SCRAPELY_API_KEY
|
|
23
|
+
|
|
24
|
+
account = client.account.get()
|
|
25
|
+
print(account["balance"], "credits")
|
|
26
|
+
|
|
27
|
+
products = client.products.fetch(platform="amazon", ids=["B0009KNLV6"], tier="lite")
|
|
28
|
+
for item in products["results"]:
|
|
29
|
+
print(item["id"], item["status"], item.get("price"))
|
|
30
|
+
|
|
31
|
+
# Structured endpoints are grouped by platform.
|
|
32
|
+
results = client.structured.amazon.search(query="wireless earbuds")
|
|
33
|
+
posts = client.structured.reddit.posts(subreddit="deals")
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Async:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import asyncio
|
|
40
|
+
from scrapelyserp import AsyncScrapely
|
|
41
|
+
|
|
42
|
+
async def main() -> None:
|
|
43
|
+
async with AsyncScrapely() as client:
|
|
44
|
+
account = await client.account.get()
|
|
45
|
+
async for item in client.watchlists.list_items_iter("wl_…"):
|
|
46
|
+
print(item["id"])
|
|
47
|
+
|
|
48
|
+
asyncio.run(main())
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
client = Scrapely(
|
|
55
|
+
api_key="sk_live_…", # default: SCRAPELY_API_KEY
|
|
56
|
+
base_url="https://scrapelyserp.com", # default: SCRAPELY_BASE_URL, then this
|
|
57
|
+
max_retries=2, # 429, 5xx (except 501) and network errors
|
|
58
|
+
timeout=360.0, # seconds per attempt
|
|
59
|
+
headers={"x-my-header": "1"},
|
|
60
|
+
http_client=httpx.Client(...), # your own httpx client (proxies, transports, tests)
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use it as a context manager (`with Scrapely() as client:`) or call `client.close()`.
|
|
65
|
+
|
|
66
|
+
## Resources
|
|
67
|
+
|
|
68
|
+
`client.products`, `client.offers`, `client.platforms`, `client.structured` (one sub-resource per platform:
|
|
69
|
+
`client.structured.ebay.image_search(...)`), `client.watchlists`, `client.destinations`,
|
|
70
|
+
`client.webhook_endpoints`, `client.s3_export`, `client.account`, `client.meta`.
|
|
71
|
+
|
|
72
|
+
Path parameters are positional; query parameters are keyword arguments; a body is a dict, keyword arguments, or both
|
|
73
|
+
(keywords win):
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
wl = client.watchlists.create(name="Consoles", platform="target", ids=["83887639"], every="15m")
|
|
77
|
+
client.watchlists.update(wl["id"], status="paused")
|
|
78
|
+
page = client.watchlists.list_items(wl["id"], state="active", limit=100)
|
|
79
|
+
client.destinations.set_for_watchlist(wl["id"], destinations=[])
|
|
80
|
+
|
|
81
|
+
# Any operation by its OpenAPI operationId:
|
|
82
|
+
client.request("getWatchlist", path={"id": wl["id"]})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Every method also takes `options={"headers": ..., "timeout": ..., "max_retries": ...}`.
|
|
86
|
+
|
|
87
|
+
## Pagination
|
|
88
|
+
|
|
89
|
+
List operations with a `starting_after` cursor have an `..._iter` twin that walks every page:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
for item in client.watchlists.list_items_iter("wl_…", changed_since="2026-11-01T00:00:00Z"):
|
|
93
|
+
print(item["id"], item.get("snapshot"))
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Errors
|
|
97
|
+
|
|
98
|
+
Every error is a `ScrapelyError`. API answers are an `APIError` subclass with `status`, `code` (stable: branch on
|
|
99
|
+
it), `message`, `param`, `docs` and `request_id`:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from scrapelyserp import APIError, InsufficientCreditsError
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
client.products.fetch(platform="walmart", ids=["5689919121"])
|
|
106
|
+
except InsufficientCreditsError:
|
|
107
|
+
print("Top up first")
|
|
108
|
+
except APIError as e:
|
|
109
|
+
print(e.code, e.param, e.request_id)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`BadRequestError` (400), `AuthenticationError` (401), `InsufficientCreditsError` (402), `PermissionDeniedError`
|
|
113
|
+
(403), `NotFoundError` (404), `ConflictError` (409), `RateLimitError` (429), `InternalServerError` (5xx),
|
|
114
|
+
`ComingSoonError` (501: announced, not live yet; nothing charged), `APIConnectionError` / `APITimeoutError`
|
|
115
|
+
(no answer).
|
|
116
|
+
|
|
117
|
+
## Retries and idempotency
|
|
118
|
+
|
|
119
|
+
429 and 5xx answers (except 501) and network errors are retried `max_retries` times, waiting for `Retry-After` when
|
|
120
|
+
the API sends it, else 0.5 s, 1 s, 2 s... Operations that accept an `Idempotency-Key` (creating a watchlist) get one
|
|
121
|
+
generated per call and reused across its retries; pass `idempotency_key=` to choose your own.
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
`types.py`, `_routes.py` and `_resources.py` are generated from the API's OpenAPI document by
|
|
126
|
+
`scripts/sdk/generate.ts` in the Scrapely repository; do not edit them by hand.
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
python -m unittest discover -s tests # offline, against httpx.MockTransport
|
|
130
|
+
python -m build # sdist + wheel
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.21"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scrapelyserp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Official Python SDK for the Scrapely API: product, price and stock data, structured search results, and watchlists that alert on change."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
dependencies = ["httpx>=0.24,<1"]
|
|
14
|
+
keywords = ["scrapely", "scrapelyserp", "api", "sdk", "price monitoring", "product data"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://scrapelyserp.com"
|
|
23
|
+
Documentation = "https://scrapelyserp.com/docs"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["src/scrapelyserp"]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Official Python SDK for the Scrapely API (https://scrapelyserp.com).
|
|
2
|
+
|
|
3
|
+
from scrapelyserp import Scrapely
|
|
4
|
+
|
|
5
|
+
client = Scrapely() # reads SCRAPELY_API_KEY
|
|
6
|
+
print(client.account.get()["balance"])
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from . import types
|
|
10
|
+
from ._base import DEFAULT_BASE_URL, RequestOptions, normalize_base_url
|
|
11
|
+
from ._errors import (
|
|
12
|
+
APIConnectionError,
|
|
13
|
+
APIError,
|
|
14
|
+
APITimeoutError,
|
|
15
|
+
AuthenticationError,
|
|
16
|
+
BadRequestError,
|
|
17
|
+
ComingSoonError,
|
|
18
|
+
ConflictError,
|
|
19
|
+
InsufficientCreditsError,
|
|
20
|
+
InternalServerError,
|
|
21
|
+
NotFoundError,
|
|
22
|
+
PermissionDeniedError,
|
|
23
|
+
RateLimitError,
|
|
24
|
+
ScrapelyError,
|
|
25
|
+
)
|
|
26
|
+
from ._resources import AsyncScrapely, Scrapely
|
|
27
|
+
from ._version import __version__
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"Scrapely",
|
|
31
|
+
"AsyncScrapely",
|
|
32
|
+
"RequestOptions",
|
|
33
|
+
"DEFAULT_BASE_URL",
|
|
34
|
+
"normalize_base_url",
|
|
35
|
+
"types",
|
|
36
|
+
"ScrapelyError",
|
|
37
|
+
"APIError",
|
|
38
|
+
"BadRequestError",
|
|
39
|
+
"AuthenticationError",
|
|
40
|
+
"InsufficientCreditsError",
|
|
41
|
+
"PermissionDeniedError",
|
|
42
|
+
"NotFoundError",
|
|
43
|
+
"ConflictError",
|
|
44
|
+
"RateLimitError",
|
|
45
|
+
"InternalServerError",
|
|
46
|
+
"ComingSoonError",
|
|
47
|
+
"APIConnectionError",
|
|
48
|
+
"APITimeoutError",
|
|
49
|
+
"__version__",
|
|
50
|
+
]
|