From 478a8ad51795539c429865c80ca5821221f6f4da Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Thu, 4 Dec 2025 15:16:45 +0100 Subject: [PATCH 01/13] addec conda environment.yml --- environment.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 environment.yml diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..d08134b5 --- /dev/null +++ b/environment.yml @@ -0,0 +1,20 @@ +name: pywps +channels: + - conda-forge +dependencies: + - python >=3.10,<3.14 + - pip >=25.0 + - owslib >=0.35.0 + - requests >=2.32.5 + - werkzeug >=3.1.4 + - sqlalchemy >=2.0.44 + - lxml >=6.0.2 + - urllib3 >=2.5.0 + - markupsafe >=3.0.3 + - numpy >=1.22.2 + - zarr <3 + - fiona + - geotiff + # tests + - pytest + From 4a70b83d104e75a1941bcd7b2f3a200a21d8f9c9 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Thu, 4 Dec 2025 15:29:46 +0100 Subject: [PATCH 02/13] added makefile with shortcuts --- Makefile | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..053c935d --- /dev/null +++ b/Makefile @@ -0,0 +1,104 @@ +# Configuration +APP_ROOT := $(abspath $(lastword $(MAKEFILE_LIST))/..) + +# end of configuration + +define PRINT_HELP_PYSCRIPT +import re, sys + +for line in sys.stdin: + match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) + if match: + target, help = match.groups() + print("%-20s %s" % (target, help)) + else: + match = re.match(r'^## (.*)$$', line) + if match: + help = match.groups()[0] + print("\n%s" % (help)) +endef +export PRINT_HELP_PYSCRIPT + +.DEFAULT_GOAL := help + +help: ## print this help message. (Default) + @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) + +## Build targets: + +install: ## install pywps + @echo "Installing pywps ..." + @-bash -c 'pip install -e .' + +develop: ## install pywps with development libraries + @echo "Installing development requirements for tests and docs ..." + @-bash -c 'pip install -e ".[dev]"' + +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts + +clean-build: ## remove build artifacts + @echo "Removing build artifacts ..." + @-rm -fr build/ + @-rm -fr dist/ + @-rm -fr .eggs/ + @-find . -name '*.egg-info' -exec rm -fr {} + + @-find . -name '*.egg' -exec rm -f {} + + @-find . -name '*.log' -exec rm -fr {} + + @-find . -name '*.sqlite' -exec rm -fr {} + + +clean-pyc: ## remove Python file artifacts + @echo "Removing Python file artifacts ..." + @-find . -name '*.pyc' -exec rm -f {} + + @-find . -name '*.pyo' -exec rm -f {} + + @-find . -name '*~' -exec rm -f {} + + @-find . -name '__pycache__' -exec rm -fr {} + + +clean-test: ## remove test and coverage artifacts + @echo "Removing test artifacts ..." + @-rm -fr .tox/ + @-rm -f .coverage + @-rm -fr .pytest_cache + +clean-dist: clean ## remove git ignored files and directories + @echo "Running 'git clean' ..." + @git diff --quiet HEAD || echo "There are uncommitted changes! Aborting 'git clean' ..." + ## do not use git clean -e/--exclude here, add them to .gitignore instead + @-git clean -dfx + +clean-docs: ## remove documentation artifacts + @echo "Removing documentation artifacts ..." + $(MAKE) -C docs clean + +lint: ## check style with ruff + @echo "Running code style checks ..." + @bash -c 'ruff check src tests docs' + +## Testing targets: + +test: ## run tests quickly with the default Python (skip slow and online tests) + @echo "Running tests (skip slow and online tests) ..." + @bash -c 'pytest -v -m "not slow and not online" tests/' + +test-all: ## run all tests quickly with the default Python + @echo "Running all tests (including slow and online tests) ..." + @bash -c 'pytest -v tests/' + +## Sphinx targets: + +docs: clean-docs ## generate Sphinx HTML documentation, including API docs + @echo "Generating docs with Sphinx ..." + $(MAKE) -C docs html + @echo "Open your browser to: file:/$(APP_ROOT)/docs/build/html/index.html" + ## do not execute xdg-open automatically since it hangs ReadTheDocs and job does not complete + @echo "xdg-open $(APP_ROOT)/docs/build/html/index.html" + + +## Deployment targets: + +dist: clean ## builds source and wheel package + python -m flit build + ls -l dist + +release: dist ## package and upload a release + python -m flit publish dist/* + From 6f37d1b9e77a9d850c314a2aa2c6f2b66fe8f663 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Thu, 4 Dec 2025 15:44:17 +0100 Subject: [PATCH 03/13] skip python 3.9 --- .github/workflows/main.yml | 12 ++++++------ environment.yml | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 99d3bf16..a6dd8ccf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" - name: Install tox run: | pip install tox>=4.0 @@ -33,12 +33,12 @@ jobs: strategy: matrix: include: - - tox-env: py39-extra - python-version: "3.9" - tox-env: py310-extra python-version: "3.10" - tox-env: py311-extra python-version: "3.11" + - tox-env: py311-extra + python-version: "3.12" steps: - uses: actions/checkout@v4 - name: Install packages 📦 @@ -54,7 +54,7 @@ jobs: - name: Run tests with tox ⚙️ run: tox -e ${{ matrix.tox-env }} - name: Run coveralls ⚙️ - if: matrix.python-version == 3.9 + if: matrix.python-version == 3.10 uses: AndreMiras/coveralls-python-action@develop docs: @@ -64,9 +64,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - name: Setup Python 3.9 + name: Setup Python 3.10 with: - python-version: 3.9 + python-version: 3.10 - name: Build documentation 🏗️ run: | pip install -e .[dev] diff --git a/environment.yml b/environment.yml index d08134b5..552d89a0 100644 --- a/environment.yml +++ b/environment.yml @@ -17,4 +17,7 @@ dependencies: - geotiff # tests - pytest + - ruff >=0.5.7 + # docs + - sphinx >=7.0.0 From 7c70d36394f5fe96bed6ce3a369e93ea2ea8e2c2 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Thu, 4 Dec 2025 15:45:07 +0100 Subject: [PATCH 04/13] skip python 3.9 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 0d89477a..a43925f8 100644 --- a/setup.py +++ b/setup.py @@ -49,16 +49,16 @@ "Operating System :: OS Independent", "Programming Language :: Python", "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 :: GIS", ], "install_requires": INSTALL_REQUIRES, "extras_require": dict( dev=DEV_REQUIRES, ), - "python_requires": ">=3.9,<4", + "python_requires": ">=3.10,<4", "packages": find_packages(exclude=["docs", "tests.*", "tests"]), "include_package_data": True, "scripts": [], From 717c7e6e3fa36d2601daf90953f05ea16dc6d75b Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 13:41:40 +0100 Subject: [PATCH 05/13] fixed tox config --- .github/workflows/main.yml | 4 +++- tox.ini | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a6dd8ccf..ff93686a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,8 +37,10 @@ jobs: python-version: "3.10" - tox-env: py311-extra python-version: "3.11" - - tox-env: py311-extra + - tox-env: py312-extra python-version: "3.12" + - tox-env: py313-extra + python-version: "3.13" steps: - uses: actions/checkout@v4 - name: Install packages 📦 diff --git a/tox.ini b/tox.ini index f92509e7..98d44a69 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,9 @@ [tox] min_version = 4.0 envlist = - py{39,310,311}{-extra,}, + py{310,311,312,313}{-extra,}, lint -requires = pip >= 20.0 +requires = pip >=25.2 opts = --verbose [testenv:lint] From c8ac516295ce6e7d8fc2a6b2ee5fab840d020b7d Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 13:42:13 +0100 Subject: [PATCH 06/13] added support for python 3.13 --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index a43925f8..b280f852 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,7 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: GIS", ], "install_requires": INSTALL_REQUIRES, From 15357916a5d38ed730f5c2950f0cf39b168023b5 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 13:46:16 +0100 Subject: [PATCH 07/13] fixed docs workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ff93686a..fd2e4f3b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,7 +68,7 @@ jobs: - uses: actions/setup-python@v5 name: Setup Python 3.10 with: - python-version: 3.10 + python-version: "3.10" - name: Build documentation 🏗️ run: | pip install -e .[dev] From 56767598dfd087982bf693cce9e103d3e1a47867 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:01:54 +0100 Subject: [PATCH 08/13] using ruff instead of flake8 --- Makefile | 2 +- pyproject.toml | 8 ++++++++ pywps/validator/complexvalidator.py | 4 ++-- requirements-dev.txt | 2 +- setup.cfg | 7 ------- tox.ini | 4 ++-- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 053c935d..ecddf241 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ clean-docs: ## remove documentation artifacts lint: ## check style with ruff @echo "Running code style checks ..." - @bash -c 'ruff check src tests docs' + @bash -c 'ruff check pywps' ## Testing targets: diff --git a/pyproject.toml b/pyproject.toml index fed528d4..69c40b3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,11 @@ [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" + +[tool.ruff] +lint.select = ["E", "W", "F", "C90"] # Flake8-equivalent rule families +lint.ignore = ["F401", "E402", "C901"] + +line-length = 120 +exclude = ["tests"] + diff --git a/pywps/validator/complexvalidator.py b/pywps/validator/complexvalidator.py index b2472715..fb0362ca 100644 --- a/pywps/validator/complexvalidator.py +++ b/pywps/validator/complexvalidator.py @@ -223,7 +223,7 @@ def validategeojson(data_input, mode): >>> from io import StringIO >>> class FakeInput(object): ... json = open('point.geojson','w') - ... json.write('''{"type":"Feature", "properties":{}, "geometry":{"type":"Point", "coordinates":[8.5781228542328, 22.87500500679]}, "crs":{"type":"name", "properties":{"name":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}''') # noqa + ... json.write('''{"type":"Feature", "properties":{}, "geometry":{"type":"Point", "coordinates":[8.5781228542328, 22.87500500679]}, "crs":{"type":"name", "properties":{"name":"urn:ogc:def:crs:OGC:1.3:CRS84"}}}''') ... json.close() ... file = 'point.geojson' >>> class FakeDataFormat(object): @@ -232,7 +232,7 @@ def validategeojson(data_input, mode): >>> fake_input.data_format = FakeDataFormat() >>> validategeojson(fake_input, MODE.SIMPLE) True - """ + """ # noqa LOGGER.info('validating GeoJSON; Mode: {}'.format(mode)) passed = False diff --git a/requirements-dev.txt b/requirements-dev.txt index 0ed95084..e7c0b465 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,7 +2,7 @@ bump2version coverage coveralls docutils -flake8 +ruff pylint pytest pytest-cov diff --git a/setup.cfg b/setup.cfg index fc2a44b4..331c4695 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,11 +17,4 @@ replace = {new_version} [coverage:run] relative_files = True -[flake8] -ignore = - F401 - E402 - W606 -max-line-length = 120 -exclude = tests diff --git a/tox.ini b/tox.ini index 98d44a69..b8d0b61d 100644 --- a/tox.ini +++ b/tox.ini @@ -10,9 +10,9 @@ opts = --verbose skip_install = true extras = deps = - flake8 + ruff commands = - flake8 pywps + ruff check pywps [testenv] setenv = From c1ea827b509ab53877ed9ca79653af1175d2f4c8 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:08:55 +0100 Subject: [PATCH 09/13] clean up make --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ecddf241..df70f644 100644 --- a/Makefile +++ b/Makefile @@ -95,10 +95,10 @@ docs: clean-docs ## generate Sphinx HTML documentation, including API docs ## Deployment targets: -dist: clean ## builds source and wheel package - python -m flit build - ls -l dist +# dist: clean ## builds source and wheel package +# python -m flit build +# ls -l dist -release: dist ## package and upload a release - python -m flit publish dist/* +# release: dist ## package and upload a release +# python -m flit publish dist/* From cdf6652d14b6f5a46263e4ece981cb451044b66d Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:14:31 +0100 Subject: [PATCH 10/13] update readme --- README.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b634e6ab..4a3eeba7 100644 --- a/README.md +++ b/README.md @@ -11,17 +11,26 @@ the Open Geospatial Consortium. PyWPS is written in Python. [![Join the chat at https://gitter.im/geopython/pywps](https://badges.gitter.im/geopython/pywps.svg)](https://gitter.im/geopython/pywps?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -# License +## License As of PyWPS 4.0.0, PyWPS is released under an [MIT](https://en.wikipedia.org/wiki/MIT_License) license (see [LICENSE.txt](LICENSE.txt)). -# Dependencies +## Dependencies See [requirements.txt](requirements.txt) file -# Run tests +## Install + +Install it from GitHub: +```bash +$ git clone https://github.com/geopython/pywps.git +$ cd pywps/ +$ pip install . +``` + +## Run tests ```bash pip install -r requirements-dev.txt @@ -32,9 +41,13 @@ python -m coverage run --source=pywps -m unittest tests python -m coverage report -m ``` -# Run web application +## Quick Guide with Conda -## Example service +Using git + +## Run web application + +### Example service Clone the example service after having installed PyWPS: @@ -44,7 +57,9 @@ cd pywps-flask python demo.py ``` -## Apache configuration +Access example service: http://localhost:5000 + +### Apache configuration 1. Enable WSGI extension @@ -92,7 +107,7 @@ python demo.py ``` -# Issues +## Issues On Windows PyWPS does not support multiprocessing which is used when making requests storing the response document and updating the status to displaying From 8193f5db66ad7615139b2917911528bb5a84150f Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:30:49 +0100 Subject: [PATCH 11/13] added conda section --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a3eeba7..46216d7a 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,31 @@ python -m coverage report -m ## Quick Guide with Conda -Using git +Checkout source from GitHub: +```bash +$ git clone https://github.com/geopython/pywps.git +$ cd pywps/ +``` + +Build conda environment: +```bash +conda env create -f environment.yml +``` + +Install pywps: +```bash +make install +``` + +Or the development version: +```bash +make develop +``` + +Run tests: +```bash +make tests +``` ## Run web application From 33accf527a6661d400c42ef1ba4ef355790c8e8d Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:31:06 +0100 Subject: [PATCH 12/13] removed obsolete INSTALL.md --- INSTALL.md | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 5f521c91..00000000 --- a/INSTALL.md +++ /dev/null @@ -1,44 +0,0 @@ -PyWPS 4 Installation -==================== - -Dependencies ------------- - -To use PyWPS 4 the third party libraries GIT and GDAL need to be installed in the system. - -In Debian based systems these can be installed with: - - $ sudo apt-get install git python-gdal - -In Windows systems a Git client should be installed (e.g. GitHub for Windows). - -Install PyWPS 4 ---------------- - -Using pip: - - $ sudo pip install -e git+https://github.com/geopython/pywps.git@main#egg=pywps - -Or in alternative install it manually: - - $ git clone https://github.com/geopython/pywps.git - - $ cd pywps/ - - $ sudo pip install . - -Install example service ------------------------ - - $ git clone https://github.com/geopython/pywps-flask.git pywps-flask - - -Run example service -------------------- - - $ python demo.py - -Access example service ----------------------- - - http://localhost:5000 From acb0058b1d636f3903c40763dbf0523fe23dcb22 Mon Sep 17 00:00:00 2001 From: Pingu Carsti Date: Fri, 5 Dec 2025 14:36:34 +0100 Subject: [PATCH 13/13] added conda badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 46216d7a..a035da75 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ the Open Geospatial Consortium. PyWPS is written in Python. [![Build Status](https://github.com/geopython/pywps/actions/workflows/main.yml/badge.svg)](https://github.com/geopython/pywps/actions/workflows/main.yml) [![Coverage Status](https://coveralls.io/repos/github/geopython/pywps/badge.svg?branch=main)](https://coveralls.io/github/geopython/pywps?branch=main) [![PyPI](https://img.shields.io/pypi/dm/pywps.svg)](https://pypi.org/project/pywps/) +[![Conda](https://anaconda.org/conda-forge/pywps/badges/version.svg)](https://anaconda.org/channels/conda-forge/packages/pywps/overview) [![GitHub license](https://img.shields.io/github/license/geopython/pywps.svg)]() [![Join the chat at https://gitter.im/geopython/pywps](https://badges.gitter.im/geopython/pywps.svg)](https://gitter.im/geopython/pywps?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)