diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index e69de29b..00000000 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29bd985a..cdee3c72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,14 +47,24 @@ jobs: - name: "Install dependencies" run: | sudo apt-get install graphviz - pip install --upgrade tox - - name: "Run tests" - run: tox -e clean,lint,py310,coverage + pip install --upgrade hatch + - name: "Tutorials" + run: hatch run tutorials:lint + - name: "Docs" + run: hatch run docs:check + - name: "Clean" + run: hatch run clean + - name: "Lint" + run: hatch run dev:lint + - name: "Test" + run: hatch run dev:test - name: "Upload test results" uses: actions/upload-artifact@v2 with: name: pytest-results-${{ matrix.python-version }} path: junit.xml + - name: "Coverage" + run: hatch run dev:cov - name: "Upload coverage results" uses: codecov/codecov-action@v1 with: diff --git a/.readthedocs.yml b/.readthedocs.yml index 0613f576..fb84004e 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -27,5 +27,5 @@ python: - method: pip path: . extra_requirements: - - all - docs + - all diff --git a/constraints.txt b/constraints.txt index cddbf5f2..0b482ab0 100644 --- a/constraints.txt +++ b/constraints.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with python 3.10 # To update, run: # -# pip-compile --all-extras --no-emit-index-url --output-file=constraints.txt --strip-extras +# pip-compile --extra=dev,docs,dask,graphviz,mlflow,rest,sql --no-emit-index-url --output-file=constraints.txt --strip-extras pyproject.toml # alabaster==0.7.12 # via sphinx @@ -30,7 +30,7 @@ backcall==0.2.0 beautifulsoup4==4.11.1 # via nbconvert black==22.10.0 - # via forml (setup.py) + # via forml (pyproject.toml) bleach==5.0.1 # via nbconvert build==0.9.0 @@ -51,8 +51,7 @@ click==8.1.3 # databricks-cli # distributed # flask - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow # pip-tools # typer @@ -61,15 +60,12 @@ cloudpickle==2.2.0 # via # dask # distributed - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow coverage==6.5.0 # via pytest-cov dask==2022.10.2 - # via - # distributed - # forml + # via distributed databricks-cli==0.17.3 # via mlflow decorator==5.1.1 @@ -81,7 +77,7 @@ dill==0.3.6 distlib==0.3.6 # via virtualenv distributed==2022.10.2 - # via forml (setup.py) + # via forml (pyproject.toml) docker==6.0.1 # via mlflow docutils==0.19 @@ -108,17 +104,15 @@ flake8==5.0.4 # flake8-colors # flake8-typing-imports flake8-bugbear==22.10.27 - # via forml (setup.py) + # via forml (pyproject.toml) flake8-colors==0.1.9 - # via forml (setup.py) + # via forml (pyproject.toml) flake8-typing-imports==1.14.0 - # via forml (setup.py) + # via forml (pyproject.toml) flask==2.2.2 # via # mlflow # prometheus-flask-exporter -forml==0.8 - # via forml (setup.py) fsspec==2022.10.0 # via dask future==0.18.2 @@ -128,9 +122,7 @@ gitdb==4.0.9 gitpython==3.1.29 # via mlflow graphviz==0.20.1 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) greenlet==2.0.1 # via sqlalchemy gunicorn==20.1.0 @@ -162,7 +154,7 @@ ipython==8.6.0 # via black isort==5.10.1 # via - # forml (setup.py) + # forml (pyproject.toml) # pylint itsdangerous==2.1.2 # via @@ -174,8 +166,7 @@ jinja2==3.1.2 # via # distributed # flask - # forml - # forml (setup.py) + # forml (pyproject.toml) # nbconvert # nbsphinx # sphinx @@ -186,7 +177,7 @@ jsonschema==4.17.0 # via nbformat jupyter-client==7.2.2 # via - # forml (setup.py) + # forml (pyproject.toml) # nbclient jupyter-core==4.11.2 # via @@ -221,9 +212,7 @@ mccabe==0.7.0 mistune==2.0.4 # via nbconvert mlflow==1.30.0 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) msgpack==1.0.4 # via distributed mypy-extensions==0.4.3 @@ -240,7 +229,7 @@ nbformat==5.7.0 # nbconvert # nbsphinx nbsphinx==0.8.9 - # via forml (setup.py) + # via forml (pyproject.toml) nest-asyncio==1.5.6 # via # jupyter-client @@ -249,8 +238,7 @@ nodeenv==1.7.0 # via pre-commit numpy==1.23.4 # via - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow # pandas # scikit-learn @@ -263,16 +251,14 @@ packaging==21.3 # dask # distributed # docker - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow # nbconvert # pytest # sphinx pandas==1.5.1 # via - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow pandocfilters==1.5.0 # via nbconvert @@ -291,7 +277,7 @@ pexpect==4.8.0 pickleshare==0.7.5 # via ipython pip-tools==6.9.0 - # via forml (setup.py) + # via forml (pyproject.toml) platformdirs==2.5.3 # via # black @@ -302,7 +288,7 @@ pluggy==1.0.0 pockets==0.9.1 # via sphinxcontrib-napoleon pre-commit==2.20.0 - # via forml (setup.py) + # via forml (pyproject.toml) prometheus-client==0.15.0 # via prometheus-flask-exporter prometheus-flask-exporter==0.20.3 @@ -311,14 +297,14 @@ prompt-toolkit==3.0.32 # via ipython protobuf==4.21.9 # via mlflow -psutil==5.9.3 +psutil==5.9.4 # via distributed ptyprocess==0.7.0 # via pexpect pure-eval==0.2.2 # via stack-data pycln==2.1.1 - # via forml (setup.py) + # via forml (pyproject.toml) pycodestyle==2.9.1 # via flake8 pydantic==1.10.2 @@ -333,13 +319,11 @@ pygments==2.13.0 # nbconvert # sphinx pyhive==0.6.5 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) pyjwt==2.6.0 # via databricks-cli pylint==2.15.5 - # via forml (setup.py) + # via forml (pyproject.toml) pyparsing==3.0.9 # via packaging pyrsistent==0.19.2 @@ -350,11 +334,11 @@ pytest==7.2.0 # pytest-cov # pytest-xdist pytest-asyncio==0.20.1 - # via forml (setup.py) + # via forml (pyproject.toml) pytest-cov==4.0.0 - # via forml (setup.py) + # via forml (pyproject.toml) pytest-xdist==3.0.2 - # via forml (setup.py) + # via forml (pyproject.toml) python-dateutil==2.8.2 # via # jupyter-client @@ -390,9 +374,7 @@ requests==2.28.1 rfc3986==1.5.0 # via httpx scikit-learn==1.1.3 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) scipy==1.9.3 # via # mlflow @@ -421,20 +403,20 @@ soupsieve==2.3.2.post1 # via beautifulsoup4 sphinx==5.3.0 # via - # forml (setup.py) + # forml (pyproject.toml) # nbsphinx # sphinx-copybutton # sphinx-immaterial # sphinxcontrib-details-directive # sphinxcontrib-spelling sphinx-copybutton==0.5.0 - # via forml (setup.py) + # via forml (pyproject.toml) sphinx-immaterial==0.10.0 - # via forml (setup.py) + # via forml (pyproject.toml) sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-details-directive==0.1.0 - # via forml (setup.py) + # via forml (pyproject.toml) sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.0 @@ -442,27 +424,24 @@ sphinxcontrib-htmlhelp==2.0.0 sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-napoleon==0.7 - # via forml (setup.py) + # via forml (pyproject.toml) sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx sphinxcontrib-spelling==7.6.2 - # via forml (setup.py) + # via forml (pyproject.toml) sqlalchemy==1.4.43 # via # alembic - # forml - # forml (setup.py) + # forml (pyproject.toml) # mlflow sqlparse==0.4.3 # via mlflow stack-data==0.6.0 # via ipython starlette==0.21.0 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) tabulate==0.9.0 # via databricks-cli tblib==1.7.0 @@ -475,16 +454,14 @@ tokenize-rt==5.0.0 # via black toml==0.10.2 # via - # forml - # forml (setup.py) + # forml (pyproject.toml) # pre-commit tomli==2.0.1 # via # black # build # coverage - # forml - # forml (setup.py) + # forml (pyproject.toml) # pep517 # pylint # pytest @@ -527,9 +504,7 @@ urllib3==1.26.12 # docker # requests uvicorn==0.19.0 - # via - # forml - # forml (setup.py) + # via forml (pyproject.toml) virtualenv==20.16.6 # via pre-commit wcwidth==0.2.5 diff --git a/pyproject.toml b/pyproject.toml index 4784af0f..63a7722e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,8 +16,8 @@ # under the License. [build-system] -requires = ["setuptools", "wheel", "tomli"] -build-backend = "setuptools.build_meta" +requires = ["hatchling"] +build-backend = "hatchling.build" [project] @@ -80,6 +80,7 @@ docs = [ "sphinxcontrib-napoleon", "sphinxcontrib-spelling", "nbsphinx", # also needs pandoc binary + "jupyter-client==7.2.2", # hold back for tornado-dask compatibility ] graphviz = ["graphviz"] mlflow = ["mlflow"] @@ -88,22 +89,138 @@ sql = ["pyhive", "sqlalchemy"] all = ["forml[dask,graphviz,mlflow,rest,sql]"] [project.urls] -homepage = "http://forml.io/" -source = "https://github.com/formlio/forml" -documentation = "https://docs.forml.io/" -changelog = "https://github.com/formlio/forml/blob/master/CHANGELOG.md" +Homepage = "http://forml.io/" +Source = "https://github.com/formlio/forml/" +Documentation = "https://docs.forml.io/" +Issues = "https://github.com/formlio/forml/issues/" +Changelog = "https://github.com/formlio/forml/blob/master/CHANGELOG.md" +# == Hatch ==================================================================== +# https://hatch.pypa.io/latest/ +[tool.hatch.version] +path = "forml/__init__.py" + +[tool.hatch.envs.default] +[tool.hatch.envs.default.env-vars] +LC_COLLATE = "en_US.UTF-8" +PIP_CONSTRAINT = "constraints.txt" +[tool.hatch.envs.default.scripts] +clean = [ + """rm -vrf \ + .coverage .coverage.* coverage.xml \ + docs/_auto/ docs/_build/ \ + htmlcov/ \ + junit.xml \ + .pytest_cache/ \ + tutorials/titanic/dist/""", + """find {root} \ + \\( \ + -name .git -o \ + -name .idea -o \ + -name .venv \ + \\) -prune -o \ + \\( \ + -type d \ + \\( \ + -name build -o \ + -name .eggs -o \ + -name '*.egg-info' -o \ + -name .ipynb_checkpoints -o \ + -name __pycache__ \ + \\) -prune -o \ + -type f \ + \\( \ + -name '*.log' -o -name '*.log.*' -o \ + -name '*.dot' -o -name '*.dot.*' \ + \\) \ + \\) -print -exec rm -rf {{}} \\;""", +] +update = "pip-compile --extra=dev,docs,dask,graphviz,mlflow,rest,sql --output-file={env:PIP_CONSTRAINT} --no-emit-index-url --strip-extras --rebuild --upgrade pyproject.toml" + +[tool.hatch.envs.dev] +dependencies = [ + "forml[dev,all]", +] +[tool.hatch.envs.dev.scripts] +lint = [ + "black --check --diff --config=pyproject.toml {args: forml tests}", + "isort --check --diff --settings-path=pyproject.toml {args: forml tests}", + "pycln --check --diff --config=pyproject.toml {args: forml tests}", + "flake8 --config=.flake8 {args: forml tests}", + "pylint --rcfile=.pylintrc {args: forml tests}", + "sort --check .gitignore", +] +test = "pytest -rxXs --junitxml=junit.xml --cov-config=pyproject.toml --cov=forml --cov-append --cov-report=term --numprocesses=auto --dist=loadscope {args: forml tests}" +cov = [ + "coverage xml", + "coverage html", +] + +[tool.hatch.envs.docs] +dependencies = [ + "forml[docs,all]", +] +[tool.hatch.envs.docs.env-vars] +SPHINXOPTS = "-W" +[tool.hatch.envs.docs.scripts] +check = [ + "make -C docs linkcheck", + "make -C docs spelling", + "sort --check docs/spelling_wordlist.txt", +] + +[tool.hatch.envs.tutorials] +dependencies = [ + "forml[dev]", + "openschema", +] +[tool.hatch.envs.tutorials.env-vars] +PYTHONPATH = "tutorials:tutorials/titanic" +[tool.hatch.envs.tutorials.scripts] +lint = [ + "black --check --diff --config=pyproject.toml {args: tutorials}", + "isort --check --diff --settings-path=pyproject.toml {args: tutorials}", + "pycln --check --diff --config=pyproject.toml {args: tutorials}", + "flake8 --config=.flake8 {args: tutorials}", + "pylint --rcfile=.pylintrc {args: tutorials}", +] + +[tool.hatch.build.targets.sdist] +include = [ + "/forml", +] + +# == Coverage ================================================================= +# https://coverage.readthedocs.io/en/latest/config.html +[tool.coverage.run] +branch = true +parallel = false + +[tool.coverage.report] +exclude_lines = [ + "no cov", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", +] + + +# == Black ==================================================================== +# https://black.readthedocs.io/en/stable/usage_and_configuration/index.html [tool.black] line-length = 120 target-version = ["py39", "py310"] skip-string-normalization = true +# == Pycln ==================================================================== +# https://hadialqattan.github.io/pycln/#/?id=integrations [tool.pycln] all = true +# == Isort ==================================================================== +# https://pycqa.github.io/isort/docs/configuration/config_files [tool.isort] line_length = 120 multi_line_output = 3 @@ -111,3 +228,10 @@ include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true ensure_newline_before_comments = true + + +# == Pytest =================================================================== +# https://docs.pytest.org/en/latest/reference/customize.html +[tool.pytest.ini_options] +junit_family = "xunit2" +asyncio_mode = "auto" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b7fd01ea..00000000 --- a/setup.cfg +++ /dev/null @@ -1,34 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -[metadata] -version = attr: forml.__version__ - -[options] -packages = find: -zip_safe = False - -[options.packages.find] -include = forml* - -[options.package_data] -forml.setup = config.toml, logging.ini, templates/** - - -[tool:pytest] -junit_family = xunit2 -asyncio_mode = auto diff --git a/setup.py b/setup.py deleted file mode 100644 index a1fe92bd..00000000 --- a/setup.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# 'License'); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -""" -Setuptools script for ForML package. -""" -from setuptools import setup - -setup() diff --git a/tox.ini b/tox.ini deleted file mode 100644 index e49028d9..00000000 --- a/tox.ini +++ /dev/null @@ -1,100 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -[tox] -envlist = - clean - lint - py310 - py39 - coverage - docs - -[gh] -python = - 3.10 = clean, lint, py310, coverage, docs - 3.9 = py39 - -[testenv] -setenv = PIP_CONSTRAINT = constraints.txt -deps = -extras = - dev - all -commands = pytest -rxXs --junitxml=junit.xml --cov=forml --cov-append --cov-report=term --numprocesses=auto --dist=loadscope {posargs: forml tests} - -[testenv:lint] -setenv = - LC_COLLATE = en_US.UTF-8 - PIP_CONSTRAINT = constraints.txt -deps = -extras = - dev - all -commands = - black --check --diff --config=pyproject.toml {posargs: forml tests} - isort --check --diff --settings-path=pyproject.toml {posargs: forml tests} - pycln --check --diff --config=pyproject.toml {posargs: forml tests} - flake8 --config=.flake8 {posargs: forml tests} - pylint --rcfile=.pylintrc {posargs: forml tests} - sort --check .gitignore -whitelist_externals = sort - -[testenv:coverage] -setenv = PIP_CONSTRAINT = constraints.txt -deps = coverage -skip_install = true -commands = - coverage xml - coverage html - -[testenv:clean] -setenv = PIP_CONSTRAINT = constraints.txt -deps = coverage -skip_install = true -commands = coverage erase - -[testenv:tutorials] -setenv = - LC_COLLATE = en_US.UTF-8 - PIP_CONSTRAINT = constraints.txt - PYTHONPATH = {toxinidir}/tutorials:{toxinidir}/tutorials/titanic -deps = openschema -extras = dev -commands = - black --check --diff --config=pyproject.toml {posargs: tutorials} - isort --check --diff --settings-path=pyproject.toml {posargs: tutorials} - pycln --check --diff --config=pyproject.toml {posargs: tutorials} - flake8 --config=.flake8 {posargs: tutorials} - pylint --rcfile=.pylintrc {posargs: tutorials} - -[testenv:docs] -setenv = - LC_COLLATE = en_US.UTF-8 - PIP_CONSTRAINT = constraints.txt - SPHINXOPTS = -W -deps = -extras = - docs - all -commands = - make -C docs linkcheck - make -C docs spelling - sort --check docs/spelling_wordlist.txt -whitelist_externals = - make - sort