____ __ __ ___ __ __ __
/ __ \/ /_ / |/ /_ __/ //_/___ ____/ /__
/ / / / __ \/ /|_/ / / / / ,< / __ \/ __ / _ \
/ /_/ / / / / / / / /_/ / /| / /_/ / /_/ / __/
\____/_/ /_/_/ /_/\__, /_/ |_\____/\__,_/\___/
/____/
A clean, modern, and well-structured Python project template inspired by the OhMyKode approach:
Observe β Model β Kodify
A simple, powerful, and intuitive workflow to build better Python projects:
- Observe the problem deeply and clearly
- Model the underlying logic, structure or mathematics
- Kodify the solution cleanly, using modern engineering practices
This template helps you start projects the way engineers do:
reproducible, modular, configurable, and easy to maintain.
The OMK methodology is the guiding flow behind this template:
Break down the problem.
Identify patterns, constraints, and structure.
Clarify the βwhyβ before touching the keyboard.
Translate intuition into a clean architecture.
Use configuration, modular code, and clear separation of concerns.
Make each part easy to test, extend, and reason about.
Implement the solution cleanly, with clarity, structure, and reproducibility in mind.
Most Python projects begin with a single script.py that grows until it becomes unmaintainable.
This template shows how to structure a project like a real engineer:
- A dedicated place for source code
- A clean area for data
- Separate zones for notebooks, configs, tests
- Proper handling of logs, models, and documentation
β‘οΈ A clear structure leads to clear thinking β and cleaner code.
- Modern Python stack:
uv,hydra,loguru - Clear, scalable folder structure
- Hydraβpowered configuration for reproducible experiments
- Isolated logs, outputs, and models per run
- Makefile shortcuts for a consistent developer experience
- Tools included to keep your project clean and maintainable
- Beginnerβfriendly, no unnecessary complexity
.
βββ conf/ # Hydra configuration (main config + groups)
β βββ config.yaml
β βββ data/default.yaml
β βββ model/default.yaml
β βββ pipeline/default.yaml
β
βββ src/
β βββ core/ # Main logic: algorithms, pipelines, workflows
β βββ data/ # Data helpers (optional)
β
βββ data/
β βββ input/ # Raw, immutable input data
β βββ output/ # Processed or generated outputs
β
βββ models/ # Saved models or artifacts
βββ notebooks/ # Exploratory notebooks & experimentation
βββ logs/ # Logs automatically created per run
βββ tests/ # Unit/integration tests
βββ docs/ # Documentation, diagrams, architecture notes
β
βββ tools/ # Project maintenance utilities
β βββ debug_env.py # Show environment + config + deps
β βββ clean_cache.py # Clean Python caches (crossβplatform)
β βββ helpers.py # Shared utility helpers dedicated to internal tooling scripts
β
βββ main.py # Project entrypoint (Hydra-powered)
βββ Makefile # Automation of common tasks
βββ pyproject.toml # Project configuration and dependencies (uv)
βββ uv.lock # Fully pinned dependency list
βββ CHANGELOG # Version tracking
Why this structure?
- Each directory has ONE clear purpose
- Code, config, data, and logs are cleanly separated
- Scales smoothly from small scripts to real ML pipelines
- Matches modern engineering practice (ML, data, automation, research)
This template uses uv, a fast, modern Python package manager.
git clone https://github.com/OhMyKode/omk-python-project-template
cd omk-python-project-template
uv sync
make runOnce the packages are installed, you can refer to the Makefile for all the available commands:
- cloc: Count lines of code using cloc (must be installed first)
- format: Format code with black and ruff
- help: List available commands
- lock: Update uv.lock file
- major: Bump major version without committing
- minor: Bump minor version without committing
- notebook: Launch Jupyter notebook.
- patch: Bump patch version without committing
- quality: Check code quality metrics with radon
- reqs: Export dependencies to requirements.txt. Do not edit it manually
- run: Run the main script.
- set-version: Usage: make set-version version=1.2.3
- show-version: Show project's version
- test: Run unit tests
- upgrade: Upgrade all dependencies to their latest versions
Principle:
Makefile provides stable, memorable commands, so anyone should be able to run and explore the project with one command.
P.S. You can install make on Windows using Scoop or just copy paste the commands from file and execute them in the terminal.
All configurable parameters live in:
conf/
βββ config.yaml
βββ data/default.yaml
βββ model/default.yaml
βββ pipeline/default.yaml
Hydra enables:
Every run gets its own timestamped directory with:
- logs
- configs used
- outputs
No hardβcoded paths or values inside Python files.
Override parameters without modifying code.
You can quickly check the overall quality of the codebase using:
make qualityThis command runs Radon, which calculates several helpful metrics:
- Cyclomatic Complexity (cc) : Measures how many decision paths a function has. More branches β harder to read and test. Lower is better.
- Maintainability Index (mi): Gives a score (0β100) estimating how easy the code is to understand and modify. Higher is better.
- Halstead Metrics (hal): Analyze the βeffortβ required to read and understand the code based on operators and operands. Itβs not something you need to memorize β it simply highlights code that might be too dense.
These metrics help you spot:
- functions that are becoming too complex
- code that may be hard to maintain later
- opportunities to simplify or refactor
Use make quality as a friendly guide to keep the code clean and easy to work with β especially as the project grows.
All exploratory work goes here:
- EDA
- prototyping
- sketches
- rapid experiments
Notebooks should not modify the source code directly.
Use this folder for:
- architecture diagrams
- explanations
- learning notes
- model descriptions
- internal documentation
This template encourages a clear and intentional Git history.
feat/add-training-step
fix/data-path
refactor/pipeline-cleanup
Principle:
Each change has a purpose and a name.
Use clean prefixes (Inspired by conventional commits):
- :feat: feat: a new feature
- :fix: fix: a bug fix
- :docs: docs: documentation only changes
- :style: style: changes that do not affect the meaning of the code
(white-space, formatting, missing semi-colons, etc)
- :refactor: refactor: a code change that neither fixes a bug nor adds a feature
- :perf: perf: a code change that improves performance
- :test: test: adding missing or correcting existing tests
- :chore: chore: changes to the build process or auxiliary
tools and libraries such as documentation generation
- :chore-release: chore(release): code deployment or publishing to external repositories
- :chore-deps: chore(deps): add or delete dependencies
- :build: build: changes related to build processes
- :ci: ci: updates to the continuous integration system
- :config: config: Changing configuration files.
- :security: security: Fixing security issues.Examples:
feat: add basic pipeline runner
refactor: isolate data loader
fix: correct output directory path
Principle:
Your future self should understand your past decisions instantly.
The template uses MAJOR.MINOR.PATCH (semantic versioning):
- MAJOR β breaking changes
- MINOR β new features
- PATCH β small fixes, polish
Update automatically using:
make major
make minor
make patchP.S. Project's version should not be edited manually. To set a specific project's version, use make set-version available command.
Principle:
Version numbers should reflect the scope of change so users instantly understand what to expect.
- πΊ YouTube: https://youtube.com/@OhMyKode
- π GitHub: https://github.com/ohmykode
- π¨ Contact: ohmykode@gmail.com
This project is licensed under the MIT License (see LICENSE file).