This guide covers setting up a development environment, running tests, and project conventions.
# Clone and enter the project
git clone https://github.com/EndoTheDev/OMeter.git
cd OMeter
# Create virtual environment and install dependencies
uv sync
# Install as a tool
uv tool install .# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=ometer --cov-report=term-missing
# Run a specific test file
uv run pytest tests/test_api.pyTest files are located in tests/:
| File | Covers |
|---|---|
test_api.py |
api.py — fetch, benchmark, sort functions |
test_cli.py |
cli.py — argument parsing, mode resolution, model matching, export flags |
test_config.py |
config.py — env loading, clamping, defaults |
test_display.py |
display.py — formatting, thresholds, coloring, export-only, _collect_pending |
test_export.py |
export.py — JSON/CSV formatting, file output |
Defined in pyproject.toml [project.dependencies]:
| Package | Purpose |
|---|---|
httpx |
Async HTTP client for Ollama API communication |
rich |
Terminal formatting, tables, live display, spinners |
python-dotenv |
.env file parsing for configuration |
inquirerpy |
Interactive CLI menu for model selection |
Defined in pyproject.toml [dependency-groups.dev]:
| Package | Purpose |
|---|---|
pytest |
Test framework |
pytest-asyncio |
Async test support |
pytest-httpx |
Mock HTTP client for API tests |
pytest-cov |
Coverage reporting |
OMeter/
├── src/ometer/
│ ├── __init__.py # Package version (__version__)
│ ├── __main__.py # `python -m ometer` entry point
│ ├── api.py # API communication, BenchmarkResult, benchmarking
│ ├── cli.py # Argument parsing, model matching, main loop
│ ├── config.py # Config class, .env loading
│ ├── display.py # Rich tables, live display, color logic
│ └── export.py # JSON/CSV formatting and file output
├── tests/
│ ├── __init__.py
│ ├── test_api.py
│ ├── test_cli.py
│ ├── test_config.py
│ ├── test_display.py
│ └── test_export.py
├── assets/ # Screenshots for README
├── docs/ # Project documentation
├── pyproject.toml # Project metadata, dependencies, entry points
├── .env.example # Template environment file
├── .gitignore
├── .markdownlint.jsonc # Markdown linting config
├── AGENTS.md # AI assistant rules
├── LICENSE # MIT License
└── README.mdOMeter uses hatchling as its build backend (configured in pyproject.toml):
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/ometer"]Two CLI commands are registered:
[project.scripts]
ometer = "ometer.cli:main_entrypoint"
Both commands are identical and invoke the same main_entrypoint() function.
- Self-documenting code — no docstrings or comments (per AGENTS.md)
- Prefer classes over free functions where appropriate
- Keep it simple — don't over-engineer
- Python 3.14+ required (uses modern type syntax like
X | None)
Configured in .markdownlint.jsonc:
- MD013 (line length): Disabled — technical docs often contain long URLs/commands.
- MD033 (inline HTML): Allows
<p>,<img>,<details>,<summary>,<strong>,<code>— needed for screenshots and collapsible sections.
.envis in.gitignoreto prevent leaking API keys..coverageis ignored (generated bypytest-cov).- Never stage or commit code (per AGENTS.md).
[tool.coverage.run]
source = ["ometer"]
[tool.coverage.report]
omit = ["tests/*", "*/__main__.py"]