1313from pydantic .error_wrappers import ErrorWrapper
1414from pydantic .typing import Dict , Optional , Union
1515
16+ from feast .errors import (
17+ FeastFeatureServerTypeInvalidError ,
18+ FeastFeatureServerTypeSetError ,
19+ FeastProviderNotSetError ,
20+ )
1621from feast .importer import get_class_from_type
1722from feast .usage import log_exceptions
1823
3237 "redshift" : "feast.infra.offline_stores.redshift.RedshiftOfflineStore" ,
3338}
3439
40+ FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE = {
41+ "aws_lambda" : "feast.infra.feature_servers.aws_lambda.config.AwsLambdaFeatureServerConfig" ,
42+ }
43+
3544
3645class FeastBaseModel (BaseModel ):
3746 """ Feast Pydantic Configuration Class """
@@ -86,6 +95,9 @@ class RepoConfig(FeastBaseModel):
8695 offline_store : Any
8796 """ OfflineStoreConfig: Offline store configuration (optional depending on provider) """
8897
98+ feature_server : Optional [Any ]
99+ """ FeatureServerConfig: Feature server configuration (optional depending on provider) """
100+
89101 repo_path : Optional [Path ] = None
90102
91103 def __init__ (self , ** data : Any ):
@@ -105,6 +117,11 @@ def __init__(self, **data: Any):
105117 elif isinstance (self .offline_store , str ):
106118 self .offline_store = get_offline_config_from_type (self .offline_store )()
107119
120+ if isinstance (self .feature_server , Dict ):
121+ self .feature_server = get_feature_server_config_from_type (
122+ self .feature_server ["type" ]
123+ )(** self .feature_server )
124+
108125 def get_registry_config (self ):
109126 if isinstance (self .registry , str ):
110127 return RegistryConfig (path = self .registry )
@@ -190,6 +207,43 @@ def _validate_offline_store_config(cls, values):
190207
191208 return values
192209
210+ @root_validator (pre = True )
211+ def _validate_feature_server_config (cls , values ):
212+ # Having no feature server is the default.
213+ if "feature_server" not in values :
214+ return values
215+
216+ # Skip if we aren't creating the configuration from a dict
217+ if not isinstance (values ["feature_server" ], Dict ):
218+ return values
219+
220+ # Make sure that the provider configuration is set. We need it to set the defaults
221+ if "provider" not in values :
222+ raise FeastProviderNotSetError ()
223+
224+ # Make sure that the type is not set, since we will set it based on the provider.
225+ if "type" in values ["feature_server" ]:
226+ raise FeastFeatureServerTypeSetError (values ["feature_server" ]["type" ])
227+
228+ # Set the default type. We only support AWS Lambda for now.
229+ if values ["provider" ] == "aws" :
230+ values ["feature_server" ]["type" ] = "aws_lambda"
231+
232+ feature_server_type = values ["feature_server" ]["type" ]
233+
234+ # Validate the dict to ensure one of the union types match
235+ try :
236+ feature_server_config_class = get_feature_server_config_from_type (
237+ feature_server_type
238+ )
239+ feature_server_config_class (** values ["feature_server" ])
240+ except ValidationError as e :
241+ raise ValidationError (
242+ [ErrorWrapper (e , loc = "feature_server" )], model = RepoConfig ,
243+ )
244+
245+ return values
246+
193247 @validator ("project" )
194248 def _validate_project_name (cls , v ):
195249 from feast .repo_operations import is_valid_name
@@ -244,6 +298,16 @@ def get_offline_config_from_type(offline_store_type: str):
244298 return get_class_from_type (module_name , config_class_name , config_class_name )
245299
246300
301+ def get_feature_server_config_from_type (feature_server_type : str ):
302+ # We do not support custom feature servers right now.
303+ if feature_server_type not in FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE :
304+ raise FeastFeatureServerTypeInvalidError (feature_server_type )
305+
306+ feature_server_type = FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE [feature_server_type ]
307+ module_name , config_class_name = feature_server_type .rsplit ("." , 1 )
308+ return get_class_from_type (module_name , config_class_name , config_class_name )
309+
310+
247311def load_repo_config (repo_path : Path ) -> RepoConfig :
248312 config_path = repo_path / "feature_store.yaml"
249313
0 commit comments