Skip to content

API Reference

This document provides detailed information about the internal APIs and functions available in the Fitness Dashboard codebase, including analytics services and statistical analysis utilities.

Core Services

DatabaseService (src/services/database_service.py)

The primary interface for database operations.

Class Definition

class DatabaseService:
    """Centralized database operations with connection management and error handling"""

    def __init__(self, config: Optional[Dict] = None):
        """Initialize database service with optional configuration override"""

Connection Management

get_connection()
@contextmanager
def get_connection(self) -> pymysql.Connection:
    """
    Context manager for database connections with automatic cleanup.

    Yields:
        pymysql.Connection: Active database connection

    Raises:
        DatabaseError: If connection cannot be established

    Example:
        with db_service.get_connection() as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM workout_summary")
    """
test_connection()
def test_connection(self) -> bool:
    """
    Test database connectivity.

    Returns:
        bool: True if connection successful, False otherwise

    Example:
        if not db_service.test_connection():
            logger.error("Database unavailable")
    """

Query Operations

execute_query()
def execute_query(self, query: str, params: Optional[Tuple] = None) -> List[Dict]:
    """
    Execute SELECT queries with optional parameters.

    Args:
        query (str): SQL SELECT statement
        params (Optional[Tuple]): Query parameters for prepared statements

    Returns:
        List[Dict]: Query results as list of dictionaries

    Raises:
        DatabaseError: If query execution fails
        ValidationError: If query is invalid

    Example:
        results = db_service.execute_query(
            "SELECT * FROM workout_summary WHERE activity_type = %s",
            ("Running",)
        )
    """
execute_update()
def execute_update(self, query: str, params: Optional[Tuple] = None) -> int:
    """
    Execute INSERT, UPDATE, or DELETE queries.

    Args:
        query (str): SQL modification statement
        params (Optional[Tuple]): Query parameters

    Returns:
        int: Number of affected rows

    Raises:
        DatabaseError: If query execution fails

    Example:
        affected = db_service.execute_update(
            "UPDATE workout_summary SET kcal_burned = %s WHERE workout_id = %s",
            (450, "workout_123")
        )
    """

Bulk Operations

bulk_insert()
def bulk_insert(self, table: str, data: List[Dict], 
                batch_size: int = 1000) -> int:
    """
    Efficiently insert multiple records.

    Args:
        table (str): Target table name
        data (List[Dict]): List of records to insert
        batch_size (int): Number of records per batch (default: 1000)

    Returns:
        int: Total number of inserted records

    Raises:
        DatabaseError: If bulk insert fails
        ValidationError: If data format is invalid

    Example:
        workouts = [
            {"workout_id": "1", "activity_type": "Running", ...},
            {"workout_id": "2", "activity_type": "Cycling", ...}
        ]
        count = db_service.bulk_insert("workout_summary", workouts)
    """

AI/ML Intelligence Services

FitnessIntelligenceService (src/services/intelligence_service.py)

The core AI engine providing machine learning classification and automated insights.

Class Definition

class FitnessIntelligenceService:
    """AI-powered fitness intelligence with ML classification and analytics"""

    def __init__(self):
        """Initialize intelligence service with caching and ML models"""

Workout Classification

classify_workout_types()
def classify_workout_types(self, df: pd.DataFrame) -> pd.DataFrame:
    """
    Classify workouts using K-means clustering on pace and distance patterns.

    Args:
        df (pd.DataFrame): Workout data with avg_pace, distance_mi columns

    Returns:
        pd.DataFrame: Input data enhanced with predicted_activity_type column

    Categories:
        - real_run: Focused running sessions (8-12 min/mile pace)
        - choco_adventure: Walking activities (20-28 min/mile pace)  
        - mixed: Sessions combining running and walking
        - outlier: Unusual patterns requiring attention

    Example:
        classified_df = intelligence.classify_workout_types(workout_df)
        print(classified_df['predicted_activity_type'].value_counts())
    """
