Personalized workout routine generator, accessible via Telegram Bot.
- Overview
- Bot Features and Commands
- UX Screenshots
- Project Architecture
- Repository Structure
- Installation Guide
- Development and Code Quality
- Testing
- CI/CD Pipeline
- Tech Stack
FitBot is a Telegram Bot designed to generate personalized workout routines (WOD — Workout of the Day) based on the user's physical profile, experience level, and available equipment.
The project was developed following Quality Development principles with a focus on:
- ✅ Decoupled core logic — business logic is completely separated from the Telegram interface
- ✅ Testable architecture — each layer can be tested in isolation
- ✅ Test coverage ≥ 75% — automatically enforced in the CI pipeline
- ✅ Complete static analysis — Black, isort, Flake8, Pylint, Mypy (strict mode)
- ✅ Pre-commit hooks — guaranteed quality on every commit
- ✅ CI/CD with GitHub Actions — automated linting + testing on every push/PR
| Command / Button | Emoji | Description |
|---|---|---|
/start |
👋 | Starts the bot and shows the main menu with all available commands |
| Nuova scheda (New Routine) | 🏆 | Creates a new personalized workout routine via a guided onboarding process. The user inputs their data (level, frequency, split, equipment) or uses their existing profile |
| Profilo (Profile) | 👤 | Displays the full user profile with all personal information (name, height, weight, BMI, body type, level, frequency, split, equipment). Includes option to edit the profile |
| 🔥 WOD del giorno (WOD of the day) | 🔥 | Shows the Workout of the Day — the daily workout based on the active routine, with navigation between days of the week (Back/Forward) |
| 📜 Storico (History) | 📜 | Review past generated workout routines, with the ability to download them in PDF or TXT format |
| ⭐ Preferiti (Favorites) | ⭐ | Access favorited routines for quick access to your most appreciated workouts |
/start → Main Menu
├── 🏆 Nuova scheda → Onboarding (level, frequency, split, equipment) → Generated routine
├── 👤 Profilo → View/Edit personal data
├── 🔥 WOD del giorno → Daily navigation of the active routine
├── 📜 Storico → List of past routines → Download PDF/TXT
└── ⭐ Preferiti → Saved routines
Below are the main screens of the Telegram bot interface:
The project follows a three-layer architecture with a clear separation of concerns, designed to maximize testability and decoupling:
┌─────────────────────────────────────────────────┐
│ Telegram Bot │
│ (Handlers & Keyboards) │
│ src/wod/bot/ │
├─────────────────────────────────────────────────┤
│ Core Logic │
│ (Engine, Split Generator, BMI, Intensity) │
│ src/wod/core/ │
├─────────────────────────────────────────────────┤
│ Data Layer │
│ (SQLAlchemy Models & Repositories) │
│ src/wod/db/ │
└─────────────────────────────────────────────────┘
| Layer | Path | Responsibility | Quality Principle |
|---|---|---|---|
| Bot | src/wod/bot/ |
Telegram Interface — command handling, keyboards, message formatting | Thin controller — no business logic |
| Core | src/wod/core/ |
Domain logic — exercise filtering, split generation, BMI and intensity calculation | Pure business logic with no external dependencies |
| DB | src/wod/db/ |
Persistence — SQLAlchemy models, repository pattern, data seeding | Repository pattern to isolate data access |
| Config | src/wod/config.py |
Centralized configuration via Pydantic Settings | Automatic validation, type-safe |
- Dependency Inversion — Higher layers do not depend on the concrete implementation of lower layers
- Repository Pattern — Data access is encapsulated in dedicated repositories, simplifying mocking and testing
- Pure Functions — Core logic is implemented as pure functions, easily testable without complex setup
- Configuration as Code — All settings are managed via
pydantic-settingswith automatic validation
FitBot-Generator/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions — lint + test pipeline
├── data/
│ └── seed_exercises.json # Exercise catalog for DB seeding
├── docs/
│ └── screenshots/ # UX screenshots of the bot
├── scripts/
│ └── seed_db.py # Script for manual database seeding
├── src/
│ └── wod/
│ ├── __init__.py
│ ├── config.py # App configuration (Pydantic Settings)
│ ├── bot/ # 🤖 Telegram Layer
│ │ ├── formatters/ # Message formatting modules (text, pdf)
│ │ ├── handlers/ # Command handlers (onboarding, profile, wod, etc.)
│ │ ├── keyboards.py # Inline and reply keyboards
│ │ ├── locales.py # Localization and translations
│ │ ├── main.py # Entry point — assembles handlers and starts polling
│ │ └── utils.py # Shared bot utilities
│ ├── core/ # 🧠 Business Logic Layer
│ │ ├── bmi.py # BMI calculation (WHO classification)
│ │ ├── engine.py # Exercise filtering by equipment and muscles
│ │ ├── intensity.py # Sets, reps, and intensity calculation
│ │ ├── split_generator.py # Weekly split generation
│ │ └── types.py # Enums and domain value objects
│ └── db/ # 💾 Persistence Layer
│ ├── models/ # SQLAlchemy Models (user, exercise, etc.)
│ ├── repositories.py # Repository pattern for data access
│ ├── seeding.py # Auto-seeding of the exercise catalog
│ └── session.py # Async database session management
├── tests/ # 🧪 Test Suite
│ ├── bot/ # Bot layer tests
│ ├── core/ # Core layer tests
│ ├── db/ # DB layer tests
│ ├── conftest.py # Shared fixtures (In-memory DB, mocks)
│ └── test_config.py # Configuration tests
├── .coveragerc # Code coverage configuration
├── .flake8 # Flake8 configuration
├── .pre-commit-config.yaml # Pre-commit hooks
├── .pylintrc # Pylint configuration
├── mypy.ini # MyPy configuration
├── pyproject.toml # Project and dependencies configuration
└── README.md
- Python 3.11+ — Download
- Git — Download
- Telegram Bot Token — Obtainable via @BotFather on Telegram
git clone https://github.com/SimoneAndreaCilia/FitBot-Generator.git
cd FitBot-Generator# Create the virtual environment
python -m venv .venv
# Activate the virtual environment
.venv\Scripts\activate # Windows (PowerShell / CMD)
# source .venv/bin/activate # macOS / Linux# Install the project in editable mode with development dependencies
pip install -e ".[dev]"# Create the .env file from the template
cp .env.example .envEdit the .env file and insert your Telegram token:
TELEGRAM_BOT_TOKEN=your-token-hereTip
To get a token, open Telegram, search for @BotFather, send /newbot and follow the instructions.
# Start the bot in long-polling mode
wod-botThe bot will connect to Telegram and start receiving messages. Search for your bot on Telegram and send /start to begin! 🎉
This project implements a comprehensive quality toolchain, aligning with the best practices of the Quality Development subject.
The project uses pre-commit to ensure the code meets formatting and quality standards before every commit.
# Install pre-commit
pip install pre-commit
# Install pre-commit hooks in the local repository
pre-commit installThe following checks run automatically on every git commit:
| Hook | Tool | Function |
|---|---|---|
| Trailing whitespace | pre-commit | Removes trailing whitespace |
| End-of-file fixer | pre-commit | Ensures a blank line at the end of files |
| YAML check | pre-commit | Validates YAML syntax |
| Code formatting | Black | Automatic code formatting |
| Import sorting | isort | Automatic import sorting |
| Style checking | Flake8 | PEP 8 style checking |
| Static analysis | Pylint | Deep static analysis |
| Type checking | MyPy | Strict mode type checking |
You can run checks manually without making a commit:
# Run all pre-commit checks
pre-commit run --all-files
# Or run individual tools:
black src/ tests/ # Code formatting
isort src/ tests/ # Import sorting
flake8 src/ tests/ # Style checking
pylint src/wod/ # Static analysis
mypy src/wod/ # Type checkingThe test suite is structured to mirror the three layers of the architecture:
tests/
├── core/ → Unit tests for business logic (pure, without I/O)
├── bot/ → Telegram handlers tests (with API mocking)
└── db/ → Persistence layer tests (in-memory DB)
# Run all tests with coverage report
pytest
# Run tests for a specific layer only
pytest tests/core/ # Core logic only
pytest tests/bot/ # Bot handlers only
pytest tests/db/ # Database only
# Run a single test file
pytest tests/core/test_bmi.py
# Run with verbose output
pytest -v --tb=shortThe minimum coverage is set to 75% and is verified automatically:
# pyproject.toml
[tool.pytest.ini_options]
addopts = [
"--strict-markers",
"--cov=src/wod",
"--cov-report=term-missing",
"--cov-fail-under=75",
]Important
If the coverage drops below 75%, the tests will fail both locally and in the CI pipeline.
The project uses GitHub Actions for continuous integration. The pipeline runs automatically on every push and pull_request to the main branch.
CI Pipeline
│
├── 🔍 Job: Lint & Type-check
│ ├── black --check (formatting)
│ ├── isort --check-only (import sorting)
│ ├── flake8 (PEP 8 style)
│ ├── pylint (static analysis)
│ └── mypy (strict type checking)
│
└── 🧪 Job: Tests (depends on Lint)
└── pytest --cov --cov-fail-under=75
Note
The test job runs only if the linting job passes all checks, ensuring the code meets quality standards before verifying functional correctness.
| Technology | Version | Role |
|---|---|---|
| Python | 3.11+ | Main Language |
| python-telegram-bot | 21.x | Telegram Bot API Framework |
| SQLAlchemy | 2.0 | ORM and Database Management |
| aiosqlite | 0.20+ | Async SQLite driver |
| Pydantic | 2.0 | Data validation and configuration |
| ReportLab | 4.0 | PDF file generation |
| pytest | 8.0 | Testing framework |
| Black | 24.x | Automatic code formatter |
| MyPy | 1.8+ | Static type checker (strict) |
| Pylint | 3.x | Static code analyzer |
| Flake8 | 7.0 | PEP 8 style checker |
| GitHub Actions | — | CI/CD pipeline |
Developed as a project for the Quality Development course 💪




