mrscraper-sdk 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.
@@ -0,0 +1,64 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+ *.egg
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ eggs/
12
+ parts/
13
+ var/
14
+ sdist/
15
+ wheels/
16
+ pip-wheel-metadata/
17
+ share/python-wheels/
18
+ *.manifest
19
+ *.spec
20
+ debug_dir/
21
+ .ruff_cache/
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ env/
27
+ ENV/
28
+
29
+ # Distribution / packaging
30
+ .eggs/
31
+ *.tar.gz
32
+
33
+ # Unit test / coverage
34
+ .coverage
35
+ .coverage.*
36
+ htmlcov/
37
+ .cache
38
+ .pytest_cache/
39
+ nosetests.xml
40
+ coverage.xml
41
+ *.cover
42
+ .hypothesis/
43
+
44
+ # Type checking
45
+ .mypy_cache/
46
+ .dmypy.json
47
+ dmypy.json
48
+ .pytype/
49
+ .pyre/
50
+
51
+ # IDEs
52
+ .idea/
53
+ .vscode/
54
+ *.swp
55
+ *.swo
56
+ *~
57
+
58
+ # macOS
59
+ .DS_Store
60
+
61
+ # Environment files
62
+ .env
63
+ .env.*
64
+ !.env.example
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MrScraper
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,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: mrscraper-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the MrScraper web-scraping API
5
+ Project-URL: Homepage, https://mrscraper.com
6
+ Project-URL: Documentation, https://docs.mrscraper.com
7
+ Project-URL: Repository, https://github.com/mrscraper/mrscraper-python
8
+ Project-URL: Bug Tracker, https://github.com/mrscraper/mrscraper-python/issues
9
+ Author: MrScraper
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,mrscraper,scraping,sdk,web scraping
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.9
26
+ Requires-Dist: httpx>=0.27
27
+ Provides-Extra: dev
28
+ Requires-Dist: mypy>=1.10; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
30
+ Requires-Dist: pytest>=8; extra == 'dev'
31
+ Requires-Dist: respx>=0.21; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # MrScraper Python SDK
36
+
37
+ A clean, typed Python client for the [MrScraper](https://mrscraper.com) web-scraping API.
38
+ Supports **async/await** usage.
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install mrscraper-sdk
46
+ ```
47
+
48
+ Requires Python 3.9+.
49
+
50
+ ---
51
+
52
+ ## Authentication
53
+
54
+ Every client is initialised with your MrScraper API token.
55
+ Get yours at <https://app.mrscraper.com>.
56
+
57
+ ```python
58
+ from mrscraper import MrScraper
59
+
60
+ client = MrScraper(token="atk_your_token_here")
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Quick Start
66
+
67
+ ### Fetch raw HTML (stealth browser)
68
+
69
+ ```python
70
+ import asyncio
71
+ from mrscraper import MrScraper
72
+
73
+ async def main():
74
+ client = MrScraper(token="atk_your_token_here")
75
+
76
+ result = await client.fetch_html(
77
+ "https://stockx.com/air-jordan-1-retro-low-og-chicago-2025",
78
+ geo_code="US",
79
+ timeout=120,
80
+ block_resources=False,
81
+ )
82
+ print(result["data"]) # raw HTML string
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ### Create an AI scraper
88
+
89
+ ```python
90
+ result = await client.create_scraper(
91
+ url="https://example.com/products",
92
+ message="Extract all product names, prices, and ratings",
93
+ agent="listing", # "general" | "listing" | "map"
94
+ proxy_country="US",
95
+ )
96
+ scraper_id = result["data"]["data"]["id"]
97
+ print("Scraper ID:", scraper_id)
98
+ ```
99
+
100
+ ### Rerun a scraper on a new URL
101
+
102
+ ```python
103
+ result = await client.rerun_scraper(
104
+ scraper_id=scraper_id,
105
+ url="https://example.com/products?page=2",
106
+ )
107
+ ```
108
+
109
+ ### Bulk rerun on multiple URLs (AI scraper)
110
+
111
+ ```python
112
+ result = await client.bulk_rerun_scraper(
113
+ scraper_id=scraper_id,
114
+ urls=[
115
+ "https://example.com/products/item1",
116
+ "https://example.com/products/item2",
117
+ "https://example.com/products/item3",
118
+ ],
119
+ )
120
+ ```
121
+
122
+ ### Rerun a manually configured scraper
123
+
124
+ ```python
125
+ result = await client.rerun_manual_scraper(
126
+ scraper_id="manual_scraper_67890",
127
+ url="https://example.com/products/new-item",
128
+ )
129
+ ```
130
+
131
+ ### Bulk rerun manual scraper on multiple URLs
132
+
133
+ ```python
134
+ result = await client.bulk_rerun_manual_scraper(
135
+ scraper_id="scraper_12345",
136
+ urls=[
137
+ "https://www.example.com/products/item1",
138
+ "https://www.example.com/products/item2",
139
+ "https://www.example.com/products/item3",
140
+ ],
141
+ )
142
+ ```
143
+
144
+ ### Retrieve results
145
+
146
+ ```python
147
+ # All results (paginated)
148
+ page = await client.get_all_results(
149
+ sort_field="updatedAt",
150
+ sort_order="DESC",
151
+ page_size=20,
152
+ page=1,
153
+ search="product",
154
+ date_range_column="updatedAt",
155
+ start_at="2024-01-01",
156
+ end_at="2024-01-31",
157
+ )
158
+ print(page["data"])
159
+
160
+ # A specific result by ID
161
+ result = await client.get_result_by_id("result_12345")
162
+ print(result["data"])
163
+ ```
164
+
165
+ ---
166
+
167
+ ## API Reference
168
+
169
+ ### `MrScraper`
170
+
171
+ All methods are coroutines and must be awaited.
172
+
173
+ | Method | Description |
174
+ |--------|-------------|
175
+ | `fetch_html(url, *, timeout, geo_code, block_resources)` | Fetch rendered HTML via the MrScraper stealth browser |
176
+ | `create_scraper(url, message, *, agent, proxy_country, ...)` | Create & run an AI-powered scraper |
177
+ | `rerun_scraper(scraper_id, url, *, max_depth, max_pages, limit, ...)` | Rerun an AI scraper on a new URL |
178
+ | `bulk_rerun_scraper(scraper_id, urls)` | Rerun an AI scraper on multiple URLs in one batch |
179
+ | `rerun_manual_scraper(scraper_id, url)` | Rerun a manually configured scraper on a single URL |
180
+ | `bulk_rerun_manual_scraper(scraper_id, urls)` | Rerun a manual scraper on multiple URLs in one batch |
181
+ | `get_all_results(*, sort_field, sort_order, page_size, page, search, ...)` | List all results with filtering & pagination |
182
+ | `get_result_by_id(result_id)` | Fetch a single result by its ID |
183
+
184
+ All methods return a `dict` with the following keys:
185
+
186
+ | Key | Type | Description |
187
+ |-----|------|-------------|
188
+ | `status_code` | `int` | HTTP status code |
189
+ | `data` | `Any` | Parsed JSON body or raw text |
190
+ | `headers` | `dict` | Response headers |
191
+
192
+ ### `bulk_rerun_manual_scraper`
193
+
194
+ Reruns a manually configured scraper on multiple URLs simultaneously in a single batch operation. This is more efficient than calling `rerun_manual_scraper` multiple times, as it processes all URLs in parallel and returns consolidated results. Ideal for scraping multiple pages, products, or articles with the same extraction logic.
195
+
196
+ | Argument | Description |
197
+ |----------|-------------|
198
+ | `scraper_id` | The ID of the manual scraper to rerun (obtained from the MrScraper dashboard). Must be a scraper created manually through the web interface, not an AI scraper. Find it at https://app.mrscraper.com |
199
+ | `urls` | A list of target URLs to scrape (required, must contain at least one URL). Each URL will be processed independently using the scraper's extraction logic. Example: `["https://example.com/page1", "https://example.com/page2"]` |
200
+
201
+ **Returns:** A dict with `status_code`, `data` (bulk job info including job ID, status, metadata; use `get_all_results` or `get_result_by_id` to fetch per-URL results), and `headers`.
202
+
203
+ **Example:**
204
+
205
+ ```python
206
+ result = await client.bulk_rerun_manual_scraper(
207
+ scraper_id="scraper_12345",
208
+ urls=[
209
+ "https://www.example.com/products/item1",
210
+ "https://www.example.com/products/item2",
211
+ "https://www.example.com/products/item3",
212
+ ],
213
+ )
214
+ ```
215
+
216
+ ### `create_scraper` — agent types
217
+
218
+ | Agent | Best used for |
219
+ |-------|---------------|
220
+ | `"general"` | Default; handles almost any page |
221
+ | `"listing"` | Product listings, job boards, search results |
222
+ | `"map"` | Crawling all sub-pages / sitemaps of a site |
223
+
224
+ The `max_depth`, `max_pages`, `limit`, `include_patterns`, and `exclude_patterns`
225
+ parameters are only meaningful when `agent="map"`.
226
+
227
+ ---
228
+
229
+ ## Exceptions
230
+
231
+ | Exception | Raised when |
232
+ |-----------|-------------|
233
+ | `MrScraperError` | Base class for all SDK errors |
234
+ | `AuthenticationError` | API token is invalid or missing (HTTP 401) |
235
+ | `APIError` | API returned a non-2xx error; has `.status_code` attribute |
236
+ | `NetworkError` | Connection timeout or network-level failure |
237
+
238
+ ```python
239
+ from mrscraper.exceptions import AuthenticationError, APIError, NetworkError
240
+
241
+ try:
242
+ result = await client.fetch_html("https://example.com")
243
+ except AuthenticationError:
244
+ print("Check your API token at https://app.mrscraper.com")
245
+ except APIError as e:
246
+ print(f"API error {e.status_code}: {e}")
247
+ except NetworkError as e:
248
+ print(f"Network problem: {e}")
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Development
254
+
255
+ ```bash
256
+ # Install with dev dependencies
257
+ pip install -e ".[dev]"
258
+
259
+ # Run tests
260
+ pytest
261
+
262
+ # Lint & format
263
+ ruff check .
264
+ ruff format .
265
+
266
+ # Type check
267
+ mypy src/mrscraper
268
+ ```
269
+
270
+ ---
271
+
272
+ ## License
273
+
274
+ MIT © MrScraper
@@ -0,0 +1,240 @@
1
+ # MrScraper Python SDK
2
+
3
+ A clean, typed Python client for the [MrScraper](https://mrscraper.com) web-scraping API.
4
+ Supports **async/await** usage.
5
+
6
+ ---
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pip install mrscraper-sdk
12
+ ```
13
+
14
+ Requires Python 3.9+.
15
+
16
+ ---
17
+
18
+ ## Authentication
19
+
20
+ Every client is initialised with your MrScraper API token.
21
+ Get yours at <https://app.mrscraper.com>.
22
+
23
+ ```python
24
+ from mrscraper import MrScraper
25
+
26
+ client = MrScraper(token="atk_your_token_here")
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Quick Start
32
+
33
+ ### Fetch raw HTML (stealth browser)
34
+
35
+ ```python
36
+ import asyncio
37
+ from mrscraper import MrScraper
38
+
39
+ async def main():
40
+ client = MrScraper(token="atk_your_token_here")
41
+
42
+ result = await client.fetch_html(
43
+ "https://stockx.com/air-jordan-1-retro-low-og-chicago-2025",
44
+ geo_code="US",
45
+ timeout=120,
46
+ block_resources=False,
47
+ )
48
+ print(result["data"]) # raw HTML string
49
+
50
+ asyncio.run(main())
51
+ ```
52
+
53
+ ### Create an AI scraper
54
+
55
+ ```python
56
+ result = await client.create_scraper(
57
+ url="https://example.com/products",
58
+ message="Extract all product names, prices, and ratings",
59
+ agent="listing", # "general" | "listing" | "map"
60
+ proxy_country="US",
61
+ )
62
+ scraper_id = result["data"]["data"]["id"]
63
+ print("Scraper ID:", scraper_id)
64
+ ```
65
+
66
+ ### Rerun a scraper on a new URL
67
+
68
+ ```python
69
+ result = await client.rerun_scraper(
70
+ scraper_id=scraper_id,
71
+ url="https://example.com/products?page=2",
72
+ )
73
+ ```
74
+
75
+ ### Bulk rerun on multiple URLs (AI scraper)
76
+
77
+ ```python
78
+ result = await client.bulk_rerun_scraper(
79
+ scraper_id=scraper_id,
80
+ urls=[
81
+ "https://example.com/products/item1",
82
+ "https://example.com/products/item2",
83
+ "https://example.com/products/item3",
84
+ ],
85
+ )
86
+ ```
87
+
88
+ ### Rerun a manually configured scraper
89
+
90
+ ```python
91
+ result = await client.rerun_manual_scraper(
92
+ scraper_id="manual_scraper_67890",
93
+ url="https://example.com/products/new-item",
94
+ )
95
+ ```
96
+
97
+ ### Bulk rerun manual scraper on multiple URLs
98
+
99
+ ```python
100
+ result = await client.bulk_rerun_manual_scraper(
101
+ scraper_id="scraper_12345",
102
+ urls=[
103
+ "https://www.example.com/products/item1",
104
+ "https://www.example.com/products/item2",
105
+ "https://www.example.com/products/item3",
106
+ ],
107
+ )
108
+ ```
109
+
110
+ ### Retrieve results
111
+
112
+ ```python
113
+ # All results (paginated)
114
+ page = await client.get_all_results(
115
+ sort_field="updatedAt",
116
+ sort_order="DESC",
117
+ page_size=20,
118
+ page=1,
119
+ search="product",
120
+ date_range_column="updatedAt",
121
+ start_at="2024-01-01",
122
+ end_at="2024-01-31",
123
+ )
124
+ print(page["data"])
125
+
126
+ # A specific result by ID
127
+ result = await client.get_result_by_id("result_12345")
128
+ print(result["data"])
129
+ ```
130
+
131
+ ---
132
+
133
+ ## API Reference
134
+
135
+ ### `MrScraper`
136
+
137
+ All methods are coroutines and must be awaited.
138
+
139
+ | Method | Description |
140
+ |--------|-------------|
141
+ | `fetch_html(url, *, timeout, geo_code, block_resources)` | Fetch rendered HTML via the MrScraper stealth browser |
142
+ | `create_scraper(url, message, *, agent, proxy_country, ...)` | Create & run an AI-powered scraper |
143
+ | `rerun_scraper(scraper_id, url, *, max_depth, max_pages, limit, ...)` | Rerun an AI scraper on a new URL |
144
+ | `bulk_rerun_scraper(scraper_id, urls)` | Rerun an AI scraper on multiple URLs in one batch |
145
+ | `rerun_manual_scraper(scraper_id, url)` | Rerun a manually configured scraper on a single URL |
146
+ | `bulk_rerun_manual_scraper(scraper_id, urls)` | Rerun a manual scraper on multiple URLs in one batch |
147
+ | `get_all_results(*, sort_field, sort_order, page_size, page, search, ...)` | List all results with filtering & pagination |
148
+ | `get_result_by_id(result_id)` | Fetch a single result by its ID |
149
+
150
+ All methods return a `dict` with the following keys:
151
+
152
+ | Key | Type | Description |
153
+ |-----|------|-------------|
154
+ | `status_code` | `int` | HTTP status code |
155
+ | `data` | `Any` | Parsed JSON body or raw text |
156
+ | `headers` | `dict` | Response headers |
157
+
158
+ ### `bulk_rerun_manual_scraper`
159
+
160
+ Reruns a manually configured scraper on multiple URLs simultaneously in a single batch operation. This is more efficient than calling `rerun_manual_scraper` multiple times, as it processes all URLs in parallel and returns consolidated results. Ideal for scraping multiple pages, products, or articles with the same extraction logic.
161
+
162
+ | Argument | Description |
163
+ |----------|-------------|
164
+ | `scraper_id` | The ID of the manual scraper to rerun (obtained from the MrScraper dashboard). Must be a scraper created manually through the web interface, not an AI scraper. Find it at https://app.mrscraper.com |
165
+ | `urls` | A list of target URLs to scrape (required, must contain at least one URL). Each URL will be processed independently using the scraper's extraction logic. Example: `["https://example.com/page1", "https://example.com/page2"]` |
166
+
167
+ **Returns:** A dict with `status_code`, `data` (bulk job info including job ID, status, metadata; use `get_all_results` or `get_result_by_id` to fetch per-URL results), and `headers`.
168
+
169
+ **Example:**
170
+
171
+ ```python
172
+ result = await client.bulk_rerun_manual_scraper(
173
+ scraper_id="scraper_12345",
174
+ urls=[
175
+ "https://www.example.com/products/item1",
176
+ "https://www.example.com/products/item2",
177
+ "https://www.example.com/products/item3",
178
+ ],
179
+ )
180
+ ```
181
+
182
+ ### `create_scraper` — agent types
183
+
184
+ | Agent | Best used for |
185
+ |-------|---------------|
186
+ | `"general"` | Default; handles almost any page |
187
+ | `"listing"` | Product listings, job boards, search results |
188
+ | `"map"` | Crawling all sub-pages / sitemaps of a site |
189
+
190
+ The `max_depth`, `max_pages`, `limit`, `include_patterns`, and `exclude_patterns`
191
+ parameters are only meaningful when `agent="map"`.
192
+
193
+ ---
194
+
195
+ ## Exceptions
196
+
197
+ | Exception | Raised when |
198
+ |-----------|-------------|
199
+ | `MrScraperError` | Base class for all SDK errors |
200
+ | `AuthenticationError` | API token is invalid or missing (HTTP 401) |
201
+ | `APIError` | API returned a non-2xx error; has `.status_code` attribute |
202
+ | `NetworkError` | Connection timeout or network-level failure |
203
+
204
+ ```python
205
+ from mrscraper.exceptions import AuthenticationError, APIError, NetworkError
206
+
207
+ try:
208
+ result = await client.fetch_html("https://example.com")
209
+ except AuthenticationError:
210
+ print("Check your API token at https://app.mrscraper.com")
211
+ except APIError as e:
212
+ print(f"API error {e.status_code}: {e}")
213
+ except NetworkError as e:
214
+ print(f"Network problem: {e}")
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Development
220
+
221
+ ```bash
222
+ # Install with dev dependencies
223
+ pip install -e ".[dev]"
224
+
225
+ # Run tests
226
+ pytest
227
+
228
+ # Lint & format
229
+ ruff check .
230
+ ruff format .
231
+
232
+ # Type check
233
+ mypy src/mrscraper
234
+ ```
235
+
236
+ ---
237
+
238
+ ## License
239
+
240
+ MIT © MrScraper
@@ -0,0 +1,79 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "mrscraper-sdk"
7
+ version = "0.1.0"
8
+ description = "Python SDK for the MrScraper web-scraping API"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ { name = "MrScraper", url = "https://mrscraper.com" },
14
+ ]
15
+ keywords = ["scraping", "web scraping", "mrscraper", "api", "sdk"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Internet :: WWW/HTTP",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ "Typing :: Typed",
29
+ ]
30
+ dependencies = [
31
+ "httpx>=0.27",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://mrscraper.com"
36
+ Documentation = "https://docs.mrscraper.com"
37
+ Repository = "https://github.com/mrscraper/mrscraper-python"
38
+ "Bug Tracker" = "https://github.com/mrscraper/mrscraper-python/issues"
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/mrscraper"]
42
+
43
+ [tool.hatch.build.targets.sdist]
44
+ include = [
45
+ "src/",
46
+ "tests/",
47
+ "README.md",
48
+ "LICENSE",
49
+ "pyproject.toml",
50
+ ]
51
+
52
+ [project.optional-dependencies]
53
+ dev = [
54
+ "pytest>=8",
55
+ "pytest-asyncio>=0.24",
56
+ "respx>=0.21",
57
+ "ruff>=0.4",
58
+ "mypy>=1.10",
59
+ ]
60
+
61
+ [tool.ruff]
62
+ line-length = 100
63
+ target-version = "py39"
64
+
65
+ [tool.ruff.lint]
66
+ select = ["E", "F", "I", "UP", "B", "SIM"]
67
+ ignore = ["E501"]
68
+
69
+ [tool.mypy]
70
+ python_version = "3.9"
71
+ strict = true
72
+ files = ["src/mrscraper"]
73
+
74
+ [tool.pytest.ini_options]
75
+ asyncio_mode = "auto"
76
+ testpaths = ["tests"]
77
+ markers = [
78
+ "integration: marks tests as integration tests (hit real API)",
79
+ ]
@@ -0,0 +1,31 @@
1
+ """
2
+ MrScraper Python SDK
3
+
4
+ A clean Python client for the `MrScraper <https://mrscraper.com>`_ API.
5
+ Supports async/await usage.
6
+
7
+ Quickstart::
8
+
9
+ import asyncio
10
+ from mrscraper import MrScraper
11
+
12
+ async def main():
13
+ client = MrScraper(token="atk_your_token_here")
14
+ result = await client.fetch_html("https://example.com")
15
+ print(result["data"])
16
+
17
+ asyncio.run(main())
18
+ """
19
+
20
+ from .mrscraper import MrScraper
21
+ from .exceptions import APIError, AuthenticationError, MrScraperError, NetworkError
22
+
23
+ __all__ = [
24
+ "MrScraper",
25
+ "MrScraperError",
26
+ "AuthenticationError",
27
+ "APIError",
28
+ "NetworkError",
29
+ ]
30
+
31
+ __version__ = "0.1.0"