[Git][debian-gis-team/pygeoapi][master] 3 commits: New upstream version 0.23.4
Edward Betts (@edward)
gitlab at salsa.debian.org
Fri Jun 26 10:55:30 BST 2026
Edward Betts pushed to branch master at Debian GIS Project / pygeoapi
Commits:
042cbf51 by Edward Betts at 2026-06-25T20:04:41+01:00
New upstream version 0.23.4
- - - - -
b0ede4ed by Edward Betts at 2026-06-25T20:04:54+01:00
Update upstream source from tag 'upstream/0.23.4'
Update to upstream version '0.23.4'
with Debian dir 6aedd4b5e429fa05b6a2dcd7357a3b58ecfe713d
- - - - -
fe270c27 by Edward Betts at 2026-06-26T10:55:00+01:00
New upstream release
* Upload to Debian sid. (Closes: #1140752)
* Run unit tests during build and via autopkgtest.
* Build and install documentation.
* Add more detail to package description.
* Update copyright to match LICENSE.md.
* Add debian/salsa-ci.yml.
* Add my name to Uploaders and debian/copyright.
- - - - -
21 changed files:
- debian/changelog
- debian/clean
- debian/control
- debian/copyright
- + debian/doc-base
- + debian/docs
- + debian/pybuild.testfiles
- + debian/pybuild.testfiles.autopkgtest
- debian/rules
- + debian/salsa-ci.yml
- docs/source/conf.py
- docs/source/configuration.rst
- pygeoapi/__init__.py
- pygeoapi/process/base.py
- pygeoapi/process/manager/base.py
- pygeoapi/provider/filesystem.py
- pygeoapi/resources/schemas/config/pygeoapi-config-0.x.yml
- pygeoapi/util.py
- requirements.txt
- tests/other/test_util.py
- tests/provider/test_filesystem_provider.py
Changes:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,16 @@
+pygeoapi (0.23.4-1) UNRELEASED; urgency=medium
+
+ * New upstream release.
+ * Upload to Debian sid. (Closes: #1140752)
+ * Run unit tests during build and via autopkgtest.
+ * Build and install documentation.
+ * Add more detail to package description.
+ * Update copyright to match LICENSE.md.
+ * Add debian/salsa-ci.yml.
+ * Add my name to Uploaders and debian/copyright.
+
+ -- Edward Betts <edward at 4angle.com> Fri, 26 Jun 2026 08:53:09 +0100
+
pygeoapi (0.23.2-1) UNRELEASED; urgency=medium
[ Angelos Tzotsos ]
=====================================
debian/clean
=====================================
@@ -1 +1,2 @@
*-info/
+docs/_build/
=====================================
debian/control
=====================================
@@ -2,28 +2,75 @@ Source: pygeoapi
Section: python
Maintainer: Debian GIS Project <pkg-grass-devel at lists.alioth.debian.org>
Uploaders: Angelos Tzotsos <gcpp.kalxas at gmail.com>,
- Felix Delattre <debian at xama.nu>
+ Felix Delattre <debian at xama.nu>,
+ Edward Betts <edward at 4angle.com>,
Build-Depends: debhelper-compat (= 13),
- dh-python,
+ dh-doc-privacy,
dh-sequence-python3,
+ dh-sequence-sphinxdoc <!nodoc>,
pybuild-plugin-pyproject,
python3-all,
- python3-setuptools
+ python3-setuptools,
+Build-Depends-Indep: libsqlite3-mod-spatialite <!nocheck>,
+ python3-django-cors-headers <!nocheck>,
+ python3-elasticsearch <!nocheck>,
+ python3-filelock <!nocheck>,
+ python3-fiona <!nocheck>,
+ python3-flask <!nocheck>,
+ python3-flask-cors <!nocheck>,
+ python3-gdal <!nocheck>,
+ python3-geoalchemy2 <!nocheck>,
+ python3-geopandas <!nocheck>,
+ python3-httpx <!nocheck>,
+ python3-jsonpatch <!nocheck>,
+ python3-jsonschema <!nocheck>,
+ python3-netcdf4 <!nocheck>,
+ python3-oracledb <!nocheck>,
+ python3-owslib <!nocheck>,
+ python3-polyfactory <!nocheck>,
+ python3-pyarrow <!nocheck>,
+ python3-pydantic <!nocheck>,
+ python3-pygeofilter <!nocheck>,
+ python3-pyld <!nocheck>,
+ python3-pymongo <!nocheck>,
+ python3-pyproj <!nocheck>,
+ python3-pytest <!nocheck>,
+ python3-rasterio <!nocheck>,
+ python3-s3fs <!nocheck>,
+ python3-sodapy <!nocheck>,
+ python3-sphinx <!nodoc>,
+ python3-sphinx-rtd-theme <!nodoc>,
+ python3-starlette <!nocheck>,
+ python3-tinydb <!nocheck>,
+ python3-xarray <!nocheck>,
+ python3-zarr <!nocheck>,
Standards-Version: 4.7.4
Vcs-Browser: https://salsa.debian.org/debian-gis-team/pygeoapi
Vcs-Git: https://salsa.debian.org/debian-gis-team/pygeoapi.git
+Testsuite: autopkgtest-pkg-pybuild
Homepage: https://pygeoapi.io/
Package: python3-pygeoapi
Architecture: all
-Depends: ${python3:Depends},
- ${misc:Depends}
+Depends: ${misc:Depends},
+ ${python3:Depends},
+ ${sphinxdoc:Depends},
Suggests: python3-elasticsearch,
python3-fiona,
python3-geojson,
python3-pyproj,
- python3-rasterio
-Description: pygeoapi provides an API to geospatial data
- pygeoapi is a Python server implementation of the OGC API suite of standards
- and provides the capability to deploy a RESTful OGC API endpoint using
- OpenAPI, GeoJSON, and HTML.
+ python3-rasterio,
+Built-Using:
+ ${sphinxdoc:Built-Using},
+Description: OGC API server for publishing geospatial data
+ This library publishes geospatial resources through RESTful HTTP services that
+ conform to the OGC API family of standards. It exposes configured collections
+ using standard web representations, including OpenAPI descriptions, GeoJSON
+ responses, and HTML pages for browsing.
+ .
+ pygeoapi acts as a service layer between HTTP clients and geospatial data
+ sources. It talks to web clients, GIS applications, catalogues, and other OGC
+ API consumers over HTTP, and reads from configured data providers such as
+ files, databases, and web-accessible services. It can describe available
+ collections, return features and metadata, and provide machine-readable API
+ definitions for client software.
=====================================
debian/copyright
=====================================
@@ -4,11 +4,12 @@ Upstream-Contact: Tom Kralidis <tomkralidis at gmail.com>
Source: https://github.com/geopython/pygeoapi
Files: *
-Copyright: 2018-2024, Tom Kralidis <tomkralidis at gmail.com>
+Copyright: 2018-2026 pygeoapi development team
License: MIT
Files: debian/*
-Copyright: 2021-2024, Angelos Tzotsos <gcpp.kalxas at gmail.com>
+Copyright: 2026, Edward Betts <edward at 4angle.com>
+ 2021-2024, Angelos Tzotsos <gcpp.kalxas at gmail.com>
2023, Felix Delattre <debian at xama.nu>
License: GPL-2+
=====================================
debian/doc-base
=====================================
@@ -0,0 +1,8 @@
+Document: pygeoapi
+Title: pygeoapi documentation
+Author: Tom Kralidis <tomkralidis at gmail.com>
+Section: Programming
+
+Format: HTML
+Index: /usr/share/doc/python3-pygeoapi/html/index.html
+Files: /usr/share/doc/python3-pygeoapi/html/*.html
=====================================
debian/docs
=====================================
@@ -0,0 +1,2 @@
+README.md
+docs/_build/html
=====================================
debian/pybuild.testfiles
=====================================
@@ -0,0 +1,19 @@
+pyproject.toml
+pytest.ini
+pygeoapi-config.yml
+tests/data tests/data
+tests/pygeoapi-test-asyncapi.yml tests/pygeoapi-test-asyncapi.yml
+tests/pygeoapi-test-config-admin-empty-resources.yml tests/pygeoapi-test-config-admin-empty-resources.yml
+tests/pygeoapi-test-config-admin.yml tests/pygeoapi-test-config-admin.yml
+tests/pygeoapi-test-config-apirules.yml tests/pygeoapi-test-config-apirules.yml
+tests/pygeoapi-test-config-enclosure.yml tests/pygeoapi-test-config-enclosure.yml
+tests/pygeoapi-test-config-envvars.yml tests/pygeoapi-test-config-envvars.yml
+tests/pygeoapi-test-config-failing-collection.yml tests/pygeoapi-test-config-failing-collection.yml
+tests/pygeoapi-test-config-hidden-resources.yml tests/pygeoapi-test-config-hidden-resources.yml
+tests/pygeoapi-test-config-ogr.yml tests/pygeoapi-test-config-ogr.yml
+tests/pygeoapi-test-config-postgresql-manager.yml tests/pygeoapi-test-config-postgresql-manager.yml
+tests/pygeoapi-test-config-postgresql.yml tests/pygeoapi-test-config-postgresql.yml
+tests/pygeoapi-test-config-pubsub.yml tests/pygeoapi-test-config-pubsub.yml
+tests/pygeoapi-test-config.yml tests/pygeoapi-test-config.yml
+tests/pygeoapi-test-openapi.yml tests/pygeoapi-test-openapi.yml
+tests/pygeoapi-test-stac-api-config.yml tests/pygeoapi-test-stac-api-config.yml
=====================================
debian/pybuild.testfiles.autopkgtest
=====================================
@@ -0,0 +1,3 @@
+pyproject.toml
+pytest.ini
+tests tests
=====================================
debian/rules
=====================================
@@ -1,13 +1,38 @@
#!/usr/bin/make -f
-# -*- makefile -*-
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-export PYBUILD_NAME=pygeoapi
+export http_proxy=
+export https_proxy=
+export PYBUILD_TEST_ARGS=-x --ignore=tests/provider/test_xarray_netcdf_provider.py \
+ --ignore=tests/provider/test_xarray_zarr_provider.py \
+ --ignore=tests/provider/test_opensearch__provider.py \
+ --ignore=tests/provider/test_elasticsearch__provider.py \
+ --ignore=tests/manager/test_postgresql_manager.py \
+ --ignore=tests/provider/test_csw_provider.py \
+ --ignore=tests/provider/test_esri_provider.py \
+ --ignore=tests/provider/test_filesystem_provider.py \
+ --ignore=tests/provider/test_mongo_provider.py \
+ --ignore=tests/provider/test_mysql_provider.py \
+ --ignore=tests/provider/test_oracle_provider.py \
+ --ignore=tests/provider/test_postgresql_mvt_provider.py \
+ --ignore=tests/provider/test_postgresql_provider.py \
+ --ignore=tests/provider/test_sensorthings_edr_provider.py \
+ --ignore=tests/provider/test_sensorthings_provider.py \
+ --ignore=tests/other/test_ogr_capabilities.py \
+ --ignore=tests/api/test_coverages.py \
+ --ignore=tests/api/test_environmental_data_retrieval.py \
+ --ignore=tests/provider/test_api_ogr_provider.py \
+ --ignore=tests/provider/test_parquet_provider.py \
+ --ignore-glob=tests/provider/test_ogr_*.py \
+ --ignore=tests/api/test_pubsub.py \
+ --ignore=tests/other/test_django.py \
+ -k "not test_admin and not test_describe_collections and not test_describe_processes and not test_django_edr_without_instance_id and not test_get_oas and not test_is_request_allowed and not test_modify_pygeofilter and not test_prefetcher and not test_unique_subclass_query_types and not test_apirules_active and not test_apirules_inactive and not test_api_exception and not test_gzip"
%:
dh $@ --buildsystem pybuild
-override_dh_auto_test:
- @echo "nocheck set, not running tests"
+override_dh_auto_build:
+ dh_auto_build $@ --buildsystem=pybuild
+ dh_doc_privacy docs README.md
+ cd docs; PYTHONPATH=$(CURDIR) LC_ALL=C.UTF-8 LANGUAGE=C.UTF-8 sphinx-build -bhtml -d _build/doctrees source _build/html
+
+before-pybuild-autopkgtest:
+ cp debian/pybuild.testfiles.autopkgtest debian/pybuild.testfiles
=====================================
debian/salsa-ci.yml
=====================================
@@ -0,0 +1,3 @@
+---
+include:
+ - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
=====================================
docs/source/conf.py
=====================================
@@ -112,7 +112,7 @@ today_fmt = '%Y-%m-%d'
# built documents.
#
# The short X.Y version.
-version = '0.23.2'
+version = '0.23.4'
# The full version, including alpha/beta/rc tags.
release = version
=====================================
docs/source/configuration.rst
=====================================
@@ -292,6 +292,10 @@ default.
type: process # REQUIRED (collection, process, or stac-collection)
processor:
name: HelloWorld # Python path of process definition
+ # optional, allow for internal HTTP request execution
+ # if set to True, enables requests to link local ranges and loopback
+ # default: False
+ allow_internal_requests: True
.. seealso::
=====================================
pygeoapi/__init__.py
=====================================
@@ -30,7 +30,7 @@
#
# =================================================================
-__version__ = '0.23.2'
+__version__ = '0.23.4'
import click
try:
=====================================
pygeoapi/process/base.py
=====================================
@@ -3,7 +3,7 @@
# Authors: Tom Kralidis <tomkralidis at gmail.com>
# Francesco Martinelli <francesco.martinelli at ingv.it>
#
-# Copyright (c) 2022 Tom Kralidis
+# Copyright (c) 2026 Tom Kralidis
# Copyright (c) 2024 Francesco Martinelli
#
# Permission is hereby granted, free of charge, to any person
@@ -53,6 +53,8 @@ class BaseProcessor:
self.name = processor_def['name']
self.metadata = process_metadata
self.supports_outputs = False
+ self.allow_internal_requests = processor_def.get(
+ 'allow_internal_requests', False)
def set_job_id(self, job_id: str) -> None:
"""
=====================================
pygeoapi/process/manager/base.py
=====================================
@@ -46,10 +46,12 @@ from pygeoapi.process.base import (
BaseProcessor,
JobNotFoundError,
JobResultNotFoundError,
+ ProcessorExecuteError,
UnknownProcessError,
)
from pygeoapi.util import (
get_current_datetime,
+ is_request_allowed,
JobStatus,
ProcessExecutionMode,
RequestedProcessExecutionMode,
@@ -105,7 +107,11 @@ class BaseManager:
except KeyError as err:
raise UnknownProcessError('Invalid process identifier') from err
else:
- return load_plugin('process', process_conf['processor'])
+ pp = load_plugin('process', process_conf['processor'])
+ pp.allow_internal_requests = process_conf.get(
+ 'allow_internal_requests', False)
+
+ return pp
def get_jobs(self,
status: JobStatus = None,
@@ -394,13 +400,13 @@ class BaseManager:
"""
job_id = str(uuid.uuid1())
- processor = self.get_processor(process_id)
- processor.set_job_id(job_id)
+ self.processor = self.get_processor(process_id)
+ self.processor.set_job_id(job_id)
extra_execute_handler_parameters = {
'requested_response': requested_response
}
- job_control_options = processor.metadata.get(
+ job_control_options = self.processor.metadata.get(
'jobControlOptions', [])
if execution_mode == RequestedProcessExecutionMode.respond_async:
@@ -473,7 +479,7 @@ class BaseManager:
# TODO: handler's response could also be allowed to include more HTTP
# headers
mime_type, outputs, status = handler(
- processor,
+ self.processor,
job_id,
data_dict,
requested_outputs,
@@ -483,26 +489,37 @@ class BaseManager:
def _send_in_progress_notification(self, subscriber: Optional[Subscriber]):
if subscriber and subscriber.in_progress_uri:
- response = requests.post(subscriber.in_progress_uri, json={})
- LOGGER.debug(
- f'In progress notification response: {response.status_code}'
- )
+ self.__do_subscriber_request(subscriber.in_progress_uri)
def _send_success_notification(
self, subscriber: Optional[Subscriber], outputs: Any
):
- if subscriber:
- response = requests.post(subscriber.success_uri, json=outputs)
- LOGGER.debug(
- f'Success notification response: {response.status_code}'
- )
+ if subscriber and subscriber.success_uri:
+ self.__do_subscriber_request(subscriber.success_uri, outputs)
def _send_failed_notification(self, subscriber: Optional[Subscriber]):
if subscriber and subscriber.failed_uri:
- response = requests.post(subscriber.failed_uri, json={})
- LOGGER.debug(
- f'Failed notification response: {response.status_code}'
- )
+ self.__do_subscriber_request(subscriber.failed_uri)
+
+ def __do_subscriber_request(self, url: str, data: dict = {}) -> None:
+ """
+ Helper function to execute a subscriber URL via HTTP POST
+
+ :param url: `str` of URL
+ :param data: `dict` of request payload
+
+ :returns: `None`
+ """
+
+ if not is_request_allowed(url, self.processor.allow_internal_requests):
+ msg = 'URL not allowed'
+ LOGGER.error(f'{msg}: {url}')
+ raise ProcessorExecuteError(msg)
+
+ response = requests.post(url, json=data)
+ LOGGER.debug(
+ f'Response: {response.status_code}'
+ )
def __repr__(self):
return f'<BaseManager> {self.name}'
=====================================
pygeoapi/provider/filesystem.py
=====================================
@@ -2,7 +2,7 @@
#
# Authors: Tom Kralidis <tomkralidis at gmail.com>
#
-# Copyright (c) 2023 Tom Kralidis
+# Copyright (c) 2026 Tom Kralidis
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
@@ -34,6 +34,7 @@ import logging
import os
from pygeoapi.provider.base import (BaseProvider, ProviderConnectionError,
+ ProviderInvalidQueryError,
ProviderNotFoundError)
from pygeoapi.util import file_modified_iso8601, get_path_basename, url_join
@@ -76,9 +77,15 @@ class FileSystemProvider(BaseProvider):
root_link = None
child_links = []
- data_path = os.path.join(self.data, dirpath)
+ if '..' in dirpath:
+ msg = 'Invalid path requested'
+ LOGGER.error(f'{msg}: {dirpath}')
+ raise ProviderInvalidQueryError(msg)
+
data_path = self.data + dirpath
+ LOGGER.debug(f'Data path: {data_path}')
+
if '/' not in dirpath: # root
root_link = baseurl
else:
=====================================
pygeoapi/resources/schemas/config/pygeoapi-config-0.x.yml
=====================================
@@ -682,7 +682,11 @@ properties:
For custom built plugins, use the import path (e.g. `mypackage.provider.MyProvider`)
required:
- name
- required:
+ allow_internal_requests:
+ type: boolean
+ description: whether to allow internal HTTP requests
+ default: false
+ requred:
- type
- processor
definitions:
=====================================
pygeoapi/util.py
=====================================
@@ -36,6 +36,7 @@ from datetime import date, datetime, time, timezone
from decimal import Decimal
from enum import Enum
from heapq import heappush
+import ipaddress
import json
import logging
import mimetypes
@@ -43,6 +44,7 @@ import os
import pathlib
from pathlib import Path
import re
+import socket
from typing import Any, IO, Union, List, Optional
from urllib.parse import urlparse
from urllib.request import urlopen
@@ -754,3 +756,30 @@ def remove_url_auth(url: str) -> str:
u = urlparse(url)
auth = f'{u.username}:{u.password}@'
return url.replace(auth, '')
+
+
+def is_request_allowed(url: str, allow_internal: bool = False) -> bool:
+ """
+ Test whether an HTTP request is allowed to be executed
+
+ :param url: `str` of URL
+ :param allow_internal: `bool` of whether internal requests are
+ allowed (default `False`)
+
+ :returns: `bool` of whether HTTP request execution is allowed
+ """
+
+ is_allowed = False
+
+ u = urlparse(url)
+
+ ip = socket.gethostbyname(u.hostname)
+
+ is_private = ipaddress.ip_address(ip).is_private
+
+ if not is_private:
+ is_allowed = True
+ if is_private and allow_internal:
+ is_allowed = True
+
+ return is_allowed
=====================================
requirements.txt
=====================================
@@ -1,18 +1,18 @@
-Babel==2.10.3
-click==8.1.6
-filelock==3.25.0
-Flask==3.1.3
-jinja2==3.1.2
-jsonschema==4.26.0
-pydantic==1.10.14
-pygeofilter==0.3.3
-pygeoif==1.6.0
-pyproj==3.6.1
-python-dateutil==2.8.2
-pytz==2026.1.post1
-PyYAML==6.0.1
-rasterio==1.3.9
-requests==2.31.0
-shapely==2.0.3
-SQLAlchemy==2.0.48
-tinydb==3.15.2
+Babel
+click
+filelock
+Flask
+jinja2
+jsonschema
+pydantic
+pygeofilter
+pygeoif
+pyproj
+python-dateutil
+pytz
+PyYAML
+rasterio
+requests
+shapely
+SQLAlchemy
+tinydb
=====================================
tests/other/test_util.py
=====================================
@@ -2,7 +2,7 @@
#
# Authors: Tom Kralidis <tomkralidis at gmail.com>
#
-# Copyright (c) 2025 Tom Kralidis
+# Copyright (c) 2026 Tom Kralidis
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
@@ -321,3 +321,21 @@ def test_get_choice_from_headers():
'accept') == 'application/ld+json'
assert util.get_choice_from_headers(
{'accept-language': 'en_US', 'accept': '*/*'}, 'accept') == '*/*'
+
+
+ at pytest.mark.parametrize('url,allow_internal,result', [
+ ['http://127.0.0.1/test', False, False],
+ ['http://127.0.0.1/test', True, True],
+ ['http://192.168.0.12/test', False, False],
+ ['http://192.168.0.12/test', True, True],
+ ['http://169.254.0.11/test', False, False],
+ ['http://169.254.0.11/test', True, True],
+ ['http://0.0.0.0/test', True, True],
+ ['http://0.0.0.0/test', False, False],
+ ['http://localhost:5000/test', False, False],
+ ['http://localhost:5000/test', True, True],
+ ['https://pygeoapi.io', False, True],
+ ['https://pygeoapi.io', True, True]
+])
+def test_is_request_allowed(url, allow_internal, result):
+ assert util.is_request_allowed(url, allow_internal) is result
=====================================
tests/provider/test_filesystem_provider.py
=====================================
@@ -2,7 +2,7 @@
#
# Authors: Tom Kralidis <tomkralidis at gmail.com>
#
-# Copyright (c) 2021 Tom Kralidis
+# Copyright (c) 2026 Tom Kralidis
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
@@ -30,6 +30,7 @@
import os
import pytest
+from pygeoapi.provider.base import ProviderInvalidQueryError
from pygeoapi.provider.filesystem import FileSystemProvider
THISDIR = os.path.dirname(os.path.realpath(__file__))
@@ -73,3 +74,6 @@ def test_query(config):
'osm_id': 'int'
}
assert r['assets']['default']['href'] == 'http://example.org/stac/poi_portugal.gpkg' # noqa
+
+ with pytest.raises(ProviderInvalidQueryError):
+ _ = p.get_data_path(baseurl, urlpath, '../../poi_portugal')
View it on GitLab: https://salsa.debian.org/debian-gis-team/pygeoapi/-/compare/5b5becad831d33ebd7d7589974c52ef9c0043343...fe270c27de42157ad6dd71b6afc24c7803077f71
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/pygeoapi/-/compare/5b5becad831d33ebd7d7589974c52ef9c0043343...fe270c27de42157ad6dd71b6afc24c7803077f71
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260626/8a8d11c3/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list