9
9
import pandas as pd
10
10
import pydantic
11
11
import tlz
12
+ from pydantic import ConfigDict
12
13
13
14
from ._search import search , search_apply_require_all_on
14
15
@@ -40,9 +41,7 @@ class AggregationType(str, enum.Enum):
40
41
join_existing = 'join_existing'
41
42
union = 'union'
42
43
43
- class Config :
44
- validate_all = True
45
- validate_assignment = True
44
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
46
45
47
46
48
47
class DataFormat (str , enum .Enum ):
@@ -51,57 +50,47 @@ class DataFormat(str, enum.Enum):
51
50
reference = 'reference'
52
51
opendap = 'opendap'
53
52
54
- class Config :
55
- validate_all = True
56
- validate_assignment = True
53
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
57
54
58
55
59
56
class Attribute (pydantic .BaseModel ):
60
57
column_name : pydantic .StrictStr
61
58
vocabulary : pydantic .StrictStr = ''
62
59
63
- class Config :
64
- validate_all = True
65
- validate_assignment = True
60
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
66
61
67
62
68
63
class Assets (pydantic .BaseModel ):
69
64
column_name : pydantic .StrictStr
70
- format : typing .Optional [DataFormat ]
71
- format_column_name : typing .Optional [pydantic .StrictStr ]
65
+ format : typing .Optional [DataFormat ] = None
66
+ format_column_name : typing .Optional [pydantic .StrictStr ] = None
72
67
73
- class Config :
74
- validate_all = True
75
- validate_assignment = True
68
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
76
69
77
- @pydantic .root_validator
78
- def _validate_data_format (cls , values ):
79
- data_format , format_column_name = values . get ( ' format' ), values . get ( ' format_column_name' )
70
+ @pydantic .model_validator ( mode = 'after' )
71
+ def _validate_data_format (cls , model ):
72
+ data_format , format_column_name = model . format , model . format_column_name
80
73
if data_format is not None and format_column_name is not None :
81
74
raise ValueError ('Cannot set both format and format_column_name' )
82
75
elif data_format is None and format_column_name is None :
83
76
raise ValueError ('Must set one of format or format_column_name' )
84
- return values
77
+ return model
85
78
86
79
87
80
class Aggregation (pydantic .BaseModel ):
88
81
type : AggregationType
89
82
attribute_name : pydantic .StrictStr
90
- options : typing . Optional [ dict ] = {}
83
+ options : dict = {}
91
84
92
- class Config :
93
- validate_all = True
94
- validate_assignment = True
85
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
95
86
96
87
97
88
class AggregationControl (pydantic .BaseModel ):
98
89
variable_column_name : pydantic .StrictStr
99
90
groupby_attrs : list [pydantic .StrictStr ]
100
91
aggregations : list [Aggregation ] = []
101
92
102
- class Config :
103
- validate_all = True
104
- validate_assignment = True
93
+ model_config = ConfigDict (validate_default = True , validate_assignment = True )
105
94
106
95
107
96
class ESMCatalogModel (pydantic .BaseModel ):
@@ -113,35 +102,33 @@ class ESMCatalogModel(pydantic.BaseModel):
113
102
attributes : list [Attribute ]
114
103
assets : Assets
115
104
aggregation_control : typing .Optional [AggregationControl ] = None
116
- id : typing . Optional [ str ] = ''
105
+ id : str = ''
117
106
catalog_dict : typing .Optional [list [dict ]] = None
118
- catalog_file : pydantic .StrictStr = None
119
- description : pydantic .StrictStr = None
120
- title : pydantic .StrictStr = None
107
+ catalog_file : typing . Optional [ pydantic .StrictStr ] = None
108
+ description : typing . Optional [ pydantic .StrictStr ] = None
109
+ title : typing . Optional [ pydantic .StrictStr ] = None
121
110
last_updated : typing .Optional [typing .Union [datetime .datetime , datetime .date ]] = None
122
- _df : typing . Optional [ pd .DataFrame ] = pydantic .PrivateAttr ()
111
+ _df : pd .DataFrame = pydantic .PrivateAttr ()
123
112
124
- class Config :
125
- arbitrary_types_allowed = True
126
- underscore_attrs_are_private = True
127
- validate_all = True
128
- validate_assignment = True
113
+ model_config = ConfigDict (
114
+ arbitrary_types_allowed = True , validate_default = True , validate_assignment = True
115
+ )
129
116
130
- @pydantic .root_validator
131
- def validate_catalog (cls , values ):
132
- catalog_dict , catalog_file = values . get ( ' catalog_dict' ), values . get ( ' catalog_file' )
117
+ @pydantic .model_validator ( mode = 'after' )
118
+ def validate_catalog (cls , model ):
119
+ catalog_dict , catalog_file = model . catalog_dict , model . catalog_file
133
120
if catalog_dict is not None and catalog_file is not None :
134
121
raise ValueError ('catalog_dict and catalog_file cannot be set at the same time' )
135
122
136
- return values
123
+ return model
137
124
138
125
@classmethod
139
126
def from_dict (cls , data : dict ) -> 'ESMCatalogModel' :
140
127
esmcat = data ['esmcat' ]
141
128
df = data ['df' ]
142
129
if 'last_updated' not in esmcat :
143
130
esmcat ['last_updated' ] = None
144
- cat = cls .parse_obj (esmcat )
131
+ cat = cls .model_validate (esmcat )
145
132
cat ._df = df
146
133
return cat
147
134
@@ -254,7 +241,7 @@ def load(
254
241
data = json .loads (fobj .read ())
255
242
if 'last_updated' not in data :
256
243
data ['last_updated' ] = None
257
- cat = cls .parse_obj (data )
244
+ cat = cls .model_validate (data )
258
245
if cat .catalog_file :
259
246
if _mapper .fs .exists (cat .catalog_file ):
260
247
csv_path = cat .catalog_file
@@ -417,32 +404,32 @@ class QueryModel(pydantic.BaseModel):
417
404
418
405
query : dict [pydantic .StrictStr , typing .Union [typing .Any , list [typing .Any ]]]
419
406
columns : list [str ]
420
- require_all_on : typing .Union [str , list [typing .Any ]] = None
407
+ require_all_on : typing .Optional [ typing . Union [str , list [typing .Any ] ]] = None
421
408
422
- class Config :
423
- validate_all = True
424
- validate_assignment = True
409
+ # TODO: Seem to be unable to modify fields in model_validator with
410
+ # validate_assignment=True since it leads to recursion
411
+ model_config = ConfigDict ( validate_default = True , validate_assignment = False )
425
412
426
- @pydantic .root_validator ( pre = False )
427
- def validate_query (cls , values ):
428
- query = values . get ( ' query' , {})
429
- columns = values . get ( ' columns' )
430
- require_all_on = values . get ( ' require_all_on' , [])
413
+ @pydantic .model_validator ( mode = 'after' )
414
+ def validate_query (cls , model ):
415
+ query = model . query
416
+ columns = model . columns
417
+ require_all_on = model . require_all_on
431
418
432
419
if query :
433
420
for key in query :
434
421
if key not in columns :
435
422
raise ValueError (f'Column { key } not in columns { columns } ' )
436
423
if isinstance (require_all_on , str ):
437
- values [ ' require_all_on' ] = [require_all_on ]
424
+ model . require_all_on = [require_all_on ]
438
425
if require_all_on is not None :
439
- for key in values [ ' require_all_on' ] :
426
+ for key in model . require_all_on :
440
427
if key not in columns :
441
428
raise ValueError (f'Column { key } not in columns { columns } ' )
442
429
_query = query .copy ()
443
430
for key , value in _query .items ():
444
431
if isinstance (value , (str , int , float , bool )) or value is None or value is pd .NA :
445
432
_query [key ] = [value ]
446
433
447
- values [ ' query' ] = _query
448
- return values
434
+ model . query = _query
435
+ return model
0 commit comments