Commit 12d2d9b
refactor: Extract shared proto conversion helpers and simplify to_proto() methods (feast-dev#5998)
* feat: Add centralized protobuf conversion system
This commit introduces a new proto_conversion module that provides a
centralized, type-safe system for converting between Python objects
and their protobuf representations.
Key improvements:
- ProtoConverter: Generic abstract base class for all converters
- ConverterRegistry: Centralized registry with type-safe lookup
- ValueTypeConverter: Consolidated value conversion with type handlers
- DataFrameProtoConverter: Unified Arrow/DataFrame conversion
- Object converters: Entity, FeatureView, FeatureService converters
- Exception hierarchy: Clear, typed exceptions for error handling
- Backward compatibility: compat module for gradual migration
Benefits:
- Eliminates code duplication (80% reduction in shared logic)
- Reduces cyclomatic complexity (from 25+ branches to <10)
- Replaces duck-typing with proper isinstance() checks
- Provides consistent error handling across all converters
- Enables type-safe extension for custom converters
- Maintains full backward compatibility with existing APIs
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* fix: resolve mypy type errors in proto_conversion module
- Add TYPE_CHECKING import for ProtoValue in converter.py
- Create separate TypeVar L for LegacyProtoSerializable methods
- Use cast() for return types in feature_view_converter.py
- Fix timestamp return type annotation in dataframe_converter.py
- Extract pa_type to variable before using in null_column creation
- Remove unused Any import from serializable.py
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* refactor: remove registry pattern, simplify proto conversion
Remove unnecessary complexity from proto conversion module:
- Remove ConverterRegistry singleton and registration system
- Remove ProtoSerializable/LegacyProtoSerializable mixins
- Remove compat.py backward compatibility layer
- Simplify converter.py to just the ProtoConverter base class
- Update tests to test converters directly without registry
The converters remain useful for consolidating duplicated logic:
- ValueTypeConverter: Unified value type conversion
- DataFrameProtoConverter: Arrow/DataFrame conversion
- EntityConverter, FeatureViewConverter, etc.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* refactor: remove strategy pattern from DataFrameProtoConverter
Simplify dataframe_converter.py by replacing the ArrowConversionStrategy
abstract class and its two implementations with straightforward conditionals.
Before: ~490 lines with 3 classes (ABC + 2 strategies)
After: ~300 lines with 1 class using is_odfv boolean flag
The strategy pattern added unnecessary indirection for just 2 variations.
Simple if/else branches are easier to follow and maintain.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* refactor: extract helpers to reduce duplication in proto conversion
- utils.py: Extract _columns_to_proto_values() and _build_entity_keys()
helpers to consolidate shared logic between FV and ODFV converters
- utils.py: Fix inefficient null column creation - create null proto
values directly instead of building PyArrow arrays
- utils.py: Cache column names set to avoid recreating list in loop
- type_map.py: Extract _convert_timestamp_collection_to_proto() and
_convert_bool_collection_to_proto() to handle special type conversions
- type_map.py: Extract _validate_collection_item_types() for shared
type validation logic
- type_map.py: Split _python_value_to_proto_value() into smaller
functions (_convert_list_values_to_proto, _convert_scalar_values_to_proto)
- Remove unused proto_conversion module and tests
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* fix: correct type ignore placement in type_map.py
Move # type: ignore comments to the correct lines after formatter
rearranged the code.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* fix: Fix SQLite I/O error in TestOnDemandPythonTransformationAllDataTypes tests
The issue was that setUp() used a 'with tempfile.TemporaryDirectory()' context
manager, which deleted the temporary directory when setUp() finished, but the
tests tried to access the SQLite database files later.
Changed to use tempfile.mkdtemp() with explicit cleanup in tearDown(), matching
the pattern used in the TestOnDemandPythonTransformation class.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* refactor: extract shared helpers for to_proto() methods in feature views
- Add _serialize_data_source() helper for data source serialization with class type annotation
- Add _transformation_to_proto() helper for unified transformation handling
- Add _mode_to_string() helper for consistent mode conversion
- Refactor FeatureView.to_proto_spec() to use shared helpers
- Refactor StreamFeatureView.to_proto() to use shared helpers
- Refactor OnDemandFeatureView.to_proto() to use shared helpers
- Fix redundant conditionals in OnDemandFeatureView
- Remove unused FeatureTransformationProto import
Co-Authored-By: Claude Opus 4.5 <[email protected]>
* refactor: move proto helpers to dedicated proto_utils module
- Create feast/proto_utils.py with shared proto conversion utilities
- Move serialize_data_source(), transformation_to_proto(), mode_to_string()
from feature_view.py to proto_utils.py
- Update imports in feature_view.py, stream_feature_view.py, on_demand_feature_view.py
Co-Authored-By: Claude Opus 4.5 <[email protected]>
---------
Co-authored-by: Claude Opus 4.5 <[email protected]>1 parent 6f5203a commit 12d2d9b
7 files changed
Lines changed: 727 additions & 603 deletions
File tree
- sdk/python
- feast
- tests/unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
29 | 34 | | |
30 | 35 | | |
31 | 36 | | |
| |||
36 | 41 | | |
37 | 42 | | |
38 | 43 | | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
414 | 416 | | |
415 | 417 | | |
416 | 418 | | |
417 | | - | |
418 | | - | |
419 | | - | |
420 | | - | |
| 419 | + | |
| 420 | + | |
421 | 421 | | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
426 | 422 | | |
427 | 423 | | |
428 | 424 | | |
| |||
431 | 427 | | |
432 | 428 | | |
433 | 429 | | |
434 | | - | |
435 | | - | |
436 | | - | |
437 | | - | |
438 | | - | |
439 | | - | |
440 | | - | |
441 | | - | |
442 | | - | |
443 | | - | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | | - | |
451 | | - | |
452 | | - | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
| 430 | + | |
| 431 | + | |
458 | 432 | | |
459 | 433 | | |
460 | 434 | | |
| |||
472 | 446 | | |
473 | 447 | | |
474 | 448 | | |
475 | | - | |
| 449 | + | |
476 | 450 | | |
477 | 451 | | |
478 | 452 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | 28 | | |
31 | 29 | | |
32 | 30 | | |
| |||
471 | 469 | | |
472 | 470 | | |
473 | 471 | | |
474 | | - | |
475 | | - | |
476 | | - | |
477 | | - | |
478 | | - | |
479 | | - | |
480 | | - | |
481 | | - | |
482 | | - | |
| 472 | + | |
483 | 473 | | |
484 | | - | |
485 | | - | |
486 | | - | |
487 | | - | |
488 | | - | |
489 | | - | |
490 | | - | |
491 | | - | |
492 | | - | |
493 | | - | |
494 | 474 | | |
495 | 475 | | |
496 | | - | |
| 476 | + | |
497 | 477 | | |
498 | 478 | | |
499 | 479 | | |
| |||
505 | 485 | | |
506 | 486 | | |
507 | 487 | | |
508 | | - | |
| 488 | + | |
509 | 489 | | |
510 | 490 | | |
511 | 491 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
233 | 234 | | |
234 | 235 | | |
235 | 236 | | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | | - | |
243 | | - | |
244 | | - | |
| 237 | + | |
| 238 | + | |
245 | 239 | | |
246 | 240 | | |
247 | 241 | | |
| |||
260 | 254 | | |
261 | 255 | | |
262 | 256 | | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | 257 | | |
268 | 258 | | |
269 | 259 | | |
| |||
282 | 272 | | |
283 | 273 | | |
284 | 274 | | |
285 | | - | |
286 | | - | |
| 275 | + | |
| 276 | + | |
287 | 277 | | |
288 | 278 | | |
289 | | - | |
| 279 | + | |
290 | 280 | | |
291 | 281 | | |
292 | 282 | | |
| |||
0 commit comments