Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ All notable changes to env-doctor will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.4] - 2026-06-15

### Added
- **Jupyter / notebook HTML output**: `from env_doctor import check; check()` auto-detects a live Jupyter kernel and renders a rich, self-contained HTML report inline. Falls back to the familiar terminal text report everywhere else.
- **`CheckReport` public API**: `check()` returns a `CheckReport` object with `_repr_html_()` (Jupyter display protocol), `__repr__()`, `.html` (raw HTML string), and `.to_dict()`.
- **`--format {text,html,json}` CLI flag**: `env-doctor check --format html` emits a self-contained HTML fragment for CI reports or `> report.html`. `--json` / `--ci` still work identically.
- **`report` module**: `env_doctor.report.is_notebook()` detects Jupyter/Colab kernels; `env_doctor.report.format_result_html(output)` produces inline-CSS HTML with no external deps.
- **`[notebook]` optional extra**: `pip install env-doctor[notebook]` pulls in IPython. Core deps unchanged — IPython stays optional and lazily imported.

### Changed
- Extracted `collect_check_results()` and `render_check_text()` from `check_command()` so the JSON, HTML, text, and public API renderers share a single detection pass.
- Logo in HTML report now uses the project SVG (`src/env_doctor/report/logo.svg`) instead of an emoji.

---

## [0.3.2] - 2026-05-02

### Fixed
Expand Down Expand Up @@ -301,6 +316,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Basic CUDA toolkit detection
- Library installation commands

[0.3.4]: https://github.com/mitulgarg/env-doctor/compare/v0.3.3...v0.3.4
[0.3.1]: https://github.com/mitulgarg/env-doctor/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/mitulgarg/env-doctor/compare/v0.2.9...v0.3.0
[0.2.9]: https://github.com/mitulgarg/env-doctor/compare/v0.2.8...v0.2.9
Expand Down
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "env-doctor"
version = "0.3.3"
version = "0.3.4"
description = "A CLI tool to verify and fix AI/ML environment compatibility (Driver <-> CUDA <-> Wheels) with platform-specific installation guides."
readme = "README.md"
license = { file = "LICENSE" }
Expand Down Expand Up @@ -39,6 +39,9 @@ dashboard = [
"sqlalchemy>=2.0.0,<3.0.0",
"aiosqlite>=0.17.0,<1.0.0",
]
notebook = [
"ipython>=7.0",
]

[project.scripts]
env-doctor = "env_doctor.cli:main"
Expand All @@ -57,7 +60,7 @@ package-dir = {"" = "src"}
where = ["src"]

[tool.setuptools.package-data]
"*" = ["data/*.json", "web/**/*"]
"*" = ["data/*.json", "web/**/*", "report/*.svg"]

[dependency-groups]
dev = ["pytest"]
Expand Down
6 changes: 5 additions & 1 deletion src/env_doctor/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
__version__ = "0.3.3"
__version__ = "0.3.4"

from .api import check, CheckReport

__all__ = ["check", "CheckReport", "__version__"]
78 changes: 78 additions & 0 deletions src/env_doctor/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""Public Python API for env-doctor, designed for notebook use.

Typical usage inside a Jupyter notebook::

from env_doctor import check
check() # last cell expression -> rich HTML report

In a plain terminal / script the same call prints the familiar text report.
"""
from __future__ import annotations

from typing import Any, Dict, Optional

from .report import is_notebook, format_result_html


class CheckReport:
"""Result of :func:`check`, with format-aware display hooks.

- In Jupyter, being the last expression in a cell triggers
``_repr_html_`` and renders the rich HTML report.
- In an interactive terminal, ``__repr__`` shows a one-line summary
(the full text report is printed by :func:`check` itself).
- ``.html`` and ``.to_dict()`` expose the report for programmatic use.
"""

def __init__(self, output: Dict[str, Any]) -> None:
self._output = output

def to_dict(self) -> Dict[str, Any]:
"""Return the underlying structured result dict."""
return self._output

@property
def html(self) -> str:
"""Return the self-contained HTML report as a string."""
return format_result_html(self._output)

def _repr_html_(self) -> str: # noqa: D401 - IPython display protocol
return self.html

def __repr__(self) -> str:
summary = self._output.get("summary", {})
return (
f"<CheckReport status={self._output.get('status', 'unknown')} "
f"issues={summary.get('issues_count', 0)}>"
)


def check(format: Optional[str] = None) -> CheckReport:
"""Run the environment check and render it for the current environment.

In a notebook, return the result as a cell's last expression and Jupyter
renders the rich HTML automatically (via ``_repr_html_``) — no explicit
``display()`` call, so it never double-renders. In a terminal/script the
familiar text report is printed.

Args:
format: Force a renderer regardless of environment: ``"text"`` always
prints the terminal report; ``"html"`` skips the text print and
leaves rendering to the returned object's ``_repr_html_`` (use
``check(format="html").html`` for the raw string). ``None``
(default) auto-detects: HTML in a notebook, text in a terminal.

Returns:
A :class:`CheckReport`.
"""
# Imported here to avoid a circular import (cli imports report, api).
from .cli import collect_check_results, render_check_text

bundle = collect_check_results()
report = CheckReport(bundle["output"])

render_html = format == "html" or (format is None and is_notebook())
if not render_html:
render_check_text(bundle)

return report
Loading
Loading