def get_feature_server_config_from_type(feature_server_type: str): # We do not support custom feature servers right now. if feature_server_type not in FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE: raise FeastFeatureServerTypeInvalidError(feature_server_type) feature_server_type = FEATURE_SERVER_CONFIG_CLASS_FOR_TYPE[feature_server_type] module_name, config_class_name = feature_server_type.rsplit(".", 1) return get_class_from_type(module_name, config_class_name, config_class_name)
def get_offline_config_from_type(offline_store_type: str): if offline_store_type in OFFLINE_STORE_CLASS_FOR_TYPE: offline_store_type = OFFLINE_STORE_CLASS_FOR_TYPE[offline_store_type] else: assert offline_store_type.endswith("OfflineStore") module_name, offline_store_class_type = offline_store_type.rsplit(".", 1) config_class_name = f"{offline_store_class_type}Config" return get_class_from_type(module_name, config_class_name, config_class_name)
def get_registry_store_class_from_type(registry_store_type: str): if not registry_store_type.endswith("RegistryStore"): raise Exception( 'Registry store class name should end with "RegistryStore"') if registry_store_type in REGISTRY_STORE_CLASS_FOR_TYPE: registry_store_type = REGISTRY_STORE_CLASS_FOR_TYPE[ registry_store_type] module_name, registry_store_class_name = registry_store_type.rsplit(".", 1) return importer.get_class_from_type(module_name, registry_store_class_name, "RegistryStore")
def get_provider(config: RepoConfig, repo_path: Path) -> Provider: if "." not in config.provider: if config.provider not in PROVIDERS_CLASS_FOR_TYPE: raise errors.FeastProviderNotImplementedError(config.provider) provider = PROVIDERS_CLASS_FOR_TYPE[config.provider] else: provider = config.provider # Split provider into module and class names by finding the right-most dot. # For example, provider 'foo.bar.MyProvider' will be parsed into 'foo.bar' and 'MyProvider' module_name, class_name = provider.rsplit(".", 1) cls = importer.get_class_from_type(module_name, class_name, "Provider") return cls(config)
def get_provider(config: RepoConfig, repo_path: Path) -> Provider: if "." not in config.provider: if config.provider in {"gcp", "aws", "local"}: from feast.infra.passthrough_provider import PassthroughProvider return PassthroughProvider(config) else: raise errors.FeastProviderNotImplementedError(config.provider) else: # Split provider into module and class names by finding the right-most dot. # For example, provider 'foo.bar.MyProvider' will be parsed into 'foo.bar' and 'MyProvider' module_name, class_name = config.provider.rsplit(".", 1) cls = importer.get_class_from_type(module_name, class_name, "Provider") return cls(config)
def get_provider(config: RepoConfig, repo_path: Path) -> Provider: if "." not in config.provider: if config.provider == "gcp": from feast.infra.gcp import GcpProvider return GcpProvider(config) elif config.provider == "aws": from feast.infra.aws import AwsProvider return AwsProvider(config) elif config.provider == "local": from feast.infra.local import LocalProvider return LocalProvider(config) else: raise errors.FeastProviderNotImplementedError(config.provider) else: # Split provider into module and class names by finding the right-most dot. # For example, provider 'foo.bar.MyProvider' will be parsed into 'foo.bar' and 'MyProvider' module_name, class_name = config.provider.rsplit(".", 1) cls = importer.get_class_from_type(module_name, class_name, "Provider") return cls(config, repo_path)
def get_data_source_class_from_type(data_source_type: str): module_name, config_class_name = data_source_type.rsplit(".", 1) return get_class_from_type(module_name, config_class_name, "Source")
def construct_test_environment( test_repo_config: TestRepoConfig, create_and_apply: bool = False, materialize: bool = False, ) -> Environment: """ This method should take in the parameters from the test repo config and created a feature repo, apply it, and return the constructed feature store object to callers. This feature store object can be interacted for the purposes of tests. The user is *not* expected to perform any clean up actions. :param test_repo_config: configuration :return: A feature store built using the supplied configuration. """ df = create_dataset() project = f"test_correctness_{str(uuid.uuid4()).replace('-', '')[:8]}" module_name, config_class_name = test_repo_config.offline_store_creator.rsplit( ".", 1) offline_creator: DataSourceCreator = importer.get_class_from_type( module_name, config_class_name, "DataSourceCreator")(project) ds = offline_creator.create_data_source(project, df, field_mapping={ "ts_1": "ts", "id": "driver_id" }) offline_store = offline_creator.create_offline_store_config() online_store = test_repo_config.online_store with tempfile.TemporaryDirectory() as repo_dir_name: config = RepoConfig( registry=str(Path(repo_dir_name) / "registry.db"), project=project, provider=test_repo_config.provider, offline_store=offline_store, online_store=online_store, repo_path=repo_dir_name, ) fs = FeatureStore(config=config) environment = Environment( name=project, test_repo_config=test_repo_config, feature_store=fs, data_source=ds, data_source_creator=offline_creator, ) fvs = [] entities = [] try: if create_and_apply: entities.extend([driver(), customer()]) fvs.extend([ environment.driver_stats_feature_view(), environment.customer_feature_view(), ]) fs.apply(fvs + entities) if materialize: fs.materialize(environment.start_date, environment.end_date) yield environment finally: offline_creator.teardown() fs.teardown()