pygeoapi 0.23.2__tar.gz → 0.23.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pygeoapi-0.23.2/pygeoapi.egg-info → pygeoapi-0.23.4}/PKG-INFO +19 -19
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/__init__.py +1 -1
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/base.py +3 -1
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/base.py +35 -18
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/filesystem.py +9 -2
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/schemas/config/pygeoapi-config-0.x.yml +5 -1
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/util.py +29 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4/pygeoapi.egg-info}/PKG-INFO +19 -19
- pygeoapi-0.23.4/pygeoapi.egg-info/requires.txt +18 -0
- pygeoapi-0.23.4/requirements.txt +18 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_util.py +19 -1
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_filesystem_provider.py +5 -1
- pygeoapi-0.23.2/pygeoapi.egg-info/requires.txt +0 -18
- pygeoapi-0.23.2/requirements.txt +0 -18
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/LICENSE.md +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/MANIFEST.in +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/README.md +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/admin.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/collection.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/coverages.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/environmental_data_retrieval.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/itemtypes.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/maps.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/processes.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/pubsub.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/stac.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/api/tiles.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/asyncapi.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/config.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/crs.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_/settings.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_/urls.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_/views.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_/wsgi.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/django_app.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/error.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/flask_app.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/formats.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/formatter/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/formatter/base.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/formatter/csv_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/l10n.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/linked_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/log.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/config.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/openapi.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/provider/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/provider/base.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/models/provider/mvt.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/openapi.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/plugin.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/echo.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/hello_world.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/dummy.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/mongodb_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/postgresql.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/manager/tinydb_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/process/shapely_functions.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/azure_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/base.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/base_edr.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/base_mvt.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/csv_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/csw_facade.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/elasticsearch_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/erddap.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/esri.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/geojson.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/hateoas.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mapscript_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mongo.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mvt_elastic.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mvt_postgresql.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mvt_proxy.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/mvt_tippecanoe.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/ogr.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/opensearch_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/oracle.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/parquet.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/rasterio_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/sensorthings.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/sensorthings_edr.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/socrata.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/sql.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/sqlite.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/tile.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/tinydb_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/wms_facade.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/wmts_facade.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/xarray_.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/provider/xarray_edr.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/pubsub/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/pubsub/base.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/pubsub/http.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/pubsub/kafka.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/pubsub/mqtt.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/definitions/tiles/WebMercatorQuad.json +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/definitions/tiles/WorldCRS84Quad.json +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/schemas/asyncapi/asyncapi-3.0.0.json +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/schemas/openapi/openapi-3.0.x.json +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/starlette_app.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/static/css/default.css +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/static/img/favicon.ico +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/static/img/logo.png +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/static/img/pygeoapi.png +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/_base.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/admin/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/asyncapi.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/collection.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/edr/instance.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/edr/instances.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/edr/query.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/items/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/items/index.jsonld +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/items/item.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/items/item.jsonld +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/map/metadata.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/queryables.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/schema.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/tiles/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/collections/tiles/metadata.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/conformance.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/exception.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/jobs/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/jobs/job.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/jobs/results/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/landing_page.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/openapi/redoc.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/openapi/swagger.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/processes/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/processes/process.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/stac/catalog.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/stac/collection.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/stac/collection_base.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/stac/item.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/tilematrixsets/index.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/templates/tilematrixsets/tilematrixset.html +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi.egg-info/SOURCES.txt +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi.egg-info/dependency_links.txt +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi.egg-info/entry_points.txt +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi.egg-info/top_level.txt +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/pyproject.toml +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/setup.cfg +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/setup.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/conftest.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/formatter/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/formatter/test_csv__formatter.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/load_es_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/load_mongo_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/load_opensearch_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/load_oracle_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/load_tinydb_records.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/manager/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/manager/test_manager.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/manager/test_postgresql_manager.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/manager/test_tinydb_manager_for_parallel_requests.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_config.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_crs.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_django.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_l10n.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_linked_data.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_ogr_capabilities.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/other/test_openapi.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/__init__.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_api_ogr_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_base_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_csv__provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_csw_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_elasticsearch__provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_esri_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_geojson_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_mongo_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_mysql_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_csv_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_esrijson_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_gpkg_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_shapefile_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_sqlite_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_wfs_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_ogr_wfs_provider_live.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_opensearch__provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_oracle_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_parquet_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_postgresql_mvt_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_postgresql_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_rasterio_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_sensorthings_edr_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_sensorthings_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_socrata_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_socrata_provider_live.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_sqlite_geopackage_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_tinydb_catalogue_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_tinydb_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_xarray_netcdf_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/provider/test_xarray_zarr_provider.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/test_models.py +0 -0
- {pygeoapi-0.23.2 → pygeoapi-0.23.4}/tests/util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeoapi
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.4
|
|
4
4
|
Summary: pygeoapi provides an API to geospatial data
|
|
5
5
|
Home-page: https://pygeoapi.io
|
|
6
6
|
Author: Tom Kralidis
|
|
@@ -20,24 +20,24 @@ Classifier: Topic :: Scientific/Engineering :: GIS
|
|
|
20
20
|
Requires-Python: >=3.12
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE.md
|
|
23
|
-
Requires-Dist: Babel
|
|
24
|
-
Requires-Dist: click
|
|
25
|
-
Requires-Dist: filelock
|
|
26
|
-
Requires-Dist: Flask
|
|
27
|
-
Requires-Dist: jinja2
|
|
28
|
-
Requires-Dist: jsonschema
|
|
29
|
-
Requires-Dist: pydantic
|
|
30
|
-
Requires-Dist: pygeofilter
|
|
31
|
-
Requires-Dist: pygeoif
|
|
32
|
-
Requires-Dist: pyproj
|
|
33
|
-
Requires-Dist: python-dateutil
|
|
34
|
-
Requires-Dist: pytz
|
|
35
|
-
Requires-Dist: PyYAML
|
|
36
|
-
Requires-Dist: rasterio
|
|
37
|
-
Requires-Dist: requests
|
|
38
|
-
Requires-Dist: shapely
|
|
39
|
-
Requires-Dist: SQLAlchemy
|
|
40
|
-
Requires-Dist: tinydb
|
|
23
|
+
Requires-Dist: Babel
|
|
24
|
+
Requires-Dist: click
|
|
25
|
+
Requires-Dist: filelock
|
|
26
|
+
Requires-Dist: Flask
|
|
27
|
+
Requires-Dist: jinja2
|
|
28
|
+
Requires-Dist: jsonschema
|
|
29
|
+
Requires-Dist: pydantic
|
|
30
|
+
Requires-Dist: pygeofilter
|
|
31
|
+
Requires-Dist: pygeoif
|
|
32
|
+
Requires-Dist: pyproj
|
|
33
|
+
Requires-Dist: python-dateutil
|
|
34
|
+
Requires-Dist: pytz
|
|
35
|
+
Requires-Dist: PyYAML
|
|
36
|
+
Requires-Dist: rasterio
|
|
37
|
+
Requires-Dist: requests
|
|
38
|
+
Requires-Dist: shapely
|
|
39
|
+
Requires-Dist: SQLAlchemy
|
|
40
|
+
Requires-Dist: tinydb
|
|
41
41
|
Dynamic: author
|
|
42
42
|
Dynamic: author-email
|
|
43
43
|
Dynamic: classifier
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
4
4
|
# Francesco Martinelli <francesco.martinelli@ingv.it>
|
|
5
5
|
#
|
|
6
|
-
# Copyright (c)
|
|
6
|
+
# Copyright (c) 2026 Tom Kralidis
|
|
7
7
|
# Copyright (c) 2024 Francesco Martinelli
|
|
8
8
|
#
|
|
9
9
|
# Permission is hereby granted, free of charge, to any person
|
|
@@ -53,6 +53,8 @@ class BaseProcessor:
|
|
|
53
53
|
self.name = processor_def['name']
|
|
54
54
|
self.metadata = process_metadata
|
|
55
55
|
self.supports_outputs = False
|
|
56
|
+
self.allow_internal_requests = processor_def.get(
|
|
57
|
+
'allow_internal_requests', False)
|
|
56
58
|
|
|
57
59
|
def set_job_id(self, job_id: str) -> None:
|
|
58
60
|
"""
|
|
@@ -46,10 +46,12 @@ from pygeoapi.process.base import (
|
|
|
46
46
|
BaseProcessor,
|
|
47
47
|
JobNotFoundError,
|
|
48
48
|
JobResultNotFoundError,
|
|
49
|
+
ProcessorExecuteError,
|
|
49
50
|
UnknownProcessError,
|
|
50
51
|
)
|
|
51
52
|
from pygeoapi.util import (
|
|
52
53
|
get_current_datetime,
|
|
54
|
+
is_request_allowed,
|
|
53
55
|
JobStatus,
|
|
54
56
|
ProcessExecutionMode,
|
|
55
57
|
RequestedProcessExecutionMode,
|
|
@@ -105,7 +107,11 @@ class BaseManager:
|
|
|
105
107
|
except KeyError as err:
|
|
106
108
|
raise UnknownProcessError('Invalid process identifier') from err
|
|
107
109
|
else:
|
|
108
|
-
|
|
110
|
+
pp = load_plugin('process', process_conf['processor'])
|
|
111
|
+
pp.allow_internal_requests = process_conf.get(
|
|
112
|
+
'allow_internal_requests', False)
|
|
113
|
+
|
|
114
|
+
return pp
|
|
109
115
|
|
|
110
116
|
def get_jobs(self,
|
|
111
117
|
status: JobStatus = None,
|
|
@@ -394,13 +400,13 @@ class BaseManager:
|
|
|
394
400
|
"""
|
|
395
401
|
|
|
396
402
|
job_id = str(uuid.uuid1())
|
|
397
|
-
processor = self.get_processor(process_id)
|
|
398
|
-
processor.set_job_id(job_id)
|
|
403
|
+
self.processor = self.get_processor(process_id)
|
|
404
|
+
self.processor.set_job_id(job_id)
|
|
399
405
|
extra_execute_handler_parameters = {
|
|
400
406
|
'requested_response': requested_response
|
|
401
407
|
}
|
|
402
408
|
|
|
403
|
-
job_control_options = processor.metadata.get(
|
|
409
|
+
job_control_options = self.processor.metadata.get(
|
|
404
410
|
'jobControlOptions', [])
|
|
405
411
|
|
|
406
412
|
if execution_mode == RequestedProcessExecutionMode.respond_async:
|
|
@@ -473,7 +479,7 @@ class BaseManager:
|
|
|
473
479
|
# TODO: handler's response could also be allowed to include more HTTP
|
|
474
480
|
# headers
|
|
475
481
|
mime_type, outputs, status = handler(
|
|
476
|
-
processor,
|
|
482
|
+
self.processor,
|
|
477
483
|
job_id,
|
|
478
484
|
data_dict,
|
|
479
485
|
requested_outputs,
|
|
@@ -483,26 +489,37 @@ class BaseManager:
|
|
|
483
489
|
|
|
484
490
|
def _send_in_progress_notification(self, subscriber: Optional[Subscriber]):
|
|
485
491
|
if subscriber and subscriber.in_progress_uri:
|
|
486
|
-
|
|
487
|
-
LOGGER.debug(
|
|
488
|
-
f'In progress notification response: {response.status_code}'
|
|
489
|
-
)
|
|
492
|
+
self.__do_subscriber_request(subscriber.in_progress_uri)
|
|
490
493
|
|
|
491
494
|
def _send_success_notification(
|
|
492
495
|
self, subscriber: Optional[Subscriber], outputs: Any
|
|
493
496
|
):
|
|
494
|
-
if subscriber:
|
|
495
|
-
|
|
496
|
-
LOGGER.debug(
|
|
497
|
-
f'Success notification response: {response.status_code}'
|
|
498
|
-
)
|
|
497
|
+
if subscriber and subscriber.success_uri:
|
|
498
|
+
self.__do_subscriber_request(subscriber.success_uri, outputs)
|
|
499
499
|
|
|
500
500
|
def _send_failed_notification(self, subscriber: Optional[Subscriber]):
|
|
501
501
|
if subscriber and subscriber.failed_uri:
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
502
|
+
self.__do_subscriber_request(subscriber.failed_uri)
|
|
503
|
+
|
|
504
|
+
def __do_subscriber_request(self, url: str, data: dict = {}) -> None:
|
|
505
|
+
"""
|
|
506
|
+
Helper function to execute a subscriber URL via HTTP POST
|
|
507
|
+
|
|
508
|
+
:param url: `str` of URL
|
|
509
|
+
:param data: `dict` of request payload
|
|
510
|
+
|
|
511
|
+
:returns: `None`
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
if not is_request_allowed(url, self.processor.allow_internal_requests):
|
|
515
|
+
msg = 'URL not allowed'
|
|
516
|
+
LOGGER.error(f'{msg}: {url}')
|
|
517
|
+
raise ProcessorExecuteError(msg)
|
|
518
|
+
|
|
519
|
+
response = requests.post(url, json=data)
|
|
520
|
+
LOGGER.debug(
|
|
521
|
+
f'Response: {response.status_code}'
|
|
522
|
+
)
|
|
506
523
|
|
|
507
524
|
def __repr__(self):
|
|
508
525
|
return f'<BaseManager> {self.name}'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
4
4
|
#
|
|
5
|
-
# Copyright (c)
|
|
5
|
+
# Copyright (c) 2026 Tom Kralidis
|
|
6
6
|
#
|
|
7
7
|
# Permission is hereby granted, free of charge, to any person
|
|
8
8
|
# obtaining a copy of this software and associated documentation
|
|
@@ -34,6 +34,7 @@ import logging
|
|
|
34
34
|
import os
|
|
35
35
|
|
|
36
36
|
from pygeoapi.provider.base import (BaseProvider, ProviderConnectionError,
|
|
37
|
+
ProviderInvalidQueryError,
|
|
37
38
|
ProviderNotFoundError)
|
|
38
39
|
from pygeoapi.util import file_modified_iso8601, get_path_basename, url_join
|
|
39
40
|
|
|
@@ -76,9 +77,15 @@ class FileSystemProvider(BaseProvider):
|
|
|
76
77
|
root_link = None
|
|
77
78
|
child_links = []
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
if '..' in dirpath:
|
|
81
|
+
msg = 'Invalid path requested'
|
|
82
|
+
LOGGER.error(f'{msg}: {dirpath}')
|
|
83
|
+
raise ProviderInvalidQueryError(msg)
|
|
84
|
+
|
|
80
85
|
data_path = self.data + dirpath
|
|
81
86
|
|
|
87
|
+
LOGGER.debug(f'Data path: {data_path}')
|
|
88
|
+
|
|
82
89
|
if '/' not in dirpath: # root
|
|
83
90
|
root_link = baseurl
|
|
84
91
|
else:
|
{pygeoapi-0.23.2 → pygeoapi-0.23.4}/pygeoapi/resources/schemas/config/pygeoapi-config-0.x.yml
RENAMED
|
@@ -682,7 +682,11 @@ properties:
|
|
|
682
682
|
For custom built plugins, use the import path (e.g. `mypackage.provider.MyProvider`)
|
|
683
683
|
required:
|
|
684
684
|
- name
|
|
685
|
-
|
|
685
|
+
allow_internal_requests:
|
|
686
|
+
type: boolean
|
|
687
|
+
description: whether to allow internal HTTP requests
|
|
688
|
+
default: false
|
|
689
|
+
requred:
|
|
686
690
|
- type
|
|
687
691
|
- processor
|
|
688
692
|
definitions:
|
|
@@ -36,6 +36,7 @@ from datetime import date, datetime, time, timezone
|
|
|
36
36
|
from decimal import Decimal
|
|
37
37
|
from enum import Enum
|
|
38
38
|
from heapq import heappush
|
|
39
|
+
import ipaddress
|
|
39
40
|
import json
|
|
40
41
|
import logging
|
|
41
42
|
import mimetypes
|
|
@@ -43,6 +44,7 @@ import os
|
|
|
43
44
|
import pathlib
|
|
44
45
|
from pathlib import Path
|
|
45
46
|
import re
|
|
47
|
+
import socket
|
|
46
48
|
from typing import Any, IO, Union, List, Optional
|
|
47
49
|
from urllib.parse import urlparse
|
|
48
50
|
from urllib.request import urlopen
|
|
@@ -754,3 +756,30 @@ def remove_url_auth(url: str) -> str:
|
|
|
754
756
|
u = urlparse(url)
|
|
755
757
|
auth = f'{u.username}:{u.password}@'
|
|
756
758
|
return url.replace(auth, '')
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
def is_request_allowed(url: str, allow_internal: bool = False) -> bool:
|
|
762
|
+
"""
|
|
763
|
+
Test whether an HTTP request is allowed to be executed
|
|
764
|
+
|
|
765
|
+
:param url: `str` of URL
|
|
766
|
+
:param allow_internal: `bool` of whether internal requests are
|
|
767
|
+
allowed (default `False`)
|
|
768
|
+
|
|
769
|
+
:returns: `bool` of whether HTTP request execution is allowed
|
|
770
|
+
"""
|
|
771
|
+
|
|
772
|
+
is_allowed = False
|
|
773
|
+
|
|
774
|
+
u = urlparse(url)
|
|
775
|
+
|
|
776
|
+
ip = socket.gethostbyname(u.hostname)
|
|
777
|
+
|
|
778
|
+
is_private = ipaddress.ip_address(ip).is_private
|
|
779
|
+
|
|
780
|
+
if not is_private:
|
|
781
|
+
is_allowed = True
|
|
782
|
+
if is_private and allow_internal:
|
|
783
|
+
is_allowed = True
|
|
784
|
+
|
|
785
|
+
return is_allowed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeoapi
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.4
|
|
4
4
|
Summary: pygeoapi provides an API to geospatial data
|
|
5
5
|
Home-page: https://pygeoapi.io
|
|
6
6
|
Author: Tom Kralidis
|
|
@@ -20,24 +20,24 @@ Classifier: Topic :: Scientific/Engineering :: GIS
|
|
|
20
20
|
Requires-Python: >=3.12
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE.md
|
|
23
|
-
Requires-Dist: Babel
|
|
24
|
-
Requires-Dist: click
|
|
25
|
-
Requires-Dist: filelock
|
|
26
|
-
Requires-Dist: Flask
|
|
27
|
-
Requires-Dist: jinja2
|
|
28
|
-
Requires-Dist: jsonschema
|
|
29
|
-
Requires-Dist: pydantic
|
|
30
|
-
Requires-Dist: pygeofilter
|
|
31
|
-
Requires-Dist: pygeoif
|
|
32
|
-
Requires-Dist: pyproj
|
|
33
|
-
Requires-Dist: python-dateutil
|
|
34
|
-
Requires-Dist: pytz
|
|
35
|
-
Requires-Dist: PyYAML
|
|
36
|
-
Requires-Dist: rasterio
|
|
37
|
-
Requires-Dist: requests
|
|
38
|
-
Requires-Dist: shapely
|
|
39
|
-
Requires-Dist: SQLAlchemy
|
|
40
|
-
Requires-Dist: tinydb
|
|
23
|
+
Requires-Dist: Babel
|
|
24
|
+
Requires-Dist: click
|
|
25
|
+
Requires-Dist: filelock
|
|
26
|
+
Requires-Dist: Flask
|
|
27
|
+
Requires-Dist: jinja2
|
|
28
|
+
Requires-Dist: jsonschema
|
|
29
|
+
Requires-Dist: pydantic
|
|
30
|
+
Requires-Dist: pygeofilter
|
|
31
|
+
Requires-Dist: pygeoif
|
|
32
|
+
Requires-Dist: pyproj
|
|
33
|
+
Requires-Dist: python-dateutil
|
|
34
|
+
Requires-Dist: pytz
|
|
35
|
+
Requires-Dist: PyYAML
|
|
36
|
+
Requires-Dist: rasterio
|
|
37
|
+
Requires-Dist: requests
|
|
38
|
+
Requires-Dist: shapely
|
|
39
|
+
Requires-Dist: SQLAlchemy
|
|
40
|
+
Requires-Dist: tinydb
|
|
41
41
|
Dynamic: author
|
|
42
42
|
Dynamic: author-email
|
|
43
43
|
Dynamic: classifier
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
4
4
|
#
|
|
5
|
-
# Copyright (c)
|
|
5
|
+
# Copyright (c) 2026 Tom Kralidis
|
|
6
6
|
#
|
|
7
7
|
# Permission is hereby granted, free of charge, to any person
|
|
8
8
|
# obtaining a copy of this software and associated documentation
|
|
@@ -321,3 +321,21 @@ def test_get_choice_from_headers():
|
|
|
321
321
|
'accept') == 'application/ld+json'
|
|
322
322
|
assert util.get_choice_from_headers(
|
|
323
323
|
{'accept-language': 'en_US', 'accept': '*/*'}, 'accept') == '*/*'
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
@pytest.mark.parametrize('url,allow_internal,result', [
|
|
327
|
+
['http://127.0.0.1/test', False, False],
|
|
328
|
+
['http://127.0.0.1/test', True, True],
|
|
329
|
+
['http://192.168.0.12/test', False, False],
|
|
330
|
+
['http://192.168.0.12/test', True, True],
|
|
331
|
+
['http://169.254.0.11/test', False, False],
|
|
332
|
+
['http://169.254.0.11/test', True, True],
|
|
333
|
+
['http://0.0.0.0/test', True, True],
|
|
334
|
+
['http://0.0.0.0/test', False, False],
|
|
335
|
+
['http://localhost:5000/test', False, False],
|
|
336
|
+
['http://localhost:5000/test', True, True],
|
|
337
|
+
['https://pygeoapi.io', False, True],
|
|
338
|
+
['https://pygeoapi.io', True, True]
|
|
339
|
+
])
|
|
340
|
+
def test_is_request_allowed(url, allow_internal, result):
|
|
341
|
+
assert util.is_request_allowed(url, allow_internal) is result
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
|
4
4
|
#
|
|
5
|
-
# Copyright (c)
|
|
5
|
+
# Copyright (c) 2026 Tom Kralidis
|
|
6
6
|
#
|
|
7
7
|
# Permission is hereby granted, free of charge, to any person
|
|
8
8
|
# obtaining a copy of this software and associated documentation
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
import os
|
|
31
31
|
import pytest
|
|
32
32
|
|
|
33
|
+
from pygeoapi.provider.base import ProviderInvalidQueryError
|
|
33
34
|
from pygeoapi.provider.filesystem import FileSystemProvider
|
|
34
35
|
|
|
35
36
|
THISDIR = os.path.dirname(os.path.realpath(__file__))
|
|
@@ -73,3 +74,6 @@ def test_query(config):
|
|
|
73
74
|
'osm_id': 'int'
|
|
74
75
|
}
|
|
75
76
|
assert r['assets']['default']['href'] == 'http://example.org/stac/poi_portugal.gpkg' # noqa
|
|
77
|
+
|
|
78
|
+
with pytest.raises(ProviderInvalidQueryError):
|
|
79
|
+
_ = p.get_data_path(baseurl, urlpath, '../../poi_portugal')
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
Babel==2.10.3
|
|
2
|
-
click==8.1.6
|
|
3
|
-
filelock==3.25.0
|
|
4
|
-
Flask==3.1.3
|
|
5
|
-
jinja2==3.1.2
|
|
6
|
-
jsonschema==4.26.0
|
|
7
|
-
pydantic==1.10.14
|
|
8
|
-
pygeofilter==0.3.3
|
|
9
|
-
pygeoif==1.6.0
|
|
10
|
-
pyproj==3.6.1
|
|
11
|
-
python-dateutil==2.8.2
|
|
12
|
-
pytz==2026.1.post1
|
|
13
|
-
PyYAML==6.0.1
|
|
14
|
-
rasterio==1.3.9
|
|
15
|
-
requests==2.31.0
|
|
16
|
-
shapely==2.0.3
|
|
17
|
-
SQLAlchemy==2.0.48
|
|
18
|
-
tinydb==3.15.2
|
pygeoapi-0.23.2/requirements.txt
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
Babel==2.10.3
|
|
2
|
-
click==8.1.6
|
|
3
|
-
filelock==3.25.0
|
|
4
|
-
Flask==3.1.3
|
|
5
|
-
jinja2==3.1.2
|
|
6
|
-
jsonschema==4.26.0
|
|
7
|
-
pydantic==1.10.14
|
|
8
|
-
pygeofilter==0.3.3
|
|
9
|
-
pygeoif==1.6.0
|
|
10
|
-
pyproj==3.6.1
|
|
11
|
-
python-dateutil==2.8.2
|
|
12
|
-
pytz==2026.1.post1
|
|
13
|
-
PyYAML==6.0.1
|
|
14
|
-
rasterio==1.3.9
|
|
15
|
-
requests==2.31.0
|
|
16
|
-
shapely==2.0.3
|
|
17
|
-
SQLAlchemy==2.0.48
|
|
18
|
-
tinydb==3.15.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|