1
1
import json
2
2
import logging
3
- from typing import Union , TextIO , Optional , Dict , Type , List
3
+ from pathlib import Path
4
+ from typing import Union , TextIO , Optional , Type , List
4
5
5
6
from hbreader import FileInfo
6
7
14
15
class JSONLoader (Loader ):
15
16
16
17
def load_as_dict (self ,
17
- source : Union [str , dict , TextIO ],
18
+ source : Union [str , dict , TextIO ],
18
19
* ,
19
20
base_dir : Optional [str ] = None ,
20
21
metadata : Optional [FileInfo ] = None ) -> Union [dict , List [dict ]]:
@@ -23,12 +24,33 @@ def load_as_dict(self,
23
24
return self .json_clean (data_as_dict )
24
25
25
26
def load_any (self ,
26
- source : Union [str , dict , TextIO ],
27
+ source : Union [str , dict , TextIO , Path ],
27
28
target_class : Type [Union [BaseModel , YAMLRoot ]],
28
29
* ,
29
30
base_dir : Optional [str ] = None ,
30
31
metadata : Optional [FileInfo ] = None ,
31
32
** _ ) -> Union [BaseModel , YAMLRoot , List [BaseModel ], List [YAMLRoot ]]:
33
+ """
34
+ Load the JSON in source into the python target_class structure
35
+
36
+ :param source: JSON data source. Can be a URL, a file name, a JSON string, a resolveable filepath or an existing graph
37
+ :param target_class: LinkML class to load the JSON into
38
+ :param base_dir: Base directory that can be used if file name or URL. This is copied into metadata if present
39
+ :param metadata: source information. Used by some loaders to record where information came from
40
+ :return: data instances of target_class
41
+ """
42
+
43
+ # see https://github.com/linkml/linkml/issues/2458, this works around a limitation in hbreader
44
+ if isinstance (source , Path ):
45
+ full_path = source .resolve ()
46
+ try :
47
+ with full_path .open ("r" , encoding = "utf-8" ) as file :
48
+ new_source = json .load (file )
49
+ source = new_source
50
+ except FileNotFoundError as e :
51
+ raise ValueError (f"File not found: { source } " ) from e
52
+ except json .JSONDecodeError as e :
53
+ raise ValueError (f"Invalid JSON in { source } : { e } " )
32
54
data_as_dict = self .load_as_dict (source , base_dir = base_dir , metadata = metadata )
33
55
34
56
if isinstance (data_as_dict , dict ):
0 commit comments