scrapely-python 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.
Files changed (58) hide show
  1. scrapely_python-0.1.0/PKG-INFO +83 -0
  2. scrapely_python-0.1.0/README.md +47 -0
  3. scrapely_python-0.1.0/pyproject.toml +85 -0
  4. scrapely_python-0.1.0/setup.cfg +4 -0
  5. scrapely_python-0.1.0/src/scrapely/__init__.py +246 -0
  6. scrapely_python-0.1.0/src/scrapely/_browser_locations.py +5470 -0
  7. scrapely_python-0.1.0/src/scrapely/actor.py +1836 -0
  8. scrapely_python-0.1.0/src/scrapely/browser_configuration.py +146 -0
  9. scrapely_python-0.1.0/src/scrapely/charging.py +1143 -0
  10. scrapely_python-0.1.0/src/scrapely/charging_client.py +107 -0
  11. scrapely_python-0.1.0/src/scrapely/configuration.py +375 -0
  12. scrapely_python-0.1.0/src/scrapely/crypto/__init__.py +21 -0
  13. scrapely_python-0.1.0/src/scrapely/crypto/_secrets.py +210 -0
  14. scrapely_python-0.1.0/src/scrapely/errors.py +153 -0
  15. scrapely_python-0.1.0/src/scrapely/events/__init__.py +57 -0
  16. scrapely_python-0.1.0/src/scrapely/events/_types.py +194 -0
  17. scrapely_python-0.1.0/src/scrapely/events/event_manager.py +292 -0
  18. scrapely_python-0.1.0/src/scrapely/log.py +39 -0
  19. scrapely_python-0.1.0/src/scrapely/patch_browser_pool.py +861 -0
  20. scrapely_python-0.1.0/src/scrapely/pricing_types.py +172 -0
  21. scrapely_python-0.1.0/src/scrapely/proxy_configuration.py +741 -0
  22. scrapely_python-0.1.0/src/scrapely/py.typed +2 -0
  23. scrapely_python-0.1.0/src/scrapely/request_loaders/__init__.py +5 -0
  24. scrapely_python-0.1.0/src/scrapely/request_loaders/_scrapely_request_list.py +169 -0
  25. scrapely_python-0.1.0/src/scrapely/storage/__init__.py +48 -0
  26. scrapely_python-0.1.0/src/scrapely/storage/_file_system/__init__.py +9 -0
  27. scrapely_python-0.1.0/src/scrapely/storage/_file_system/_key_value_store_client.py +155 -0
  28. scrapely_python-0.1.0/src/scrapely/storage/_file_system/_storage_client.py +50 -0
  29. scrapely_python-0.1.0/src/scrapely/storage/_metadata.py +138 -0
  30. scrapely_python-0.1.0/src/scrapely/storage/api_client.py +350 -0
  31. scrapely_python-0.1.0/src/scrapely/storage/client.py +618 -0
  32. scrapely_python-0.1.0/src/scrapely/storage/patch_storage.py +257 -0
  33. scrapely_python-0.1.0/src/scrapely/storage/scrapely_dataset_client.py +305 -0
  34. scrapely_python-0.1.0/src/scrapely/storage/scrapely_kvs_client.py +220 -0
  35. scrapely_python-0.1.0/src/scrapely/storage/scrapely_rq_client.py +496 -0
  36. scrapely_python-0.1.0/src/scrapely/storage/scrapely_storage_client.py +192 -0
  37. scrapely_python-0.1.0/src/scrapely/storage/smart_scrapely_storage_client.py +109 -0
  38. scrapely_python-0.1.0/src/scrapely/storage/types.py +601 -0
  39. scrapely_python-0.1.0/src/scrapely/storage/utils.py +38 -0
  40. scrapely_python-0.1.0/src/scrapely/storage_clients/__init__.py +25 -0
  41. scrapely_python-0.1.0/src/scrapely/storages/__init__.py +5 -0
  42. scrapely_python-0.1.0/src/scrapely/types.py +269 -0
  43. scrapely_python-0.1.0/src/scrapely/webhook.py +82 -0
  44. scrapely_python-0.1.0/src/scrapely_python.egg-info/PKG-INFO +83 -0
  45. scrapely_python-0.1.0/src/scrapely_python.egg-info/SOURCES.txt +56 -0
  46. scrapely_python-0.1.0/src/scrapely_python.egg-info/dependency_links.txt +1 -0
  47. scrapely_python-0.1.0/src/scrapely_python.egg-info/requires.txt +15 -0
  48. scrapely_python-0.1.0/src/scrapely_python.egg-info/top_level.txt +1 -0
  49. scrapely_python-0.1.0/tests/test_apify_parity.py +85 -0
  50. scrapely_python-0.1.0/tests/test_browser_configuration.py +93 -0
  51. scrapely_python-0.1.0/tests/test_charging_parity.py +340 -0
  52. scrapely_python-0.1.0/tests/test_charging_pending.py +459 -0
  53. scrapely_python-0.1.0/tests/test_parity.py +355 -0
  54. scrapely_python-0.1.0/tests/test_patch_browser_pool.py +1212 -0
  55. scrapely_python-0.1.0/tests/test_proxy_configuration.py +586 -0
  56. scrapely_python-0.1.0/tests/test_run_control.py +499 -0
  57. scrapely_python-0.1.0/tests/test_secrets.py +134 -0
  58. scrapely_python-0.1.0/tests/test_storage.py +456 -0
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: scrapely-python
3
+ Version: 0.1.0
4
+ Summary: Scrapely Python SDK - A toolkit for building Actors on the Scrapely platform
5
+ Author-email: Scrapely <support@scrape.ly>
6
+ License: MIT
7
+ Project-URL: Homepage, https://scrape.ly
8
+ Project-URL: Documentation, https://docs.scrape.ly
9
+ Project-URL: Repository, https://github.com/SandeepDev1/scrapely
10
+ Keywords: scraping,actor,serverless,apify,scrapely
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: httpx>=0.25.0
23
+ Requires-Dist: crawlee<2.0.0,>=1.8.0
24
+ Requires-Dist: websockets>=12.0
25
+ Requires-Dist: scrapely-client-python<2,>=1.0.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: cryptography>=42.0.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"
31
+ Requires-Dist: black>=23.0.0; extra == "dev"
32
+ Requires-Dist: isort>=5.12.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
34
+ Requires-Dist: playwright>=1.40.0; extra == "dev"
35
+ Requires-Dist: browserforge>=1.2.0; extra == "dev"
36
+
37
+ # Scrapely Python SDK
38
+
39
+ Build Python Actors for the [Scrapely](https://scrape.ly) platform with lifecycle helpers, Crawlee-compatible storage, platform events, remote browser CDP, run control, webhooks, and pay-per-event accounting.
40
+
41
+ ## Install
42
+
43
+ Scrapely requires Python 3.9 or newer.
44
+
45
+ ```bash
46
+ python -m pip install scrapely
47
+ ```
48
+
49
+ Install the appropriate Crawlee/Playwright browser dependencies separately when your Actor uses a browser.
50
+
51
+ ## Quick start
52
+
53
+ ```python
54
+ import asyncio
55
+
56
+ from scrapely import Actor
57
+
58
+
59
+ async def main() -> None:
60
+ actor_input = await Actor.get_input_or_throw()
61
+ await Actor.push_data({
62
+ "url": actor_input["url"],
63
+ "status": "processed",
64
+ })
65
+
66
+
67
+ if __name__ == "__main__":
68
+ asyncio.run(Actor.main(main))
69
+ ```
70
+
71
+ `Actor.main()` initializes the Actor, awaits your callback, closes events and storage, and exits the process. For embedded applications and tests, use `async with Actor:` instead.
72
+
73
+ ## Highlights
74
+
75
+ - Local file-system storage and Scrapely API-backed datasets, key-value stores, and request queues
76
+ - Crawlee request loaders and storage objects
77
+ - Platform event WebSocket integration and state persistence
78
+ - Automatic remote Chromium CDP wiring through `CDP_URL`
79
+ - Actor start, call, abort, reboot, and metamorph operations
80
+ - Ad-hoc webhooks, proxy configuration, and charging/pricing types
81
+ - Apify-compatible environment aliases and asynchronous client access
82
+
83
+ See the [complete Python SDK guide](../docs/sdk-python.md) for lifecycle details, option objects, storage selection, events, CDP behavior, run control, environment variables, errors, and the full public export list.
@@ -0,0 +1,47 @@
1
+ # Scrapely Python SDK
2
+
3
+ Build Python Actors for the [Scrapely](https://scrape.ly) platform with lifecycle helpers, Crawlee-compatible storage, platform events, remote browser CDP, run control, webhooks, and pay-per-event accounting.
4
+
5
+ ## Install
6
+
7
+ Scrapely requires Python 3.9 or newer.
8
+
9
+ ```bash
10
+ python -m pip install scrapely
11
+ ```
12
+
13
+ Install the appropriate Crawlee/Playwright browser dependencies separately when your Actor uses a browser.
14
+
15
+ ## Quick start
16
+
17
+ ```python
18
+ import asyncio
19
+
20
+ from scrapely import Actor
21
+
22
+
23
+ async def main() -> None:
24
+ actor_input = await Actor.get_input_or_throw()
25
+ await Actor.push_data({
26
+ "url": actor_input["url"],
27
+ "status": "processed",
28
+ })
29
+
30
+
31
+ if __name__ == "__main__":
32
+ asyncio.run(Actor.main(main))
33
+ ```
34
+
35
+ `Actor.main()` initializes the Actor, awaits your callback, closes events and storage, and exits the process. For embedded applications and tests, use `async with Actor:` instead.
36
+
37
+ ## Highlights
38
+
39
+ - Local file-system storage and Scrapely API-backed datasets, key-value stores, and request queues
40
+ - Crawlee request loaders and storage objects
41
+ - Platform event WebSocket integration and state persistence
42
+ - Automatic remote Chromium CDP wiring through `CDP_URL`
43
+ - Actor start, call, abort, reboot, and metamorph operations
44
+ - Ad-hoc webhooks, proxy configuration, and charging/pricing types
45
+ - Apify-compatible environment aliases and asynchronous client access
46
+
47
+ See the [complete Python SDK guide](../docs/sdk-python.md) for lifecycle details, option objects, storage selection, events, CDP behavior, run control, environment variables, errors, and the full public export list.
@@ -0,0 +1,85 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "scrapely-python"
7
+ version = "0.1.0"
8
+ description = "Scrapely Python SDK - A toolkit for building Actors on the Scrapely platform"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Scrapely", email = "support@scrape.ly"}
13
+ ]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
24
+ ]
25
+ keywords = ["scraping", "actor", "serverless", "apify", "scrapely"]
26
+ requires-python = ">=3.11"
27
+ dependencies = [
28
+ "httpx>=0.25.0",
29
+ "crawlee>=1.8.0,<2.0.0",
30
+ "websockets>=12.0",
31
+ "scrapely-client-python>=1.0.0,<2",
32
+ "pydantic>=2.0.0",
33
+ "cryptography>=42.0.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=8.0.0",
39
+ "pytest-asyncio>=1.0.0",
40
+ "black>=23.0.0",
41
+ "isort>=5.12.0",
42
+ "mypy>=1.0.0",
43
+ "playwright>=1.40.0",
44
+ "browserforge>=1.2.0",
45
+ ]
46
+
47
+
48
+ [project.urls]
49
+ Homepage = "https://scrape.ly"
50
+ Documentation = "https://docs.scrape.ly"
51
+ Repository = "https://github.com/SandeepDev1/scrapely"
52
+
53
+ [tool.setuptools.packages.find]
54
+ where = ["src"]
55
+
56
+ [tool.setuptools.package-data]
57
+ scrapely = ["py.typed"]
58
+
59
+ [tool.black]
60
+ line-length = 100
61
+ target-version = ["py311", "py312"]
62
+
63
+ [tool.isort]
64
+ profile = "black"
65
+ line_length = 100
66
+
67
+ [tool.mypy]
68
+ python_version = "3.11"
69
+ plugins = ["pydantic.mypy"]
70
+ warn_return_any = true
71
+ warn_unused_configs = true
72
+ disallow_untyped_defs = true
73
+ disallow_incomplete_defs = true
74
+ check_untyped_defs = true
75
+ disallow_untyped_decorators = true
76
+ no_implicit_optional = true
77
+ warn_redundant_casts = true
78
+ warn_unused_ignores = true
79
+ warn_no_return = true
80
+ warn_unreachable = true
81
+ strict_equality = true
82
+
83
+ [tool.pytest.ini_options]
84
+ asyncio_mode = "auto"
85
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,246 @@
1
+ """
2
+ Scrapely Python SDK - A toolkit for building Actors on the Scrapely platform.
3
+
4
+ Usage:
5
+ from scrapely import Actor, Dataset
6
+
7
+ async def main():
8
+ async with Actor:
9
+ actor_input = await Actor.get_input()
10
+ await Actor.push_data({'url': actor_input['url']})
11
+ """
12
+
13
+ # Side-effect: patch Crawlee Playwright browser pool to use remote CDP (CDP_URL).
14
+ # Must run on package import so `from scrapely import Actor` enables the patch
15
+ # before PlaywrightCrawler launches a browser (Node SDK parity).
16
+ from .patch_browser_pool import set_cdp_url # noqa: F401
17
+
18
+ from crawlee import Request
19
+
20
+ from crawlee.request_loaders import (
21
+ RequestLoader,
22
+ RequestManager,
23
+ RequestManagerTandem,
24
+ SitemapRequestLoader,
25
+ )
26
+ from crawlee.storages import Dataset, KeyValueStore, RequestQueue
27
+ from crawlee.storage_clients.models import DatasetItemsListPage
28
+
29
+ from .actor import Actor
30
+ from .configuration import Configuration
31
+ from .charging_client import (
32
+ USES_PUSH_DATA_INTERCEPTION,
33
+ create_charging_client,
34
+ push_data_charging_context,
35
+ )
36
+ from .storage import (
37
+ ApiStorageClient,
38
+ FileSystemStorageClient,
39
+ MemoryStorageClient,
40
+ ScrapelyStorageClient,
41
+ SmartScrapelyStorageClient,
42
+ StorageClient,
43
+ set_api_storage,
44
+ )
45
+ from .request_loaders import ScrapelyRequestList
46
+ from crawlee.events import EventListener
47
+ from .events import (
48
+ AbortingEvent,
49
+ ActorEventTypes,
50
+ CrawleeEventManager,
51
+ DeprecatedEvent,
52
+ Event,
53
+ EventAbortingData,
54
+ EventExitData,
55
+ EventManager,
56
+ EventMessage,
57
+ EventMigratingData,
58
+ EventPersistStateData,
59
+ EventSystemInfoData,
60
+ EventWithoutData,
61
+ ExitEvent,
62
+ LocalEventManager,
63
+ MigratingEvent,
64
+ PersistStateEvent,
65
+ ScrapelyEventManager,
66
+ SystemInfoEvent,
67
+ SystemInfoEventData,
68
+ UnknownEvent,
69
+ )
70
+ from .proxy_configuration import ProxyConfiguration
71
+ from .browser_configuration import BrowserConfiguration
72
+ from .charging import (
73
+ ChargingManager,
74
+ ChargeUncertainError,
75
+ ChargeRejectedError,
76
+ has_default_dataset_item_event_in_pricing,
77
+ is_default_dataset_item_event,
78
+ merge_charge_results,
79
+ push_data_and_charge,
80
+ resolve_default_dataset_item_event_name,
81
+ APIFY_DEFAULT_DATASET_ITEM_EVENT,
82
+ SCRAPELY_DEFAULT_DATASET_ITEM_EVENT,
83
+ DEFAULT_DATASET_ITEM_EVENT,
84
+ )
85
+
86
+ from .types import (
87
+ ActorInput,
88
+ ActorPermissionLevel,
89
+ ActorRun,
90
+ ApifyEnv,
91
+ AbortOptions,
92
+ CallOptions,
93
+ ExitOptions,
94
+ InitOptions,
95
+ MetamorphOptions,
96
+ OpenStorageOptions,
97
+ ProxyInfo,
98
+ RebootOptions,
99
+ RecordOptions,
100
+ SetStatusMessageOptions,
101
+ StartOptions,
102
+ WebhookOptions,
103
+ )
104
+
105
+ from .webhook import (
106
+ Webhook,
107
+ WebhookEventType,
108
+ )
109
+ from .pricing_types import (
110
+ PricingModel,
111
+ FreeActorPricingInfo,
112
+ FlatPricePerMonthActorPricingInfo,
113
+ PricePerDatasetItemActorPricingInfo,
114
+ PayPerEventActorPricingInfo,
115
+ PricingPerEvent,
116
+ ActorPricingInfo,
117
+ ActorChargeEvent,
118
+ ChargeResult,
119
+ ActorPricingInfoResult,
120
+ )
121
+ from .errors import (
122
+ ScrapelyClientError,
123
+ ScrapelyApiError,
124
+ InvalidResponseBodyError,
125
+ InvalidRequestError,
126
+ UnauthorizedError,
127
+ ForbiddenError,
128
+ NotFoundError,
129
+ ConflictError,
130
+ RateLimitError,
131
+ ServerError,
132
+ raise_for_status,
133
+ )
134
+
135
+ __version__ = '0.1.0'
136
+ __all__ = [
137
+ # Core
138
+ 'Actor',
139
+ 'Configuration',
140
+ 'set_cdp_url',
141
+ # ApifyClient
142
+ 'create_charging_client',
143
+ 'USES_PUSH_DATA_INTERCEPTION',
144
+ 'push_data_charging_context',
145
+
146
+ # Storage
147
+ 'Dataset',
148
+ 'KeyValueStore',
149
+ 'RequestQueue',
150
+ 'Request',
151
+ 'DatasetItemsListPage',
152
+ # Storage clients
153
+ 'ApiStorageClient',
154
+ 'ScrapelyStorageClient',
155
+ 'SmartScrapelyStorageClient',
156
+ 'FileSystemStorageClient',
157
+ 'MemoryStorageClient',
158
+ 'StorageClient',
159
+ 'set_api_storage',
160
+ # Request loaders
161
+ 'ScrapelyRequestList',
162
+ 'RequestLoader',
163
+ 'RequestManager',
164
+ 'RequestManagerTandem',
165
+ 'SitemapRequestLoader',
166
+ # Events
167
+ 'Event',
168
+ 'EventManager',
169
+ 'ScrapelyEventManager',
170
+ 'CrawleeEventManager',
171
+ 'LocalEventManager',
172
+ # Event data types
173
+ 'SystemInfoEventData',
174
+ 'EventAbortingData',
175
+ 'EventExitData',
176
+ 'EventListener',
177
+ 'EventMigratingData',
178
+ 'EventPersistStateData',
179
+ 'EventSystemInfoData',
180
+ # Event types
181
+ 'PersistStateEvent',
182
+ 'SystemInfoEvent',
183
+ 'MigratingEvent',
184
+ 'AbortingEvent',
185
+ 'ExitEvent',
186
+ 'EventWithoutData',
187
+ 'DeprecatedEvent',
188
+ 'UnknownEvent',
189
+ 'EventMessage',
190
+ 'ActorEventTypes',
191
+ # Proxy
192
+ 'ProxyConfiguration',
193
+ 'ProxyInfo',
194
+ # Remote browser
195
+ 'BrowserConfiguration',
196
+ # Charging
197
+ 'ChargingManager',
198
+ 'ChargeResult',
199
+ 'ChargeUncertainError',
200
+ 'ChargeRejectedError',
201
+ 'merge_charge_results',
202
+ 'push_data_and_charge',
203
+
204
+ # Types
205
+ 'ActorInput',
206
+ 'ActorPermissionLevel',
207
+ 'ActorRun',
208
+ 'ApifyEnv',
209
+ 'AbortOptions',
210
+ 'CallOptions',
211
+ 'ExitOptions',
212
+ 'InitOptions',
213
+ 'MetamorphOptions',
214
+ 'OpenStorageOptions',
215
+ 'RebootOptions',
216
+ 'RecordOptions',
217
+ 'SetStatusMessageOptions',
218
+ 'StartOptions',
219
+ 'WebhookOptions',
220
+
221
+ # Webhook
222
+ 'Webhook',
223
+ 'WebhookEventType',
224
+ # Pricing
225
+ 'PricingModel',
226
+ 'FreeActorPricingInfo',
227
+ 'FlatPricePerMonthActorPricingInfo',
228
+ 'PricePerDatasetItemActorPricingInfo',
229
+ 'PayPerEventActorPricingInfo',
230
+ 'PricingPerEvent',
231
+ 'ActorPricingInfo',
232
+ 'ActorChargeEvent',
233
+ 'ActorPricingInfoResult',
234
+ # Errors
235
+ 'ScrapelyClientError',
236
+ 'ScrapelyApiError',
237
+ 'InvalidResponseBodyError',
238
+ 'InvalidRequestError',
239
+ 'UnauthorizedError',
240
+ 'ForbiddenError',
241
+ 'NotFoundError',
242
+ 'ConflictError',
243
+ 'RateLimitError',
244
+ 'ServerError',
245
+ 'raise_for_status',
246
+ ]