scrapely-python 0.1.0__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.
Files changed (43) hide show
  1. scrapely/__init__.py +246 -0
  2. scrapely/_browser_locations.py +5470 -0
  3. scrapely/actor.py +1836 -0
  4. scrapely/browser_configuration.py +146 -0
  5. scrapely/charging.py +1143 -0
  6. scrapely/charging_client.py +107 -0
  7. scrapely/configuration.py +375 -0
  8. scrapely/crypto/__init__.py +21 -0
  9. scrapely/crypto/_secrets.py +210 -0
  10. scrapely/errors.py +153 -0
  11. scrapely/events/__init__.py +57 -0
  12. scrapely/events/_types.py +194 -0
  13. scrapely/events/event_manager.py +292 -0
  14. scrapely/log.py +39 -0
  15. scrapely/patch_browser_pool.py +861 -0
  16. scrapely/pricing_types.py +172 -0
  17. scrapely/proxy_configuration.py +741 -0
  18. scrapely/py.typed +2 -0
  19. scrapely/request_loaders/__init__.py +5 -0
  20. scrapely/request_loaders/_scrapely_request_list.py +169 -0
  21. scrapely/storage/__init__.py +48 -0
  22. scrapely/storage/_file_system/__init__.py +9 -0
  23. scrapely/storage/_file_system/_key_value_store_client.py +155 -0
  24. scrapely/storage/_file_system/_storage_client.py +50 -0
  25. scrapely/storage/_metadata.py +138 -0
  26. scrapely/storage/api_client.py +350 -0
  27. scrapely/storage/client.py +618 -0
  28. scrapely/storage/patch_storage.py +257 -0
  29. scrapely/storage/scrapely_dataset_client.py +305 -0
  30. scrapely/storage/scrapely_kvs_client.py +220 -0
  31. scrapely/storage/scrapely_rq_client.py +496 -0
  32. scrapely/storage/scrapely_storage_client.py +192 -0
  33. scrapely/storage/smart_scrapely_storage_client.py +109 -0
  34. scrapely/storage/types.py +601 -0
  35. scrapely/storage/utils.py +38 -0
  36. scrapely/storage_clients/__init__.py +25 -0
  37. scrapely/storages/__init__.py +5 -0
  38. scrapely/types.py +269 -0
  39. scrapely/webhook.py +82 -0
  40. scrapely_python-0.1.0.dist-info/METADATA +83 -0
  41. scrapely_python-0.1.0.dist-info/RECORD +43 -0
  42. scrapely_python-0.1.0.dist-info/WHEEL +5 -0
  43. scrapely_python-0.1.0.dist-info/top_level.txt +1 -0
