1414
1515from feast import PushSource
1616from feast .batch_feature_view import BatchFeatureView
17- from feast .data_source import DataSource , KafkaSource
17+ from feast .data_source import DataSource , KafkaSource , KinesisSource
1818from feast .diff .registry_diff import extract_objects_for_keep_delete_update_add
1919from feast .entity import Entity
2020from feast .feature_service import FeatureService
@@ -114,44 +114,64 @@ def parse_repo(repo_root: Path) -> RepoContents:
114114 request_feature_views = [],
115115 )
116116
117- data_sources_set = set ()
118117 for repo_file in get_repo_files (repo_root ):
119118 module_path = py_path_to_module (repo_file )
120119 module = importlib .import_module (module_path )
120+
121121 for attr_name in dir (module ):
122122 obj = getattr (module , attr_name )
123+
123124 if isinstance (obj , DataSource ) and not any (
124125 (obj is ds ) for ds in res .data_sources
125126 ):
126127 res .data_sources .append (obj )
127- data_sources_set .add (obj )
128+
129+ # Handle batch sources defined within stream sources.
130+ if (
131+ isinstance (obj , PushSource )
132+ or isinstance (obj , KafkaSource )
133+ or isinstance (obj , KinesisSource )
134+ ):
135+ batch_source = obj .batch_source
136+
137+ if batch_source and not any (
138+ (batch_source is ds ) for ds in res .data_sources
139+ ):
140+ res .data_sources .append (batch_source )
128141 if (
129142 isinstance (obj , FeatureView )
130143 and not any ((obj is fv ) for fv in res .feature_views )
131144 and not isinstance (obj , StreamFeatureView )
132145 and not isinstance (obj , BatchFeatureView )
133146 ):
134147 res .feature_views .append (obj )
135- if isinstance (obj .stream_source , PushSource ) and not any (
136- (obj is ds ) for ds in res .data_sources
137- ):
138- push_source_dep = obj .stream_source .batch_source
139- # Don't add if the push source's batch source is a duplicate of an existing batch source
140- if push_source_dep not in data_sources_set :
141- res .data_sources .append (push_source_dep )
148+
149+ # Handle batch sources defined with feature views.
150+ batch_source = obj .batch_source
151+ assert batch_source
152+ if not any ((batch_source is ds ) for ds in res .data_sources ):
153+ res .data_sources .append (batch_source )
154+
155+ # Handle stream sources defined with feature views.
156+ if obj .stream_source :
157+ stream_source = obj .stream_source
158+ if not any ((stream_source is ds ) for ds in res .data_sources ):
159+ res .data_sources .append (stream_source )
142160 elif isinstance (obj , StreamFeatureView ) and not any (
143161 (obj is sfv ) for sfv in res .stream_feature_views
144162 ):
145163 res .stream_feature_views .append (obj )
146- if (
147- isinstance (obj .stream_source , PushSource )
148- or isinstance (obj .stream_source , KafkaSource )
149- and not any ((obj is ds ) for ds in res .data_sources )
150- ):
151- batch_source_dep = obj .stream_source .batch_source
152- # Don't add if the push source's batch source is a duplicate of an existing batch source
153- if batch_source_dep and batch_source_dep not in data_sources_set :
154- res .data_sources .append (batch_source_dep )
164+
165+ # Handle batch sources defined with feature views.
166+ batch_source = obj .batch_source
167+ if not any ((batch_source is ds ) for ds in res .data_sources ):
168+ res .data_sources .append (batch_source )
169+
170+ # Handle stream sources defined with feature views.
171+ stream_source = obj .stream_source
172+ assert stream_source
173+ if not any ((stream_source is ds ) for ds in res .data_sources ):
174+ res .data_sources .append (stream_source )
155175 elif isinstance (obj , Entity ) and not any (
156176 (obj is entity ) for entity in res .entities
157177 ):
@@ -168,6 +188,7 @@ def parse_repo(repo_root: Path) -> RepoContents:
168188 (obj is rfv ) for rfv in res .request_feature_views
169189 ):
170190 res .request_feature_views .append (obj )
191+
171192 res .entities .append (DUMMY_ENTITY )
172193 return res
173194
@@ -300,7 +321,6 @@ def log_infra_changes(
300321
301322@log_exceptions_and_usage
302323def apply_total (repo_config : RepoConfig , repo_path : Path , skip_source_validation : bool ):
303-
304324 os .chdir (repo_path )
305325 project , registry , repo , store = _prepare_registry_and_repo (repo_config , repo_path )
306326 apply_total_with_repo_instance (
0 commit comments