refactor(core): add transition path to using PEP8 naming for Pydantic models

Aperta
#888 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
42/100
Tipo di issue
Refactoring
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
python
Ambito
backend

Direzione di ricerca

Inizia controllando la versione di Pydantic, quindi leggi i requisiti di orchestrator/utilities/base_model.py e i modelli esistenti in orchestrator/core/operation/config.py e orchestrator/modules/operators/randomwalk.py. Usa tests/core/test_operation_dual_naming.py e tests/utilities/test_base_model.py per verificare entrambe le convenzioni di denominazione, il comportamento della serializzazione e i round trip. Il lavoro è completato quando il modello base e le migrazioni iniziali funzionano senza rompere i test esistenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

enhancement refactor

Is your feature request related to a problem? Please describe.

Currently, ado uses camelCase naming conventions for pydantic model fields
(e.g., numberEntities, batchSize), which is inconsistent with Python's PEP8
style guide that recommends snake_case for variable and attribute names. This
creates friction for Python developers who expect standard Python naming
conventions and makes the codebase less Pythonic.

⚠️ IMPORTANT: Requires Pydantic 2.11+

This feature requires pydantic 2.11 or higher for the serialize_by_alias
configuration option. Before implementing, verify the pydantic version:

python -c "import pydantic; print(pydantic.VERSION)"

If needed, update pydantic:

uv add "pydantic>=2.11"

Describe the solution you'd like

Create an ADOBaseModel base class that all pydantic models inherit from,
enabling:

  1. Dual naming support during migration: Accept both camelCase and
    snake_case field names
  2. PEP8-compliant serialization: Output uses snake_case by default
  3. Backward compatibility: Existing camelCase code continues to work
  4. Gradual migration path: Teams can migrate to snake_case incrementally

Proposed ADOBaseModel Implementation

Create orchestrator/utilities/base_model.py:

# Copyright IBM Corporation 2025, 2026
# SPDX-License-Identifier: MIT

"""Base pydantic model for ado with common configuration."""

import pydantic
from pydantic import ConfigDict
from pydantic.alias_generators import to_snake


class ADOBaseModel(pydantic.BaseModel):
    """Base model for ado pydantic models with common configuration.

    This base model provides:
    - populate_by_name=True: Allows both field names and aliases to be used during validation
    - alias_generator: Automatically generates snake_case aliases for all camelCase field names
      using pydantic's built-in to_snake function
    - serialize_by_alias=True: Serializes using snake_case aliases by default
      ⚠️ REQUIRES PYDANTIC 2.11+

    All ado pydantic models should inherit from this base class to ensure
    consistent behavior across the codebase, particularly for supporting both
    camelCase and snake_case field naming conventions.

    Field aliases are automatically generated via alias_generator, so no manual
    alias definition is needed. For example, a field named `numberEntities` will
    automatically accept both `numberEntities` and `number_entities` as input,
    and will serialize as `number_entities` by default.
    """

    model_config = ConfigDict(
        populate_by_name=True,
        alias_generator=to_snake,
        serialize_by_alias=True,  # ⚠️ Requires pydantic 2.11+
    )

Usage Examples

Before:

class MyModel(pydantic.BaseModel):
    numberEntities: int
    batchSize: int

After:

from orchestrator.utilities.base_model import ADOBaseModel

class MyModel(ADOBaseModel):
    numberEntities: int  # Still camelCase in code for backward compatibility
    batchSize: int
    # But accepts both numberEntities and number_entities during validation
    # And serializes as number_entities by default

Input - accepts both naming conventions:

m1 = MyModel(numberEntities=100, batchSize=10)  # camelCase works
m2 = MyModel(number_entities=100, batch_size=10)  # snake_case works
m3 = MyModel(numberEntities=100, batch_size=10)  # mixed works

Output - serializes to snake_case by default:

m1.model_dump()
# {'number_entities': 100, 'batch_size': 10}

# Can override to get camelCase output if needed
m1.model_dump(by_alias=False)
# {'numberEntities': 100, 'batchSize': 10}

Implementation Plan

