| 1194 | |
| 1195 | |
| 1196 | def _get_feature_views_to_use( |
| 1197 | registry: "BaseRegistry", |
| 1198 | project, |
| 1199 | features: Union[List[str], "FeatureService"], |
| 1200 | allow_cache=False, |
| 1201 | hide_dummy_entity: bool = True, |
| 1202 | ) -> Tuple[List["FeatureView"], List["OnDemandFeatureView"]]: |
| 1203 | from feast.feature_service import FeatureService |
| 1204 | from feast.feature_view import DUMMY_ENTITY_NAME |
| 1205 | from feast.on_demand_feature_view import OnDemandFeatureView |
| 1206 | |
| 1207 | if isinstance(features, FeatureService): |
| 1208 | feature_views = [ |
| 1209 | (projection.name, None, projection) |
| 1210 | for projection in features.feature_view_projections |
| 1211 | ] |
| 1212 | else: |
| 1213 | assert features is not None |
| 1214 | # Parse version-qualified refs: 'fv@v2:feat' -> ('fv', 2, None) |
| 1215 | parsed = [] |
| 1216 | seen = set() |
| 1217 | for feature in features: |
| 1218 | fv_name, version_num, _ = _parse_feature_ref(feature) |
| 1219 | key = (fv_name, version_num) |
| 1220 | if key not in seen: |
| 1221 | seen.add(key) |
| 1222 | parsed.append((fv_name, version_num, None)) |
| 1223 | feature_views = parsed # type: ignore[assignment] |
| 1224 | |
| 1225 | fvs_to_use, od_fvs_to_use = [], [] |
| 1226 | for name, version_num, projection in feature_views: |
| 1227 | if version_num is not None: |
| 1228 | if not getattr(registry, "enable_online_versioning", False): |
| 1229 | raise ValueError( |
| 1230 | f"Version-qualified ref '{name}@v{version_num}' not supported: " |
| 1231 | f"online versioning is disabled. Set 'enable_online_feature_view_versioning: true' " |
| 1232 | f"under 'registry' in feature_store.yaml." |
| 1233 | ) |
| 1234 | # Version-qualified reference: look up the specific version snapshot |
| 1235 | try: |
| 1236 | fv = registry.get_feature_view_by_version( |
| 1237 | name, project, version_num, allow_cache |
| 1238 | ) |
| 1239 | except NotImplementedError: |
| 1240 | # Fall back for v0 on registries that don't implement versioned lookup |
| 1241 | if version_num == 0: |
| 1242 | fv = registry.get_any_feature_view(name, project, allow_cache) |
| 1243 | else: |
| 1244 | raise |
| 1245 | # Set version_tag on the projection so name_to_use() returns versioned key |
| 1246 | if hasattr(fv, "projection") and fv.projection is not None: |
| 1247 | fv.projection.version_tag = version_num |
| 1248 | else: |
| 1249 | fv = registry.get_any_feature_view(name, project, allow_cache) |
| 1250 | |
| 1251 | if hasattr(fv, "enabled") and not fv.enabled: |
| 1252 | raise ValueError( |
| 1253 | f"Feature view '{name}' is disabled and cannot serve features. " |