Skip to content

Commit fdd19c6

Browse files
move base type adapters
1 parent e36b18c commit fdd19c6

File tree

9 files changed

+54
-44
lines changed

9 files changed

+54
-44
lines changed

packages/aws-library/src/aws_library/s3/_client.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from boto3.s3.transfer import TransferConfig
1414
from botocore import exceptions as botocore_exc
1515
from botocore.client import Config
16+
from common_library.pydantic_type_adapters import AnyUrlLegacyAdapter
1617
from models_library.api_schemas_storage import ETag, S3BucketName, UploadedPart
1718
from models_library.basic_types import SHA256Str
1819
from pydantic import AnyUrl, ByteSize, TypeAdapter
@@ -43,8 +44,8 @@
4344
_MAX_CONCURRENT_COPY: Final[int] = 4
4445
_AWS_MAX_ITEMS_PER_PAGE: Final[int] = 1000
4546

46-
_ANY_URL_ADAPTER: Final[TypeAdapter[AnyUrl]] = TypeAdapter(AnyUrl)
47-
_LIST_ANY_URL_ADAPTER: Final[TypeAdapter[list[AnyUrl]]] = TypeAdapter(list[AnyUrl])
47+
48+
ListAnyUrlTypeAdapter: Final[TypeAdapter[list[AnyUrl]]] = TypeAdapter(list[AnyUrl])
4849

4950

5051
class UploadedBytesTransferredCallback(Protocol):
@@ -263,7 +264,7 @@ async def create_single_presigned_download_link(
263264
Params={"Bucket": bucket, "Key": object_key},
264265
ExpiresIn=expiration_secs,
265266
)
266-
return _ANY_URL_ADAPTER.validate_python(generated_link)
267+
return AnyUrlLegacyAdapter.validate_python(generated_link)
267268