generate_daily_intelligence_brief()
def generate_daily_intelligence_brief(self, df: pd.DataFrame) -> Dict[str, Any]:
    """
    Generate comprehensive AI-powered fitness insights.

    Args:
        df (pd.DataFrame): Workout data for analysis

    Returns:
        Dict[str, Any]: Intelligence brief with insights, trends, and recommendations

    Structure:
        {
            'insights': {
                'performance': List[str],  # Performance-related insights
                'trends': List[str],       # Trend analysis insights  
                'consistency': List[str],  # Consistency observations
                'recommendations': List[str] # AI recommendations
            },
            'metrics': Dict[str, float],   # Key performance metrics
            'classification_stats': Dict   # ML model performance stats
        }

    Example:
        brief = intelligence.generate_daily_intelligence_brief(df)
        for insight in brief['insights']['performance']:
            print(f"💡 {insight}")
    """

ConsistencyAnalyzer (src/utils/consistency_analyzer.py)

Multi-dimensional consistency analysis with advanced scoring algorithms.

Class Definition

class ConsistencyAnalyzer:
    """Advanced consistency analysis and scoring system"""

    def __init__(self, df: pd.DataFrame):
        """
        Initialize analyzer with workout dataframe.

        Args:
            df (pd.DataFrame): Workout data with workout_date column
        """

Core Analysis Methods

calculate_consistency_score()
def calculate_consistency_score(self, periods: int = 30) -> Dict[str, Any]:
    """
    Calculate comprehensive consistency score across multiple dimensions.

    Args:
        periods (int): Number of days to analyze for consistency

    Returns:
        Dict[str, Any]: Multi-dimensional consistency metrics

    Scoring Dimensions:
        - frequency_score: Workout frequency consistency (40% weight)
        - timing_score: Day-of-week and interval patterns (20% weight)  
        - performance_score: Metric consistency across workouts (20% weight)
        - streak_score: Current and historical streaks (20% weight)

    Score Range: 0-100 (higher = more consistent)

    Example:
        analyzer = ConsistencyAnalyzer(df)
        consistency = analyzer.calculate_consistency_score(30)
        print(f"Overall Score: {consistency['consistency_score']}")
    """
generate_consistency_insights()
def generate_consistency_insights(self) -> List[str]:
    """
    Generate human-readable consistency insights.

    Returns:
        List[str]: AI-generated insights about workout consistency patterns

    Insight Categories:
        - Overall consistency assessment with scoring
        - Day-of-week preferences and patterns  
        - Activity type preferences and distribution
        - Frequency trends and recommendations

    Example:
        insights = analyzer.generate_consistency_insights()
        for insight in insights:
            print(f"🔥 {insight}")
    """

Statistical Analysis Engine (src/utils/statistics.py)

Advanced statistical analysis with trend detection and forecasting capabilities.

TrendAnalysis

class TrendAnalysis:
    """Advanced trend analysis for fitness metrics"""

    @staticmethod
    def calculate_trend(values: pd.Series, periods: int = 30) -> Dict[str, Any]:
        """
        Calculate trend analysis with statistical confidence.

        Returns:
            Dict containing trend_direction, trend_strength, confidence, 
            slope, r_squared, and p_value
        """

    @staticmethod  
    def forecast_values(values: pd.Series, periods: int = 14) -> Dict[str, Any]:
        """
        Forecast future values with confidence intervals.

        Returns:
            Dict with forecast arrays and confidence bounds
        """

PerformanceMetrics

class PerformanceMetrics:
    """Advanced performance metrics calculation"""

    @staticmethod
    def calculate_consistency_score(values: pd.Series, method: str = 'cv') -> float:
        """Calculate 0-100 consistency score using coefficient of variation"""

    @staticmethod
    def calculate_improvement_rate(values: pd.Series, periods: int = 90) -> Dict[str, float]:
        """Calculate performance improvement rate with confidence metrics"""

Configuration Management

AppConfig (src/config/app.py)

