Coverage for python/lsst/daf/butler/core/json.py: 47%
30 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-04 02:04 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-04 02:04 -0800
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, Optional, Protocol, Type
29if TYPE_CHECKING: 29 ↛ 30line 29 didn't jump to line 30, because the condition on line 29 was never true
30 from ..registry import Registry
31 from .dimensions import DimensionUniverse
34class SupportsSimple(Protocol):
35 _serializedType: Type
37 def to_simple(self, minimal: bool) -> Any:
38 ...
40 @classmethod
41 def from_simple(
42 cls, simple: Any, universe: Optional[DimensionUniverse] = None, registry: Optional[Registry] = None
43 ) -> SupportsSimple:
44 ...
47def to_json_pydantic(self: SupportsSimple, minimal: bool = False) -> str:
48 """Convert this class to JSON assuming that the ``to_simple()`` returns
49 a pydantic model.
51 """
52 return self.to_simple(minimal=minimal).json(exclude_defaults=True, exclude_unset=True)
55def from_json_pydantic(
56 cls: Type[SupportsSimple],
57 json_str: str,
58 universe: Optional[DimensionUniverse] = None,
59 registry: Optional[Registry] = None,
60) -> SupportsSimple:
61 """Convert from JSON to a pydantic model."""
62 simple = cls._serializedType.parse_raw(json_str)
63 try:
64 return cls.from_simple(simple, universe=universe, registry=registry)
65 except AttributeError as e:
66 raise AttributeError(f"JSON deserialization requires {cls} has a from_simple() class method") from e
69def to_json_generic(self: SupportsSimple, minimal: bool = False) -> str:
70 """Convert this class to JSON form.
72 The class type is not recorded in the JSON so the JSON decoder
73 must know which class is represented.
75 Parameters
76 ----------
77 minimal : `bool`, optional
78 Use minimal serialization. Requires Registry to convert
79 back to a full type.
81 Returns
82 -------
83 json : `str`
84 The class in JSON string format.
85 """
86 # For now use the core json library to convert a dict to JSON
87 # for us.
88 return json.dumps(self.to_simple(minimal=minimal))
91def from_json_generic(
92 cls: Type[SupportsSimple],
93 json_str: str,
94 universe: Optional[DimensionUniverse] = None,
95 registry: Optional[Registry] = None,
96) -> SupportsSimple:
97 """Return new class from JSON string.
99 Converts a JSON string created by `to_json` and return
100 something of the supplied class.
102 Parameters
103 ----------
104 json_str : `str`
105 Representation of the dimensions in JSON format as created
106 by `to_json()`.
107 universe : `DimensionUniverse`, optional
108 The special graph of all known dimensions. Passed directly
109 to `from_simple()`.
110 registry : `lsst.daf.butler.Registry`, optional
111 Registry to use to convert simple name of a DatasetType to
112 a full `DatasetType`. Passed directly to `from_simple()`.
114 Returns
115 -------
116 constructed : Any
117 Newly-constructed object.
118 """
119 simple = json.loads(json_str)
120 try:
121 return cls.from_simple(simple, universe=universe, registry=registry)
122 except AttributeError as e:
123 raise AttributeError(f"JSON deserialization requires {cls} has a from_simple() class method") from e