From d981ccadfe3965f5d4bb8756ebac93bef955de40 Mon Sep 17 00:00:00 2001 From: Trevor James Smith <10819524+Zeitsperre@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:01:11 -0400 Subject: [PATCH] fast-forward cookiecutter, update pre-commit --- .codacy.yml | 6 +- .cruft.json | 3 +- .gitignore | 3 + .pre-commit-config.yaml | 4 +- .yamllint.yaml | 39 +++ CHANGES.rst => CHANGELOG.rst | 0 CODE_OF_CONDUCT.rst | 84 +++++++ CONTRIBUTING.rst | 22 +- MANIFEST.in | 7 - Makefile | 14 +- README.rst | 6 +- docs/source/changelog.rst | 1 + docs/source/changes.rst | 1 - docs/source/conf.py | 1 - docs/source/index.rst | 2 +- environment-dev.yml | 22 ++ environment-docs.yml | 7 +- environment.yml | 13 +- pyproject.toml | 224 ++++++++++++++++++ rook/__init__.py | 16 -- setup.cfg | 45 ---- setup.py | 63 ----- src/rook/__init__.py | 34 +++ {rook => src/rook}/__version__.py | 4 +- {rook => src/rook}/catalog/__init__.py | 0 {rook => src/rook}/catalog/db.py | 0 {rook => src/rook}/cli.py | 63 +++-- {rook => src/rook}/dashboard/__init__.py | 0 {rook => src/rook}/dashboard/base.py | 0 {rook => src/rook}/dashboard/dashboard.py | 0 {rook => src/rook}/dashboard/models.py | 0 .../rook}/dashboard/plots/__init__.py | 0 .../rook}/dashboard/plots/activity.py | 0 .../rook}/dashboard/plots/activity2.py | 0 {rook => src/rook}/dashboard/plots/base.py | 0 .../rook}/dashboard/plots/concurrency.py | 0 {rook => src/rook}/dashboard/plots/day.py | 0 .../rook}/dashboard/plots/downloads.py | 0 .../rook}/dashboard/plots/duration.py | 0 {rook => src/rook}/dashboard/plots/hour.py | 0 {rook => src/rook}/dashboard/plots/pulse.py | 0 .../rook}/dashboard/plots/transfer.py | 0 .../rook}/dashboard/tables/__init__.py | 0 {rook => src/rook}/dashboard/tables/base.py | 0 .../rook}/dashboard/tables/messages.py | 0 .../rook}/dashboard/tables/overview.py | 0 .../rook}/dashboard/templates/base.html | 0 .../rook}/dashboard/templates/dashboard.html | 0 .../rook}/dashboard/templates/navbar.html | 0 {rook => src/rook}/default.cfg | 0 {rook => src/rook}/director/__init__.py | 0 {rook => src/rook}/director/alignment.py | 0 {rook => src/rook}/director/director.py | 0 {rook => src/rook}/etc/roocs.ini | 0 {rook => src/rook}/exceptions.py | 0 {rook => src/rook}/operator.py | 0 {rook => src/rook}/processes/__init__.py | 4 + .../rook}/processes/wps_average_dim.py | 0 .../rook}/processes/wps_average_shape.py | 0 .../rook}/processes/wps_average_time.py | 0 .../rook}/processes/wps_average_weighted.py | 0 {rook => src/rook}/processes/wps_concat.py | 0 {rook => src/rook}/processes/wps_dashboard.py | 0 .../rook}/processes/wps_orchestrate.py | 0 {rook => src/rook}/processes/wps_regrid.py | 0 {rook => src/rook}/processes/wps_subset.py | 0 {rook => src/rook}/processes/wps_usage.py | 0 {rook => src/rook}/provenance.py | 0 src/rook/rook.py | 1 + {rook => src/rook}/templates/pywps.cfg | 6 +- {rook => src/rook}/usage/__init__.py | 0 {rook => src/rook}/usage/base.py | 0 {rook => src/rook}/usage/combine.py | 0 {rook => src/rook}/usage/downloads.py | 0 {rook => src/rook}/usage/wpsusage.py | 0 {rook => src/rook}/utils/__init__.py | 0 {rook => src/rook}/utils/apply_fixes.py | 0 {rook => src/rook}/utils/atlas_fixes.py | 0 {rook => src/rook}/utils/average_utils.py | 0 {rook => src/rook}/utils/concat_utils.py | 0 {rook => src/rook}/utils/decadal_fixes.py | 0 {rook => src/rook}/utils/input_utils.py | 0 {rook => src/rook}/utils/metalink_utils.py | 0 {rook => src/rook}/utils/regrid_utils.py | 0 {rook => src/rook}/utils/response_utils.py | 0 {rook => src/rook}/utils/subset_utils.py | 0 .../rook}/utils/weighted_average_utils.py | 0 {rook => src/rook}/workflow.py | 0 {rook => src/rook}/wsgi.py | 4 +- tests/common.py | 12 +- tox.ini | 31 ++- 91 files changed, 523 insertions(+), 219 deletions(-) create mode 100644 .yamllint.yaml rename CHANGES.rst => CHANGELOG.rst (100%) create mode 100644 CODE_OF_CONDUCT.rst delete mode 100644 MANIFEST.in create mode 100644 docs/source/changelog.rst delete mode 100644 docs/source/changes.rst create mode 100644 environment-dev.yml create mode 100644 pyproject.toml delete mode 100644 rook/__init__.py delete mode 100644 setup.py create mode 100644 src/rook/__init__.py rename {rook => src/rook}/__version__.py (80%) rename {rook => src/rook}/catalog/__init__.py (100%) rename {rook => src/rook}/catalog/db.py (100%) rename {rook => src/rook}/cli.py (80%) rename {rook => src/rook}/dashboard/__init__.py (100%) rename {rook => src/rook}/dashboard/base.py (100%) rename {rook => src/rook}/dashboard/dashboard.py (100%) rename {rook => src/rook}/dashboard/models.py (100%) rename {rook => src/rook}/dashboard/plots/__init__.py (100%) rename {rook => src/rook}/dashboard/plots/activity.py (100%) rename {rook => src/rook}/dashboard/plots/activity2.py (100%) rename {rook => src/rook}/dashboard/plots/base.py (100%) rename {rook => src/rook}/dashboard/plots/concurrency.py (100%) rename {rook => src/rook}/dashboard/plots/day.py (100%) rename {rook => src/rook}/dashboard/plots/downloads.py (100%) rename {rook => src/rook}/dashboard/plots/duration.py (100%) rename {rook => src/rook}/dashboard/plots/hour.py (100%) rename {rook => src/rook}/dashboard/plots/pulse.py (100%) rename {rook => src/rook}/dashboard/plots/transfer.py (100%) rename {rook => src/rook}/dashboard/tables/__init__.py (100%) rename {rook => src/rook}/dashboard/tables/base.py (100%) rename {rook => src/rook}/dashboard/tables/messages.py (100%) rename {rook => src/rook}/dashboard/tables/overview.py (100%) rename {rook => src/rook}/dashboard/templates/base.html (100%) rename {rook => src/rook}/dashboard/templates/dashboard.html (100%) rename {rook => src/rook}/dashboard/templates/navbar.html (100%) rename {rook => src/rook}/default.cfg (100%) rename {rook => src/rook}/director/__init__.py (100%) rename {rook => src/rook}/director/alignment.py (100%) rename {rook => src/rook}/director/director.py (100%) rename {rook => src/rook}/etc/roocs.ini (100%) rename {rook => src/rook}/exceptions.py (100%) rename {rook => src/rook}/operator.py (100%) rename {rook => src/rook}/processes/__init__.py (95%) rename {rook => src/rook}/processes/wps_average_dim.py (100%) rename {rook => src/rook}/processes/wps_average_shape.py (100%) rename {rook => src/rook}/processes/wps_average_time.py (100%) rename {rook => src/rook}/processes/wps_average_weighted.py (100%) rename {rook => src/rook}/processes/wps_concat.py (100%) rename {rook => src/rook}/processes/wps_dashboard.py (100%) rename {rook => src/rook}/processes/wps_orchestrate.py (100%) rename {rook => src/rook}/processes/wps_regrid.py (100%) rename {rook => src/rook}/processes/wps_subset.py (100%) rename {rook => src/rook}/processes/wps_usage.py (100%) rename {rook => src/rook}/provenance.py (100%) create mode 100644 src/rook/rook.py rename {rook => src/rook}/templates/pywps.cfg (81%) rename {rook => src/rook}/usage/__init__.py (100%) rename {rook => src/rook}/usage/base.py (100%) rename {rook => src/rook}/usage/combine.py (100%) rename {rook => src/rook}/usage/downloads.py (100%) rename {rook => src/rook}/usage/wpsusage.py (100%) rename {rook => src/rook}/utils/__init__.py (100%) rename {rook => src/rook}/utils/apply_fixes.py (100%) rename {rook => src/rook}/utils/atlas_fixes.py (100%) rename {rook => src/rook}/utils/average_utils.py (100%) rename {rook => src/rook}/utils/concat_utils.py (100%) rename {rook => src/rook}/utils/decadal_fixes.py (100%) rename {rook => src/rook}/utils/input_utils.py (100%) rename {rook => src/rook}/utils/metalink_utils.py (100%) rename {rook => src/rook}/utils/regrid_utils.py (100%) rename {rook => src/rook}/utils/response_utils.py (100%) rename {rook => src/rook}/utils/subset_utils.py (100%) rename {rook => src/rook}/utils/weighted_average_utils.py (100%) rename {rook => src/rook}/workflow.py (100%) rename {rook => src/rook}/wsgi.py (74%) diff --git a/.codacy.yml b/.codacy.yml index 9700d78b..34195902 100644 --- a/.codacy.yml +++ b/.codacy.yml @@ -1,8 +1,8 @@ --- engines: - pylint: - enabled: true - python_version: 3 + pylint: + enabled: true + python_version: 3 exclude_paths: - 'tests/**' - 'docs/source/conf.py' diff --git a/.cruft.json b/.cruft.json index 8a7dc3d2..e45612ba 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/bird-house/cookiecutter-birdhouse.git", - "commit": "231d17eca6986f606d280cc25262d0153efd92c4", + "commit": "d25191ecc41c091d9b4a392f0ac89d70ff27db55", "context": { "cookiecutter": { "full_name": "Carsten Ehbrecht", @@ -20,6 +20,7 @@ "_copy_without_render": [ "{{cookiecutter.project_slug}}/templates/*.cfg" ], + "__gh_slug": "roocs/rook", "_template": "https://github.com/bird-house/cookiecutter-birdhouse.git" } }, diff --git a/.gitignore b/.gitignore index c420ecab..f0427f5b 100644 --- a/.gitignore +++ b/.gitignore @@ -122,6 +122,9 @@ target/ # pyenv .python-version +# Dask worker cache +dask-worker-space/ + # celery beat schedule file celerybeat-schedule diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4b438cf4..2be5745a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace exclude: setup.cfg @@ -12,7 +12,7 @@ repos: - id: check-yaml - id: debug-statements - repo: https://github.com/ambv/black - rev: 24.8.0 + rev: 24.10.0 hooks: - id: black args: ["--target-version", "py39"] diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 00000000..ce25c395 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,39 @@ +--- + +rules: + + brackets: + forbid: false + min-spaces-inside: 1 + max-spaces-inside: 1 + + commas: + min-spaces-after: 1 + + document-start: disable + + float-values: + require-numeral-before-decimal: true + + hyphens: + max-spaces-after: 1 + + indentation: + indent-sequences: whatever + spaces: consistent + + key-duplicates: + forbid-duplicated-merge-keys: true + + line-length: + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + max: 180 + level: warning + + new-lines: + type: unix + + trailing-spaces: {} + + truthy: disable diff --git a/CHANGES.rst b/CHANGELOG.rst similarity index 100% rename from CHANGES.rst rename to CHANGELOG.rst diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..d11c563e --- /dev/null +++ b/CODE_OF_CONDUCT.rst @@ -0,0 +1,84 @@ +==================================== +Contributor Covenant Code of Conduct +==================================== + +Our Pledge +---------- + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +Our Standards +------------- + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Our Responsibilities +-------------------- + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +Scope +----- + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +Enforcement +----------- + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at [INSERT EMAIL ADDRESS]. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +Attribution +----------- + +This Code of Conduct is adapted from the `Contributor Covenant`_, version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq + +.. _`Contributor Covenant`: https://www.contributor-covenant.org diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3cd4084a..80575855 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -51,8 +51,7 @@ If you are proposing a feature: * Explain in detail how it would work. * Keep the scope as narrow as possible, to make it easier to implement. -* Remember that this is a volunteer-driven project, and that contributions - are welcome :) +* Remember that this is a volunteer-driven project, and that contributions are welcome :) Get Started! ------------ @@ -79,9 +78,10 @@ Ready to contribute? Here's how to set up `rook` for local development. 5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: - $ flake8 rook tests - $ python setup.py test or pytest - $ tox + $ make lint + $ make test + Or + $ make test-all To get flake8 and tox, just pip install them into your virtualenv. @@ -100,7 +100,7 @@ Before you submit a pull request, check that it meets these guidelines: 1. The pull request should include tests. 2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst. -3. The pull request should work for Python 3.7, 3.8, 3.9, 3.10 and 3.11. Check https://github.com/roocs/rook/actions and make sure that the tests pass for all supported Python versions. +3. The pull request should work for all supported Python versions. Check https://github.com/roocs/rook/actions and make sure that the tests pass for all supported Python versions. Tips ---- @@ -117,6 +117,14 @@ A reminder for the maintainers on how to deploy. Make sure all your changes are committed (including an entry in HISTORY.rst). Then run:: - $ bump2version patch # possible: major / minor / patch + $ bump-my-version bump patch # possible: major / minor / patch $ git push $ git push --tags + +Code of Conduct +--------------- + +Please note that this project is released with a `Contributor Code of Conduct`_. +By participating in this project you agree to abide by its terms. + +.. _`Contributor Code of Conduct`: CODE_OF_CONDUCT.rst diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 1dadbc44..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include Makefile -include *.txt -include *.rst -include tox.ini -recursive-include rook * -global-exclude __pycache__ -global-exclude *.py[co] diff --git a/Makefile b/Makefile index cf01be63..8c1aa807 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ clean-docs: ## remove documentation artifacts lint/flake8: ## check style with flake8 @echo "Running flake8 code style checks ..." - @bash -c 'flake8 rook tests' + @bash -c 'ruff check rook tests' lint: lint/flake8 ## check style @@ -128,7 +128,6 @@ notebook-sanitizer: ## download notebook output sanitizer @echo "Copying notebook output sanitizer ..." @-bash -c "curl -L $(SANITIZE_FILE) -o $(CURDIR)/docs/source/output-sanitize.cfg --silent" - test-notebooks: notebook-sanitizer ## run notebook-based tests @echo "Running notebook-based tests" @bash -c "env WPS_URL=$(WPS_URL) pytest --nbval --rootdir tests/ --verbose $(CURDIR)/docs/source/notebooks/ --sanitize-with $(CURDIR)/docs/source/output-sanitize.cfg --ignore $(CURDIR)/docs/source/notebooks/.ipynb_checkpoints" @@ -156,11 +155,7 @@ servedocs: docs ## compile the docs watching for changes @echo "Compiling the docs and watching for changes ..." @watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . -notebook-sanitizer: ## sanitize notebooks with configuration file - @echo "Copying notebook output sanitizer ..." - @-bash -c "curl -L $(SANITIZE_FILE) -o $(CURDIR)/docs/source/output-sanitize.cfg --silent" - -refresh-notebooks: ## refreshing all notebook outputs under docs/source/notebooks +refresh-notebooks: notebook-sanitizer ## refreshing all notebook outputs under docs/source/notebooks @echo "Refresh all notebook outputs under docs/source/notebooks" @bash -c 'for nb in $(CURDIR)/docs/source/notebooks/*.ipynb; do WPS_URL="$(WPS_URL)" jupyter nbconvert --to notebook --execute --ExecutePreprocessor.timeout=60 --output "$$nb" "$$nb"; sed -i "s@$(WPS_URL)/outputs/@$(OUTPUT_URL)/@g" "$$nb"; done; cd $(APP_ROOT)' @@ -168,10 +163,9 @@ refresh-notebooks: ## refreshing all notebook outputs under docs/source/notebook dist: clean ## build source and wheel package @echo "Building source and wheel package ..." - @python setup.py sdist - @python setup.py bdist_wheel + @python -m build --sdist @bash -c 'ls -l dist/' release: dist ## upload source and wheel packages @echo "Uploading source and wheel packages ..." - @bash -c 'twine upload dist/*' + @python -m flit publish dist/* diff --git a/README.rst b/README.rst index 69e44e99..9d0da464 100644 --- a/README.rst +++ b/README.rst @@ -40,7 +40,7 @@ Contributing You can find information about contributing in our `Developer Guide`_. -Please use bump2version_ to release a new version. +Please use bump-my-version_ to release a new version. Tests ----- @@ -61,9 +61,9 @@ Credits This package was created with Cookiecutter_ and the `bird-house/cookiecutter-birdhouse`_ project template. -.. _Cookiecutter: https://github.com/audreyr/cookiecutter +.. _Cookiecutter: https://github.com/cookiecutter/cookiecutter .. _`bird-house/cookiecutter-birdhouse`: https://github.com/bird-house/cookiecutter-birdhouse .. _`Developer Guide`: https://rook-wps.readthedocs.io/en/latest/dev_guide.html -.. _bump2version: https://rook.readthedocs.io/en/latest/dev_guide.html#bump-a-new-version +.. _bump-my-version: https://rook.readthedocs.io/en/latest/dev_guide.html#bump-a-new-version .. _daops: https://github.com/roocs/daops .. _locust: https://locust.io/ diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 00000000..09929fe4 --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1 @@ +.. include:: ../../CHANGELOG.rst diff --git a/docs/source/changes.rst b/docs/source/changes.rst deleted file mode 100644 index d76c92b6..00000000 --- a/docs/source/changes.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../CHANGES.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index 921c0653..f7a6cee6 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -63,7 +63,6 @@ "hdf5", "matplotlib", "netCDF4", - "networkx", "numba", "numpy", "ocgis", diff --git a/docs/source/index.rst b/docs/source/index.rst index 31913448..d1ce0b53 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -11,7 +11,7 @@ processes authors prov - changes + changelog Indices and tables ================== diff --git a/environment-dev.yml b/environment-dev.yml new file mode 100644 index 00000000..44f55ab1 --- /dev/null +++ b/environment-dev.yml @@ -0,0 +1,22 @@ +name: rook-dev +channels: + - conda-forge + - defaults +dependencies: + - python >=3.9,<3.13 + # development + - bump-my-version >=0.26.0 + - coverage >=7.5.0 + - cruft >=2.15.0 + - flit >=3.9.0,<4.0 + - nbsphinx >=0.9.5 + - nbval >=0.10.0 + - ruff >=0.5.7 + - sphinx >=7.0.0 + - tox >=4.18.0 + - watchdog >=4.0.0 + # tests + - pytest >=8.0.0 + - pytest-cov >=5.0.0 + - pytest-timeout >=2.3.1 + - beautifulsoup4 >4.12.3 diff --git a/environment-docs.yml b/environment-docs.yml index d8364982..f14cb63e 100644 --- a/environment-docs.yml +++ b/environment-docs.yml @@ -2,9 +2,10 @@ name: rook channels: - conda-forge + - defaults dependencies: - - python >=3.9,<3.10 - - pywps >=4.5.2,<4.7 + - python >=3.9,<3.12 + - pywps >=4.6 - sphinx >=7.0.0 - nbsphinx >=0.9.5 - - ipython >=8.13.0 + - ipython >=8.5.0 diff --git a/environment.yml b/environment.yml index b1f02635..6143fed9 100644 --- a/environment.yml +++ b/environment.yml @@ -1,12 +1,13 @@ name: rook channels: - conda-forge + - defaults dependencies: - python >=3.9,<3.12 - - pywps >=4.5.2,<4.7 - - jinja2 - - click - - psutil + - pywps >=4.6 + - jinja2 >=3.1.4 + - click >=8.1.7 + - psutil >=6.0.0 - requests - cftime >=1.2.1 - xarray >=0.21,<2023.3.0 # https://github.com/pydata/xarray/issues/7794 @@ -31,7 +32,3 @@ dependencies: - aiohttp # dashboard - bokeh - # tests - - pytest - - pytest-timeout - - beautifulsoup4 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..e6e5ac9f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,224 @@ +[build-system] +requires = ["flit_core >=3.9,<4"] +build-backend = "flit_core.buildapi" + +[project] +name = "rook" +authors = [ + {name = "Carsten Ehbrecht", email = "ehbrecht@dkrz.de"} +] +maintainers = [ + {name = "Carsten Ehbrecht", email = "ehbrecht@dkrz.de"} +] +readme = {file = "README.rst", content-type = "text/x-rst"} +requires-python = ">=3.9.0" +keywords = ["wps", "pywps", "birdhouse", "rook"] +license = {file = "LICENSE"} +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", + "Programming Language :: Python", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + # "Programming Language :: Python :: 3.12", + "Topic :: Scientific/Engineering :: Atmospheric Science" +] +dynamic = ["description", "version"] +dependencies = [ + "click >=8.1.7", + "jinja2 >=3.1.4", + "psutil >=6.0.0", + "pywps >=4.5.1,<4.6" +] + +[project.optional-dependencies] +dev = [ + "pip >=24.2.0", + "bump-my-version >=0.26.0", + "coverage >=7.5.0", + "cruft >=2.15.0", + "flit >=3.9.0,<4.0", + "nbsphinx >=0.9.5", + "nbval >=0.10.0", + "pytest >=8.0.0", + "pytest-cov >=5.0.0", + "ruff >=0.5.7", + "sphinx >=7.0.0", + "tox >=4.18.0", + "watchdog >=4.0.0" +] + +[project.scripts] +rook = "rook.cli:cli" + +[project.urls] +"Issue tracker" = "https://github.com/roocs/rook/issues" +"Changelog" = "https://github.com/roocs/rook/blob/master/changelog.rst" +"Homepage" = "https://github.com/roocs/rook" + +[tool] + +[tool.bumpversion] +current_version = "0.13.1" +commit = true +commit_args = "--no-verify" +tag = true +tag_name = "v{new_version}" +allow_dirty = true + +[[tool.bumpversion.files]] +filename = "src/rook/__version__.py" +search = "__version__ = \"{current_version}\"" +replace = "__version__ = \"{new_version}\"" + +[[tool.bumpversion.files]] +filenam = "Dockerfile" +search = "Version=\"{current_version}\"" +replace = "Version=\"{new_version}\"" + +[[tool.bumpversion.files]] +filename = ".cruft.json" +search = "\"version\": \"{current_version}\"" +replace = "\"version\": \"{new_version}\"" + +[tool.coverage.paths] +source = ["src/rook/", "*/site-packages/rook/"] + +[tool.coverage.run] +omit = ["tests/*.py"] +relative_files = true +source = ["rook"] + +[tool.flit.sdist] +include = [ + ".zenodo.json", + "AUTHORS.rst", + "CHANGELOG.rst", + "CONTRIBUTING.rst", + "LICENSE", + "Makefile", + "README.rst", + "environment.yml", + "environment-dev.yml", + "environment-docs.yml", + "docs/_static/_images/*.gif", + "docs/_static/_images/*.jpg", + "docs/_static/_images/*.png", + "docs/_static/_images/*.rst", + "docs/Makefile", + "docs/conf.py", + "docs/make.bat", + "src/rook", + "tests/*.py", + "tox.ini" +] +exclude = [ + "*.py[co]", + "__pycache__", + ".codacy.yml", + ".dockerignore", + ".editorconfig", + ".gitignore", + ".pre-commit-config.yaml", + ".readthedocs.yml", + ".yamllint.yaml", + "Dockerfile", + "docker-compose.yml", + "docs/_*", + "docs/apidoc/modules.rst", + "docs/apidoc/rook*.rst" +] + +[tool.mypy] +files = "." +# Use strict defaults +strict = true +warn_unreachable = true +warn_no_return = true + +[[tool.mypy.overrides]] +# Don't require test functions to include types +module = "tests.*" +allow_untyped_defs = true +disable_error_code = "attr-defined" + +[tool.pytest.ini_options] +addopts = [ + "--color=yes", + "--cov=rook", + "--cov-report=term-missing", + "--ignore=setup.py", + "--strict-markers", + "--tb=native" +] +python_files = ["test_*.py"] +markers = [ + "online: mark test to need internet connection", + "slow: mark test to be slow", + "smoke: mark test as a smoke/sanity test" +] + +[tool.ruff] +src = ["rook"] +line-length = 150 +exclude = [ + ".eggs", + ".git", + "build", + "docs" +] + +[tool.ruff.format] +line-ending = "auto" + +[tool.ruff.lint] +extend-select = [ + "RUF022" # unsorted-dunder-all +] +ignore = [ + "COM", # commas + "D205", # blank-line-after-summary + "D400", # ends-in-period + "D401" # non-imperative-mood +] +preview = true +select = [ + "BLE", # blind-except + "C90", # mccabe-complexity + "D", # docstrings + "E", # pycodestyle errors + "FLY002", # static-join-to-fstring + "G", # logging-format + "N", # naming conventions + "PERF", # iterator performance + "PTH", # pathlib + "RUF010", # explicit-f-string-type-conversion + "RUF013", # implicit-optional + "S", # bandit + "UP", # python version conventions + "W" # pycodestyle warnings +] + +[tool.ruff.lint.flake8-bandit] +check-typed-exception = true + +[tool.ruff.lint.mccabe] +max-complexity = 15 + +[tool.ruff.lint.per-file-ignores] +"docs/**" = ["E402"] +"src/rook/**/__init__.py" = ["F401", "F403"] +"tests/**" = ["D100", "D101", "D102", "D103", "S101"] + +[tool.ruff.lint.pycodestyle] +max-doc-length = 180 + +[tool.ruff.lint.pydocstyle] +convention = "numpy" diff --git a/rook/__init__.py b/rook/__init__.py deleted file mode 100644 index 02021982..00000000 --- a/rook/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Top-level package for rook.""" - -from .__version__ import __author__, __email__, __version__ # noqa: F401 - -from roocs_utils.config import get_config - - -# Workaround for roocs_utils to not re-import rook -class Package: - __file__ = __file__ # noqa - - -package = Package() -CONFIG = get_config(package) - -from .wsgi import application # noqa: F401 diff --git a/setup.cfg b/setup.cfg index 1b6d82b6..35cb38c4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,44 +1,3 @@ -[bumpversion] -current_version = 0.13.1 -commit = True -tag = True - -[metadata] -description-file = README.rst - -[bumpversion:file:rook/__version__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:docs/source/conf.py] -parse = version|release = {current_version} -replace = {new_version} - -[bumpversion:file:Dockerfile] -search = Version="{current_version}" -replace = Version="{new_version}" - -[bumpversion:file:.cruft.json] -search = "version": "{current_version}", -replace = "version": "{new_version}", - -[bdist_wheel] -universal = 1 - -[tool:pytest] -addopts = - --color=yes - --cov=rook - --cov-report=term-missing - --ignore=setup.py - --strict-markers - --tb=native -python_files = test_*.py -markers = - online: mark test to need internet connection - slow: mark test to be slow - smoke: mark test as a smoke/sanity test - [flake8] max-line-length = 120 exclude = @@ -54,7 +13,3 @@ ignore = E402 W503 E203 - -[doc8] -ignore-path = docs/build,docs/source/_templates,docs/source/_static -max-line-length = 120 diff --git a/setup.py b/setup.py deleted file mode 100644 index f0d39816..00000000 --- a/setup.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -"""The setup script.""" - -import os - -from setuptools import find_packages, setup - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, "README.rst")).read() -CHANGES = open(os.path.join(here, "CHANGES.rst")).read() -REQUIRES_PYTHON = ">=3.9.0" - -about = {} -with open(os.path.join(here, "rook", "__version__.py")) as f: - exec(f.read(), about) - -requirements = [line.strip() for line in open("requirements.txt")] -dev_reqs = [line.strip() for line in open("requirements_dev.txt")] - -classifiers = [ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX", - "Programming Language :: Python", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - # "Programming Language :: Python :: 3.12", - "Topic :: Scientific/Engineering :: Atmospheric Science", - "License :: OSI Approved :: Apache Software License", -] - -setup( - name="roocs-rook", - version=about["__version__"], - description="A WPS service for roocs.", - long_description=README + "\n\n" + CHANGES, - long_description_content_type="text/x-rst", - author=about["__author__"], - author_email=about["__email__"], - url="https://github.com/roocs/rook", - python_requires=REQUIRES_PYTHON, - classifiers=classifiers, - license="Apache Software License 2.0", - zip_safe=False, - keywords="wps pywps birdhouse rook", - packages=find_packages(), - include_package_data=True, - install_requires=requirements, - extras_require={ - "dev": dev_reqs, # pip install ".[dev]" - }, - entry_points={ - "console_scripts": [ - "rook=rook.cli:cli", - ] - }, -) diff --git a/src/rook/__init__.py b/src/rook/__init__.py new file mode 100644 index 00000000..da2ddd0e --- /dev/null +++ b/src/rook/__init__.py @@ -0,0 +1,34 @@ +"""A WPS service for roocs.""" + +################################################################################### +# Apache Software License 2.0 +# +# Copyright (c) 2024, Carsten Ehbrecht, Eleanor Smith, Ag Stephens +# +# Licensed 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. +################################################################################### + +from .__version__ import __author__, __email__, __version__ # noqa: F401 + +from roocs_utils.config import get_config + + +# Workaround for roocs_utils to not re-import rook +class Package: + __file__ = __file__ # noqa + + +package = Package() +CONFIG = get_config(package) + +from .wsgi import application # noqa: F401 diff --git a/rook/__version__.py b/src/rook/__version__.py similarity index 80% rename from rook/__version__.py rename to src/rook/__version__.py index c977c495..e58b435b 100644 --- a/rook/__version__.py +++ b/src/rook/__version__.py @@ -1,7 +1,9 @@ +"""rook version information.""" + # This information is located in its own file so that it can be loaded # without importing the main package when its dependencies are not installed. # See: https://packaging.python.org/guides/single-sourcing-package-version -__author__ = "Carsten Ehbrecht" +__author__ = """Carsten Ehbrecht""" __email__ = "ehbrecht@dkrz.de" __version__ = "0.13.1" diff --git a/rook/catalog/__init__.py b/src/rook/catalog/__init__.py similarity index 100% rename from rook/catalog/__init__.py rename to src/rook/catalog/__init__.py diff --git a/rook/catalog/db.py b/src/rook/catalog/db.py similarity index 100% rename from rook/catalog/db.py rename to src/rook/catalog/db.py diff --git a/rook/cli.py b/src/rook/cli.py similarity index 80% rename from rook/cli.py rename to src/rook/cli.py index 9498c6cd..77905857 100644 --- a/rook/cli.py +++ b/src/rook/cli.py @@ -1,37 +1,43 @@ +"""Demo WPS service for testing and debugging.""" + ########################################################### -# Demo WPS service for testing and debugging. -# # See the werkzeug documentation on how to use the debugger: # http://werkzeug.pocoo.org/docs/0.12/debug/ ########################################################### import os -from urllib.parse import urlparse +from pathlib import Path -import click import psutil +import click from jinja2 import Environment, PackageLoader from pywps import configuration from . import wsgi +from urllib.parse import urlparse -PID_FILE = os.path.abspath(os.path.join(os.path.curdir, "pywps.pid")) +PID_FILE = Path(__file__).parent.joinpath("pywps.pid").resolve() CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) -template_env = Environment(loader=PackageLoader("rook", "templates"), autoescape=True) +template_env = Environment( + loader=PackageLoader("rook", "templates"), + autoescape=True, +) def write_user_config(**kwargs): + """Write a custom configuration file.""" config_templ = template_env.get_template("pywps.cfg") rendered_config = config_templ.render(**kwargs) - config_file = os.path.abspath(os.path.join(os.path.curdir, ".custom.cfg")) - with open(config_file, "w") as fp: + config_file = Path(__file__).parent.joinpath(".custom.cfg").resolve() + with config_file.open("w") as fp: fp.write(rendered_config) return config_file def get_host(): + """Gather host information.""" url = configuration.get_config_value("server", "url") url = url or "http://localhost:5000/wps" @@ -48,11 +54,10 @@ def get_host(): def run_process_action(action=None): - """Run an action with psutil on current process - and return a status message.""" + """Run an action with psutil on current process and return a status message.""" action = action or "status" try: - with open(PID_FILE) as fp: + with PID_FILE.open() as fp: pid = int(fp.read()) p = psutil.Process(pid) if action == "stop": @@ -61,11 +66,9 @@ def run_process_action(action=None): else: from psutil import _pprint_secs - msg = "pid={}, status={}, created={}".format( - p.pid, p.status(), _pprint_secs(p.create_time()) - ) + msg = f"pid={p.pid}, status={p.status()}, created={_pprint_secs(p.create_time())}" if action == "stop": - os.remove(PID_FILE) + PID_FILE.unlink() except OSError: msg = 'No PID file found. Service not running? Try "netstat -nlp | grep :5000".' except psutil.NoSuchProcess as e: @@ -97,24 +100,25 @@ def _run(application, bind_host=None, daemon=False): @click.group(context_settings=CONTEXT_SETTINGS) @click.version_option() def cli(): - """Command line to start/stop a PyWPS service. + """ + Command line to start/stop a PyWPS service. Do not use this service in a production environment. It's intended to be running in a test environment only! - For more documentation, visit http://pywps.org/doc + For more documentation, visit https://pywps.org/doc """ pass @cli.command() def status(): - """Show status of PyWPS service""" + """Show status of PyWPS service.""" run_process_action(action="status") @cli.command() def stop(): - """Stop PyWPS service""" + """Stop PyWPS service.""" run_process_action(action="stop") @@ -173,6 +177,10 @@ def stop(): default="sqlite:///pywps-logs.sqlite", help="database in PyWPS configuration", ) +@click.option("--outputurl", default="", help="base URL for file downloads") +@click.option( + "--outputpath", default="", help="base directory where outputs are written" +) def start( config, bind_host, @@ -185,15 +193,18 @@ def start( log_level, log_file, database, + outputurl, + outputpath, ): - """Start PyWPS service. + """ + Start PyWPS service. + This service is by default available at http://localhost:5000/wps """ - if os.path.exists(PID_FILE): + if PID_FILE.exists(): click.echo(f'PID file exists: "{PID_FILE}". Service still running?') os._exit(0) - cfgfiles = [] - cfgfiles.append( + cfgfiles = [ write_user_config( wps_hostname=hostname, wps_port=port, @@ -203,8 +214,10 @@ def start( wps_log_level=log_level, wps_log_file=log_file, wps_database=database, + wps_outputurl=outputurl, + wps_outputpath=outputpath, ) - ) + ] if config: cfgfiles.append(config) app = wsgi.create_app(cfgfiles) @@ -219,7 +232,7 @@ def start( pid = os.fork() if pid: click.echo(f"forked process id: {pid}") - with open(PID_FILE, "w") as fp: + with PID_FILE.open("w") as fp: fp.write(f"{pid}") except OSError as e: raise Exception("%s [%d]" % (e.strerror, e.errno)) diff --git a/rook/dashboard/__init__.py b/src/rook/dashboard/__init__.py similarity index 100% rename from rook/dashboard/__init__.py rename to src/rook/dashboard/__init__.py diff --git a/rook/dashboard/base.py b/src/rook/dashboard/base.py similarity index 100% rename from rook/dashboard/base.py rename to src/rook/dashboard/base.py diff --git a/rook/dashboard/dashboard.py b/src/rook/dashboard/dashboard.py similarity index 100% rename from rook/dashboard/dashboard.py rename to src/rook/dashboard/dashboard.py diff --git a/rook/dashboard/models.py b/src/rook/dashboard/models.py similarity index 100% rename from rook/dashboard/models.py rename to src/rook/dashboard/models.py diff --git a/rook/dashboard/plots/__init__.py b/src/rook/dashboard/plots/__init__.py similarity index 100% rename from rook/dashboard/plots/__init__.py rename to src/rook/dashboard/plots/__init__.py diff --git a/rook/dashboard/plots/activity.py b/src/rook/dashboard/plots/activity.py similarity index 100% rename from rook/dashboard/plots/activity.py rename to src/rook/dashboard/plots/activity.py diff --git a/rook/dashboard/plots/activity2.py b/src/rook/dashboard/plots/activity2.py similarity index 100% rename from rook/dashboard/plots/activity2.py rename to src/rook/dashboard/plots/activity2.py diff --git a/rook/dashboard/plots/base.py b/src/rook/dashboard/plots/base.py similarity index 100% rename from rook/dashboard/plots/base.py rename to src/rook/dashboard/plots/base.py diff --git a/rook/dashboard/plots/concurrency.py b/src/rook/dashboard/plots/concurrency.py similarity index 100% rename from rook/dashboard/plots/concurrency.py rename to src/rook/dashboard/plots/concurrency.py diff --git a/rook/dashboard/plots/day.py b/src/rook/dashboard/plots/day.py similarity index 100% rename from rook/dashboard/plots/day.py rename to src/rook/dashboard/plots/day.py diff --git a/rook/dashboard/plots/downloads.py b/src/rook/dashboard/plots/downloads.py similarity index 100% rename from rook/dashboard/plots/downloads.py rename to src/rook/dashboard/plots/downloads.py diff --git a/rook/dashboard/plots/duration.py b/src/rook/dashboard/plots/duration.py similarity index 100% rename from rook/dashboard/plots/duration.py rename to src/rook/dashboard/plots/duration.py diff --git a/rook/dashboard/plots/hour.py b/src/rook/dashboard/plots/hour.py similarity index 100% rename from rook/dashboard/plots/hour.py rename to src/rook/dashboard/plots/hour.py diff --git a/rook/dashboard/plots/pulse.py b/src/rook/dashboard/plots/pulse.py similarity index 100% rename from rook/dashboard/plots/pulse.py rename to src/rook/dashboard/plots/pulse.py diff --git a/rook/dashboard/plots/transfer.py b/src/rook/dashboard/plots/transfer.py similarity index 100% rename from rook/dashboard/plots/transfer.py rename to src/rook/dashboard/plots/transfer.py diff --git a/rook/dashboard/tables/__init__.py b/src/rook/dashboard/tables/__init__.py similarity index 100% rename from rook/dashboard/tables/__init__.py rename to src/rook/dashboard/tables/__init__.py diff --git a/rook/dashboard/tables/base.py b/src/rook/dashboard/tables/base.py similarity index 100% rename from rook/dashboard/tables/base.py rename to src/rook/dashboard/tables/base.py diff --git a/rook/dashboard/tables/messages.py b/src/rook/dashboard/tables/messages.py similarity index 100% rename from rook/dashboard/tables/messages.py rename to src/rook/dashboard/tables/messages.py diff --git a/rook/dashboard/tables/overview.py b/src/rook/dashboard/tables/overview.py similarity index 100% rename from rook/dashboard/tables/overview.py rename to src/rook/dashboard/tables/overview.py diff --git a/rook/dashboard/templates/base.html b/src/rook/dashboard/templates/base.html similarity index 100% rename from rook/dashboard/templates/base.html rename to src/rook/dashboard/templates/base.html diff --git a/rook/dashboard/templates/dashboard.html b/src/rook/dashboard/templates/dashboard.html similarity index 100% rename from rook/dashboard/templates/dashboard.html rename to src/rook/dashboard/templates/dashboard.html diff --git a/rook/dashboard/templates/navbar.html b/src/rook/dashboard/templates/navbar.html similarity index 100% rename from rook/dashboard/templates/navbar.html rename to src/rook/dashboard/templates/navbar.html diff --git a/rook/default.cfg b/src/rook/default.cfg similarity index 100% rename from rook/default.cfg rename to src/rook/default.cfg diff --git a/rook/director/__init__.py b/src/rook/director/__init__.py similarity index 100% rename from rook/director/__init__.py rename to src/rook/director/__init__.py diff --git a/rook/director/alignment.py b/src/rook/director/alignment.py similarity index 100% rename from rook/director/alignment.py rename to src/rook/director/alignment.py diff --git a/rook/director/director.py b/src/rook/director/director.py similarity index 100% rename from rook/director/director.py rename to src/rook/director/director.py diff --git a/rook/etc/roocs.ini b/src/rook/etc/roocs.ini similarity index 100% rename from rook/etc/roocs.ini rename to src/rook/etc/roocs.ini diff --git a/rook/exceptions.py b/src/rook/exceptions.py similarity index 100% rename from rook/exceptions.py rename to src/rook/exceptions.py diff --git a/rook/operator.py b/src/rook/operator.py similarity index 100% rename from rook/operator.py rename to src/rook/operator.py diff --git a/rook/processes/__init__.py b/src/rook/processes/__init__.py similarity index 95% rename from rook/processes/__init__.py rename to src/rook/processes/__init__.py index c60ad589..6a07f3ce 100644 --- a/rook/processes/__init__.py +++ b/src/rook/processes/__init__.py @@ -1,3 +1,5 @@ +"""Processes module.""" + from .wps_usage import Usage from .wps_dashboard import DashboardProcess from .wps_average_time import AverageByTime @@ -7,6 +9,8 @@ from .wps_orchestrate import Orchestrate from .wps_subset import Subset from .wps_concat import Concat + + from .wps_regrid import Regrid processes = [ diff --git a/rook/processes/wps_average_dim.py b/src/rook/processes/wps_average_dim.py similarity index 100% rename from rook/processes/wps_average_dim.py rename to src/rook/processes/wps_average_dim.py diff --git a/rook/processes/wps_average_shape.py b/src/rook/processes/wps_average_shape.py similarity index 100% rename from rook/processes/wps_average_shape.py rename to src/rook/processes/wps_average_shape.py diff --git a/rook/processes/wps_average_time.py b/src/rook/processes/wps_average_time.py similarity index 100% rename from rook/processes/wps_average_time.py rename to src/rook/processes/wps_average_time.py diff --git a/rook/processes/wps_average_weighted.py b/src/rook/processes/wps_average_weighted.py similarity index 100% rename from rook/processes/wps_average_weighted.py rename to src/rook/processes/wps_average_weighted.py diff --git a/rook/processes/wps_concat.py b/src/rook/processes/wps_concat.py similarity index 100% rename from rook/processes/wps_concat.py rename to src/rook/processes/wps_concat.py diff --git a/rook/processes/wps_dashboard.py b/src/rook/processes/wps_dashboard.py similarity index 100% rename from rook/processes/wps_dashboard.py rename to src/rook/processes/wps_dashboard.py diff --git a/rook/processes/wps_orchestrate.py b/src/rook/processes/wps_orchestrate.py similarity index 100% rename from rook/processes/wps_orchestrate.py rename to src/rook/processes/wps_orchestrate.py diff --git a/rook/processes/wps_regrid.py b/src/rook/processes/wps_regrid.py similarity index 100% rename from rook/processes/wps_regrid.py rename to src/rook/processes/wps_regrid.py diff --git a/rook/processes/wps_subset.py b/src/rook/processes/wps_subset.py similarity index 100% rename from rook/processes/wps_subset.py rename to src/rook/processes/wps_subset.py diff --git a/rook/processes/wps_usage.py b/src/rook/processes/wps_usage.py similarity index 100% rename from rook/processes/wps_usage.py rename to src/rook/processes/wps_usage.py diff --git a/rook/provenance.py b/src/rook/provenance.py similarity index 100% rename from rook/provenance.py rename to src/rook/provenance.py diff --git a/src/rook/rook.py b/src/rook/rook.py new file mode 100644 index 00000000..dd0b80ed --- /dev/null +++ b/src/rook/rook.py @@ -0,0 +1 @@ +"""Main module.""" diff --git a/rook/templates/pywps.cfg b/src/rook/templates/pywps.cfg similarity index 81% rename from rook/templates/pywps.cfg rename to src/rook/templates/pywps.cfg index 20951f8a..c4ed66ce 100644 --- a/rook/templates/pywps.cfg +++ b/src/rook/templates/pywps.cfg @@ -21,7 +21,7 @@ workdir={{ wps_workdir }} {% endif %} [logging] -level = {{ wps_log_level|default('INFO') }} -file = {{ wps_log_file|default('pywps.log') }} -database = {{ wps_database|default('sqlite:///pywps-logs.sqlite') }} +level = INFO +file = pywps.log +database = sqlite:///pywps-logs.sqlite format = %(asctime)s] [%(levelname)s] line=%(lineno)s module=%(module)s %(message)s diff --git a/rook/usage/__init__.py b/src/rook/usage/__init__.py similarity index 100% rename from rook/usage/__init__.py rename to src/rook/usage/__init__.py diff --git a/rook/usage/base.py b/src/rook/usage/base.py similarity index 100% rename from rook/usage/base.py rename to src/rook/usage/base.py diff --git a/rook/usage/combine.py b/src/rook/usage/combine.py similarity index 100% rename from rook/usage/combine.py rename to src/rook/usage/combine.py diff --git a/rook/usage/downloads.py b/src/rook/usage/downloads.py similarity index 100% rename from rook/usage/downloads.py rename to src/rook/usage/downloads.py diff --git a/rook/usage/wpsusage.py b/src/rook/usage/wpsusage.py similarity index 100% rename from rook/usage/wpsusage.py rename to src/rook/usage/wpsusage.py diff --git a/rook/utils/__init__.py b/src/rook/utils/__init__.py similarity index 100% rename from rook/utils/__init__.py rename to src/rook/utils/__init__.py diff --git a/rook/utils/apply_fixes.py b/src/rook/utils/apply_fixes.py similarity index 100% rename from rook/utils/apply_fixes.py rename to src/rook/utils/apply_fixes.py diff --git a/rook/utils/atlas_fixes.py b/src/rook/utils/atlas_fixes.py similarity index 100% rename from rook/utils/atlas_fixes.py rename to src/rook/utils/atlas_fixes.py diff --git a/rook/utils/average_utils.py b/src/rook/utils/average_utils.py similarity index 100% rename from rook/utils/average_utils.py rename to src/rook/utils/average_utils.py diff --git a/rook/utils/concat_utils.py b/src/rook/utils/concat_utils.py similarity index 100% rename from rook/utils/concat_utils.py rename to src/rook/utils/concat_utils.py diff --git a/rook/utils/decadal_fixes.py b/src/rook/utils/decadal_fixes.py similarity index 100% rename from rook/utils/decadal_fixes.py rename to src/rook/utils/decadal_fixes.py diff --git a/rook/utils/input_utils.py b/src/rook/utils/input_utils.py similarity index 100% rename from rook/utils/input_utils.py rename to src/rook/utils/input_utils.py diff --git a/rook/utils/metalink_utils.py b/src/rook/utils/metalink_utils.py similarity index 100% rename from rook/utils/metalink_utils.py rename to src/rook/utils/metalink_utils.py diff --git a/rook/utils/regrid_utils.py b/src/rook/utils/regrid_utils.py similarity index 100% rename from rook/utils/regrid_utils.py rename to src/rook/utils/regrid_utils.py diff --git a/rook/utils/response_utils.py b/src/rook/utils/response_utils.py similarity index 100% rename from rook/utils/response_utils.py rename to src/rook/utils/response_utils.py diff --git a/rook/utils/subset_utils.py b/src/rook/utils/subset_utils.py similarity index 100% rename from rook/utils/subset_utils.py rename to src/rook/utils/subset_utils.py diff --git a/rook/utils/weighted_average_utils.py b/src/rook/utils/weighted_average_utils.py similarity index 100% rename from rook/utils/weighted_average_utils.py rename to src/rook/utils/weighted_average_utils.py diff --git a/rook/workflow.py b/src/rook/workflow.py similarity index 100% rename from rook/workflow.py rename to src/rook/workflow.py diff --git a/rook/wsgi.py b/src/rook/wsgi.py similarity index 74% rename from rook/wsgi.py rename to src/rook/wsgi.py index 12677601..0464b071 100644 --- a/rook/wsgi.py +++ b/src/rook/wsgi.py @@ -1,4 +1,5 @@ import os +from pathlib import Path from pywps.app.Service import Service @@ -6,7 +7,8 @@ def create_app(cfgfiles=None): - config_files = [os.path.join(os.path.dirname(__file__), "default.cfg")] + """Create PyWPS application.""" + config_files = [Path(__file__).parent.joinpath("default.cfg")] if cfgfiles: config_files.extend(cfgfiles) if "PYWPS_CFG" in os.environ: diff --git a/tests/common.py b/tests/common.py index 36bb4c2f..f6a4b0bd 100644 --- a/tests/common.py +++ b/tests/common.py @@ -66,7 +66,7 @@ class WpsTestClient(WpsClient): def get(self, *args, **kwargs): query = "?" for key, value in kwargs.items(): - query += "{}={}&".format(key, value) + query += f"{key}={value}&" return super().get(query) @@ -75,8 +75,8 @@ def client_for(service): def get_output(doc): - """Copied from pywps/tests/test_execute.py. - TODO: make this helper method public in pywps.""" + """Copied from pywps/tests/test_execute.py.""" + # TODO: make this helper method public in pywps. output = {} for output_el in xpath_ns( doc, "/wps:ExecuteResponse" "/wps:ProcessOutputs/wps:Output" @@ -84,15 +84,15 @@ def get_output(doc): [identifier_el] = xpath_ns(output_el, "./ows:Identifier") lit_el = xpath_ns(output_el, "./wps:Data/wps:LiteralData") - if lit_el != []: + if lit_el: output[identifier_el.text] = lit_el[0].text ref_el = xpath_ns(output_el, "./wps:Reference") - if ref_el != []: + if ref_el: output[identifier_el.text] = ref_el[0].attrib["href"] data_el = xpath_ns(output_el, "./wps:Data/wps:ComplexData") - if data_el != []: + if data_el: output[identifier_el.text] = data_el[0].text return output diff --git a/tox.ini b/tox.ini index 2cadf791..fbe3a836 100644 --- a/tox.ini +++ b/tox.ini @@ -1,25 +1,32 @@ [tox] -min_version = 4.0 +min_version = 4.18.0 envlist = - py{39,310,311}, - flake8 -requires = pip >= 23.1.0 + py{39,310,311,312}, + lint +requires = pip >= 24.2.0 opts = -v -[testenv:flake8] +[testenv:lint] basepython = python -deps = flake8 -commands = flake8 rook tests +skip_install = true +deps = + ruff >=0.5.7 +commands = + make lint +allowlist_externals = + make [testenv] setenv = PYTHONPATH = {toxinidir} +passenv = + GITHUB_* install_command = python -m pip install --no-user {opts} {packages} download = True deps = - -r{toxinidir}/requirements_dev.txt -; If you want to make tox run the tests with the same versions, create a -; requirements.txt with the pinned versions and uncomment the following line: -; -r{toxinidir}/requirements.txt +extras = dev +commands_pre = + python -m pip list + python -m pip check commands = - pytest --basetemp={envtmpdir} + python -m pytest --basetemp={envtmpdir}