Skip to content

Commit bb45023

Browse files
authored
🎨 Replaces built-in JSON serialization with common_library utilities (#7569)
1 parent 2d68a47 commit bb45023

File tree

46 files changed

+157
-231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+157
-231
lines changed

.github/copilot-instructions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ This document provides guidelines and best practices for using GitHub Copilot in
2323
- ensure we use `fastapi` >0.100 compatible code
2424
- use f-string formatting
2525

26+
27+
### Json serialization
28+
29+
- Generally use `json_dumps`/`json_loads` from `common_library.json_serialization` to built-in `json.dumps` / `json.loads`.
30+
- Prefer Pydantic model methods (e.g., `model.model_dump_json()`) for serialization.
31+
32+
2633
## Node.js-Specific Instructions
2734

2835
- Use ES6+ syntax and features.

packages/dask-task-models-library/src/dask_task_models_library/container_tasks/io.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from pathlib import Path
44
from typing import Annotated, Any, TypeAlias
55

6+
from common_library.json_serialization import json_loads
67
from models_library.basic_regex import MIME_TYPE_RE
78
from models_library.generics import DictModel
89
from models_library.services_types import ServicePortKey
@@ -160,7 +161,7 @@ def from_task_output(
160161
with suppress(json.JSONDecodeError):
161162
# NOTE: The suppression here is ok, since if the data is empty,
162163
# there will be a validation error anyway
163-
data = json.loads(output_data_file.read_text())
164+
data = json_loads(output_data_file.read_text())
164165

165166
for output_key, output_params in schema.items():
166167
if isinstance(output_params, FilePortSchema):

packages/models-library/src/models_library/function_services_catalog/_settings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import json
22
import os
33

4+
from common_library.json_serialization import json_loads
45
from pydantic_settings import BaseSettings
56

67
# Expects env var: FUNCTION_SERVICES_AUTHORS='{"OM":{"name": ...}, "EN":{...} }'
78
try:
8-
AUTHORS = json.loads(os.environ.get("FUNCTION_SERVICES_AUTHORS", "{}"))
9+
AUTHORS = json_loads(os.environ.get("FUNCTION_SERVICES_AUTHORS", "{}"))
910
except json.decoder.JSONDecodeError:
1011
AUTHORS = {}
1112

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
from .services_resources import DEFAULT_SINGLE_SERVICE_NAME
2828

2929
_BaseConfig = ConfigDict(
30-
extra="forbid", arbitrary_types_allowed=True, ignored_types=(cached_property,)
30+
extra="forbid",
31+
arbitrary_types_allowed=True,
32+
ignored_types=(cached_property,),
3133
)
3234

3335

packages/models-library/src/models_library/utils/change_case.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
""" String convesion
1+
"""String convesion
22
33
44
Example of usage in pydantic:
55
66
[...]
7-
class Config:
8-
extra = Extra.forbid
9-
alias_generator = snake_to_camel # <--------
10-
json_loads = orjson.loads
11-
json_dumps = json_dumps
7+
model_config = ConfigDict(
8+
alias_generator=snake_to_camel, # <-- note
9+
)
1210
1311
"""
12+
1413
# Partially taken from https://github.com/autoferrit/python-change-case/blob/master/change_case/change_case.py#L131
1514
import re
1615
from typing import Final

packages/models-library/src/models_library/utils/labels_annotations.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
""" Image labels annotations
1+
"""Image labels annotations
22
33
osparc expects the service configuration (in short: config) attached to the service's image as label annotations.
44
This module defines how this config is serialized/deserialized to/from docker labels annotations
55
"""
66

7-
import json
87
from json.decoder import JSONDecodeError
98
from typing import Any, TypeAlias
109

11-
from common_library.json_serialization import json_dumps
10+
from common_library.json_serialization import json_dumps, json_loads
1211

1312
LabelsAnnotationsDict: TypeAlias = dict[str, str | float | bool | None]
1413

@@ -57,7 +56,7 @@ def from_labels(
5756
for key, label in labels.items():
5857
if key.startswith(f"{prefix_key}."):
5958
try:
60-
value = json.loads(label) # type: ignore
59+
value = json_loads(label)
6160
except JSONDecodeError:
6261
value = label
6362

packages/models-library/src/models_library/utils/nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ async def compute_node_hash(
6464
if payload is not None:
6565
resolved_payload[port_type][port_key] = payload
6666

67-
# now create the hash
6867
# WARNING: Here we cannot change to json_serialization.json_dumps because if would create a different dump string and therefore a different hash
68+
# typically test_node_ports_v2_serialization_v2.py::test_dump will fail if you do this change.
6969
# NOTE that these hashes might have been already stored elsewhere
7070
block_string = json.dumps(resolved_payload, sort_keys=True).encode("utf-8")
7171
raw_hash = hashlib.sha256(block_string)

packages/postgres-database/src/simcore_postgres_database/models/products.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
- Every product has a front-end with exactly the same name
66
"""
77

8-
import json
98
from typing import Literal
109

1110
import sqlalchemy as sa
11+
from common_library.json_serialization import json_dumps
1212
from sqlalchemy.dialects.postgresql import JSONB
1313
from sqlalchemy.sql import func
1414
from typing_extensions import ( # https://docs.pydantic.dev/latest/api/standard_library_types/#typeddict
@@ -114,7 +114,7 @@ class ProductLoginSettingsDict(TypedDict, total=False):
114114

115115
# NOTE: defaults affects migration!!
116116
LOGIN_SETTINGS_DEFAULT = ProductLoginSettingsDict() # = {}
117-
_LOGIN_SETTINGS_SERVER_DEFAULT = json.dumps(LOGIN_SETTINGS_DEFAULT)
117+
_LOGIN_SETTINGS_SERVER_DEFAULT = json_dumps(LOGIN_SETTINGS_DEFAULT)
118118

119119

120120
#

packages/service-integration/src/service_integration/cli/_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import json
21
from pathlib import Path
32
from typing import Annotated, Final
43

54
import rich
65
import typer
76
import yaml
7+
from common_library.json_serialization import json_loads
88
from models_library.utils.labels_annotations import LabelsAnnotationsDict
99
from pydantic import BaseModel
1010

@@ -57,7 +57,7 @@ def _save(service_name: str, filename: Path, model: BaseModel):
5757
rich.print(f"Creating {output_path} ...", end="")
5858

5959
with output_path.open("wt") as fh:
60-
data = json.loads(
60+
data = json_loads(
6161
model.model_dump_json(by_alias=True, exclude_none=True)
6262
)
6363
yaml.safe_dump(data, fh, sort_keys=False)

packages/service-integration/src/service_integration/pytest_plugin/docker_integration.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import jsonschema
1919
import pytest
2020
import yaml
21+
from common_library.json_serialization import json_loads
2122
from docker.errors import APIError
2223
from docker.models.containers import Container
2324

@@ -206,7 +207,7 @@ def convert_to_simcore_labels(image_labels: dict) -> dict:
206207
io_simcore_labels = {}
207208
for key, value in image_labels.items():
208209
if str(key).startswith("io.simcore."):
209-
simcore_label = json.loads(value)
210+
simcore_label = json_loads(value)
210211
simcore_keys = list(simcore_label.keys())
211212
assert len(simcore_keys) == 1
212213
simcore_key = simcore_keys[0]

0 commit comments

Comments
 (0)