Coverage for python/lsst/daf/butler/core/json.py: 48%
27 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-14 09:11 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-14 09:11 +0000
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22from __future__ import annotations
24__all__ = ("to_json_generic", "from_json_generic", "to_json_pydantic", "from_json_pydantic")
26import json
27from typing import TYPE_CHECKING, Any, Protocol
29if TYPE_CHECKING:
30 from pydantic import BaseModel
32 from ..registry import Registry
33 from .dimensions import DimensionUniverse
36class SupportsSimple(Protocol):
37 _serializedType: type[BaseModel]
39 def to_simple(self, minimal: bool) -> Any:
40 ...
42 @classmethod
43 def from_simple(
44 cls, simple: Any, universe: DimensionUniverse | None = None, registry: Registry | None = None
45 ) -> SupportsSimple:
46 ...
49def to_json_pydantic(self: SupportsSimple, minimal: bool = False) -> str:
50 """Convert this class to JSON assuming that the ``to_simple()`` returns
51 a pydantic model.
53 """
54 return self.to_simple(minimal=minimal).json(exclude_defaults=True, exclude_unset=True)
57def from_json_pydantic(
58 cls: type[SupportsSimple],
59 json_str: str,
60 universe: DimensionUniverse | None = None,
61 registry: Registry | None = None,
62) -> SupportsSimple:
63 """Convert from JSON to a pydantic model."""
64 simple = cls._serializedType.parse_raw(json_str)
65 try:
66 return cls.from_simple(simple, universe=universe, registry=registry)
67 except AttributeError as e:
68 raise AttributeError(f"JSON deserialization requires {cls} has a from_simple() class method") from e
71def to_json_generic(self: SupportsSimple, minimal: bool = False) -> str:
72 """Convert this class to JSON form.
74 The class type is not recorded in the JSON so the JSON decoder
75 must know which class is represented.
77 Parameters
78 ----------
79 minimal : `bool`, optional
80 Use minimal serialization. Requires Registry to convert
81 back to a full type.
83 Returns
84 -------
85 json : `str`
86 The class in JSON string format.
87 """
88 # For now use the core json library to convert a dict to JSON
89 # for us.
90 return json.dumps(self.to_simple(minimal=minimal))
93def from_json_generic(
94 cls: type[SupportsSimple],
95 json_str: str,
96 universe: DimensionUniverse | None = None,
97 registry: Registry | None = None,
98) -> SupportsSimple:
99 """Return new class from JSON string.
101 Converts a JSON string created by `to_json` and return
102 something of the supplied class.
104 Parameters
105 ----------
106 json_str : `str`
107 Representation of the dimensions in JSON format as created
108 by `to_json()`.
109 universe : `DimensionUniverse`, optional
110 The special graph of all known dimensions. Passed directly
111 to `from_simple()`.
112 registry : `lsst.daf.butler.Registry`, optional
113 Registry to use to convert simple name of a DatasetType to
114 a full `DatasetType`. Passed directly to `from_simple()`.
116 Returns
117 -------
118 constructed : Any
119 Newly-constructed object.
120 """
121 simple = json.loads(json_str)
122 try:
123 return cls.from_simple(simple, universe=universe, registry=registry)
124 except AttributeError as e:
125 raise AttributeError(f"JSON deserialization requires {cls} has a from_simple() class method") from e