From cb4838fc155fe447e5245b37e317cf95bf2abcec Mon Sep 17 00:00:00 2001 From: rhoadesScholar Date: Tue, 5 Mar 2024 12:12:56 -0500 Subject: [PATCH] build: Initial Commit --- .cruft.json | 21 +++++ .github/ISSUE_TEMPLATE.md | 15 ++++ .github/TEST_FAIL_TEMPLATE.md | 12 +++ .github/dependabot.yml | 10 +++ .github/workflows/ci.yml | 100 +++++++++++++++++++++ .github_changelog_generator | 6 ++ .gitignore | 105 ++++++++++++++++++++++ .pre-commit-config.yaml | 38 ++++++++ LICENSE | 26 ++++++ README.md | 9 ++ pyproject.toml | 161 ++++++++++++++++++++++++++++++++++ src/cellmap_data/__init__.py | 10 +++ src/cellmap_data/py.typed | 0 tests/test_cellmap_data.py | 2 + 14 files changed, 515 insertions(+) create mode 100644 .cruft.json create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/TEST_FAIL_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github_changelog_generator create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pyproject.toml create mode 100644 src/cellmap_data/__init__.py create mode 100644 src/cellmap_data/py.typed create mode 100644 tests/test_cellmap_data.py diff --git a/.cruft.json b/.cruft.json new file mode 100644 index 0000000..5901c83 --- /dev/null +++ b/.cruft.json @@ -0,0 +1,21 @@ +{ + "template": "https://github.com/tlambert03/pyrepo-cookiecutter", + "commit": "a464b9946d054b0769a71daa07a3c1ad9c50ea3e", + "checkout": null, + "context": { + "cookiecutter": { + "full_name": "Jeff Rhoades", + "email": "rhoadesj@hhmi.org", + "github_username": "rhoadesScholar", + "project_name": "cellmap.data", + "project_slug": "cellmap_data", + "project_short_description": "Utility for loading CellMap data for machine learning training, utilizing PyTorch, TensorStore, and PyDantic.", + "pypi_username": "rhoadesScholar", + "_copy_without_render": [ + ".github/workflows/*" + ], + "_template": "https://github.com/tlambert03/pyrepo-cookiecutter" + } + }, + "directory": null +} diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..fc30a73 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ +* cellmap.data version: +* Python version: +* Operating System: + +### Description + +Describe what you were trying to get done. +Tell us what happened, what went wrong, and what you expected to happen. + +### What I Did + +``` +Paste the command(s) you ran and the output. +If there was a crash, please include the traceback here. +``` diff --git a/.github/TEST_FAIL_TEMPLATE.md b/.github/TEST_FAIL_TEMPLATE.md new file mode 100644 index 0000000..3512972 --- /dev/null +++ b/.github/TEST_FAIL_TEMPLATE.md @@ -0,0 +1,12 @@ +--- +title: "{{ env.TITLE }}" +labels: [bug] +--- +The {{ workflow }} workflow failed on {{ date | date("YYYY-MM-DD HH:mm") }} UTC + +The most recent failing test was on {{ env.PLATFORM }} py{{ env.PYTHON }} +with commit: {{ sha }} + +Full run: https://github.com/{{ repo }}/actions/runs/{{ env.RUN_ID }} + +(This post will be updated if another test fails, as long as this issue remains open.) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..96505a9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "ci(dependabot):" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..608ef37 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,100 @@ +name: CI + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: + - main + tags: + - "v*" + pull_request: + workflow_dispatch: + schedule: + - cron: "0 0 * * 0" # every week (for --pre release tests) + +jobs: + check-manifest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: pipx run check-manifest + + test: + name: ${{ matrix.platform }} (${{ matrix.python-version }}) + runs-on: ${{ matrix.platform }} + strategy: + fail-fast: false + matrix: + python-version: ['3.8', '3.9', '3.10', '3.11'] + platform: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache-dependency-path: "pyproject.toml" + cache: "pip" + + # if running a cron job, we add the --pre flag to test against pre-releases + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install .[test] ${{ github.event_name == 'schedule' && '--pre' || '' }} + + - name: Test + run: pytest --color=yes --cov --cov-report=xml --cov-report=term-missing + + # If something goes wrong, we can open an issue in the repo + - name: Report --pre Failures + if: failure() && github.event_name == 'schedule' + uses: JasonEtco/create-an-issue@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PLATFORM: ${{ matrix.platform }} + PYTHON: ${{ matrix.python-version }} + RUN_ID: ${{ github.run_id }} + TITLE: '[test-bot] pip install --pre is failing' + with: + filename: .github/TEST_FAIL_TEMPLATE.md + update_existing: true + + - name: Coverage + uses: codecov/codecov-action@v3 + + deploy: + name: Deploy + needs: test + if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'schedule' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: install + run: | + pip install -U pip build twine + python -m build + twine check dist/* + + - name: Build and publish + run: twine upload dist/* + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }} + + - uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000..ef1a62b --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,6 @@ +user=rhoadesScholar +project=cellmap.data +issues=false +exclude-labels=duplicate,question,invalid,wontfix,hide +add-sections={"tests":{"prefix":"**Tests & CI:**","labels":["tests"]}, "documentation":{"prefix":"**Documentation:**", "labels":["documentation"]}} +exclude-tags-regex=.*rc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3707b77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE settings +.vscode/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f840a42 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,38 @@ +ci: + autoupdate_schedule: monthly + autofix_commit_msg: "style(pre-commit.ci): auto fixes [...]" + autoupdate_commit_msg: "ci(pre-commit.ci): autoupdate" + +default_install_hook_types: [pre-commit, commit-msg] + +repos: + # - repo: https://github.com/compilerla/conventional-pre-commit + # rev: v2.1.1 + # hooks: + # - id: conventional-pre-commit + # stages: [commit-msg] + + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.252 + hooks: + - id: ruff + args: [--fix] + + - repo: https://github.com/psf/black + rev: 23.1.0 + hooks: + - id: black + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.12.1 + hooks: + - id: validate-pyproject + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.0.1 + hooks: + - id: mypy + files: "^src/" + # # you have to add the things you want to type check against here + # additional_dependencies: + # - numpy diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..373a997 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2024, Jeff Rhoades + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e30f73f --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# cellmap.data + +[![License](https://img.shields.io/pypi/l/cellmap.data.svg?color=green)](https://github.com/rhoadesScholar/cellmap.data/raw/main/LICENSE) +[![PyPI](https://img.shields.io/pypi/v/cellmap.data.svg?color=green)](https://pypi.org/project/cellmap.data) +[![Python Version](https://img.shields.io/pypi/pyversions/cellmap.data.svg?color=green)](https://python.org) +[![CI](https://github.com/rhoadesScholar/cellmap.data/actions/workflows/ci.yml/badge.svg)](https://github.com/rhoadesScholar/cellmap.data/actions/workflows/ci.yml) +[![codecov](https://codecov.io/gh/rhoadesScholar/cellmap.data/branch/main/graph/badge.svg)](https://codecov.io/gh/rhoadesScholar/cellmap.data) + +Utility for loading CellMap data for machine learning training, utilizing PyTorch, TensorStore, and PyDantic. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e59f064 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,161 @@ +# https://peps.python.org/pep-0517/ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +# https://peps.python.org/pep-0621/ +[project] +name = "cellmap.data" +description = "Utility for loading CellMap data for machine learning training, utilizing PyTorch, TensorStore, and PyDantic." +readme = "README.md" +requires-python = ">=3.8" +license = { text = "BSD 3-Clause License" } +authors = [ + { email = "rhoadesj@hhmi.org", name = "Jeff Rhoades" }, +] +classifiers = [ + "Development Status :: 3 - Alpha", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Typing :: Typed", +] +dynamic = ["version"] +dependencies = [] + +# extras +# https://peps.python.org/pep-0621/#dependencies-optional-dependencies +[project.optional-dependencies] +test = ["pytest>=6.0", "pytest-cov"] +dev = [ + "black", + "ipython", + "mypy", + "pdbpp", + "pre-commit", + "pytest-cov", + "pytest", + "rich", + "ruff", +] + +[project.urls] +homepage = "https://github.com/rhoadesScholar/cellmap.data" +repository = "https://github.com/rhoadesScholar/cellmap.data" + +# same as console_scripts entry point +# [project.scripts] +# spam-cli = "spam:main_cli" + +# Entry points +# https://peps.python.org/pep-0621/#entry-points +# [project.entry-points."spam.magical"] +# tomatoes = "spam:main_tomatoes" + +# https://hatch.pypa.io/latest/config/metadata/ +[tool.hatch.version] +source = "vcs" + +# https://hatch.pypa.io/latest/config/build/#file-selection +# [tool.hatch.build.targets.sdist] +# include = ["/src", "/tests"] + +[tool.hatch.build.targets.wheel] +only-include = ["src"] +sources = ["src"] + +# https://github.com/charliermarsh/ruff +[tool.ruff] +line-length = 88 +target-version = "py38" +src = ["src"] +# https://beta.ruff.rs/docs/rules/ +select = [ + "E", # style errors + "W", # style warnings + "F", # flakes + "D", # pydocstyle + "I", # isort + "UP", # pyupgrade + "C4", # flake8-comprehensions + "B", # flake8-bugbear + "A001", # flake8-builtins + "RUF", # ruff-specific rules +] +# I do this to get numpy-style docstrings AND retain +# D417 (Missing argument descriptions in the docstring) +# otherwise, see: +# https://beta.ruff.rs/docs/faq/#does-ruff-support-numpy-or-google-style-docstrings +# https://github.com/charliermarsh/ruff/issues/2606 +ignore = [ + "D100", # Missing docstring in public module + "D107", # Missing docstring in __init__ + "D203", # 1 blank line required before class docstring + "D212", # Multi-line docstring summary should start at the first line + "D213", # Multi-line docstring summary should start at the second line + "D401", # First line should be in imperative mood + "D413", # Missing blank line after last section + "D416", # Section name should end with a colon +] + +[tool.ruff.per-file-ignores] +"tests/*.py" = ["D", "S"] + +# https://docs.pytest.org/en/6.2.x/customize.html +[tool.pytest.ini_options] +minversion = "6.0" +testpaths = ["tests"] +filterwarnings = ["error"] + +# https://mypy.readthedocs.io/en/stable/config_file.html +[tool.mypy] +files = "src/**/" +strict = true +disallow_any_generics = false +disallow_subclassing_any = false +show_error_codes = true +pretty = true + +# # module specific overrides +# [[tool.mypy.overrides]] +# module = ["numpy.*",] +# ignore_errors = true + + +# https://coverage.readthedocs.io/en/6.4/config.html +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "if TYPE_CHECKING:", + "@overload", + "except ImportError", + "\\.\\.\\.", + "raise NotImplementedError()", +] +[tool.coverage.run] +source = ["cellmap_data"] + +# https://github.com/mgedmin/check-manifest#configuration +[tool.check-manifest] +ignore = [ + ".github_changelog_generator", + ".pre-commit-config.yaml", + ".ruff_cache/**/*", + "tests/**/*", +] + +# # for things that require compilation +# # https://cibuildwheel.readthedocs.io/en/stable/options/ +# [tool.cibuildwheel] +# # Skip 32-bit builds & PyPy wheels on all platforms +# skip = ["*-manylinux_i686", "*-musllinux_i686", "*-win32", "pp*"] +# test-extras = ["test"] +# test-command = "pytest {project}/tests -v" +# test-skip = "*-musllinux*" + +# [tool.cibuildwheel.environment] +# HATCH_BUILD_HOOKS_ENABLE = "1" diff --git a/src/cellmap_data/__init__.py b/src/cellmap_data/__init__.py new file mode 100644 index 0000000..2937414 --- /dev/null +++ b/src/cellmap_data/__init__.py @@ -0,0 +1,10 @@ +"""Utility for loading CellMap data for machine learning training, utilizing PyTorch, TensorStore, and PyDantic.""" +from importlib.metadata import PackageNotFoundError, version + +try: + __version__ = version("cellmap.data") +except PackageNotFoundError: + __version__ = "uninstalled" + +__author__ = "Jeff Rhoades" +__email__ = "rhoadesj@hhmi.org" diff --git a/src/cellmap_data/py.typed b/src/cellmap_data/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_cellmap_data.py b/tests/test_cellmap_data.py new file mode 100644 index 0000000..363b3e2 --- /dev/null +++ b/tests/test_cellmap_data.py @@ -0,0 +1,2 @@ +def test_something(): + pass