268269
@s3_exception_handler(_logger)
269270
async def create_single_presigned_upload_link(
@@ -276,7 +277,7 @@ async def create_single_presigned_upload_link(
276277
Params={"Bucket": bucket, "Key": object_key},
277278
ExpiresIn=expiration_secs,
278279
)
279-
return _ANY_URL_ADAPTER.validate_python(generated_link)
280+
return AnyUrlLegacyAdapter.validate_python(generated_link)
280281

281282
@s3_exception_handler(_logger)
282283
async def create_multipart_upload_links(
@@ -299,7 +300,7 @@ async def create_multipart_upload_links(
299300
# compute the number of links, based on the announced file size
300301
num_upload_links, chunk_size = compute_num_file_chunks(file_size)
301302
# now create the links
302-
upload_links = _LIST_ANY_URL_ADAPTER.validate_python(
303+
upload_links = ListAnyUrlTypeAdapter.validate_python(
303304
await asyncio.gather(
304305
*(
305306
self._client.generate_presigned_url(
@@ -473,6 +474,6 @@ def is_multipart(file_size: ByteSize) -> bool:
473474

474475
@staticmethod
475476
def compute_s3_url(*, bucket: S3BucketName, object_key: S3ObjectKey) -> AnyUrl:
476-
return _ANY_URL_ADAPTER.validate_python(
477+
return AnyUrlLegacyAdapter.validate_python(
477478
f"s3://{bucket}/{urllib.parse.quote(object_key)}"
478479
)
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
from typing import Annotated, TypeAlias
22

3-
from pydantic import AfterValidator, AnyHttpUrl, HttpUrl
3+
from pydantic import AfterValidator, AnyHttpUrl, AnyUrl, HttpUrl
44

55

66
def _strip_last_slash(url: str) -> str:
77
return url.rstrip("/")
88

99

10+
AnyUrlLegacy: TypeAlias = Annotated[
11+
str,
12+
AnyUrl,
13+
AfterValidator(_strip_last_slash),
14+
]
15+
1016
AnyHttpUrlLegacy: TypeAlias = Annotated[
11-
str, AnyHttpUrl, AfterValidator(_strip_last_slash)
17+
str,
18+
AnyHttpUrl,
19+
AfterValidator(_strip_last_slash),
1220
]
1321

1422

15-
HttpUrlLegacy: TypeAlias = Annotated[str, HttpUrl, AfterValidator(_strip_last_slash)]
23+
HttpUrlLegacy: TypeAlias = Annotated[
24+
str,
25+
HttpUrl,
26+
AfterValidator(_strip_last_slash),
27+
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from typing import Final
2+
3+
from common_library.pydantic_networks_extension import AnyHttpUrlLegacy, AnyUrlLegacy
4+
from pydantic import TypeAdapter
5+
6+
AnyUrlLegacyAdapter: Final[TypeAdapter[AnyUrlLegacy]] = TypeAdapter(AnyUrlLegacy)
7+
8+
AnyHttpUrlLegacyAdapter: Final[TypeAdapter] = TypeAdapter(AnyHttpUrlLegacy)

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
"""
88

99
from pathlib import Path
10-
from typing import Annotated, Final, TypeAlias
10+
from typing import Annotated, TypeAlias
1111
from uuid import UUID
1212

13+
from common_library.pydantic_type_adapters import AnyUrlLegacyAdapter
1314
from models_library.basic_types import ConstrainedStr, KeyIDStr
1415
from pydantic import (
15-
AnyUrl,
1616
BaseModel,
1717
BeforeValidator,
1818
ConfigDict,
@@ -45,9 +45,6 @@
4545
]
4646

4747

48-
_ANY_URL_ADAPTER: Final[TypeAdapter[AnyUrl]] = TypeAdapter(AnyUrl)
49-
50-
5148
class SimcoreS3DirectoryID(ConstrainedStr):
5249
"""
5350
A simcore directory has the following structure:
@@ -126,7 +123,7 @@ class DownloadLink(BaseModel):
126123
"""I/O port type to hold a generic download link to a file (e.g. S3 pre-signed link, etc)"""
127124

128125
download_link: Annotated[
129-
str, BeforeValidator(lambda x: str(_ANY_URL_ADAPTER.validate_python(x)))
126+
str, BeforeValidator(lambda x: str(AnyUrlLegacyAdapter.validate_python(x)))
130127
] = Field(..., alias="downloadLink")
131128
label: str | None = Field(default=None, description="Display name")
132129
model_config = ConfigDict(
@@ -176,9 +173,7 @@ def legacy_enforce_str_to_int(cls, v):
176173
return int(v)
177174
return v
178175

179-
model_config = ConfigDict(
180-
populate_by_name=True
181-
)
176+
model_config = ConfigDict(populate_by_name=True)
182177

183178

184179
class SimCoreFileLink(BaseFileLink):

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Annotated, Final, Generic, TypeAlias, TypeVar
22

3+
from common_library.pydantic_type_adapters import AnyHttpUrlLegacyAdapter
34
from pydantic import (
4-
AnyHttpUrl,
55
BaseModel,
66
BeforeValidator,
77
ConfigDict,
@@ -15,8 +15,6 @@
1515

1616
from .utils.common_validators import none_to_empty_list_pre_validator
1717

18-
_ANY_HTTP_URL_ADAPTER: Final[TypeAdapter[AnyHttpUrl]] = TypeAdapter(AnyHttpUrl)
19-
2018
# Default limit values
2119
# - Using same values across all pagination entrypoints simplifies
2220
# interconnecting paginated calls
@@ -101,7 +99,7 @@ class PageLinks(
10199
PageRefs[
102100
Annotated[
103101
str,
104-
BeforeValidator(lambda x: str(_ANY_HTTP_URL_ADAPTER.validate_python(x))),
102+
BeforeValidator(lambda x: str(AnyHttpUrlLegacyAdapter.validate_python(x))),
105103
]
106104
]
107105
):

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

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

4-
from pydantic import AnyHttpUrl, TypeAdapter
4+
from common_library.pydantic_type_adapters import AnyHttpUrlLegacyAdapter
55

66
from .rest_pagination import PageLinks, PageMetaInfoLimitOffset
77

@@ -29,7 +29,6 @@ def replace_query_params(self, **kwargs: Any) -> "_StarletteURL":
2929

3030

3131
_URLType = Union[_YarlURL, _StarletteURL]
32-
_ANY_HTTP_URL_ADAPTER: TypeAdapter = TypeAdapter(AnyHttpUrl)
3332

3433

3534
def _replace_query(url: _URLType, query: dict[str, Any]) -> str:
@@ -73,29 +72,29 @@ def paginate_data(
7372
),
7473
_links=PageLinks(
7574
self=(
76-
_ANY_HTTP_URL_ADAPTER.validate_python(
75+
AnyHttpUrlLegacyAdapter.validate_python(
7776
_replace_query(request_url, {"offset": offset, "limit": limit}),
7877
)
7978
),
80-
first=_ANY_HTTP_URL_ADAPTER.validate_python(
79+
first=AnyHttpUrlLegacyAdapter.validate_python(
8180
_replace_query(request_url, {"offset": 0, "limit": limit})
8281
),
83-
prev=_ANY_HTTP_URL_ADAPTER.validate_python(
82+
prev=AnyHttpUrlLegacyAdapter.validate_python(
8483
_replace_query(
8584
request_url, {"offset": max(offset - limit, 0), "limit": limit}
8685
),
8786
)
8887
if offset > 0
8988
else None,
90-
next=_ANY_HTTP_URL_ADAPTER.validate_python(
89+
next=AnyHttpUrlLegacyAdapter.validate_python(
9190
_replace_query(
9291
request_url,
9392
{"offset": min(offset + limit, last_page * limit), "limit": limit},
9493
),
9594
)
9695
if offset < (last_page * limit)
9796
else None,
98-
last=_ANY_HTTP_URL_ADAPTER.validate_python(
97+
last=AnyHttpUrlLegacyAdapter.validate_python(
9998
_replace_query(
10099
request_url, {"offset": last_page * limit, "limit": limit}
101100
),

packages/service-library/src/servicelib/aiohttp/long_running_tasks/_server.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from typing import Any
66

77
from aiohttp import web
8+
from common_library.pydantic_type_adapters import AnyHttpUrlLegacyAdapter
89
from models_library.utils.json_serialization import json_dumps
9-
from pydantic import AnyHttpUrl, PositiveFloat, TypeAdapter
10+
from pydantic import PositiveFloat
1011

1112
from ...aiohttp import status
1213
from ...long_running_tasks._models import TaskGet
@@ -28,8 +29,6 @@
2829

2930
_logger = logging.getLogger(__name__)
3031

31-
_ANY_HTTP_URL_ADAPTER: TypeAdapter[AnyHttpUrl] = TypeAdapter(AnyHttpUrl)
32-
3332

3433
def no_ops_decorator(handler: Handler):
3534
return handler
@@ -69,13 +68,13 @@ async def start_long_running_task(
6968
ip_addr, port = request_.transport.get_extra_info(
7069
"sockname"
7170
) # https://docs.python.org/3/library/asyncio-protocol.html#asyncio.BaseTransport.get_extra_info
72-
status_url = _ANY_HTTP_URL_ADAPTER.validate_python(
71+
status_url = AnyHttpUrlLegacyAdapter.validate_python(
7372
f"http://{ip_addr}:{port}{request_.app.router['get_task_status'].url_for(task_id=task_id)}" # NOSONAR
7473
)
75-
result_url = _ANY_HTTP_URL_ADAPTER.validate_python(
74+
result_url = AnyHttpUrlLegacyAdapter.validate_python(
7675
f"http://{ip_addr}:{port}{request_.app.router['get_task_result'].url_for(task_id=task_id)}" # NOSONAR
7776
)
78-
abort_url = _ANY_HTTP_URL_ADAPTER.validate_python(
77+
abort_url = AnyHttpUrlLegacyAdapter.validate_python(
7978
f"http://{ip_addr}:{port}{request_.app.router['cancel_and_delete_task'].url_for(task_id=task_id)}" # NOSONAR
8079
)
8180
task_get = TaskGet(

packages/service-library/src/servicelib/fastapi/long_running_tasks/_client.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import warnings
55
from typing import Any, Awaitable, Callable, Final
66

7-
from common_library.pydantic_networks_extension import AnyHttpUrlLegacy
7+
from common_library.pydantic_type_adapters import AnyHttpUrlLegacyAdapter
88
from fastapi import FastAPI, status
99
from httpx import AsyncClient, HTTPError
10-
from pydantic import PositiveFloat, TypeAdapter
10+
from pydantic import PositiveFloat
1111
from tenacity import RetryCallState
1212
from tenacity.asyncio import AsyncRetrying
1313
from tenacity.retry import retry_if_exception_type
@@ -24,7 +24,6 @@
2424

2525
DEFAULT_HTTP_REQUESTS_TIMEOUT: Final[PositiveFloat] = 15
2626

27-
_ANY_HTTP_URL_LEGACY_ADAPTER: TypeAdapter[AnyHttpUrlLegacy] = TypeAdapter(AnyHttpUrlLegacy)
2827

2928
logger = logging.getLogger(__name__)
3029

@@ -132,7 +131,7 @@ def _client_configuration(self) -> ClientConfiguration:
132131
return output
133132

134133
def _get_url(self, path: str) -> str:
135-
return _ANY_HTTP_URL_LEGACY_ADAPTER.validate_python(
134+
return AnyHttpUrlLegacyAdapter.validate_python(
136135
f"{self._base_url}{self._client_configuration.router_prefix}{path}",
137136
)
138137

packages/settings-library/src/settings_library/ssm.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
from typing import Annotated, Final
1+
from typing import Annotated
22

3-
from pydantic import AnyHttpUrl, BeforeValidator, Field, SecretStr, TypeAdapter
3+
from common_library.pydantic_type_adapters import AnyHttpUrlLegacyAdapter
4+
from pydantic import BeforeValidator, Field, SecretStr
45
from pydantic_settings import SettingsConfigDict
56

67
from .base import BaseCustomSettings
78

8-
_ANY_HTTP_URL_ADAPTER: Final[TypeAdapter] = TypeAdapter(AnyHttpUrl)
9-
109

1110
class SSMSettings(BaseCustomSettings):
1211
SSM_ACCESS_KEY_ID: SecretStr
1312
SSM_ENDPOINT: Annotated[
14-
str, BeforeValidator(lambda x: str(_ANY_HTTP_URL_ADAPTER.validate_python(x)))
13+
str, BeforeValidator(lambda x: str(AnyHttpUrlLegacyAdapter.validate_python(x)))
1514
] | None = Field(default=None, description="do not define if using standard AWS")
1615
SSM_REGION_NAME: str = "us-east-1"
1716
SSM_SECRET_ACCESS_KEY: SecretStr

0 commit comments

Comments
 (0)