Application-wide configuration management.

Environment Detection

@staticmethod
def get_environment() -> str:
    """
    Detect current environment based on operating system.

    Returns:
        str: 'development' for macOS (Darwin), 'production' for Linux

    Example:
        env = AppConfig.get_environment()
        if env == "development":
            enable_debug_mode()
    """

Style Configuration

@staticmethod
def load_style_config() -> Dict[str, Any]:
    """
    Load UI styling configuration from style_config.json.

    Returns:
        Dict[str, Any]: Style configuration dictionary

    Raises:
        ConfigurationError: If style config file cannot be loaded

    Example:
        styles = AppConfig.load_style_config()
        primary_color = styles["theme"]["primary_color"]
    """

DatabaseConfig (src/config/database.py)

Database connection configuration.

Connection Parameters

@staticmethod
def get_connection_params() -> Dict[str, Any]:
    """
    Get database connection parameters based on environment.

    Returns:
        Dict[str, Any]: Connection parameters including host, user, password, database

    Raises:
        ConfigurationError: If required environment variables are missing

    Example:
        params = DatabaseConfig.get_connection_params()
        connection = pymysql.connect(**params)
    """

Utility Functions

Session Management (src/utils/session_manager.py)

Streamlit session state management utilities.

SessionManager Class

class SessionManager:
    """Utilities for managing Streamlit session state"""

    @staticmethod
    def get_session_value(key: str, default: Any = None) -> Any:
        """
        Safely retrieve value from session state.

        Args:
            key (str): Session state key
            default (Any): Default value if key doesn't exist

        Returns:
            Any: Session value or default

        Example:
            user_id = SessionManager.get_session_value("user_id", "anonymous")
        """

    @staticmethod
    def set_session_value(key: str, value: Any) -> None:
        """
        Set value in session state with validation.

        Args:
            key (str): Session state key
            value (Any): Value to store

        Example:
            SessionManager.set_session_value("current_month", "2024-01")
        """

    @staticmethod
    def clear_session() -> None:
        """
        Clear all session state data.

        Example:
            SessionManager.clear_session()  # Reset user session
        """

Data Utilities (src/utils/utilities.py)

General utility functions with type safety.

Type Conversion Functions

def safe_float_conversion(value: Any) -> Optional[float]:
    """
    Safely convert value to float with error handling.

    Args:
        value (Any): Value to convert

    Returns:
        Optional[float]: Converted float or None if conversion fails

    Example:
        distance = safe_float_conversion("3.14")  # Returns 3.14
        invalid = safe_float_conversion("abc")    # Returns None
    """

def safe_int_conversion(value: Any) -> Optional[int]:
    """
    Safely convert value to integer with error handling.

    Args:
        value (Any): Value to convert

    Returns:
        Optional[int]: Converted integer or None if conversion fails

    Example:
        calories = safe_int_conversion("450")  # Returns 450
        invalid = safe_int_conversion("N/A")   # Returns None
    """

Date and Time Functions

def parse_workout_date(date_string: str) -> Optional[datetime]:
    """
    Parse workout date from various string formats.

    Args:
        date_string (str): Date string in various formats

    Returns:
        Optional[datetime]: Parsed datetime or None if parsing fails

    Supported Formats:
        - "2024-01-15 08:30:00"
        - "01/15/2024 8:30 AM"
        - "2024-01-15T08:30:00Z"

    Example:
        dt = parse_workout_date("2024-01-15 08:30:00")
        if dt:
            print(f"Workout was on {dt.date()}")
    """

def format_duration(seconds: int) -> str:
    """
    Format duration in seconds to human-readable string.

    Args:
        seconds (int): Duration in seconds

    Returns:
        str: Formatted duration string

    Example:
        duration = format_duration(3665)  # Returns "1h 1m 5s"
        duration = format_duration(90)    # Returns "1m 30s"
    """

Performance Calculations