scrapely/types.py ADDED
@@ -0,0 +1,269 @@
1
+ """
2
+ Type definitions for the Scrapely Python SDK.
3
+ """
4
+
5
+ from dataclasses import dataclass, field
6
+ from datetime import datetime
7
+ from enum import Enum
8
+ from typing import Any, Dict, List, Optional, Union
9
+
10
+ # Single source of truth for ChargeResult lives in pricing_types (pydantic model
11
+ # used by ChargingManager); re-exported here for backwards compatibility.
12
+ from .pricing_types import ChargeResult # noqa: F401 (re-export)
13
+
14
+
15
+ class ActorPermissionLevel(str, Enum):
16
+ """Actor permission level - matches Apify's ACTOR_PERMISSION_LEVEL enum."""
17
+ NONE = 'NONE'
18
+ RUN = 'RUN'
19
+ WRITE = 'WRITE'
20
+ ADMIN = 'ADMIN'
21
+
22
+
23
+ @dataclass
24
+ class ActorInput:
25
+ """Value types returned by Actor.get_input()."""
26
+ data: Dict[str, Any] = field(default_factory=dict)
27
+
28
+ def get(self, key: str, default: Any = None) -> Any:
29
+ return self.data.get(key, default)
30
+
31
+ def __getitem__(self, key: str) -> Any:
32
+ return self.data[key]
33
+
34
+ def __contains__(self, key: str) -> bool:
35
+ return key in self.data
36
+
37
+
38
+ @dataclass
39
+ class ApifyEnv:
40
+ """Parsed representation of the environment variables.
41
+
42
+ This object is returned by the Actor.get_env() function.
43
+ Fully compatible with Apify's ApifyEnv interface.
44
+
45
+ Supports both attribute access (env.memory_mbytes) and
46
+ dictionary-style subscript access (env['memory_mbytes']).
47
+ """
48
+ actor_id: Optional[str] = None
49
+ actor_build_id: Optional[str] = None
50
+ actor_build_number: Optional[str] = None
51
+ actor_build_tags: Optional[str] = None
52
+ actor_events_ws_url: Optional[str] = None
53
+ actor_full_name: Optional[str] = None
54
+ actor_max_paid_dataset_items: Optional[int] = None
55
+ actor_permission_level: Optional[ActorPermissionLevel] = None
56
+ actor_pricing_info: Optional[str] = None
57
+ actor_run_id: Optional[str] = None
58
+ actor_storages_json: Optional[str] = None
59
+ actor_task_id: Optional[str] = None
60
+ api_base_url: Optional[str] = None
61
+ api_public_base_url: Optional[str] = None
62
+ charged_event_counts: Optional[str] = None
63
+ chrome_executable_path: Optional[str] = None
64
+ container_port: Optional[int] = None
65
+ container_url: Optional[str] = None
66
+ dedicated_cpus: Optional[str] = None
67
+ default_dataset_id: Optional[str] = None
68
+ default_key_value_store_id: Optional[str] = None
69
+ default_request_queue_id: Optional[str] = None
70
+ disable_outdated_warning: Optional[int] = None
71
+ fact: Optional[str] = None
72
+ headless: Optional[str] = None
73
+ input_key: Optional[str] = None
74
+ input_secrets_private_key_file: Optional[str] = None
75
+ input_secrets_private_key_passphrase: Optional[str] = None
76
+ is_at_home: Optional[str] = None
77
+ local_storage_dir: Optional[str] = None
78
+ log_format: Optional[str] = None
79
+ log_level: Optional[str] = None
80
+ memory_mbytes: Optional[int] = None
81
+ meta_origin: Optional[str] = None
82
+ metamorph_after_sleep_millis: Optional[int] = None
83
+ persist_state_interval_millis: Optional[int] = None
84
+ proxy_hostname: Optional[str] = None
85
+ proxy_password: Optional[str] = None
86
+ proxy_port: Optional[str] = None
87
+ proxy_status_url: Optional[str] = None
88
+ purge_on_start: Optional[str] = None
89
+ sdk_latest_version: Optional[str] = None
90
+ started_at: Optional[datetime] = None
91
+ standby_port: Optional[int] = None
92
+ standby_url: Optional[str] = None
93
+ system_info_interval_millis: Optional[str] = None
94
+ timeout_at: Optional[datetime] = None
95
+ token: Optional[str] = None
96
+ user_id: Optional[str] = None
97
+ user_is_paying: Optional[str] = None
98
+ user_pricing_tier: Optional[str] = None
99
+ workflow_key: Optional[str] = None
100
+ xvfb: Optional[str] = None
101
+ # Scrapely extensions / ACTOR_* extras
102
+ max_total_charge_usd: Optional[float] = None
103
+ user_plan: Optional[str] = None
104
+ restart_on_error: Optional[str] = None
105
+
106
+
107
+ def __getitem__(self, key: str) -> Any:
108
+ """Enable dictionary-style access: env['memory_mbytes']."""
109
+ return getattr(self, key)
110
+
111
+ def __setitem__(self, key: str, value: Any) -> None:
112
+ """Enable dictionary-style assignment: env['memory_mbytes'] = 1024."""
113
+ setattr(self, key, value)
114
+
115
+ def keys(self) -> List[str]:
116
+ """Return all field names that have values set (non-None)."""
117
+ return [f.name for f in self.__dataclass_fields__.values()
118
+ if getattr(self, f.name) is not None]
119
+
120
+
121
+ @dataclass
122
+ class WebhookOptions:
123
+ """Options for Actor.add_webhook()."""
124
+ event_types: List[str] = field(default_factory=list)
125
+ request_url: str = ''
126
+ payload_template: Optional[str] = None
127
+ idempotency_key: Optional[str] = None
128
+ headers_template: Optional[str] = None
129
+ description: Optional[str] = None
130
+ ignore_ssl_errors: bool = False
131
+ do_not_retry: bool = False
132
+ should_interpolate_strings: bool = False
133
+ is_apify_integration: bool = False
134
+
135
+
136
+ @dataclass
137
+ class InitOptions:
138
+ """Options for Actor.init()."""
139
+ configuration: Optional[Dict[str, Any]] = None
140
+ # ApiStorageConfig dict or a Crawlee StorageClient (tests / custom)
141
+ storage: Optional[Any] = None
142
+ graceful_shutdown: bool = True
143
+ graceful_shutdown_delay_millis: int = 0
144
+ # Set up the default log output (Apify Actor(configure_logging=True) parity)
145
+ configure_logging: bool = True
146
+
147
+
148
+ @dataclass
149
+ class ExitOptions:
150
+ """Options for Actor.exit()."""
151
+ status_message: Optional[str] = None
152
+ timeout_secs: int = 30
153
+ exit_code: int = 0
154
+ exit: bool = True
155
+
156
+
157
+ @dataclass
158
+ class RecordOptions:
159
+ """Options for Actor.set_value() / KeyValueStore.set_value()."""
160
+ content_type: Optional[str] = None
161
+ do_not_retry_timeouts: bool = False
162
+ timeout_secs: Optional[int] = None
163
+
164
+
165
+ @dataclass
166
+ class SetStatusMessageOptions:
167
+ """Options for Actor.set_status_message()."""
168
+ is_status_message_terminal: bool = False
169
+ level: str = 'INFO' # 'DEBUG', 'INFO', 'WARNING', 'ERROR'
170
+
171
+
172
+ @dataclass
173
+ class MetamorphOptions:
174
+ """Options for Actor.metamorph()."""
175
+ build: Optional[str] = None
176
+
177
+
178
+ @dataclass
179
+ class RebootOptions:
180
+ """Options for Actor.reboot()."""
181
+ custom_after_sleep_millis: Optional[int] = None
182
+
183
+
184
+ @dataclass
185
+ class OpenStorageOptions:
186
+ """Options for Actor.open_dataset(), open_key_value_store(), and open_request_queue()."""
187
+ force_cloud: bool = False
188
+ config: Optional[Any] = None
189
+
190
+
191
+ @dataclass
192
+ class CallOptions:
193
+ """Options for Actor.call() / Actor.call_task()."""
194
+ token: Optional[str] = None
195
+ build: Optional[str] = None
196
+ max_total_charge_usd: Optional[float] = None
197
+ restart_on_error: Optional[bool] = None
198
+ memory_mbytes: Optional[int] = None
199
+ timeout: Optional[Union[int, str]] = None # number or 'inherit'
200
+ force_permission_level: Optional[ActorPermissionLevel] = None
201
+ webhooks: Optional[List[WebhookOptions]] = None
202
+
203
+
204
+ @dataclass
205
+ class StartOptions:
206
+ """Options for Actor.start()."""
207
+ token: Optional[str] = None
208
+ build: Optional[str] = None
209
+ max_total_charge_usd: Optional[float] = None
210
+ restart_on_error: Optional[bool] = None
211
+ memory_mbytes: Optional[int] = None
212
+ timeout: Optional[Union[int, str]] = None # number or 'inherit'
213
+ force_permission_level: Optional[ActorPermissionLevel] = None
214
+ webhooks: Optional[List[WebhookOptions]] = None
215
+
216
+
217
+ @dataclass
218
+ class AbortOptions:
219
+ """Options for Actor.abort()."""
220
+ token: Optional[str] = None
221
+ status_message: Optional[str] = None
222
+ gracefully: Optional[bool] = None
223
+
224
+
225
+ @dataclass
226
+ class ActorRun:
227
+ """Information about an Actor run."""
228
+ id: str
229
+ actor_id: str
230
+ status: str
231
+ started_at: Optional[datetime] = None
232
+ finished_at: Optional[datetime] = None
233
+ duration_millis: Optional[int] = None
234
+ build_id: Optional[str] = None
235
+ build_number: Optional[str] = None
236
+ default_dataset_id: Optional[str] = None
237
+ default_key_value_store_id: Optional[str] = None
238
+ default_request_queue_id: Optional[str] = None
239
+ exit_code: Optional[int] = None
240
+ status_message: Optional[str] = None
241
+ input: Optional[Dict[str, Any]] = None
242
+ output: Optional[Dict[str, Any]] = None
243
+ usage_total_usd: Optional[float] = None
244
+ usage: Optional[Dict[str, Any]] = None
245
+
246
+
247
+ @dataclass
248
+ class ProxyInfo:
249
+ """Information about a proxy configuration.
250
+
251
+ Compatible with crawlee's ProxyInfo to support crawlee's _basic_crawler.py
252
+ which calls proxy_configuration.new_proxy_info(request=..., session=...).
253
+ """
254
+ url: str
255
+ scheme: str # Required by crawlee
256
+ hostname: str
257
+ port: int
258
+ username: str = ''
259
+ password: str = ''
260
+ session_id: Optional[str] = None # Required by crawlee
261
+ proxy_tier: Optional[int] = None # Required by crawlee
262
+ groups: List[str] = field(default_factory=list)
263
+ country_code: Optional[str] = None
264
+ subdivision_code: Optional[str] = None
265
+
266
+
267
+ # Type aliases
268
+ Dictionary = Dict[str, Any]
269
+ JsonValue = Union[None, bool, int, float, str, List['JsonValue'], Dict[str, 'JsonValue']]
scrapely/webhook.py ADDED
@@ -0,0 +1,82 @@
1
+ """
2
+ Webhook types for the Scrapely Python SDK.
3
+
4
+ This module defines the Webhook class and related types for creating
5
+ ad-hoc webhooks on the Scrapely platform.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from enum import Enum
12
+ from typing import Any, Dict, List, Optional
13
+
14
+
15
+ class WebhookEventType(str, Enum):
16
+ """Event types that can trigger a webhook."""
17
+ ACTOR_RUN_CREATED = 'ACTOR.RUN.CREATED'
18
+ ACTOR_RUN_SUCCEEDED = 'ACTOR.RUN.SUCCEEDED'
19
+ ACTOR_RUN_FAILED = 'ACTOR.RUN.FAILED'
20
+ ACTOR_RUN_ABORTED = 'ACTOR.RUN.ABORTED'
21
+ ACTOR_RUN_TIMED_OUT = 'ACTOR.RUN.TIMED_OUT'
22
+
23
+
24
+ @dataclass
25
+ class Webhook:
26
+ """An Apify webhook definition used by the Actor SDK.
27
+
28
+ The same instance can be passed as an ad-hoc webhook to Actor.start() / Actor.call(),
29
+ or to Actor.add_webhook(), which registers it as an ad-hoc webhook for the current run
30
+ (the condition.actor_run_id is set automatically).
31
+ """
32
+
33
+ event_types: List[WebhookEventType]
34
+ request_url: str
35
+ payload_template: Optional[str] = None
36
+ headers_template: Optional[str] = None
37
+ idempotency_key: Optional[str] = None
38
+ do_not_retry: Optional[bool] = None
39
+ ignore_ssl_errors: Optional[bool] = None
40
+ # Server-assigned identifier, populated by Actor.add_webhook() / the API.
41
+ id: Optional[str] = None
42
+
43
+ def __post_init__(self) -> None:
44
+ """Validate the webhook after initialization."""
45
+ if not self.event_types:
46
+ raise ValueError('At least one event type must be specified')
47
+ if not self.request_url:
48
+ raise ValueError('Request URL must be specified')
49
+
50
+ def to_dict(self, actor_run_id: Optional[str] = None) -> Dict[str, Any]:
51
+ """Convert webhook to dictionary for API calls.
52
+
53
+ Args:
54
+ actor_run_id: Optional run ID to bind the webhook to.
55
+
56
+ Returns:
57
+ Dictionary representation for the API.
58
+ """
59
+ result: Dict[str, Any] = {
60
+ 'eventTypes': [e.value for e in self.event_types],
61
+ 'requestUrl': self.request_url,
62
+ }
63
+
64
+ if self.payload_template:
65
+ result['payloadTemplate'] = self.payload_template
66
+ if self.headers_template:
67
+ result['headersTemplate'] = self.headers_template
68
+ if self.idempotency_key:
69
+ result['idempotencyKey'] = self.idempotency_key
70
+ if self.do_not_retry is not None:
71
+ result['doNotRetry'] = self.do_not_retry
72
+ if self.ignore_ssl_errors is not None:
73
+ result['ignoreSslErrors'] = self.ignore_ssl_errors
74
+
75
+ # Add condition for the current run
76
+ if actor_run_id:
77
+ result['condition'] = {'actorRunId': actor_run_id}
78
+
79
+ return result
80
+
81
+
82
+ __all__ = ['Webhook', 'WebhookEventType']
@@ -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,43 @@
1
+ scrapely/__init__.py,sha256=EqZTSyL6fkCFXkbp2iej7Umi6y_F19aC7MqxOaUbB68,5745
2
+ scrapely/_browser_locations.py,sha256=8QVVnkms2bDn3_LDYgYDR59MvFx8757l_JYnZ7xb3oI,145269
3
+ scrapely/actor.py,sha256=WzvD7gvCKRMyIN_Ei_I-MfIBL7Darn_B40GQJIgAn04,74960
4
+ scrapely/browser_configuration.py,sha256=jAZapNSHLFW05B96df4wNBtcyiiU9DA3ml0yTL1FwfA,5770
5
+ scrapely/charging.py,sha256=ckqsGbGuzpdw5PgEt6Apx3cwR46sA8V2WwUDSqSSfz8,46887
6
+ scrapely/charging_client.py,sha256=tDtlPwLSVFvoRa2NBgNjyfHkAUM77SSIyYT2ACgpDm8,3710
7
+ scrapely/configuration.py,sha256=YUnbft9JeWlVTgWalr-CgJCiyJ_e_rgoQItVPvjeWRs,15406
8
+ scrapely/errors.py,sha256=DCAlVvE3jToZuPEG2HVDL7i8D8hLboomQ5JpSOcsXoQ,4107
9
+ scrapely/log.py,sha256=iVKoQdMLQXEWz1STzbSXrNUxsS_FNwiIdqoEg7CzeqU,1440
10
+ scrapely/patch_browser_pool.py,sha256=sRAjuzKoOEgn0X8695c_9qioRALzkTWXoDlorVnK9jg,37426
11
+ scrapely/pricing_types.py,sha256=J6wCddZd-U1MYeOtaaEdeHSsp1HBgiQLfvSInBOvhIo,5305
12
+ scrapely/proxy_configuration.py,sha256=lvfOvuR8tOE9uiMOS_nw6TEj11xy7GYGa56iYvPwtmA,34654
13
+ scrapely/py.typed,sha256=XtWlywqUjc6x_M2gAXlDtYXbAsYkCjKZEjFyJvaHvm4,105
14
+ scrapely/types.py,sha256=ceVuHvhYbPai2CL3vFmXLTMoGaMR27IefJFgWhzd7ws,8900
15
+ scrapely/webhook.py,sha256=4WOM42ypOSOs4lKtP5ofxAh6lX-7c8p5U9lOfuFzx-g,2830
16
+ scrapely/crypto/__init__.py,sha256=MbMPs7Eq_fGSVjOZxNts_JckDCUtxCVqdkHU0VCfN4M,481
17
+ scrapely/crypto/_secrets.py,sha256=-ETpq1yCMaW-mheTGedFaQGGhu_pGT9_VMdJ3--V1rk,7614
18
+ scrapely/events/__init__.py,sha256=8vbbxxqkV0DrQicvFkwFwacUzi96XeW-b6KQzpUBuSM,1239
19
+ scrapely/events/_types.py,sha256=UHNP1dVVG0geJqhlhivQHK00nErYJ0gaQ-PxuGBujXo,5754
20
+ scrapely/events/event_manager.py,sha256=CiI-Fiw0vaKx1iGEiXRG9Df08WDgwFDOT-DX3IIHZJg,12521
21
+ scrapely/request_loaders/__init__.py,sha256=aNgr4pRt3MziUbU6UQ_bjTT3moMNvvyUsPeCJyMQcwU,196
22
+ scrapely/request_loaders/_scrapely_request_list.py,sha256=cq7xx7Ai4qOhcqGV2TLqPR3o53FPCPKpVxWEMw5qKaM,7367
23
+ scrapely/storage/__init__.py,sha256=diAhxEvOXjc3YVhZvzkO3MttJUXQWJ5ogxstiApsh7U,1405
24
+ scrapely/storage/_metadata.py,sha256=WWawBnVN0b1iK2K-SlxZXUc6czb5wXWf8iC_0tzkgAQ,4764
25
+ scrapely/storage/api_client.py,sha256=wrRxQ8h4jKdWY50HI0gXS-XHaFpzWPbVyLQ1nOYnsnA,11305
26
+ scrapely/storage/client.py,sha256=M3o_a_9azHNn6eL_UyEeVz-VQJvnT_th1HJPuCA4PkE,21746
27
+ scrapely/storage/patch_storage.py,sha256=o3Fv0BByeZ1T9HhkzhY6bjolOFsIQcnqBoHq1EdG8Fw,8758
28
+ scrapely/storage/scrapely_dataset_client.py,sha256=gRvlCDw9c0yO5GE5LQOa1xAyXc9pnb-E37Eq7fHqHCM,10338
29
+ scrapely/storage/scrapely_kvs_client.py,sha256=ItQhe2rcSl20NkSmegfqHiRyKncH4Qg9BjQVpF6jHfk,7403
30
+ scrapely/storage/scrapely_rq_client.py,sha256=0MoLZSIlzdqaQW_wypraVmHIsQimf_fV4-LCA_lLKJc,18601
31
+ scrapely/storage/scrapely_storage_client.py,sha256=N-p2ISICuKQ8RNzmN-JiXcj_lTttULLOGl9lpLl62qI,6567
32
+ scrapely/storage/smart_scrapely_storage_client.py,sha256=OipItBvlDz83_5ctQirdC8yRSv321d_nrZTqReTwmOU,4245
33
+ scrapely/storage/types.py,sha256=7eC9tL_eiEL2neaK_Ri1VZ0aolrvHlkhwgW9HZ94z64,20844
34
+ scrapely/storage/utils.py,sha256=ngFWCNM48Kx6tdsvR05Pl3iWgiNPwTL3YlEpeRBm57w,1425
35
+ scrapely/storage/_file_system/__init__.py,sha256=dSJ28uDrA--dz6e-vqk7MpE2nYOsXVjkzIlmGvoHTZ8,318
36
+ scrapely/storage/_file_system/_key_value_store_client.py,sha256=4Ipgbh4qEqAkwQJ9fXTujFR0Uu4nsw_7jvX6UkIk-Is,6094
37
+ scrapely/storage/_file_system/_storage_client.py,sha256=aaGJ4P0QAtIgEMl6yHpuobeWFD5M4rMC5HwhOOvuGuo,1794
38
+ scrapely/storage_clients/__init__.py,sha256=cs1YX7JV2_GKBXeiiJgkQFali08b5_y_jH6Yw7iROAA,656
39
+ scrapely/storages/__init__.py,sha256=4PAELhJNZ3exJ7Uouicn-bCQ58NafKjhLBixQ8ATQc4,173
40
+ scrapely_python-0.1.0.dist-info/METADATA,sha256=AbI8nacnK9KwHjwfREv7B3uBfSMnFQuFpyzwaU-33Ag,3137
41
+ scrapely_python-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
42
+ scrapely_python-0.1.0.dist-info/top_level.txt,sha256=T4B9UMrs4q99QSAFyD1zdXhl40KnLhBKqrDkPhOTsmY,9
43
+ scrapely_python-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ scrapely