From bd974a8c9793c8c0877f2836d38194912c272866 Mon Sep 17 00:00:00 2001 From: mskumar Date: Fri, 25 Sep 2026 08:38:26 +0530 Subject: [PATCH] chore: complete PyPI packaging (metadata, publish job, professional README) --- .github/workflows/release.yml | 24 +++++++++++++++++ README.md | 51 ++++++++++++++++++++++------------- pyproject.toml | 10 +++++++ 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 58016bb..06d5a51 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,3 +22,27 @@ jobs: python -m pip install --upgrade pip build - name: Build distributions run: python -m build + + publish: + needs: [build] + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + environment: pypi + permissions: + contents: read + id-token: write + attestations: write + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: "3.11" + - name: Install build tools + run: | + python -m pip install --upgrade pip build + - name: Build distributions + run: python -m build + - name: Publish to PyPI + # First release: register a pending publisher on PyPI for this + # repo + workflow + pypi environment, then push a v* tag. + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 diff --git a/README.md b/README.md index 5399921..ecf5de6 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ [![CI](https://github.com/ms-kumar/torml/actions/workflows/ci.yml/badge.svg)](https://github.com/ms-kumar/torml/actions/workflows/ci.yml) [![Tests](https://github.com/ms-kumar/torml/actions/workflows/test.yml/badge.svg)](https://github.com/ms-kumar/torml/actions/workflows/test.yml) +[![Bandit](https://github.com/ms-kumar/torml/actions/workflows/bandit.yml/badge.svg)](https://github.com/ms-kumar/torml/actions/workflows/bandit.yml) +[![PyPI](https://img.shields.io/pypi/v/torml.svg)](https://pypi.org/project/torml/) [![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](https://github.com/ms-kumar/torml/actions/workflows/test.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) -[![Version](https://img.shields.io/badge/version-0.1.0-green)](RELEASES.md) **torml** is a scikit-learn-style machine learning library implemented from scratch with [PyTorch](https://pytorch.org/) (`torch.Tensor`, `torch.linalg`) @@ -14,31 +15,42 @@ If you know scikit-learn, you know torml: estimators expose `fit` / `predict` / `transform` / `score` / `get_params` / `set_params`, hyperparameters live in `__init__`, `fit` returns `self`, and learned attributes end with `_` (`coef_`, `classes_`, `n_features_in_`). The difference is what's underneath: -vectorized PyTorch tensor ops, so models run on CPU (and compose with the -torch ecosystem) without a second numerical stack. +vectorized PyTorch tensor ops, so models compose with the torch ecosystem +without a second numerical stack. -## Features +## Highlights -25 modules, 280 tests, typed and lint-clean (`black`, `isort`, `flake8`, -`pylint` all enforced in CI): +- **25 estimator modules** — linear models, neighbors, trees, forests, SVMs, + clustering, mixture models, naive Bayes, discriminant analysis, Gaussian + processes, preprocessing, pipelines, model selection, metrics, and more. +- **280 tests**, typed and lint-clean — `black`, `isort`, `flake8`, `pylint`, + Bandit, and CodeQL all enforced in CI across Python 3.10–3.12. +- **One runtime dependency**: `torch>=2.1`. +- **Security-first supply chain** — pinned lockfile (`uv.lock`), SHA-pinned + GitHub Actions, least-privilege workflows, Dependabot + `pip-audit` clean. + See [`SECURITY.md`](SECURITY.md). -| Area | Modules | -| --- | --- | -| Core | `base` (`BaseEstimator`, `clone`, mixins), `utils` (validation, random state, tags) | -| Supervised | `linear_model`, `neighbors`, `naive_bayes`, `tree`, `svm`, `discriminant_analysis`, `gaussian_process` | -| Unsupervised | `cluster`, `mixture`, `decomposition`, `manifold` | -| Meta-estimators | `ensemble` (voting, bagging, forests), `multiclass`, `multivariate`, `pipelines` | -| Data & evaluation | `preprocessing`, `feature_extraction`, `feature_selection`, `random_projection`, `cross_decomposition`, `covariance`, `semi_supervised` | -| Evaluation | `metrics`, `model_selection` (`train_test_split`, `KFold`, `cross_val_score`, `GridSearchCV`) | +## Installation -## Install +Requires Python 3.10–3.12: -Requires Python 3.10–3.12 and PyTorch ≥ 2.1: +```bash +pip install torml +``` + +With test and docs extras: + +```bash +pip install "torml[test]" +pip install "torml[doc]" +``` + +From source (e.g. to follow `main`): ```bash +git clone https://github.com/ms-kumar/torml.git +cd torml pip install -e . -pip install -e ".[test]" # pytest -pip install -e ".[doc]" # sphinx docs ``` With [uv](https://docs.astral.sh/uv/) (pinned interpreter + lockfile): @@ -98,7 +110,7 @@ More in [`examples/`](examples/) (one runnable script per module) and the - API reference + user guide: [`doc/`](doc/) — build with `sphinx-build -b html doc doc/_build` (needs `uv sync --extra doc`) - Wiki: https://github.com/ms-kumar/torml/wiki (conventions, validation utilities, module status) -- Examples: [`examples/`](examples/) — runnable scripts, verified in CI-adjacent local runs +- Examples: [`examples/`](examples/) — runnable scripts for every module - Benchmarks: [`benchmarks/`](benchmarks/) (micro-benchmarks, excluded from the sdist) - Contributing: [`CONTRIBUTING.md`](CONTRIBUTING.md) — dev setup, style, PR checklist - Coding guidelines: [`TORML_CODING_GUIDELINES.md`](TORML_CODING_GUIDELINES.md) @@ -111,6 +123,7 @@ More in [`examples/`](examples/) (one runnable script per module) and the uv run pytest # 280 tests uv run pre-commit run --all-files # black, isort, flake8, pylint uv run sphinx-build -b html doc doc/_build # docs (zero warnings) +python -m build && twine check dist/* # packaging check ``` ## Security diff --git a/pyproject.toml b/pyproject.toml index 866dda2..8b870fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,11 @@ readme = "README.md" license = { text = "MIT" } requires-python = ">=3.10,<3.13" authors = [{ name = "torml contributors" }] +keywords = ["machine-learning", "pytorch", "scikit-learn", "statistics", "data-science"] classifiers = [ + "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -21,6 +24,13 @@ classifiers = [ ] dependencies = ["torch>=2.1"] +[project.urls] +Homepage = "https://github.com/ms-kumar/torml" +Documentation = "https://github.com/ms-kumar/torml/tree/main/doc" +Repository = "https://github.com/ms-kumar/torml" +Issues = "https://github.com/ms-kumar/torml/issues" +Changelog = "https://github.com/ms-kumar/torml/blob/main/RELEASES.md" + [project.optional-dependencies] test = ["pytest>=7", "pytest-cov>=4"] dev = [