scrapely-python 0.1.33__tar.gz → 0.1.35__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.
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/CHANGELOG.md +9 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/PKG-INFO +1 -1
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/pyproject.toml +1 -1
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/__init__.py +1 -1
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/actor.py +96 -7
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/PKG-INFO +1 -1
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/LICENSE +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/LICENSE-APACHE +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/MANIFEST.in +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/NOTICE +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/README.md +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/setup.cfg +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/_browser_locations.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/browser_configuration.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/cdp_retry.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/charging.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/charging_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/configuration.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/crypto/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/crypto/_secrets.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/errors.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/events/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/events/_types.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/events/event_manager.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/log.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/patch_browser_pool.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/pricing_types.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/proxy_configuration.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/py.typed +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/request_loaders/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/request_loaders/_scrapely_request_list.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/_actor_runner.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/_async_thread.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/_logging_config.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/_serialization.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/_warnings.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/_graceful_stop.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/_httpcache.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/middlewares/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/middlewares/apify_proxy.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/pipelines/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/pipelines/actor_dataset_push.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/requests.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/scheduler.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/utils.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/solver.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/_file_system/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/_file_system/_key_value_store_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/_file_system/_storage_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/_metadata.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/api_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/patch_storage.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_dataset_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_kvs_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_rq_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_storage_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/smart_scrapely_storage_client.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/types.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/utils.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage_clients/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storages/__init__.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/types.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/webhook.py +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/SOURCES.txt +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/dependency_links.txt +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/requires.txt +0 -0
- {scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/top_level.txt +0 -0
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.1.35] - 2026-10-26
|
|
6
|
+
|
|
7
|
+
- Once `Actor.fail()` has run, the run stays failed. A later `Actor.exit()` keeps the failure's exit code and status message, so the usual `try: ... await Actor.fail(...) finally: await Actor.exit()` pattern now ends the run as FAILED. Before, the `exit()` in `finally` replaced the failure's exit code 1 with 0 and the run ended as SUCCEEDED with the failure message as its status. The same holds after `fail()` whose `SystemExit` was caught, after `fail(ExitOptions(exit=False))` (also inside `async with Actor(...)` and `Actor.main()`), and for a second `fail()`, which keeps the first failure's code and message.
|
|
8
|
+
- `Actor.fail(ExitOptions(...))` without an exit code exits with 1. `ExitOptions` defaults `exit_code` to 0, which made such a failure exit with 0. A non-zero `exit_code` in the options, or an explicit `exit_code=` keyword, still wins.
|
|
9
|
+
|
|
10
|
+
## [0.1.34] - 2026-10-23
|
|
11
|
+
|
|
12
|
+
- Debug captures (`Actor.debug_capture`, `Actor.debug_capture_sync`) store parsed XML/HTML elements as their markup instead of a repr such as `<Element 'change' at 0x...>`: `xml.etree.ElementTree` elements and trees, lxml elements and trees, BeautifulSoup tags, selectolax nodes and parsel / Scrapy selectors, passed alone or inside a dict or list. The text after an element (its tail) is not included. Other objects are still stored as their `str()`. Captures are only active on the platform's own diagnostic runs (`SCRAPELY_DEBUG_CAPTURE=1`).
|
|
13
|
+
|
|
5
14
|
## [0.1.33] - 2026-10-22
|
|
6
15
|
|
|
7
16
|
- Debug captures (`Actor.debug_capture`, `Actor.debug_capture_sync`) keep payloads over 256 KiB whole. They are stored gzip-compressed and base64-encoded as `{key, payload, encoding: 'gzip-base64', length, truncated}` instead of being cut at 262,144 characters; up to 8 Mi characters are kept. A payload that does not compress enough keeps its first 256 KiB, now marked `truncated: True` with its full `length`. Dict and list payloads are dumped as compact JSON, and `bytes` payloads are stored as UTF-8 text (they used to be stored as their `repr`). Captures are only active on the platform's own diagnostic runs (`SCRAPELY_DEBUG_CAPTURE=1`).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "scrapely-python"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.35"
|
|
8
8
|
description = "Scrapely Python SDK - A toolkit for building Actors on the Scrapely platform"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT AND Apache-2.0"
|
|
@@ -285,6 +285,53 @@ class _ActorMeta(type):
|
|
|
285
285
|
await cls._shutdown()
|
|
286
286
|
|
|
287
287
|
|
|
288
|
+
|
|
289
|
+
def _element_markup(obj: Any) -> Optional[str]:
|
|
290
|
+
"""The markup of a parsed XML/HTML element, or None when ``obj`` is not one.
|
|
291
|
+
|
|
292
|
+
Debug captures store the source an item was read from. Feed and page parsers hand over elements
|
|
293
|
+
(xml.etree / lxml elements and trees, BeautifulSoup tags, selectolax nodes, parsel / Scrapy
|
|
294
|
+
selectors); their ``str()`` is only a repr such as ``<Element 'change' at 0x...>``, which shows
|
|
295
|
+
nothing of the source. Optional parsers are recognised by module, never imported here.
|
|
296
|
+
"""
|
|
297
|
+
import xml.etree.ElementTree as ET
|
|
298
|
+
|
|
299
|
+
if isinstance(obj, ET.ElementTree):
|
|
300
|
+
root = obj.getroot()
|
|
301
|
+
return ET.tostring(root, encoding='unicode') if root is not None else ''
|
|
302
|
+
if isinstance(obj, ET.Element):
|
|
303
|
+
if obj.tail: # the text after the element belongs to its parent, as with lxml's with_tail=False
|
|
304
|
+
import copy
|
|
305
|
+
|
|
306
|
+
obj = copy.copy(obj)
|
|
307
|
+
obj.tail = None
|
|
308
|
+
return ET.tostring(obj, encoding='unicode')
|
|
309
|
+
modules = [getattr(c, '__module__', '') or '' for c in type(obj).__mro__]
|
|
310
|
+
if any(m == 'lxml' or m.startswith('lxml.') for m in modules):
|
|
311
|
+
from lxml import etree # type: ignore[import-not-found]
|
|
312
|
+
|
|
313
|
+
out = etree.tostring(obj, encoding='unicode', with_tail=False)
|
|
314
|
+
return out if isinstance(out, str) else None
|
|
315
|
+
if any(m == 'bs4' or m.startswith('bs4.') for m in modules):
|
|
316
|
+
return str(obj)
|
|
317
|
+
if any(m == 'selectolax' or m.startswith('selectolax.') for m in modules):
|
|
318
|
+
html = getattr(obj, 'html', None)
|
|
319
|
+
return html if isinstance(html, str) else None
|
|
320
|
+
if any(m == 'parsel' or m.startswith('parsel.') for m in modules) and callable(getattr(obj, 'get', None)):
|
|
321
|
+
out = obj.get()
|
|
322
|
+
return out if isinstance(out, str) else None
|
|
323
|
+
return None
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def _capture_json_default(obj: Any) -> Any:
|
|
327
|
+
"""json.dumps fallback for debug captures: elements as their markup, anything else as str()."""
|
|
328
|
+
try:
|
|
329
|
+
markup = _element_markup(obj)
|
|
330
|
+
except Exception: # an unusual node type must not lose the rest of the payload
|
|
331
|
+
markup = None
|
|
332
|
+
return markup if markup is not None else str(obj)
|
|
333
|
+
|
|
334
|
+
|
|
288
335
|
class Actor(metaclass=_ActorMeta):
|
|
289
336
|
"""Core class for building Actors on the Scrapely platform."""
|
|
290
337
|
|
|
@@ -302,6 +349,10 @@ class Actor(metaclass=_ActorMeta):
|
|
|
302
349
|
_cached_input: Optional[Dict[str, Any]] = None
|
|
303
350
|
_exit_code: int = 0
|
|
304
351
|
_status_message: Optional[str] = None
|
|
352
|
+
# Set by fail() for the rest of the lifecycle: (exit code, status message).
|
|
353
|
+
# A later exit() keeps them, so `fail()` followed by the usual `exit()` in a
|
|
354
|
+
# `finally:` block still ends the run as FAILED (it used to exit with 0).
|
|
355
|
+
_failure: Optional[Tuple[int, Optional[str]]] = None
|
|
305
356
|
_charging_manager: Optional[ChargingManager] = None
|
|
306
357
|
_use_state_stores: set = set()
|
|
307
358
|
# Lifecycle bookkeeping set in init() / cleared in _shutdown().
|
|
@@ -345,9 +396,11 @@ class Actor(metaclass=_ActorMeta):
|
|
|
345
396
|
elif exc_type is not None:
|
|
346
397
|
cls._exit_code = 1
|
|
347
398
|
logger.error(f'Actor failed: {exc_val}')
|
|
399
|
+
elif cls._failure is not None:
|
|
400
|
+
cls._exit_code = cls._failure[0] # fail(exit=False) earlier: the run stays failed
|
|
348
401
|
else:
|
|
349
402
|
cls._exit_code = self._instance_exit_code
|
|
350
|
-
if self._instance_status_message:
|
|
403
|
+
if self._instance_status_message and cls._failure is None:
|
|
351
404
|
cls._status_message = self._instance_status_message
|
|
352
405
|
await cls._persist_terminal_status_message(self._instance_status_message)
|
|
353
406
|
await cls._shutdown(timeout_secs=int(self._cleanup_timeout.total_seconds()))
|
|
@@ -363,6 +416,7 @@ class Actor(metaclass=_ActorMeta):
|
|
|
363
416
|
cls._main_loop = asyncio.get_running_loop() # for debug_capture_sync from worker threads
|
|
364
417
|
if cls._initialized:
|
|
365
418
|
return
|
|
419
|
+
cls._failure = None # a new lifecycle starts unfailed
|
|
366
420
|
|
|
367
421
|
if options is None or options.configure_logging:
|
|
368
422
|
_lazy('_configure_logging')()
|
|
@@ -654,13 +708,33 @@ class Actor(metaclass=_ActorMeta):
|
|
|
654
708
|
if exit_code is not None:
|
|
655
709
|
opts.exit_code = exit_code
|
|
656
710
|
|
|
657
|
-
if
|
|
711
|
+
if cls._failure is not None:
|
|
712
|
+
# Actor.fail() already ran: the run stays failed. Keep its exit code and
|
|
713
|
+
# status message; a later exit() (e.g. in a `finally:` block) only
|
|
714
|
+
# finishes the shutdown and exits with the failure's code.
|
|
715
|
+
if opts.status_message:
|
|
716
|
+
logger.info(f'[Scrapely] {opts.status_message}')
|
|
717
|
+
logger.info(
|
|
718
|
+
'[Scrapely] Actor.exit() after Actor.fail(): the run stays failed (exit code %s).',
|
|
719
|
+
cls._failure[0],
|
|
720
|
+
)
|
|
721
|
+
opts = ExitOptions(**{**opts.__dict__})
|
|
722
|
+
opts.exit_code, opts.status_message = cls._failure
|
|
723
|
+
await cls._exit_with(opts, persist_message=False)
|
|
724
|
+
return
|
|
725
|
+
|
|
726
|
+
await cls._exit_with(opts)
|
|
727
|
+
|
|
728
|
+
@classmethod
|
|
729
|
+
async def _exit_with(cls, opts: ExitOptions, persist_message: bool = True) -> None:
|
|
730
|
+
if opts.status_message and persist_message:
|
|
658
731
|
logger.info(f'[Scrapely] {opts.status_message}')
|
|
659
732
|
|
|
660
733
|
cls._exit_code = opts.exit_code
|
|
661
734
|
cls._status_message = opts.status_message
|
|
662
735
|
|
|
663
|
-
|
|
736
|
+
if persist_message:
|
|
737
|
+
await cls._persist_terminal_status_message(opts.status_message)
|
|
664
738
|
await cls._shutdown(timeout_secs=opts.timeout_secs)
|
|
665
739
|
|
|
666
740
|
if opts.exit:
|
|
@@ -689,7 +763,7 @@ class Actor(metaclass=_ActorMeta):
|
|
|
689
763
|
if isinstance(message_or_options, str):
|
|
690
764
|
opts = ExitOptions(exit_code=1, status_message=message_or_options)
|
|
691
765
|
else:
|
|
692
|
-
# Options-object form:
|
|
766
|
+
# Options-object form: a non-zero exit_code in the object wins over
|
|
693
767
|
# the fail() default of 1 (JS SDK semantics). Build the dict first —
|
|
694
768
|
# passing it alongside exit_code=1 as kwargs raises
|
|
695
769
|
# "got multiple values for keyword argument 'exit_code'".
|
|
@@ -704,12 +778,24 @@ class Actor(metaclass=_ActorMeta):
|
|
|
704
778
|
opts.status_message = status_message
|
|
705
779
|
if exit_code is not None:
|
|
706
780
|
opts.exit_code = exit_code
|
|
781
|
+
elif not opts.exit_code:
|
|
782
|
+
# ExitOptions always carries exit_code (default 0), so 0 from an options
|
|
783
|
+
# object means "not set": a failed run must not exit with 0. Only an
|
|
784
|
+
# explicit exit_code=0 keyword keeps 0.
|
|
785
|
+
opts.exit_code = 1
|
|
707
786
|
|
|
708
787
|
logger.error(
|
|
709
788
|
f'[Scrapely] Actor failed: {opts.status_message or "Unknown error"}',
|
|
710
789
|
exc_info=exception,
|
|
711
790
|
)
|
|
712
|
-
|
|
791
|
+
if cls._failure is not None:
|
|
792
|
+
# Failed already: the first failure's code and message stay.
|
|
793
|
+
opts = ExitOptions(**{**opts.__dict__})
|
|
794
|
+
opts.exit_code, opts.status_message = cls._failure
|
|
795
|
+
await cls._exit_with(opts, persist_message=False)
|
|
796
|
+
return
|
|
797
|
+
cls._failure = (opts.exit_code, opts.status_message)
|
|
798
|
+
await cls._exit_with(opts)
|
|
713
799
|
|
|
714
800
|
@classmethod
|
|
715
801
|
def is_at_home(cls) -> bool:
|
|
@@ -974,12 +1060,15 @@ class Actor(metaclass=_ActorMeta):
|
|
|
974
1060
|
if cls._debug_capture_count >= cls._DEBUG_CAPTURE_MAX_RECORDS:
|
|
975
1061
|
return
|
|
976
1062
|
try:
|
|
977
|
-
|
|
1063
|
+
markup = _element_markup(payload)
|
|
1064
|
+
if markup is not None:
|
|
1065
|
+
text = markup
|
|
1066
|
+
elif isinstance(payload, (bytes, bytearray)):
|
|
978
1067
|
text = bytes(payload).decode('utf-8', 'replace')
|
|
979
1068
|
elif isinstance(payload, str):
|
|
980
1069
|
text = payload
|
|
981
1070
|
else:
|
|
982
|
-
text = json.dumps(payload, default=
|
|
1071
|
+
text = json.dumps(payload, default=_capture_json_default, ensure_ascii=False, separators=(',', ':'))
|
|
983
1072
|
record = cls._debug_capture_record(str(key), text)
|
|
984
1073
|
cls._debug_capture_count += 1
|
|
985
1074
|
await cls.set_value(cls.debug_capture_record_key(key), record)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/__init__.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/_graceful_stop.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/extensions/_httpcache.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/middlewares/__init__.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/scrapy/middlewares/apify_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/_file_system/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_dataset_client.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_kvs_client.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_rq_client.py
RENAMED
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely/storage/scrapely_storage_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{scrapely_python-0.1.33 → scrapely_python-0.1.35}/src/scrapely_python.egg-info/top_level.txt
RENAMED
|
File without changes
|