Phase 1: Create Base Infrastructure
  1. Create orchestrator/utilities/base_model.py with ADOBaseModel
  2. Create comprehensive test suite in tests/utilities/test_base_model.py
  3. Create demo script in scripts/demo_base_model.py
Phase 2: Core Models (High Priority)
  • All models in orchestrator/core/:
    • discoveryspace/config.py
    • operation/config.py
    • actuatorconfiguration/config.py
    • samplestore/config.py
    • datacontainer/config.py
  • All models in orchestrator/schema/:
    • entity.py, experiment.py, property.py, result.py, etc.
Phase 3: Module Models (Medium Priority)
  • Models in orchestrator/modules/actuators/
  • Models in orchestrator/modules/operators/
  • CLI models in orchestrator/cli/models/
Phase 4: Testing & Documentation
  • Update all tests to use snake_case
  • Update documentation and examples to use snake_case
  • Add migration guide for users
Phase 5: Deprecation (Future)
  • After sufficient adoption period, consider deprecating camelCase-only usage
  • Add warnings for camelCase-only field access

Technical Approach

For each model:

  1. Change inheritance from pydantic.BaseModel to ADOBaseModel
  2. Keep existing camelCase field names (for backward compatibility)
  3. Remove any manual field aliases (auto-generated by ADOBaseModel)
  4. Update tests to verify both naming conventions work
  5. Update documentation to show snake_case examples

Proof-of-Concept Files

To validate the approach, create these files first:

  1. orchestrator/utilities/base_model.py - ADOBaseModel implementation (see
    above)

  2. tests/core/test_operation_dual_naming.py - Comprehensive test suite
    demonstrating:

    • Creating configurations with camelCase parameters
    • Creating configurations with snake_case parameters
    • Mixed naming conventions
    • Serialization to snake_case by default
    • Optional camelCase serialization with by_alias=False
    • Roundtrip testing (create → dump → create)
  3. scripts/demo_operation_dual_naming.py - Working demonstration script
    showing:

    • Input with both naming conventions
    • Snake_case serialization by default
    • Optional camelCase serialization
    • YAML and JSON compatibility
  4. Initial model migrations (proof of concept):

    • orchestrator/core/operation/config.py - DiscoveryOperationConfiguration
    • orchestrator/modules/operators/randomwalk.py - RandomWalkParameters

Describe alternatives you've considered

  1. Manual field aliases: Too verbose and error-prone, requires maintaining
    aliases for every field
  2. Big-bang migration: Breaking change, would require all users to update
    simultaneously
  3. Keep camelCase: Inconsistent with Python conventions, harder for Python
    developers
  4. Separate snake_case models: Code duplication, maintenance burden
  5. Custom serialization methods: More complex than using pydantic's built-in
    serialize_by_alias

Additional context

Benefits:

  • More Pythonic codebase following PEP8 conventions
  • Easier onboarding for Python developers
  • Consistent with Python ecosystem standards
  • Smooth migration path with backward compatibility
  • Leverages pydantic's built-in features (no custom code needed)

Prerequisites:

  • ⚠️ Pydantic 2.11+ required for serialize_by_alias config option
  • Verify version: python -c "import pydantic; print(pydantic.VERSION)"
  • Update if needed: uv add "pydantic>=2.11"

Success Criteria:

  • ADOBaseModel created in orchestrator/utilities/base_model.py
  • All pydantic models inherit from ADOBaseModel
  • All models accept both camelCase and snake_case input
  • All models serialize to snake_case by default
  • All existing tests pass
  • New tests verify dual naming support
  • Documentation updated with snake_case examples

Testing Requirements:

  • Unit tests for ADOBaseModel functionality
  • Integration tests for each migrated model
  • Roundtrip tests (create → serialize → deserialize)
  • Tests for both naming conventions
  • Tests for by_alias=False override
  • Verify backward compatibility with existing camelCase code
Lingua principale
Python
Stelle
67
Fork
15
Merge medio
2g 6h
PR unite (30g)
56

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di IBM/ado

Tutte le issue di IBM/ado

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.