Local Development¶
This guide covers setting up and running the Fitness Dashboard in a local development environment.
Development Environment Setup¶
Prerequisites¶
Ensure you have the following installed on your development machine:
- Python 3.10+: Download from python.org
- Poetry: For dependency management
- MySQL 8.0+: Local database server
- Git: For version control
Quick Setup¶
Follow these steps to get your development environment running:
# Clone the repository
git clone https://github.com/dagny/fitness-dashboard.git
cd fitness-dashboard
# Install dependencies with Poetry
poetry install
# Activate the virtual environment
poetry shell
# Initialize the database
python scripts/init.py
# Start the development server
streamlit run src/streamlit_app.py
Visit http://localhost:8501
to access your development dashboard.
Development Workflow¶
Directory Structure¶
Understanding the project structure helps with efficient development:
fitness-dashboard/
├── src/ # Main source code
│ ├── config/ # Configuration files
│ ├── services/ # Business logic
│ ├── utils/ # Shared utilities
│ ├── views/ # UI components
│ └── streamlit_app.py # Entry point
├── docs/ # Documentation (MkDocs)
├── tests/ # Test suite
├── scripts/ # Setup/deployment scripts
└── pyproject.toml # Project configuration
Environment Variables¶
Create a .env
file in the project root for local development:
# Database Configuration
MYSQL_USER=fitness_user
MYSQL_PWD=your_password
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DATABASE=sweat
# Application Settings
STREAMLIT_THEME=dark
DEBUG=true
# Optional: Enable additional logging
LOG_LEVEL=DEBUG
Configuration Management¶
The application automatically detects the development environment:
# src/config/app.py
def get_environment():
"""Detects macOS as development environment"""
return "development" if platform.system() == "Darwin" else "production"
This enables: - Local MySQL connection - Debug logging - Development-specific features - Hot reload capabilities
Development Tools¶
Code Quality Tools¶
Set up code quality tools for consistent development:
# Install development dependencies
poetry install --with dev
# Run tests
poetry run pytest
# Code formatting (if configured)
poetry run black src/
poetry run isort src/
# Type checking (if mypy is added)
poetry run mypy src/
Database Development¶
Local MySQL Setup¶
macOS (Homebrew):
brew install mysql
brew services start mysql
# Create development database
mysql -u root -p
CREATE DATABASE sweat;
CREATE USER 'fitness_user'@'localhost' IDENTIFIED BY 'dev_password';
GRANT ALL PRIVILEGES ON sweat.* TO 'fitness_user'@'localhost';
FLUSH PRIVILEGES;
Database Management:
# Initialize schema
python scripts/init.py
# Import sample data
python src/update_db.py
# Reset database (if needed)
mysql -u fitness_user -p sweat < scripts/reset_db.sql
Database Tools¶
Recommended tools for database development:
- MySQL Workbench: GUI for database management
- DBeaver: Universal database tool
- phpMyAdmin: Web-based MySQL administration
Streamlit Development¶
Hot Reload¶
Streamlit provides automatic reloading when files change:
# Start with file watcher (default behavior)
streamlit run src/streamlit_app.py
# The app automatically reloads when you save changes
Debug Mode¶
Enable additional debugging features:
# In your Streamlit app
import streamlit as st
# Display session state for debugging
if st.checkbox("Show Debug Info"):
st.write("Session State:", st.session_state)
st.write("Environment:", AppConfig.get_environment())
Development Server Options¶
# Run on different port
streamlit run src/streamlit_app.py --server.port 8502
# Enable CORS for external access
streamlit run src/streamlit_app.py --server.enableCORS false
# Disable file watching (for performance)
streamlit run src/streamlit_app.py --server.fileWatcherType none
Testing During Development¶
Running Tests¶
# Run all tests
poetry run pytest
# Run with coverage
poetry run pytest --cov=src
# Run specific test file
poetry run pytest tests/test_queries.py
# Run with verbose output
poetry run pytest -v
# Run tests in parallel (if pytest-xdist is installed)
poetry run pytest -n auto
Test Database¶
Set up a separate test database:
Configure test environment:
# tests/conftest.py
import pytest
from src.services.database_service import DatabaseService
@pytest.fixture(scope="session")
def test_db():
"""Test database fixture"""
# Setup test database
# Import test data
yield database_service
# Cleanup
Manual Testing¶
Create test scenarios for manual verification:
# scripts/create_test_data.py
def create_sample_workouts():
"""Generate sample workout data for testing"""
sample_data = [
{
"workout_id": "test_001",
"workout_date": datetime.now() - timedelta(days=1),
"activity_type": "Running",
"kcal_burned": 450,
"distance_mi": 3.1,
"duration_sec": 1860
},
# Add more test data...
]
db_service = DatabaseService()
db_service.bulk_insert("workout_summary", sample_data)
print(f"Inserted {len(sample_data)} test workouts")
if __name__ == "__main__":
create_sample_workouts()
Debugging¶
Streamlit Debugging¶
Debug Information Display:
# Add to your Streamlit pages
if st.sidebar.checkbox("Debug Mode"):
st.sidebar.write("Session State:", dict(st.session_state))
st.sidebar.write("Current User:", get_current_user())
st.sidebar.write("Database Status:", test_db_connection())
Error Handling:
try:
data = database_service.execute_query(query)
st.dataframe(data)
except Exception as e:
st.error(f"Query failed: {str(e)}")
if st.checkbox("Show full error"):
st.exception(e)
Database Debugging¶
Query Logging:
# Enable query logging in development
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("database")
def execute_query_with_logging(query, params=None):
logger.debug(f"Executing query: {query}")
logger.debug(f"Parameters: {params}")
# ... execute query
Performance Monitoring:
import time
from functools import wraps
def monitor_db_performance(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
execution_time = time.time() - start_time
if execution_time > 1.0: # Log slow queries
logger.warning(f"Slow query ({execution_time:.2f}s): {func.__name__}")
return result
return wrapper
Development Best Practices¶
Code Organization¶
Module Structure: - Keep related functionality together - Use clear, descriptive names - Maintain separation of concerns - Document complex functions
Error Handling:
# Consistent error handling pattern
def safe_database_operation():
try:
return database_service.execute_query(query)
except DatabaseError as e:
logger.error(f"Database error: {e}")
st.error("Database connection issue. Please try again.")
return []
except Exception as e:
logger.error(f"Unexpected error: {e}")
st.error("An unexpected error occurred.")
return []
Performance Considerations¶
Caching Strategy:
import streamlit as st
@st.cache_data(ttl=300) # Cache for 5 minutes
def get_monthly_summary(month):
"""Cached data retrieval for better performance"""
return database_service.get_monthly_data(month)
Efficient Queries:
# Use date range filters for large datasets
def get_recent_workouts(days=30):
query = """
SELECT * FROM workout_summary
WHERE workout_date >= DATE_SUB(NOW(), INTERVAL %s DAY)
ORDER BY workout_date DESC
"""
return database_service.execute_query(query, (days,))
Version Control¶
Git Workflow:
# Create feature branch
git checkout -b feature/new-visualization
# Make changes and commit frequently
git add .
git commit -m "Add new chart type for pace analysis"
# Push to remote
git push origin feature/new-visualization
# Create pull request when ready
Ignore Files:
Ensure your .gitignore
includes:
# Environment files
.env
.env.local
# Database files
*.db
sessions.db
# IDE files
.vscode/
.idea/
# Python cache
__pycache__/
*.pyc
# Streamlit cache
.streamlit/
Troubleshooting Development Issues¶
Common Problems¶
Port Already in Use
Error: Address already in use
Solutions:
Database Connection Failed
Error: Can't connect to MySQL server
Solutions:
Module Import Errors
Error: ModuleNotFoundError
Solutions:
Performance Issues¶
Slow Dashboard Loading: - Check database query performance - Implement data caching - Reduce dataset size for development - Use pagination for large results
Memory Usage: - Monitor Streamlit session state size - Clear unused cached data - Implement data cleanup routines
Documentation Development¶
MkDocs Development¶
# Install documentation dependencies (already included)
poetry install
# Serve documentation locally
mkdocs serve
# Build documentation
mkdocs build
# Open in browser
open http://localhost:8000
Documentation Best Practices¶
- Keep documentation up to date with code changes
- Include code examples in docstrings
- Write clear user guides for new features
- Test documentation links regularly
Next Steps¶
Once your development environment is set up:
- Explore the Codebase: Understand the architecture and existing patterns
- Run Tests: Ensure everything works correctly
- Make Your First Change: Start with a small improvement or bug fix
- Follow the Style Guide: Maintain consistency with existing code
- Write Tests: Add tests for new functionality
- Update Documentation: Keep docs current with changes
For production deployment, see the Production Setup Guide.