From e67b9e6c37d9444fc8f5038d3ddbdfbe360599a4 Mon Sep 17 00:00:00 2001 From: Alexander Graf <17130992+aandergr@users.noreply.github.com> Date: Mon, 12 Apr 2021 16:53:59 +0200 Subject: [PATCH] Improve docs on how to load/save FrozenNodeIterator --- docs/module/nodeiterator.rst | 7 +++++++ instaloader/nodeiterator.py | 5 +++-- instaloader/structures.py | 8 ++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/module/nodeiterator.rst b/docs/module/nodeiterator.rst index 0b82e52..8f24f5c 100644 --- a/docs/module/nodeiterator.rst +++ b/docs/module/nodeiterator.rst @@ -25,6 +25,13 @@ Iterator :class:`NodeIterator` and a context manager .. autoclass:: FrozenNodeIterator :no-show-inheritance: + A serializable representation of a :class:`NodeIterator` instance, saving + its iteration state. + + It can be serialized and deserialized with :func:`save_structure_to_file` + and :func:`load_structure_from_file`, as well as with :mod:`json` and + :mod:`pickle` thanks to being a :func:`~collections.namedtuple`. + ``resumable_iteration`` """"""""""""""""""""""" diff --git a/instaloader/nodeiterator.py b/instaloader/nodeiterator.py index 2ebbf4c..cb030b2 100644 --- a/instaloader/nodeiterator.py +++ b/instaloader/nodeiterator.py @@ -18,8 +18,6 @@ FrozenNodeIterator = NamedTuple('FrozenNodeIterator', ('total_index', int), ('best_before', Optional[float]), ('remaining_data', Optional[Dict])]) -FrozenNodeIterator.__doc__ = \ - """A serializable representation of a :class:`NodeIterator` instance, saving its iteration state.""" FrozenNodeIterator.query_hash.__doc__ = """The GraphQL ``query_hash`` parameter.""" FrozenNodeIterator.query_variables.__doc__ = """The GraphQL ``query_variables`` parameter.""" FrozenNodeIterator.query_referer.__doc__ = """The HTTP referer used for the GraphQL query.""" @@ -55,6 +53,9 @@ class NodeIterator(Iterator[T]): post_iterator = profile.get_posts() post_iterator.thaw(load("resume_information.json")) + (an appropriate method to load and save the :class:`FrozenNodeIterator` is e.g. + :func:`load_structure_from_file` and :func:`save_structure_to_file`.) + A :class:`FrozenNodeIterator` can only be thawn with a matching NodeIterator, i.e. a NodeIterator instance that has been constructed with the same parameters as the instance that is represented by the :class:`FrozenNodeIterator` in question. This is to ensure that an iteration cannot be resumed in a wrong, unmatching loop. As a quick way to diff --git a/instaloader/structures.py b/instaloader/structures.py index cf6e9ce..c1ea78b 100644 --- a/instaloader/structures.py +++ b/instaloader/structures.py @@ -1535,8 +1535,8 @@ JsonExportable = Union[Post, Profile, StoryItem, Hashtag, FrozenNodeIterator] def save_structure_to_file(structure: JsonExportable, filename: str) -> None: - """Saves a :class:`Post`, :class:`Profile`, :class:`StoryItem` or :class:`Hashtag` to a '.json' or '.json.xz' file - such that it can later be loaded by :func:`load_structure_from_file`. + """Saves a :class:`Post`, :class:`Profile`, :class:`StoryItem`, :class:`Hashtag` or :class:`FrozenNodeIterator` to a + '.json' or '.json.xz' file such that it can later be loaded by :func:`load_structure_from_file`. If the specified filename ends in '.xz', the file will be LZMA compressed. Otherwise, a pretty-printed JSON file will be created. @@ -1556,8 +1556,8 @@ def save_structure_to_file(structure: JsonExportable, filename: str) -> None: def load_structure_from_file(context: InstaloaderContext, filename: str) -> JsonExportable: - """Loads a :class:`Post`, :class:`Profile`, :class:`StoryItem` or :class:`Hashtag` from a '.json' or '.json.xz' file - that has been saved by :func:`save_structure_to_file`. + """Loads a :class:`Post`, :class:`Profile`, :class:`StoryItem`, :class:`Hashtag` or :class:`FrozenNodeIterator` from + a '.json' or '.json.xz' file that has been saved by :func:`save_structure_to_file`. :param context: :attr:`Instaloader.context` linked to the new object, used for additional queries if neccessary. :param filename: Filename, ends in '.json' or '.json.xz'