11from __future__ import annotations
22
33from copy import deepcopy
4- from typing import Any
4+ from typing import TYPE_CHECKING , Any , cast
55
66from .builder import APIBackendBuilder
77from .config import Config
88
9+ if TYPE_CHECKING :
10+ from openml ._api .resources import (
11+ DatasetAPI ,
12+ EstimationProcedureAPI ,
13+ EvaluationAPI ,
14+ EvaluationMeasureAPI ,
15+ FlowAPI ,
16+ RunAPI ,
17+ SetupAPI ,
18+ StudyAPI ,
19+ TaskAPI ,
20+ )
21+
922
1023class APIBackend :
1124 _instance : APIBackend | None = None
@@ -14,12 +27,41 @@ def __init__(self, config: Config | None = None):
1427 self ._config : Config = config or Config ()
1528 self ._backend = APIBackendBuilder .build (self ._config )
1629
17- def __getattr__ (self , name : str ) -> Any :
18- """
19- Delegate attribute access to the underlying backend.
20- Called only if attribute is not found on RuntimeBackend.
21- """
22- return getattr (self ._backend , name )
30+ @property
31+ def dataset (self ) -> DatasetAPI :
32+ return cast ("DatasetAPI" , self ._backend .dataset )
33+
34+ @property
35+ def task (self ) -> TaskAPI :
36+ return cast ("TaskAPI" , self ._backend .task )
37+
38+ @property
39+ def evaluation_measure (self ) -> EvaluationMeasureAPI :
40+ return cast ("EvaluationMeasureAPI" , self ._backend .evaluation_measure )
41+
42+ @property
43+ def estimation_procedure (self ) -> EstimationProcedureAPI :
44+ return cast ("EstimationProcedureAPI" , self ._backend .estimation_procedure )
45+
46+ @property
47+ def evaluation (self ) -> EvaluationAPI :
48+ return cast ("EvaluationAPI" , self ._backend .evaluation )
49+
50+ @property
51+ def flow (self ) -> FlowAPI :
52+ return cast ("FlowAPI" , self ._backend .flow )
53+
54+ @property
55+ def study (self ) -> StudyAPI :
56+ return cast ("StudyAPI" , self ._backend .study )
57+
58+ @property
59+ def run (self ) -> RunAPI :
60+ return cast ("RunAPI" , self ._backend .run )
61+
62+ @property
63+ def setup (self ) -> SetupAPI :
64+ return cast ("SetupAPI" , self ._backend .setup )
2365
2466 @classmethod
2567 def get_instance (cls ) -> APIBackend :
@@ -38,7 +80,7 @@ def set_config(cls, config: Config) -> None:
3880 instance ._backend = APIBackendBuilder .build (config )
3981
4082 @classmethod
41- def get_config_value (cls , key : str ) -> Config :
83+ def get_config_value (cls , key : str ) -> Any :
4284 keys = key .split ("." )
4385 config_value = cls .get_instance ()._config
4486 for k in keys :
@@ -60,3 +102,27 @@ def set_config_value(cls, key: str, value: Any) -> None:
60102 else :
61103 setattr (parent , keys [- 1 ], value )
62104 cls .set_config (config )
105+
106+ @classmethod
107+ def get_config_values (cls , keys : list [str ]) -> list [Any ]:
108+ values = []
109+ for key in keys :
110+ value = cls .get_config_value (key )
111+ values .append (value )
112+ return values
113+
114+ @classmethod
115+ def set_config_values (cls , config_dict : dict [str , Any ]) -> None :
116+ config = cls .get_instance ()._config
117+
118+ for key , value in config_dict .items ():
119+ keys = key .split ("." )
120+ parent = config
121+ for k in keys [:- 1 ]:
122+ parent = parent [k ] if isinstance (parent , dict ) else getattr (parent , k )
123+ if isinstance (parent , dict ):
124+ parent [keys [- 1 ]] = value
125+ else :
126+ setattr (parent , keys [- 1 ], value )
127+
128+ cls .set_config (config )
0 commit comments