def calculate_pace(distance_mi: float, duration_sec: int) -> Optional[float]:
    """
    Calculate pace in minutes per mile.

    Args:
        distance_mi (float): Distance in miles
        duration_sec (int): Duration in seconds

    Returns:
        Optional[float]: Pace in minutes per mile, or None if invalid input

    Example:
        pace = calculate_pace(3.1, 1860)  # Returns 10.0 (10 min/mile)
    """

def calculate_speed_mph(distance_mi: float, duration_sec: int) -> Optional[float]:
    """
    Calculate speed in miles per hour.

    Args:
        distance_mi (float): Distance in miles
        duration_sec (int): Duration in seconds

    Returns:
        Optional[float]: Speed in MPH, or None if invalid input

    Example:
        speed = calculate_speed_mph(6.0, 3600)  # Returns 6.0 MPH
    """

Data Models

Workout Data Structure

The core workout data follows this schema:

from typing import Optional, Dict, Any
from datetime import datetime

class WorkoutData:
    """
    Represents a single workout record.

    Attributes:
        workout_id (str): Unique workout identifier
        workout_date (datetime): When the workout occurred  
        activity_type (str): Type of activity (Running, Cycling, etc.)
        kcal_burned (Optional[int]): Calories burned
        distance_mi (Optional[float]): Distance in miles
        duration_sec (Optional[int]): Duration in seconds
        avg_pace (Optional[float]): Average pace in min/mile
        max_pace (Optional[float]): Best pace in min/mile
        steps (Optional[int]): Step count
        link (Optional[str]): Link to original workout data
    """

    def __init__(self, **kwargs):
        self.workout_id: str = kwargs["workout_id"]
        self.workout_date: datetime = kwargs["workout_date"]
        self.activity_type: str = kwargs["activity_type"]
        self.kcal_burned: Optional[int] = kwargs.get("kcal_burned")
        self.distance_mi: Optional[float] = kwargs.get("distance_mi")
        self.duration_sec: Optional[int] = kwargs.get("duration_sec")
        self.avg_pace: Optional[float] = kwargs.get("avg_pace")
        self.max_pace: Optional[float] = kwargs.get("max_pace")
        self.steps: Optional[int] = kwargs.get("steps")
        self.link: Optional[str] = kwargs.get("link")

    def to_dict(self) -> Dict[str, Any]:
        """Convert workout to dictionary format for database insertion."""
        return {
            "workout_id": self.workout_id,
            "workout_date": self.workout_date,
            "activity_type": self.activity_type,
            "kcal_burned": self.kcal_burned,
            "distance_mi": self.distance_mi,
            "duration_sec": self.duration_sec,
            "avg_pace": self.avg_pace,
            "max_pace": self.max_pace,
            "steps": self.steps,
            "link": self.link
        }

    @classmethod
    def from_csv_row(cls, row: Dict[str, str]) -> 'WorkoutData':
        """Create WorkoutData from CSV row with data validation."""
        return cls(
            workout_id=row["Workout Id"],
            workout_date=parse_workout_date(row["Workout Date"]),
            activity_type=row["Activity Type"],
            kcal_burned=safe_int_conversion(row.get("Total Calories")),
            distance_mi=safe_float_conversion(row.get("Distance (mi)")),
            duration_sec=safe_int_conversion(row.get("Duration")),
            avg_pace=safe_float_conversion(row.get("Avg Pace (min/mi)")),
            max_pace=safe_float_conversion(row.get("Max Pace (min/mi)")),
            steps=safe_int_conversion(row.get("Steps")),
            link=row.get("Reference")
        )

Error Handling

Exception Classes

class FitnessAppError(Exception):
    """Base exception class for fitness application errors."""

    def __init__(self, message: str, details: Optional[Dict] = None):
        super().__init__(message)
        self.details = details or {}

class DatabaseError(FitnessAppError):
    """Raised when database operations fail."""
    pass

class ValidationError(FitnessAppError):
    """Raised when data validation fails."""
    pass

