Files
bakery-ia/services/training/DEVELOPER_GUIDE.md

5.6 KiB

Training Service - Developer Guide

Quick Reference for Common Tasks

Using Constants

Always use constants instead of magic numbers:

from app.core import constants as const

# ✅ Good
if len(sales_data) < const.MIN_DATA_POINTS_REQUIRED:
    raise ValueError("Insufficient data")

# ❌ Bad
if len(sales_data) < 30:
    raise ValueError("Insufficient data")

Timezone Handling

Always use timezone utilities:

from app.utils.timezone_utils import ensure_timezone_aware, prepare_prophet_datetime

# ✅ Good - Ensure timezone-aware
dt = ensure_timezone_aware(user_input_date)

# ✅ Good - Prepare for Prophet
df = prepare_prophet_datetime(df, 'ds')

# ❌ Bad - Manual timezone handling
if dt.tzinfo is None:
    dt = dt.replace(tzinfo=timezone.utc)

Error Handling

Always raise exceptions, never return empty lists:

# ✅ Good
if not data:
    raise ValueError(f"No data available for {tenant_id}")

# ❌ Bad
if not data:
    logger.error("No data")
    return []

Database Sessions

Use context manager correctly:

# ✅ Good
async with self.database_manager.get_session() as session:
    await session.execute(query)

# ❌ Bad
async with self.database_manager.get_session()() as session:  # Double call!
    await session.execute(query)

Parallel Execution

Use asyncio.gather for concurrent operations:

# ✅ Good - Parallel
tasks = [train_product(pid) for pid in product_ids]
results = await asyncio.gather(*tasks, return_exceptions=True)

# ❌ Bad - Sequential
results = []
for pid in product_ids:
    result = await train_product(pid)
    results.append(result)

HTTP Client Configuration

Timeouts are configured automatically in DataClient:

# No need to configure timeouts manually
# They're set in DataClient.__init__() using constants
client = DataClient()  # Timeouts already configured

File Organization

Core Modules

  • core/constants.py - All configuration constants
  • core/config.py - Service settings
  • core/database.py - Database configuration

Utilities

  • utils/timezone_utils.py - Timezone handling functions
  • utils/__init__.py - Utility exports

ML Components

  • ml/trainer.py - Main training orchestration
  • ml/prophet_manager.py - Prophet model management
  • ml/data_processor.py - Data preprocessing

Services

  • services/data_client.py - External service communication
  • services/training_service.py - Training job management
  • services/training_orchestrator.py - Training pipeline coordination

Common Pitfalls

Don't Create Legacy Aliases

# ❌ Bad
MyNewClass = OldClassName  # Removed!

Don't Use Magic Numbers

# ❌ Bad
if score > 0.8:  # What does 0.8 mean?

# ✅ Good
if score > const.IMPROVEMENT_SIGNIFICANCE_THRESHOLD:

Don't Return Empty Lists on Error

# ❌ Bad
except Exception as e:
    logger.error(f"Failed: {e}")
    return []

# ✅ Good
except Exception as e:
    logger.error(f"Failed: {e}")
    raise RuntimeError(f"Operation failed: {e}")

Don't Handle Timezones Manually

# ❌ Bad
if dt.tzinfo is None:
    dt = dt.replace(tzinfo=timezone.utc)

# ✅ Good
from app.utils.timezone_utils import ensure_timezone_aware
dt = ensure_timezone_aware(dt)

Testing Checklist

Before submitting code:

  • All magic numbers replaced with constants
  • Timezone handling uses utility functions
  • Errors raise exceptions (not return empty collections)
  • Database sessions use single get_session() call
  • Parallel operations use asyncio.gather
  • No legacy compatibility aliases
  • No commented-out code
  • Logging uses structured logging

Performance Guidelines

Training Jobs

  • Use parallel execution for multiple products
  • Reduce Optuna trials for low-volume products
  • Use constants for all thresholds
  • ⚠️ Monitor memory usage during parallel training

Database Operations

  • Use repository pattern
  • Batch operations when possible
  • Close sessions properly
  • ⚠️ Connection pool limits not yet configured

HTTP Requests

  • Timeouts configured automatically
  • Use shared clients from shared/clients
  • ⚠️ Circuit breaker not yet implemented
  • ⚠️ Request retries delegated to base client

Debugging Tips

Training Failures

  1. Check logs for data validation errors
  2. Verify timezone consistency in date ranges
  3. Check minimum data point requirements
  4. Review Prophet error messages

Performance Issues

  1. Check if parallel training is being used
  2. Verify Optuna trial counts
  3. Monitor database connection usage
  4. Check HTTP timeout configurations

Data Quality Issues

  1. Review validation errors in logs
  2. Check zero-ratio thresholds
  3. Verify product classification
  4. Review date range alignment

Migration from Old Code

If You Find Legacy Code

  1. Check if alias exists (should be removed)
  2. Update imports to use new names
  3. Remove backward compatibility wrappers
  4. Update documentation

If You Find Magic Numbers

  1. Add constant to core/constants.py
  2. Update usage to reference constant
  3. Document what the number represents

If You Find Manual Timezone Handling

  1. Import from utils/timezone_utils
  2. Use appropriate utility function
  3. Remove manual implementation

Getting Help

  • Review IMPLEMENTATION_SUMMARY.md for recent changes
  • Check constants in core/constants.py for configuration
  • Look at utils/timezone_utils.py for timezone functions
  • Refer to analysis report for architectural decisions

Last Updated: 2025-10-07 Status: Current