scrapely-python 0.1.26__py3-none-any.whl → 0.1.28__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.
scrapely/__init__.py CHANGED
@@ -19,7 +19,7 @@ from typing import TYPE_CHECKING, Any
19
19
  # the Crawlee patches are applied when Crawlee's browser modules load.
20
20
  from .patch_browser_pool import set_cdp_url # noqa: F401
21
21
 
22
- # Crawlee is NOT imported here: it costs ~1 s per run under gVisor and many
22
+ # Crawlee is NOT imported here: it costs ~1 s per run on the platform and many
23
23
  # actors never touch it. Everything that needs Crawlee (the re-exported Crawlee
24
24
  # classes, storage clients, events, request loaders) is resolved on first
25
25
  # attribute access by ``__getattr__`` below; ``Actor`` imports what it needs on
@@ -227,7 +227,7 @@ if TYPE_CHECKING: # Static analysers and IDEs see the lazy names as plain impor
227
227
  set_api_storage,
228
228
  )
229
229
 
230
- __version__ = '0.1.26'
230
+ __version__ = '0.1.28'
231
231
  __all__ = [
232
232
  # Core
233
233
  'Actor',
scrapely/actor.py CHANGED
@@ -68,7 +68,7 @@ if TYPE_CHECKING:
68
68
  logger = logging.getLogger(__name__)
69
69
 
70
70
  # Names that need Crawlee, resolved on first use instead of at import: importing
71
- # Crawlee costs ~1 s per run under gVisor. They stay module attributes
71
+ # Crawlee costs ~1 s per run on the platform. They stay module attributes
72
72
  # (``scrapely.actor.Dataset`` works and can be monkeypatched): ``_lazy`` returns
73
73
  # the module-global value when one is set, else imports and caches it.
74
74
  _LAZY_ATTRS: Dict[str, Tuple[str, str]] = {
@@ -27,10 +27,10 @@ Mirrors the Node SDK ``patch-browser-pool.ts``:
27
27
  - Unpatched builds (``SCRAPELY_BROWSER_PATCH=0``, set by the worker when the
28
28
  actor's browser patch was off at build time) keep their browser binaries:
29
29
  every patched entry point falls through to the original local launch, with
30
- gVisor-safe Chromium args under ``SCRAPELY_CONTAINER_RUNTIME=runsc``.
30
+ sandbox-safe Chromium args when running on the platform.
31
31
  - Soft no-op when Playwright/Crawlee browsers are not installed (e.g. HTTP-only
32
32
  actors).
33
- - Crawlee is never imported by this module (it costs ~1 s under gVisor). The
33
+ - Crawlee is never imported by this module (it costs ~1 s on the platform). The
34
34
  Crawlee patches are applied at once when Crawlee's browser / Playwright
35
35
  crawler modules are already loaded, otherwise by a post-import hook the
36
36
  moment those modules finish loading — before actor code can use the classes.
@@ -121,8 +121,8 @@ def _browser_patch_disabled() -> bool:
121
121
  return os.environ.get('SCRAPELY_BROWSER_PATCH') == '0'
122
122
 
123
123
 
124
- # gVisor lacks crashpad support; ReadonlyRootfs + tmpfs /tmp loses crash dirs.
125
- _GVISOR_CHROME_ARGS = (
124
+ # Platform sandbox: no crash reporter; read-only rootfs + tmpfs /tmp loses crash dirs.
125
+ _SANDBOX_CHROME_ARGS = (
126
126
  '--disable-breakpad',
127
127
  '--disable-crash-reporter',
128
128
  '--disable-dev-shm-usage',
@@ -130,13 +130,13 @@ _GVISOR_CHROME_ARGS = (
130
130
  )
131
131
 
132
132
 
133
- def _with_gvisor_args(options: Optional[dict]) -> dict:
134
- """Copy of launch options with gVisor-safe Chromium args when under runsc."""
133
+ def _with_sandbox_args(options: Optional[dict]) -> dict:
134
+ """Copy of launch options with sandbox-safe Chromium args when on the platform."""
135
135
  out = dict(options or {})
136
- if os.environ.get('SCRAPELY_CONTAINER_RUNTIME') != 'runsc':
136
+ if not _is_at_home():
137
137
  return out
138
138
  args = list(out.get('args') or [])
139
- for arg in _GVISOR_CHROME_ARGS:
139
+ for arg in _SANDBOX_CHROME_ARGS:
140
140
  if arg not in args:
141
141
  args.append(arg)
142
142
  out['args'] = args
@@ -678,7 +678,7 @@ def _patch_raw_browser_type(browser_type: Any, chromium: Any, name: str, is_asyn
678
678
  async def launch(**kwargs: Any) -> Any:
679
679
  browser_configuration = _take_browser_configuration(kwargs)
680
680
  if _browser_patch_disabled():
681
- return await orig_launch(**_with_gvisor_args(kwargs))
681
+ return await orig_launch(**_with_sandbox_args(kwargs))
682
682
  cdp_url = _raw_launch_cdp_url(kwargs, browser_configuration)
683
683
  if not cdp_url:
684
684
  if not _is_at_home():
@@ -691,7 +691,7 @@ def _patch_raw_browser_type(browser_type: Any, chromium: Any, name: str, is_asyn
691
691
  async def launch_persistent_context(*args: Any, **kwargs: Any) -> Any:
692
692
  browser_configuration = _take_browser_configuration(kwargs)
693
693
  if _browser_patch_disabled():
694
- return await orig_lpc(*args, **_with_gvisor_args(kwargs))
694
+ return await orig_lpc(*args, **_with_sandbox_args(kwargs))
695
695
  cdp_url = _raw_launch_cdp_url(kwargs, browser_configuration)
696
696
  if not cdp_url:
697
697
  if not _is_at_home():
@@ -710,7 +710,7 @@ def _patch_raw_browser_type(browser_type: Any, chromium: Any, name: str, is_asyn
710
710
  def launch(**kwargs: Any) -> Any:
711
711
  browser_configuration = _take_browser_configuration(kwargs)
712
712
  if _browser_patch_disabled():
713
- return orig_launch(**_with_gvisor_args(kwargs))
713
+ return orig_launch(**_with_sandbox_args(kwargs))
714
714
  cdp_url = _raw_launch_cdp_url(kwargs, browser_configuration)
715
715
  if not cdp_url:
716
716
  if not _is_at_home():
@@ -722,7 +722,7 @@ def _patch_raw_browser_type(browser_type: Any, chromium: Any, name: str, is_asyn
722
722
  def launch_persistent_context(*args: Any, **kwargs: Any) -> Any:
723
723
  browser_configuration = _take_browser_configuration(kwargs)
724
724
  if _browser_patch_disabled():
725
- return orig_lpc(*args, **_with_gvisor_args(kwargs))
725
+ return orig_lpc(*args, **_with_sandbox_args(kwargs))
726
726
  cdp_url = _raw_launch_cdp_url(kwargs, browser_configuration)
727
727
  if not cdp_url:
728
728
  if not _is_at_home():
@@ -847,7 +847,7 @@ def _apply_pyppeteer_patch() -> None:
847
847
  options = dict(options)
848
848
  browser_configuration = _take_browser_configuration(options) or browser_configuration
849
849
  if _browser_patch_disabled():
850
- return await _orig_launch(_with_gvisor_args({**(options or {}), **kwargs}))
850
+ return await _orig_launch(_with_sandbox_args({**(options or {}), **kwargs}))
851
851
  cdp_url = get_cdp_url()
852
852
  if not cdp_url:
853
853
  if not _is_at_home():
@@ -876,7 +876,7 @@ def _apply_pyppeteer_patch() -> None:
876
876
 
877
877
  # ─── Crawlee patches without importing Crawlee ───────────────────────────────
878
878
  #
879
- # Importing Crawlee costs ~1 s per run under gVisor, so this module never
879
+ # Importing Crawlee costs ~1 s per run on the platform, so this module never
880
880
  # imports it. The Crawlee patches mutate classes in place, so they only have to
881
881
  # run before actor code uses those classes: they are applied immediately when
882
882
  # the defining modules are already loaded, otherwise by a post-import hook the
scrapely/solver.py CHANGED
@@ -88,7 +88,7 @@ DEGRADED_STATUS_MESSAGE = "Site protection temporarily unavailable, results may
88
88
  # Codes the platform answers with when a vendor cannot be solved right now.
89
89
  UNAVAILABLE_CODES = ("vendor_degraded", "vendor_down", "provider_unavailable", "vendor_unsupported", "solver_not_enabled")
90
90
 
91
- _COMPAT_SUFFIXES = ("/compat/v1", "/compat/xhrdev")
91
+ _COMPAT_SUFFIXES = ("/compat/v1",)
92
92
  _STATUS_TTL_SECS = 15.0
93
93
  _MAX_BODY = 4 * 1024 * 1024
94
94
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scrapely-python
3
- Version: 0.1.26
3
+ Version: 0.1.28
4
4
  Summary: Scrapely Python SDK - A toolkit for building Actors on the Scrapely platform
5
5
  Author-email: Scrapely <support@scrape.ly>
6
6
  License-Expression: MIT AND Apache-2.0
@@ -1,6 +1,6 @@
1
- scrapely/__init__.py,sha256=z-CyEPAlCd07V32Wnv8bNeSubMhXAuoejvSW7-XG4co,9661
1
+ scrapely/__init__.py,sha256=xBnYBJZQ88Yr59AVLs7QO2rAUt7cDT0AzK8VgnyQ-Vs,9664
2
2
  scrapely/_browser_locations.py,sha256=8QVVnkms2bDn3_LDYgYDR59MvFx8757l_JYnZ7xb3oI,145269
3
- scrapely/actor.py,sha256=1SBHZYBRLmU4k_erjKL7yRfP0EgR7ZKXefAK8wWKRz0,88004
3
+ scrapely/actor.py,sha256=CBdphCMl6zf72br8if8zcFIXsiXgDa0-VYrWuOTWgs4,88007
4
4
  scrapely/browser_configuration.py,sha256=jAZapNSHLFW05B96df4wNBtcyiiU9DA3ml0yTL1FwfA,5770
5
5
  scrapely/cdp_retry.py,sha256=hdTJEAIKhApM7IOk1DrQEl8NoflSJSmqd4RbNJ2IsgI,8540
6
6
  scrapely/charging.py,sha256=ns-kuUJtl8hBI4-3iBisC62BggJG67yYOa1yVVItoUI,83800
@@ -8,11 +8,11 @@ scrapely/charging_client.py,sha256=-4q-Ww7gu9EZXpM9QIn1Vd4vwAXmgL_WEKqaQIx3ViA,3
8
8
  scrapely/configuration.py,sha256=Of-lKm7hoPGUQO8d08kV7fAy2co9QTfb8Of_8ds5PSA,17028
9
9
  scrapely/errors.py,sha256=DCAlVvE3jToZuPEG2HVDL7i8D8hLboomQ5JpSOcsXoQ,4107
10
10
  scrapely/log.py,sha256=iVKoQdMLQXEWz1STzbSXrNUxsS_FNwiIdqoEg7CzeqU,1440
11
- scrapely/patch_browser_pool.py,sha256=R-1QDKa-ZvfdQ9wgyA8JCtmQqD9v7dOsaCZnSUoyf7U,42214
11
+ scrapely/patch_browser_pool.py,sha256=eZck-JSOvCuXdoGQaX6xUsKVGzolDlB4uKiBSBrFyr8,42190
12
12
  scrapely/pricing_types.py,sha256=J6wCddZd-U1MYeOtaaEdeHSsp1HBgiQLfvSInBOvhIo,5305
13
13
  scrapely/proxy_configuration.py,sha256=mQhUjXnqM1PcUrnRmXxVWdLnlaRlb8Je4K2j54lC6YQ,38129
14
14
  scrapely/py.typed,sha256=XtWlywqUjc6x_M2gAXlDtYXbAsYkCjKZEjFyJvaHvm4,105
15
- scrapely/solver.py,sha256=QO7sl_M5AbXRqmCzUowNWG2kBHoXoH7CgtYwAdp36VM,35880
15
+ scrapely/solver.py,sha256=RVoLNJTxniTI5SzDRpUdxe0ajzy4qqjuEmToTL1GRzA,35863
16
16
  scrapely/types.py,sha256=ceVuHvhYbPai2CL3vFmXLTMoGaMR27IefJFgWhzd7ws,8900
17
17
  scrapely/webhook.py,sha256=4WOM42ypOSOs4lKtP5ofxAh6lX-7c8p5U9lOfuFzx-g,2830
18
18
  scrapely/crypto/__init__.py,sha256=MbMPs7Eq_fGSVjOZxNts_JckDCUtxCVqdkHU0VCfN4M,481
@@ -39,10 +39,10 @@ scrapely/storage/_file_system/_key_value_store_client.py,sha256=4Ipgbh4qEqAkwQJ9
39
39
  scrapely/storage/_file_system/_storage_client.py,sha256=aaGJ4P0QAtIgEMl6yHpuobeWFD5M4rMC5HwhOOvuGuo,1794
40
40
  scrapely/storage_clients/__init__.py,sha256=cs1YX7JV2_GKBXeiiJgkQFali08b5_y_jH6Yw7iROAA,656
41
41
  scrapely/storages/__init__.py,sha256=4PAELhJNZ3exJ7Uouicn-bCQ58NafKjhLBixQ8ATQc4,173
42
- scrapely_python-0.1.26.dist-info/licenses/LICENSE,sha256=pQGY0XwjIYh-a2HfawxHq1en53bXkFkDj2Q70jKWHr4,1088
43
- scrapely_python-0.1.26.dist-info/licenses/LICENSE-APACHE,sha256=N8m0FzMq8i4UbTgXZvKEZJSD-27OF8pWZYS_atz4kTU,11355
44
- scrapely_python-0.1.26.dist-info/licenses/NOTICE,sha256=DEsNrw6UdSIqdYYqMWVFgJnyt6jUivTD7iFU6YM_e1A,1122
45
- scrapely_python-0.1.26.dist-info/METADATA,sha256=mag9UA_ijOHkoBHTTvSWq2Nai46Okg-M-wkW0aAO-Hk,3487
46
- scrapely_python-0.1.26.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
47
- scrapely_python-0.1.26.dist-info/top_level.txt,sha256=T4B9UMrs4q99QSAFyD1zdXhl40KnLhBKqrDkPhOTsmY,9
48
- scrapely_python-0.1.26.dist-info/RECORD,,
42
+ scrapely_python-0.1.28.dist-info/licenses/LICENSE,sha256=pQGY0XwjIYh-a2HfawxHq1en53bXkFkDj2Q70jKWHr4,1088
43
+ scrapely_python-0.1.28.dist-info/licenses/LICENSE-APACHE,sha256=N8m0FzMq8i4UbTgXZvKEZJSD-27OF8pWZYS_atz4kTU,11355
44
+ scrapely_python-0.1.28.dist-info/licenses/NOTICE,sha256=DEsNrw6UdSIqdYYqMWVFgJnyt6jUivTD7iFU6YM_e1A,1122
45
+ scrapely_python-0.1.28.dist-info/METADATA,sha256=J4RQA1RzD7fF1MbOd1NnJCPPAP79ZPJJuBkdKIUZ6E8,3487
46
+ scrapely_python-0.1.28.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
47
+ scrapely_python-0.1.28.dist-info/top_level.txt,sha256=T4B9UMrs4q99QSAFyD1zdXhl40KnLhBKqrDkPhOTsmY,9
48
+ scrapely_python-0.1.28.dist-info/RECORD,,