Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions scrapy_zyte_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

install_reactor("twisted.internet.asyncioreactor.AsyncioSelectorReactor")

# Register web-poet serializers
from . import _serialization # noqa: F401

from ._annotations import ExtractFrom, actions, custom_attrs
from ._middlewares import (
ScrapyZyteAPIDownloaderMiddleware,
Expand Down
1 change: 1 addition & 0 deletions scrapy_zyte_api/_page_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Actions:
results: Optional[List[_ActionResult]]


@attrs.define
class Geolocation:
"""A page input that forces a given geolocation for all other page inputs.

Expand Down
37 changes: 37 additions & 0 deletions scrapy_zyte_api/_serialization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import json

from ._page_inputs import Actions, Geolocation, Screenshot

try:
from web_poet.serialization import SerializedLeafData, register_serialization
except ImportError:
pass
else:

def _serialize_Actions(o: Actions) -> SerializedLeafData:
return {"results.json": json.dumps(o.results).encode()}

def _deserialize_Actions(cls: type[Actions], data: SerializedLeafData) -> Actions:
return cls(results=json.loads(data["results.json"]))

register_serialization(_serialize_Actions, _deserialize_Actions)

def _serialize_Geolocation(o: Geolocation) -> SerializedLeafData:
return {}

def _deserialize_Geolocation(
cls: type[Geolocation], data: SerializedLeafData
) -> Geolocation:
return cls()

register_serialization(_serialize_Geolocation, _deserialize_Geolocation)

def _serialize_Screenshot(o: Screenshot) -> SerializedLeafData:
return {"body": o.body}

def _deserialize_Screenshot(
cls: type[Screenshot], data: SerializedLeafData
) -> Screenshot:
return cls(body=data["body"])

register_serialization(_serialize_Screenshot, _deserialize_Screenshot)
2 changes: 1 addition & 1 deletion tests/test_middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

import pytest
from packaging.version import Version
from scrapy.utils.defer import deferred_f_from_coro_f
from scrapy import Request, Spider
from scrapy.http.response import Response
from scrapy.item import Item
from scrapy.utils.defer import deferred_f_from_coro_f
from scrapy.utils.test import get_crawler

from scrapy_zyte_api import (
Expand Down
24 changes: 24 additions & 0 deletions tests/test_serialization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

from scrapy_zyte_api._page_inputs import Actions, Geolocation, Screenshot


@pytest.mark.parametrize(
"case",
[
{"cls": Actions, "kwargs": {"results": [{"action": "click", "id": "x"}]}},
{"cls": Geolocation, "kwargs": {}},
{"cls": Screenshot, "kwargs": {"body": b"PNGDATA"}},
],
)
def test(case):
wp = pytest.importorskip("web_poet.serialization")
cls = case["cls"]
kwargs = case["kwargs"]

obj = cls(**kwargs)
data = wp.serialize_leaf(obj)
reconstructed = wp.deserialize_leaf(cls, data)

assert reconstructed == obj
assert id(reconstructed) != id(obj)