Page MenuHomeSoftware Heritage

D3632.id12778.diff
No OneTemporary

D3632.id12778.diff

diff --git a/mypy.ini b/mypy.ini
--- a/mypy.ini
+++ b/mypy.ini
@@ -43,3 +43,6 @@
[mypy-systemd.*]
ignore_missing_imports = True
+
+[mypy-attrs_strict.*]
+ignore_missing_imports = True
diff --git a/requirements.txt b/requirements.txt
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,3 +2,4 @@
Deprecated
PyYAML
sentry-sdk
+attrs_strict >= 0.0.7
diff --git a/swh/core/api/model.py b/swh/core/api/model.py
new file mode 100644
--- /dev/null
+++ b/swh/core/api/model.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2015-2020 The Software Heritage developers
+# See the AUTHORS file at the top-level directory of this distribution
+# License: GNU General Public License version 3, or any later version
+# See top-level LICENSE file for more information
+
+import attr
+
+from typing import (
+ Generic,
+ List,
+ Optional,
+ TypeVar,
+)
+
+from attrs_strict import type_validator
+
+
+T = TypeVar("T")
+
+
+@attr.s(frozen=True)
+class PagedResult(Generic[T]):
+ """Represents a page of results; with a token to get the next page"""
+
+ results = attr.ib(type=List[T], default=[])
+ next_page_token = attr.ib(
+ type=Optional[str], default=None, validator=type_validator()
+ )
diff --git a/swh/core/api/serializers.py b/swh/core/api/serializers.py
--- a/swh/core/api/serializers.py
+++ b/swh/core/api/serializers.py
@@ -18,6 +18,8 @@
from typing import Any, Dict, Union, Tuple
from requests import Response
+from swh.core.api.model import PagedResult
+
def encode_datetime(dt: datetime.datetime) -> str:
"""Wrapper of datetime.datetime.isoformat() that forbids naive datetimes."""
@@ -26,6 +28,20 @@
return dt.isoformat()
+def _encode_paged_result(obj: PagedResult) -> Dict[str, Any]:
+ """Serialize PagedResult to a Dict."""
+ return {
+ "__type__": type(obj).__name__,
+ "results": obj.results,
+ "next_page_token": obj.next_page_token,
+ }
+
+
+def _decode_paged_result(obj: Dict[str, Any]) -> PagedResult:
+ """Deserialize Dict into PagedResult"""
+ return PagedResult(results=obj["results"], next_page_token=obj["next_page_token"],)
+
+
ENCODERS = [
(arrow.Arrow, "arrow", arrow.Arrow.isoformat),
(datetime.datetime, "datetime", encode_datetime),
@@ -39,6 +55,7 @@
},
),
(UUID, "uuid", str),
+ (PagedResult, "core_class", _encode_paged_result),
# Only for JSON:
(bytes, "bytes", lambda o: base64.b85encode(o).decode("ascii")),
]
@@ -48,6 +65,7 @@
"datetime": lambda d: iso8601.parse_date(d, default_timezone=None),
"timedelta": lambda d: datetime.timedelta(**d),
"uuid": UUID,
+ "core_class": _decode_paged_result,
# Only for JSON:
"bytes": base64.b85decode,
}
diff --git a/swh/core/api/tests/test_serializers.py b/swh/core/api/tests/test_serializers.py
--- a/swh/core/api/tests/test_serializers.py
+++ b/swh/core/api/tests/test_serializers.py
@@ -13,6 +13,7 @@
import arrow
import requests
+from swh.core.api.model import PagedResult
from swh.core.api.serializers import (
SWHJSONDecoder,
SWHJSONEncoder,
@@ -48,33 +49,50 @@
TZ = datetime.timezone(datetime.timedelta(minutes=118))
+DATA_BYTES = b"123456789\x99\xaf\xff\x00\x12"
+ENCODED_DATA_BYTES = {"swhtype": "bytes", "d": "F)}kWH8wXmIhn8j01^"}
+
+DATA_ARROW = arrow.get("2018-04-25T16:17:53.533672+00:00")
+ENCODED_DATA_ARROW = {"swhtype": "arrow", "d": "2018-04-25T16:17:53.533672+00:00"}
+
DATA = {
- "bytes": b"123456789\x99\xaf\xff\x00\x12",
+ "bytes": DATA_BYTES,
"datetime_tz": datetime.datetime(2015, 3, 4, 18, 25, 13, 1234, tzinfo=TZ,),
"datetime_utc": datetime.datetime(
2015, 3, 4, 18, 25, 13, 1234, tzinfo=datetime.timezone.utc
),
"datetime_delta": datetime.timedelta(64),
- "arrow_date": arrow.get("2018-04-25T16:17:53.533672+00:00"),
+ "arrow_date": DATA_ARROW,
"swhtype": "fake",
"swh_dict": {"swhtype": 42, "d": "test"},
"random_dict": {"swhtype": 43},
"uuid": UUID("cdd8f804-9db6-40c3-93ab-5955d3836234"),
+ "paged-result": PagedResult(
+ results=["data0", DATA_BYTES, DATA_ARROW], next_page_token="10"
+ ),
}
ENCODED_DATA = {
- "bytes": {"swhtype": "bytes", "d": "F)}kWH8wXmIhn8j01^"},
+ "bytes": ENCODED_DATA_BYTES,
"datetime_tz": {"swhtype": "datetime", "d": "2015-03-04T18:25:13.001234+01:58",},
"datetime_utc": {"swhtype": "datetime", "d": "2015-03-04T18:25:13.001234+00:00",},
"datetime_delta": {
"swhtype": "timedelta",
"d": {"days": 64, "seconds": 0, "microseconds": 0},
},
- "arrow_date": {"swhtype": "arrow", "d": "2018-04-25T16:17:53.533672+00:00"},
+ "arrow_date": ENCODED_DATA_ARROW,
"swhtype": "fake",
"swh_dict": {"swhtype": 42, "d": "test"},
"random_dict": {"swhtype": 43},
"uuid": {"swhtype": "uuid", "d": "cdd8f804-9db6-40c3-93ab-5955d3836234"},
+ "paged-result": {
+ "d": {
+ "__type__": "PagedResult",
+ "results": ["data0", ENCODED_DATA_BYTES, ENCODED_DATA_ARROW],
+ "next_page_token": "10",
+ },
+ "swhtype": "core_class",
+ },
}

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 3, 3:35 PM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3230293

Event Timeline