class ConfigurationError(FitnessAppError):
    """Raised when configuration is invalid or missing."""
    pass

Error Handling Patterns

def safe_database_operation(operation_func: Callable) -> Any:
    """
    Wrapper for database operations with standardized error handling.

    Args:
        operation_func: Function to execute safely

    Returns:
        Any: Operation result or None if failed

    Example:
        result = safe_database_operation(
            lambda: db_service.execute_query("SELECT COUNT(*) FROM workout_summary")
        )
    """
    try:
        return operation_func()
    except pymysql.Error as e:
        logger.error(f"Database error: {e}")
        raise DatabaseError(f"Database operation failed: {str(e)}")
    except Exception as e:
        logger.error(f"Unexpected error: {e}")
        raise FitnessAppError(f"Operation failed: {str(e)}")

Logging and Monitoring

Logging Configuration

import logging
from src.config.logging_config import setup_logging

# Initialize logging
setup_logging()
logger = logging.getLogger(__name__)

# Usage examples
logger.info("Database connection established")
logger.warning("No workouts found for specified date range")
logger.error("Failed to process CSV file", exc_info=True)

Performance Monitoring

from functools import wraps
import time

def monitor_performance(func):
    """
    Decorator for monitoring function execution time.

    Example:
        @monitor_performance
        def expensive_query():
            return db_service.execute_query("SELECT * FROM large_table")
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        try:
            result = func(*args, **kwargs)
            execution_time = time.time() - start_time
            logger.info(f"{func.__name__} executed in {execution_time:.2f}s")
            return result
        except Exception as e:
            execution_time = time.time() - start_time
            logger.error(f"{func.__name__} failed after {execution_time:.2f}s: {e}")
            raise
    return wrapper

Testing Utilities

Test Fixtures

import pytest
from src.services.database_service import DatabaseService

@pytest.fixture
def mock_database_service():
    """Mock database service for testing."""
    class MockDatabaseService:
        def execute_query(self, query: str, params=None):
            # Return mock data based on query
            return [{"workout_id": "test1", "activity_type": "Running"}]

    return MockDatabaseService()

@pytest.fixture
def sample_workout_data():
    """Sample workout data for testing."""
    return {
        "workout_id": "test123",
        "workout_date": datetime(2024, 1, 15, 8, 30),
        "activity_type": "Running",
        "kcal_burned": 450,
        "distance_mi": 3.1,
        "duration_sec": 1860,
        "avg_pace": 10.0,
        "max_pace": 8.5,
        "steps": 4200,
        "link": "https://example.com/workout/test123"
    }

Extension Points

Custom Data Sources

To add support for new fitness platforms:

class CustomDataImporter:
    """Base class for implementing custom data importers."""

    def parse_csv(self, file_path: str) -> List[WorkoutData]:
        """Parse CSV file and return WorkoutData objects."""
        raise NotImplementedError

    def validate_data(self, workouts: List[WorkoutData]) -> List[WorkoutData]:
        """Validate and clean workout data."""
        raise NotImplementedError

    def import_data(self, file_path: str) -> int:
        """Complete import process."""
        workouts = self.parse_csv(file_path)
        validated_workouts = self.validate_data(workouts)
        return self.bulk_insert_workouts(validated_workouts)

# Example implementation for Strava
class StravaImporter(CustomDataImporter):
    def parse_csv(self, file_path: str) -> List[WorkoutData]:
        # Strava-specific parsing logic
        pass

Custom Visualizations

To add new visualization types:

def create_custom_chart(data: List[Dict], chart_type: str) -> Any:
    """
    Create custom Plotly charts based on data and type.

    Args:
        data: Chart data
        chart_type: Type of chart to create

    Returns:
        Plotly figure object
    """
    if chart_type == "heatmap":
        return create_activity_heatmap(data)
    elif chart_type == "performance_trend":
        return create_performance_trend_chart(data)
    else:
        raise ValueError(f"Unknown chart type: {chart_type}")

For more implementation examples, see the Contributing Guide.