Skip to content

Commit f0fc1d7

Browse files
fix pagination urls type
1 parent 4e49d2d commit f0fc1d7

File tree

4 files changed

+24
-16
lines changed

4 files changed

+24
-16
lines changed

packages/models-library/src/models_library/basic_types.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from re import Pattern
44
from typing import Annotated, Final, TypeAlias
55

6-
import pydantic
7-
from pydantic import Field, PositiveInt, StringConstraints
6+
from pydantic import Field, HttpUrl, PositiveInt, StringConstraints
87
from pydantic_core import core_schema
98

109
from .basic_regex import (
@@ -130,9 +129,6 @@ class LongTruncatedStr(ConstrainedStr):
130129
IdInt: TypeAlias = PositiveInt
131130
PrimaryKeyInt: TypeAlias = PositiveInt
132131

133-
AnyHttpUrl = Annotated[str, pydantic.AnyHttpUrl]
134-
135-
HttpUrl = Annotated[str, pydantic.HttpUrl]
136132

137133
# https e.g. https://techterms.com/definition/https
138134
class HttpSecureUrl(HttpUrl):

packages/models-library/src/models_library/rest_pagination.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pydantic import (
44
AnyHttpUrl,
55
BaseModel,
6+
BeforeValidator,
67
ConfigDict,
78
Field,
89
NonNegativeInt,
@@ -14,13 +15,17 @@
1415

1516
from .utils.common_validators import none_to_empty_list_pre_validator
1617

18+
_ANY_HTTP_URL_ADAPTER: TypeAdapter = TypeAdapter(AnyHttpUrl)
19+
1720
# Default limit values
1821
# - Using same values across all pagination entrypoints simplifies
1922
# interconnecting paginated calls
2023
MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE: Final[int] = 50
2124

2225

23-
PageLimitInt: TypeAlias = Annotated[int, Field(ge=1, lt=MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE)]
26+
PageLimitInt: TypeAlias = Annotated[
27+
int, Field(ge=1, lt=MAXIMUM_NUMBER_OF_ITEMS_PER_PAGE)
28+
]
2429

2530
DEFAULT_NUMBER_OF_ITEMS_PER_PAGE: Final[PageLimitInt] = TypeAdapter(
2631
PageLimitInt
@@ -92,7 +97,14 @@ class PageRefs(BaseModel, Generic[RefT]):
9297
model_config = ConfigDict(extra="forbid")
9398

9499

95-
class PageLinks(PageRefs[Annotated[str, AnyHttpUrl]]):
100+
class PageLinks(
101+
PageRefs[
102+
Annotated[
103+
str,
104+
BeforeValidator(lambda x: str(_ANY_HTTP_URL_ADAPTER.validate_python(x))),
105+
]
106+
]
107+
):
96108
...
97109

98110

packages/models-library/src/models_library/rest_pagination_utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from math import ceil
22
from typing import Any, Protocol, TypedDict, Union, runtime_checkable
33

4-
from pydantic import TypeAdapter
4+
from pydantic import AnyHttpUrl, TypeAdapter
55

6-
from .basic_types import AnyHttpUrl
76
from .rest_pagination import PageLinks, PageMetaInfoLimitOffset
87

98
# NOTE: In this repo we use two type of URL-like data structures:
@@ -30,6 +29,7 @@ def replace_query_params(self, **kwargs: Any) -> "_StarletteURL":
3029

3130

3231
_URLType = Union[_YarlURL, _StarletteURL]
32+
_ANY_HTTP_URL_ADAPTER: TypeAdapter = TypeAdapter(AnyHttpUrl)
3333

3434

3535
def _replace_query(url: _URLType, query: dict[str, Any]) -> str:
@@ -73,29 +73,29 @@ def paginate_data(
7373
),
7474
_links=PageLinks(
7575
self=(
76-
TypeAdapter(AnyHttpUrl).validate_python(
76+
_ANY_HTTP_URL_ADAPTER.validate_python(
7777
_replace_query(request_url, {"offset": offset, "limit": limit}),
7878
)
7979
),
80-
first=TypeAdapter(AnyHttpUrl).validate_python(
80+
first=_ANY_HTTP_URL_ADAPTER.validate_python(
8181
_replace_query(request_url, {"offset": 0, "limit": limit})
8282
),
83-
prev=TypeAdapter(AnyHttpUrl).validate_python(
83+
prev=_ANY_HTTP_URL_ADAPTER.validate_python(
8484
_replace_query(
8585
request_url, {"offset": max(offset - limit, 0), "limit": limit}
8686
),
8787
)
8888
if offset > 0
8989
else None,
90-
next=TypeAdapter(AnyHttpUrl).validate_python(
90+
next=_ANY_HTTP_URL_ADAPTER.validate_python(
9191
_replace_query(
9292
request_url,
9393
{"offset": min(offset + limit, last_page * limit), "limit": limit},
9494
),
9595
)
9696
if offset < (last_page * limit)
9797
else None,
98-
last=TypeAdapter(AnyHttpUrl).validate_python(
98+
last=_ANY_HTTP_URL_ADAPTER.validate_python(
9999
_replace_query(
100100
request_url, {"offset": last_page * limit, "limit": limit}
101101
),

packages/models-library/tests/test_rest_pagination_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def test_paginating_data(base_url):
7575
offset += len(data_chunk)
7676
assert model_instance.links.next is not None
7777

78-
data_obj: PageDict = paginate_data(
78+
data_obj: PageDict = paginate_data( # type: ignore[no-redef]
7979
data_chunk,
8080
request_url=URL(model_instance.links.next),
8181
total=total_number_of_items,
@@ -127,7 +127,7 @@ def test_paginating_data(base_url):
127127
assert offset == last_chunk_offset
128128

129129
assert model_instance.links.next is not None
130-
data_obj: PageDict = paginate_data(
130+
data_obj: PageDict = paginate_data( # type: ignore[no-redef]
131131
data_chunk,
132132
request_url=URL(model_instance.links.next),
133133
total=total_number_of_items,

0 commit comments

Comments
 (0)