diff --git a/config/settings/base.py b/config/settings/base.py index 0dd4af0..b717a6c 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -94,6 +94,7 @@ "metadata_catalogue.core", "metadata_catalogue.datasets", "metadata_catalogue.datasets.csw", + "metadata_catalogue.datasets.geoapi", ] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS @@ -310,3 +311,8 @@ "repository": "metadata_catalogue.datasets.repository.DatasetsRepository", "mappings": "metadata_catalogue.datasets.mappings", } + +GEOAPI = { + "cors": False, + "gzip": False, +} diff --git a/config/urls.py b/config/urls.py index eb4dbac..f72fdc5 100644 --- a/config/urls.py +++ b/config/urls.py @@ -15,6 +15,7 @@ path("accounts/", include("allauth.urls")), path("ht/", include("health_check.urls")), path("csw/", include("metadata_catalogue.datasets.csw.urls")), + path("geoapi/", include("metadata_catalogue.datasets.geoapi.urls")), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/metadata_catalogue/datasets/csw/models.py b/metadata_catalogue/datasets/csw/models.py index 5166027..a14af6f 100644 --- a/metadata_catalogue/datasets/csw/models.py +++ b/metadata_catalogue/datasets/csw/models.py @@ -7,7 +7,6 @@ class CSWConfig(SingletonModel): - language = models.CharField(max_length=7, null=True, blank=True) max_records = models.IntegerField(default=10) profiles = models.TextField(default="apiso", blank=True) pretty_print = models.BooleanField(default=False) @@ -21,7 +20,7 @@ def get_config(self, url=""): "home": ".", "mimetype": "application/xml; charset=UTF-8", "encoding": "UTF-8", - "language": self.language or "en-US", + "language": info.language or "en-US", "maxrecords": str(self.max_records), "pretty_print": "true" if self.pretty_print else "false", "url": url, diff --git a/metadata_catalogue/datasets/geoapi/__init__.py b/metadata_catalogue/datasets/geoapi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/metadata_catalogue/datasets/geoapi/admin.py b/metadata_catalogue/datasets/geoapi/admin.py new file mode 100644 index 0000000..3d82372 --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +from solo.admin import SingletonModelAdmin + +from .models import GeoAPIConfig + +admin.site.register(GeoAPIConfig, SingletonModelAdmin) diff --git a/metadata_catalogue/datasets/geoapi/apps.py b/metadata_catalogue/datasets/geoapi/apps.py new file mode 100644 index 0000000..e9e1aa9 --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class GeoapiConfig(AppConfig): + name = "metadata_catalogue.datasets.geoapi" + verbose_name = _("GeoAPI") diff --git a/metadata_catalogue/datasets/geoapi/migrations/0001_initial.py b/metadata_catalogue/datasets/geoapi/migrations/0001_initial.py new file mode 100644 index 0000000..c26b17f --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.6 on 2023-11-13 12:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="GeoAPIConfig", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("max_records", models.IntegerField(default=10)), + ("pretty_print", models.BooleanField(default=False)), + ("map_url", models.URLField(default="https://tile.openstreetmap.org/{z}/{x}/{y}.png")), + ( + "map_attribution", + models.TextField( + default='© OpenStreetMap contributors' + ), + ), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/metadata_catalogue/datasets/geoapi/migrations/__init__.py b/metadata_catalogue/datasets/geoapi/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/metadata_catalogue/datasets/geoapi/models.py b/metadata_catalogue/datasets/geoapi/models.py new file mode 100644 index 0000000..368ee57 --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/models.py @@ -0,0 +1,77 @@ +from pathlib import Path + +from django.apps import apps +from django.db import models +from solo.models import SingletonModel + +from ..libs.utils import safe_get + + +class GeoAPIConfig(SingletonModel): + max_records = models.IntegerField(default=10) + pretty_print = models.BooleanField(default=False) + map_url = models.URLField(default="https://tile.openstreetmap.org/{z}/{x}/{y}.png") + map_attribution = models.TextField( + default='© OpenStreetMap contributors' + ) + + def get_config(self, url=""): + ServiceInfo = apps.get_model("datasets", "ServiceInfo") + Dataset = apps.get_model("datasets", "Dataset") + info = ServiceInfo.objects.select_related("contact", "license", "provider").get() + + resources = {id: value for id, value in Dataset.objects.select_related("metadata").all().as_geoapi_resource()} + + return { + "server": { + "mimetype": "application/xml; charset=UTF-8", + "encoding": "utf-8", + "language": info.language or "en-US", + "limit": str(self.max_records), + "pretty_print": self.pretty_print, + "url": url, + "templates": {"static": str(Path(__name__).parent / "statics" / "geoapi")}, + "map": { + "url": self.map_url, + "attribute": self.map_attribution, + }, + }, + "logging": { + "level": "DEBUG", + }, + "metadata": { + "identification": { + "title": info.identification_title, + "description": info.identification_abstract, + "keywords": info.identification_keywords.split(",") if info.identification_keywords else "", + "keywords_type": "theme", + "terms_of_service": info.identification_accessconstraints, + "url": "", + }, + "license": { + "name": info.license.name if info.license else "", + "url": info.license.url if info.license else "", + }, + "provider": { + "name": info.provider, + "url": "", + }, + "contact": { + "name": str(info.contact), + "position": safe_get(info.contact, "position"), + "address": safe_get(info.contact, "delivery_point"), + "city": safe_get(info.contact, "city"), + "stateorprovince": safe_get(info.contact, "country"), + "postalcode": safe_get(info.contact, "postal_code"), + "country": safe_get(info.contact, "country"), + "phone": safe_get(info.contact, "phone"), + "fax": safe_get(info.contact, "phone"), + "email": safe_get(info.contact, "email"), + "url": "", + "hours": info.contact_hours or "", + "instructions": info.contact_instructions or "", + "role": "pointOfContact", + }, + }, + "resources": resources, + } diff --git a/metadata_catalogue/datasets/geoapi/urls.py b/metadata_catalogue/datasets/geoapi/urls.py new file mode 100644 index 0000000..24354b6 --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/urls.py @@ -0,0 +1,158 @@ +from django.conf import settings +from django.conf.urls.static import static +from django.urls import path + +from . import views + +urlpatterns = [ + path("", views.landing_page, name="landing-page"), + path("openapi/", views.openapi, name="openapi"), + path("conformance/", views.conformance, name="conformance"), + path("collections/", views.collections, name="collections"), + path( + "collections/", + views.collections, + name="collection-detail", + ), + path( + "collections//queryables/", + views.collection_queryables, + name="collection-queryables", + ), + path( + "collections//items/", + views.collection_items, + name="collection-items", + ), + path( + "collections//items/", + views.collection_item, + name="collection-item", + ), + path( + "collections//coverage/", + views.collection_coverage, + name="collection-coverage", + ), + path( + "collections//coverage/domainset/", # noqa + views.collection_coverage_domainset, + name="collection-coverage-domainset", + ), + path( + "collections//coverage/rangetype/", # noqa + views.collection_coverage_rangetype, + name="collection-coverage-rangetype", + ), + path( + "collections//map", + views.collection_map, + name="collection-map", + ), + path( + "collections//styles//map", + views.collection_style_map, + name="collection-style-map", + ), + path( + "collections//tiles/", + views.collection_tiles, + name="collection-tiles", + ), + path( + "collections//tiles/", + views.collection_tiles_metadata, + name="collection-tiles-metadata", + ), + path( + "collections//tiles//metadata", + views.collection_tiles_metadata, + name="collection-tiles-metadata", + ), + path( + "collections//tiles/\ + ///", + views.collection_item_tiles, + name="collection-item-tiles", + ), + path( + "collections//position", + views.get_collection_edr_query, + name="collection-edr-position", + ), + path( + "collections//area", + views.get_collection_edr_query, + name="collection-edr-area", + ), + path( + "collections//cube", + views.get_collection_edr_query, + name="collection-edr-cube", + ), + path( + "collections//radius", + views.get_collection_edr_query, + name="collection-edr-radius", + ), + path( + "collections//trajectory", + views.get_collection_edr_query, + name="collection-edr-trajectory", + ), + path( + "collections//corridor", + views.get_collection_edr_query, + name="collection-edr-corridor", + ), + path( + "collections//instances//position", + views.get_collection_edr_query, + name="collection-edr-instance-position", + ), + path( + "collections//instances//area", + views.get_collection_edr_query, + name="collection-edr-instance-area", + ), + path( + "collections//instances//cube", + views.get_collection_edr_query, + name="collection-edr-instance-cube", + ), + path( + "collections//instances//radius", + views.get_collection_edr_query, + name="collection-edr-instance-radius", + ), + path( + "collections//instances//trajectory", # noqa + views.get_collection_edr_query, + name="collection-edr-instance-trajectory", + ), + path( + "collections//instances//corridor", + views.get_collection_edr_query, + name="collection-edr-instance-corridor", + ), + path("processes/", views.processes, name="processes"), + path("processes/", views.processes, name="process-detail"), + path("jobs/", views.jobs, name="jobs"), + path("jobs/", views.jobs, name="job"), + path( + "jobs//results/", + views.job_results, + name="job-results", + ), + path( + "jobs//results/", + views.job_results_resource, + name="job-results-resource", + ), + path("stac/", views.stac_catalog_root, name="stac-catalog-root"), + path("stac/", views.stac_catalog_path, name="stac-catalog-path"), + path("stac/search/", views.stac_catalog_search, name="stac-catalog-search"), +] + +# Add static URLs to serve pygeoapi statics +urlpatterns += static(settings.STATIC_URL, document_root=str(settings.APPS_DIR / "static" / "geoapi")) diff --git a/metadata_catalogue/datasets/geoapi/views.py b/metadata_catalogue/datasets/geoapi/views.py new file mode 100644 index 0000000..0df3ee9 --- /dev/null +++ b/metadata_catalogue/datasets/geoapi/views.py @@ -0,0 +1,469 @@ +# ================================================================= +# +# Authors: Francesco Bartoli +# Luca Delucchi +# Krishna Lodha +# Tom Kralidis +# +# Copyright (c) 2022 Francesco Bartoli +# Copyright (c) 2022 Luca Delucchi +# Copyright (c) 2022 Krishna Lodha +# Copyright (c) 2022 Tom Kralidis +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# ================================================================= + +"""Integration module for Django""" +from collections.abc import Mapping +from typing import Dict, Optional, Tuple + +from django.http import HttpRequest, HttpResponse +from pygeoapi.api import API + +from .models import GeoAPIConfig + + +def landing_page(request: HttpRequest) -> HttpResponse: + """ + OGC API landing page endpoint + + :request Django HTTP Request + + :returns: Django HTTP Response + """ + + response_ = _feed_response(request, "landing_page") + response = _to_django_response(*response_) + + return response + + +def openapi(request: HttpRequest) -> HttpResponse: + """ + OpenAPI endpoint + + :request Django HTTP Request + + :returns: Django HTTP Response + """ + + response_ = _feed_response(request, "openapi_") + response = _to_django_response(*response_) + + return response + + +def conformance(request: HttpRequest) -> HttpResponse: + """ + OGC API conformance endpoint + + :request Django HTTP Request + + :returns: Django HTTP Response + """ + + response_ = _feed_response(request, "conformance") + response = _to_django_response(*response_) + + return response + + +def collections(request: HttpRequest, collection_id: str | None = None) -> HttpResponse: + """ + OGC API collections endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP Response + """ + + response_ = _feed_response(request, "describe_collections", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_queryables(request: HttpRequest, collection_id: str | None = None) -> HttpResponse: + """ + OGC API collections queryables endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP Response + """ + + response_ = _feed_response(request, "get_collection_queryables", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_items(request: HttpRequest, collection_id: str) -> HttpResponse: + """ + OGC API collections items endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP response + """ + + if request.method == "GET": + response_ = _feed_response( + request, + "get_collection_items", + collection_id, + ) + elif request.method == "POST": + if request.content_type is not None: + if request.content_type == "application/geo+json": + response_ = _feed_response(request, "manage_collection_item", request, "create", collection_id) + else: + response_ = _feed_response(request, "post_collection_items", request, collection_id) + elif request.method == "OPTIONS": + response_ = _feed_response(request, "manage_collection_item", request, "options", collection_id) + + response = _to_django_response(*response_) + + return response + + +def collection_map(request: HttpRequest, collection_id: str): + """ + OGC API - Maps map render endpoint + + :param collection_id: collection identifier + + :returns: HTTP response + """ + + response_ = _feed_response(request, "get_collection_map", collection_id) + + response = _to_django_response(*response_) + + return response + + +def collection_style_map(request: HttpRequest, collection_id: str, style_id: str = None): + """ + OGC API - Maps map render endpoint + + :param collection_id: collection identifier + :param collection_id: style identifier + + :returns: HTTP response + """ + + response_ = _feed_response(request, "get_collection_map", collection_id, style_id) + + response = _to_django_response(*response_) + + return response + + +def collection_item(request: HttpRequest, collection_id: str, item_id: str) -> HttpResponse: + """ + OGC API collections items endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + :param item_id: item identifier + + :returns: Django HTTP response + """ + + if request.method == "GET": + response_ = _feed_response(request, "get_collection_item", collection_id, item_id) + elif request.method == "PUT": + response_ = _feed_response(request, "manage_collection_item", request, "update", collection_id, item_id) + elif request.method == "DELETE": + response_ = _feed_response(request, "manage_collection_item", request, "delete", collection_id, item_id) + elif request.method == "OPTIONS": + response_ = _feed_response(request, "manage_collection_item", request, "options", collection_id, item_id) + + response = _to_django_response(*response_) + + return response + + +def collection_coverage(request: HttpRequest, collection_id: str) -> HttpResponse: + """ + OGC API - Coverages coverage endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_collection_coverage", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_coverage_domainset(request: HttpRequest, collection_id: str) -> HttpResponse: + """ + OGC API - Coverages coverage domainset endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_collection_coverage_domainset", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_coverage_rangetype(request: HttpRequest, collection_id: str) -> HttpResponse: + """ + OGC API - Coverages coverage rangetype endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_collection_coverage_rangetype", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_tiles(request: HttpRequest, collection_id: str) -> HttpResponse: + """ + OGC API - Tiles collection tiles endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_collection_tiles", collection_id) + response = _to_django_response(*response_) + + return response + + +def collection_tiles_metadata(request: HttpRequest, collection_id: str, tileMatrixSetId: str) -> HttpResponse: + """ + OGC API - Tiles collection tiles metadata endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + :param tileMatrixSetId: identifier of tile matrix set + + :returns: Django HTTP response + """ + + response_ = _feed_response( + request, + "get_collection_tiles_metadata", + collection_id, + tileMatrixSetId, + ) + response = _to_django_response(*response_) + + return response + + +def collection_item_tiles( + request: HttpRequest, + collection_id: str, + tileMatrixSetId: str, + tileMatrix: str, + tileRow: str, + tileCol: str, +) -> HttpResponse: + """ + OGC API - Tiles collection tiles data endpoint + + :request Django HTTP Request + :param collection_id: collection identifier + :param tileMatrixSetId: identifier of tile matrix set + :param tileMatrix: identifier of {z} matrix index + :param tileRow: identifier of {y} matrix index + :param tileCol: identifier of {x} matrix index + + :returns: Django HTTP response + """ + + response_ = _feed_response( + request, + "get_collection_tiles_metadata", + collection_id, + tileMatrixSetId, + tileMatrix, + tileRow, + tileCol, + ) + response = _to_django_response(*response_) + + return response + + +def processes(request: HttpRequest, process_id: str | None = None) -> HttpResponse: + """ + OGC API - Processes description endpoint + + :request Django HTTP Request + :param process_id: process identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "describe_processes", process_id) + response = _to_django_response(*response_) + + return response + + +def jobs(request: HttpRequest, job_id: str | None = None) -> HttpResponse: + """ + OGC API - Jobs endpoint + + :request Django HTTP Request + :param process_id: process identifier + :param job_id: job identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_jobs", job_id) + response = _to_django_response(*response_) + + return response + + +def job_results(request: HttpRequest, job_id: str | None = None) -> HttpResponse: + """ + OGC API - Job result endpoint + + :request Django HTTP Request + :param job_id: job identifier + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_job_result", job_id) + response = _to_django_response(*response_) + + return response + + +def job_results_resource(request: HttpRequest, process_id: str, job_id: str, resource: str) -> HttpResponse: + """ + OGC API - Job result resource endpoint + + :request Django HTTP Request + :param job_id: job identifier + :param resource: job resource + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_job_result_resource", job_id, resource) + response = _to_django_response(*response_) + + return response + + +def get_collection_edr_query(request: HttpRequest, collection_id: str, instance_id: str) -> HttpResponse: + """ + OGC API - EDR endpoint + + :request Django HTTP Request + :param job_id: job identifier + :param resource: job resource + + :returns: Django HTTP response + """ + + query_type = request.path.split("/")[-1] + response_ = _feed_response(request, "get_collection_edr_query", collection_id, instance_id, query_type) + response = _to_django_response(*response_) + + return response + + +def stac_catalog_root(request: HttpRequest) -> HttpResponse: + """ + STAC root endpoint + + :request Django HTTP Request + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_stac_root") + response = _to_django_response(*response_) + + return response + + +def stac_catalog_path(request: HttpRequest, path: str) -> HttpResponse: + """ + STAC path endpoint + + :request Django HTTP Request + :param path: path + + :returns: Django HTTP response + """ + + response_ = _feed_response(request, "get_stac_path", path) + response = _to_django_response(*response_) + + return response + + +def stac_catalog_search(request: HttpRequest) -> HttpResponse: + pass + + +def _feed_response(request: HttpRequest, api_definition: str, *args, **kwargs) -> tuple[dict, int, str]: + """Use pygeoapi api to process the input request""" + + config = GeoAPIConfig.get_solo() + as_dict = config.get_config(request.scheme + "://" + request.get_host() + "/geoapi/") + + api_ = API(as_dict, {}) + api = getattr(api_, api_definition) + return api(request, *args, **kwargs) + + +def _to_django_response(headers: Mapping, status_code: int, content: str) -> HttpResponse: + """Convert API payload to a django response""" + + response = HttpResponse(content, status=status_code) + + for key, value in headers.items(): + response[key] = value + return response diff --git a/metadata_catalogue/datasets/libs/geoapi/mapping.py b/metadata_catalogue/datasets/libs/geoapi/mapping.py new file mode 100644 index 0000000..d34600c --- /dev/null +++ b/metadata_catalogue/datasets/libs/geoapi/mapping.py @@ -0,0 +1,31 @@ +class ResourceMapping: + def __init__(self, dataset) -> None: + self.id = dataset.uuid + self.dataset = dataset + + def as_resource(self): + return self.id, { + "type": "collection", + "visibility": "default", + "title": self.dataset.metadata.title, + "description": self.dataset.metadata.abstract, + "keywords": [], + "context": [], + "links": [ + {"type": "application/zip", "rel": "canonical", "title": "Data", "href": self.dataset.fetch_url} + ], + "extents": { + "spatial": { + "bbox": self.dataset.metadata.bounding_box.extent, + "crs": self.dataset.metadata.bounding_box.srs.name, + } + }, + "providers": [ + { + "type": "feature", + "default": True, + "name": "CSV", + "editable": False, + } + ], + } diff --git a/metadata_catalogue/datasets/managers.py b/metadata_catalogue/datasets/managers.py index 93d9137..599f1c6 100644 --- a/metadata_catalogue/datasets/managers.py +++ b/metadata_catalogue/datasets/managers.py @@ -3,6 +3,7 @@ from . import logger from .libs.csw.mapping import CSWMapping from .libs.csw.query import Group +from .libs.geoapi.mapping import ResourceMapping SORT_CONFIG = {"title": "metadata__title", "csw_wkt_geometry": "metadata__bounding_box"} @@ -30,6 +31,10 @@ def csw_sort(self, sort): logger.warn(f"Not implemented! {sort}") return self + def as_geoapi_resource(self, *args, warn=True, **kwargs): + logger.warn("DANGER: This method consumes the queryset and returns and array of items") + return [ResourceMapping(instance).as_resource() for instance in self] + class DatasetManager(models.Manager): def get_queryset(self): diff --git a/metadata_catalogue/datasets/migrations/0008_serviceinfo_language.py b/metadata_catalogue/datasets/migrations/0008_serviceinfo_language.py new file mode 100644 index 0000000..31ff6a2 --- /dev/null +++ b/metadata_catalogue/datasets/migrations/0008_serviceinfo_language.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.6 on 2023-11-13 12:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("datasets", "0007_serviceinfo_contact_hours_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="serviceinfo", + name="language", + field=models.CharField(blank=True, max_length=7, null=True), + ), + ] diff --git a/metadata_catalogue/datasets/models.py b/metadata_catalogue/datasets/models.py index 8644da4..2f9e680 100644 --- a/metadata_catalogue/datasets/models.py +++ b/metadata_catalogue/datasets/models.py @@ -388,3 +388,4 @@ class ServiceInfo(SingletonModel): contact_instructions = models.TextField(null=True, blank=True, default="") provider = models.ForeignKey("datasets.Organization", blank=True, null=True, on_delete=models.SET_NULL) license = models.ForeignKey("datasets.License", on_delete=models.SET_NULL, null=True, blank=True) + language = models.CharField(max_length=7, null=True, blank=True) diff --git a/metadata_catalogue/static/geoapi/css/default.css b/metadata_catalogue/static/geoapi/css/default.css new file mode 100644 index 0000000..2f87fc9 --- /dev/null +++ b/metadata_catalogue/static/geoapi/css/default.css @@ -0,0 +1,66 @@ +.flat { + border: 0px; +} + +header { + display: inline-block; +} + +main { + background-color:white +} + +.crumbs { + background-color:rgb(230, 230, 230); + padding: 6px; +} + +.crumbs a { + padding: 0px 6px; + color:black; + text-decoration: none; +/* text-transform: capitalize;*/ +} + +#items-map, #collection-map { + width: 100%; + height: 400px; +} + +/* cancel mini-css header>button uppercase */ +header button, header [type="button"], header .button, header [role="button"] { + text-transform: none; +} + +html, body { + background-color: #fff; +} + +footer.sticky { + position: fixed; + width: 100%; +} + +main { + padding-bottom: 65px; /* prevent from falling under the footer */ +} + +table:not(.horizontal) { + max-height: none; +} + +mark.successful { + background-color: green; +} + +mark.accepted { + background-color: default; +} + +mark.failed { + background-color: red; +} + +mark.running { + background-color: orange; +} diff --git a/metadata_catalogue/static/geoapi/img/favicon.ico b/metadata_catalogue/static/geoapi/img/favicon.ico new file mode 100644 index 0000000..1e20f9c Binary files /dev/null and b/metadata_catalogue/static/geoapi/img/favicon.ico differ diff --git a/metadata_catalogue/static/geoapi/img/logo.png b/metadata_catalogue/static/geoapi/img/logo.png new file mode 100644 index 0000000..0477111 Binary files /dev/null and b/metadata_catalogue/static/geoapi/img/logo.png differ diff --git a/metadata_catalogue/static/geoapi/img/pygeoapi.png b/metadata_catalogue/static/geoapi/img/pygeoapi.png new file mode 100644 index 0000000..0477111 Binary files /dev/null and b/metadata_catalogue/static/geoapi/img/pygeoapi.png differ diff --git a/pdm.lock b/pdm.lock index f8f69f1..6c49f8d 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,27 @@ groups = ["default", "dev"] strategy = ["cross_platform"] lock_version = "4.4" -content_hash = "sha256:2b38b66cdb8bc8b4c3cfa362a94690491ede742380b3b156460a1e60910e5c2b" +content_hash = "sha256:77ac1138f398a6ab8b03d05cec2f24ec80ab70421c5b5f4832629d2d5bcb0337" + +[[package]] +name = "affine" +version = "2.4.0" +requires_python = ">=3.7" +summary = "Matrices describing affine transformation of the plane" +files = [ + {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, + {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, +] + +[[package]] +name = "annotated-types" +version = "0.6.0" +requires_python = ">=3.8" +summary = "Reusable constraint types to use with typing.Annotated" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] [[package]] name = "ansicon" @@ -132,6 +152,19 @@ files = [ {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] +[[package]] +name = "babel" +version = "2.13.1" +requires_python = ">=3.7" +summary = "Internationalization utilities" +dependencies = [ + "setuptools; python_version >= \"3.12\"", +] +files = [ + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, +] + [[package]] name = "backoff" version = "2.2.1" @@ -197,6 +230,16 @@ files = [ {file = "blessed-1.20.0.tar.gz", hash = "sha256:2cdd67f8746e048f00df47a2880f4d6acbcdb399031b604e34ba8f71d5787680"}, ] +[[package]] +name = "blinker" +version = "1.7.0" +requires_python = ">=3.8" +summary = "Fast, simple object-to-object and broadcast signaling" +files = [ + {file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"}, + {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, +] + [[package]] name = "certifi" version = "2023.7.22" @@ -329,6 +372,31 @@ files = [ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] +[[package]] +name = "click-plugins" +version = "1.1.1" +summary = "An extension module for click to enable registering CLI commands via setuptools entry-points." +dependencies = [ + "click>=4.0", +] +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[[package]] +name = "cligj" +version = "0.7.2" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" +summary = "Click params for commmand line interfaces to GeoJSON" +dependencies = [ + "click>=4.0", +] +files = [ + {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, + {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, +] + [[package]] name = "colorama" version = "0.4.6" @@ -440,6 +508,22 @@ files = [ {file = "cssbeautifier-1.14.11.tar.gz", hash = "sha256:40544c2b62bbcb64caa5e7f37a02df95654e5ce1bcacadac4ca1f3dc89c31513"}, ] +[[package]] +name = "dateparser" +version = "1.1.8" +requires_python = ">=3.7" +summary = "Date parsing library designed to parse dates from HTML pages" +dependencies = [ + "python-dateutil", + "pytz", + "regex!=2019.02.19,!=2021.8.27", + "tzlocal", +] +files = [ + {file = "dateparser-1.1.8-py2.py3-none-any.whl", hash = "sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f"}, + {file = "dateparser-1.1.8.tar.gz", hash = "sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3"}, +] + [[package]] name = "decorator" version = "5.1.1" @@ -884,6 +968,23 @@ files = [ {file = "flake8_isort-6.1.1.tar.gz", hash = "sha256:c1f82f3cf06a80c13e1d09bfae460e9666255d5c780b859f19f8318d420370b3"}, ] +[[package]] +name = "flask" +version = "3.0.0" +requires_python = ">=3.8" +summary = "A simple framework for building complex web applications." +dependencies = [ + "Jinja2>=3.1.2", + "Werkzeug>=3.0.0", + "blinker>=1.6.2", + "click>=8.1.3", + "itsdangerous>=2.1.2", +] +files = [ + {file = "flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638"}, + {file = "flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58"}, +] + [[package]] name = "geolinks" version = "0.2.3" @@ -896,6 +997,42 @@ files = [ {file = "geolinks-0.2.3.tar.gz", hash = "sha256:1aacd55d0c0c349cbc8319b2eea70e98dbe34be688c7be14248fbbba0c7cf54e"}, ] +[[package]] +name = "greenlet" +version = "3.0.1" +requires_python = ">=3.7" +summary = "Lightweight in-process concurrent programming" +files = [ + {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, + {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, + {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, + {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, + {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, + {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, + {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, + {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, + {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, + {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, + {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, + {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, + {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, +] + [[package]] name = "gunicorn" version = "21.2.0" @@ -1003,6 +1140,19 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[[package]] +name = "importlib-metadata" +version = "6.8.0" +requires_python = ">=3.8" +summary = "Read metadata from Python packages" +dependencies = [ + "zipp>=0.5", +] +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] + [[package]] name = "iniconfig" version = "2.0.0" @@ -1063,6 +1213,16 @@ files = [ {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, ] +[[package]] +name = "itsdangerous" +version = "2.1.2" +requires_python = ">=3.7" +summary = "Safely pass data to untrusted environments and back." +files = [ + {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] + [[package]] name = "jedi" version = "0.19.1" @@ -1151,6 +1311,15 @@ files = [ {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, ] +[[package]] +name = "lark" +version = "0.12.0" +summary = "a modern parsing library" +files = [ + {file = "lark-0.12.0-py2.py3-none-any.whl", hash = "sha256:ed1d891cbcf5151ead1c1d14663bf542443e579e63a76ae175b01b899bd854ca"}, + {file = "lark-0.12.0.tar.gz", hash = "sha256:7da76fcfddadabbbbfd949bbae221efd33938451d90b1fefbbc423c3cccf48ef"}, +] + [[package]] name = "lxml" version = "4.9.3" @@ -1637,6 +1806,97 @@ files = [ {file = "pycsw-2.6.1.tar.gz", hash = "sha256:8d4763bfc0674018f0c825b2c533352c1edef161fd76e154c5b7a3dcc44434f0"}, ] +[[package]] +name = "pydantic" +version = "2.5.0" +requires_python = ">=3.7" +summary = "Data validation using Python type hints" +dependencies = [ + "annotated-types>=0.4.0", + "pydantic-core==2.14.1", + "typing-extensions>=4.6.1", +] +files = [ + {file = "pydantic-2.5.0-py3-none-any.whl", hash = "sha256:7ce6e766c456ad026fe5712f7bcf036efc34bd5d107b3e669ef7ea01b3a9050c"}, + {file = "pydantic-2.5.0.tar.gz", hash = "sha256:69bd6fb62d2d04b7055f59a396993486a2ee586c43a0b89231ce0000de07627c"}, +] + +[[package]] +name = "pydantic-core" +version = "2.14.1" +requires_python = ">=3.7" +summary = "" +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] +files = [ + {file = "pydantic_core-2.14.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:812beca1dcb2b722cccc7e9c620bd972cbc323321194ec2725eab3222e6ac573"}, + {file = "pydantic_core-2.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2ccdc53cb88e51c7d47d74c59630d7be844428f6b8d463055ffad6f0392d8da"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd937733bf2fe7d6a8bf208c12741f1f730b7bf5636033877767a75093c29b8a"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:581bb606a31749a00796f5257947a0968182d7fe91e1dada41f06aeb6bfbc91a"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aadf74a40a7ae49c3c1aa7d32334fe94f4f968e21dd948e301bb4ed431fb2412"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b89821a2c77cc1b8f2c1fc3aacd6a3ecc5df8f7e518dc3f18aef8c4dcf66003d"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49ee28d65f506b2858a60745cc974ed005298ebab12693646b97641dd7c99c35"}, + {file = "pydantic_core-2.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97246f896b4df7fd84caa8a75a67abb95f94bc0b547665bf0889e3262b060399"}, + {file = "pydantic_core-2.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1185548665bc61bbab0dc78f10c8eafa0db0aa1e920fe9a451b77782b10a65cc"}, + {file = "pydantic_core-2.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2a7d08b39fac97540fba785fce3b21ee01a81f081a07a4d031efd791da6666f9"}, + {file = "pydantic_core-2.14.1-cp310-none-win32.whl", hash = "sha256:0a8c8daf4e3aa3aeb98e3638fc3d58a359738f3d12590b2474c6bb64031a0764"}, + {file = "pydantic_core-2.14.1-cp310-none-win_amd64.whl", hash = "sha256:4f0788699a92d604f348e9c1ac5e97e304e97127ba8325c7d0af88dcc7d35bd3"}, + {file = "pydantic_core-2.14.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:2be018a84995b6be1bbd40d6064395dbf71592a981169cf154c0885637f5f54a"}, + {file = "pydantic_core-2.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc3227408808ba7df8e95eb1d8389f4ba2203bed8240b308de1d7ae66d828f24"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42d5d0e9bbb50481a049bd0203224b339d4db04006b78564df2b782e2fd16ebc"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc6a4ea9f88a810cb65ccae14404da846e2a02dd5c0ad21dee712ff69d142638"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d312ad20e3c6d179cb97c42232b53111bcd8dcdd5c1136083db9d6bdd489bc73"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:679cc4e184f213c8227862e57340d12fd4d4d19dc0e3ddb0f653f86f01e90f94"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101df420e954966868b8bc992aefed5fa71dd1f2755104da62ee247abab28e2f"}, + {file = "pydantic_core-2.14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c964c0cc443d6c08a2347c0e5c1fc2d85a272dc66c1a6f3cde4fc4843882ada4"}, + {file = "pydantic_core-2.14.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8276bbab68a9dbe721da92d19cbc061f76655248fe24fb63969d0c3e0e5755e7"}, + {file = "pydantic_core-2.14.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:12163197fec7c95751a3c71b36dcc1909eed9959f011ffc79cc8170a6a74c826"}, + {file = "pydantic_core-2.14.1-cp311-none-win32.whl", hash = "sha256:b8ff0302518dcd001bd722bbe342919c29e5066c7eda86828fe08cdc112668b8"}, + {file = "pydantic_core-2.14.1-cp311-none-win_amd64.whl", hash = "sha256:59fa83873223f856d898452c6162a390af4297756f6ba38493a67533387d85d9"}, + {file = "pydantic_core-2.14.1-cp311-none-win_arm64.whl", hash = "sha256:798590d38c9381f07c48d13af1f1ef337cebf76ee452fcec5deb04aceced51c7"}, + {file = "pydantic_core-2.14.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:587d75aec9ae50d0d63788cec38bf13c5128b3fc1411aa4b9398ebac884ab179"}, + {file = "pydantic_core-2.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:26242e3593d4929123615bd9365dd86ef79b7b0592d64a96cd11fd83c69c9f34"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5879ac4791508d8f0eb7dec71ff8521855180688dac0c55f8c99fc4d1a939845"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ad9ea86f5fc50f1b62c31184767fe0cacaa13b54fe57d38898c3776d30602411"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:102ac85a775e77821943ae38da9634ddd774b37a8d407181b4f7b05cdfb36b55"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2459cc06572730e079ec1e694e8f68c99d977b40d98748ae72ff11ef21a56b0b"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:217dcbfaf429a9b8f1d54eb380908b9c778e78f31378283b30ba463c21e89d5d"}, + {file = "pydantic_core-2.14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d59e0d7cdfe8ed1d4fcd28aad09625c715dc18976c7067e37d8a11b06f4be3e"}, + {file = "pydantic_core-2.14.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e2be646a5155d408e68b560c0553e8a83dc7b9f90ec6e5a2fc3ff216719385db"}, + {file = "pydantic_core-2.14.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ffba979801e3931a19cd30ed2049450820effe8f152aaa317e2fd93795d318d7"}, + {file = "pydantic_core-2.14.1-cp312-none-win32.whl", hash = "sha256:132b40e479cb5cebbbb681f77aaceabbc8355df16c9124cff1d4060ada83cde2"}, + {file = "pydantic_core-2.14.1-cp312-none-win_amd64.whl", hash = "sha256:744b807fe2733b6da3b53e8ad93e8b3ea3ee3dfc3abece4dd2824cc1f39aa343"}, + {file = "pydantic_core-2.14.1-cp312-none-win_arm64.whl", hash = "sha256:24ba48f9d0b8d64fc5e42e1600366c3d7db701201294989aebdaca23110c02ab"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:53efe03cc383a83660cfdda6a3cb40ee31372cedea0fde0b2a2e55e838873ab6"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f523e116879bc6714e61d447ce934676473b068069dce6563ea040381dc7a257"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85bb66d661be51b2cba9ca06759264b3469d2dbb53c3e6effb3f05fec6322be6"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f53a3ccdc30234cb4342cec541e3e6ed87799c7ca552f0b5f44e3967a5fed526"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:1bfb63821ada76719ffcd703fc40dd57962e0d8c253e3c565252e6de6d3e0bc6"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e2c689439f262c29cf3fcd5364da1e64d8600facecf9eabea8643b8755d2f0de"}, + {file = "pydantic_core-2.14.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a15f6e5588f7afb7f6fc4b0f4ff064749e515d34f34c666ed6e37933873d8ad8"}, + {file = "pydantic_core-2.14.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f1a30eef060e21af22c7d23349f1028de0611f522941c80efa51c05a63142c62"}, + {file = "pydantic_core-2.14.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16f4a7e1ec6b3ea98a1e108a2739710cd659d68b33fbbeaba066202cab69c7b6"}, + {file = "pydantic_core-2.14.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd80a2d383940eec3db6a5b59d1820f947317acc5c75482ff8d79bf700f8ad6a"}, + {file = "pydantic_core-2.14.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a68a36d71c7f638dda6c9e6b67f6aabf3fa1471b198d246457bfdc7c777cdeb7"}, + {file = "pydantic_core-2.14.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ebc79120e105e4bcd7865f369e3b9dbabb0d492d221e1a7f62a3e8e292550278"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c8c466facec2ccdf025b0b1455b18f2c3d574d5f64d24df905d3d7b8f05d5f4e"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b91b5ec423e88caa16777094c4b2b97f11453283e7a837e5e5e1b886abba1251"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130e49aa0cb316f743bc7792c36aefa39fc2221312f1d4b333b19edbdd71f2b1"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f483467c046f549572f8aca3b7128829e09ae3a9fe933ea421f7cb7c58120edb"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dee4682bd7947afc682d342a8d65ad1834583132383f8e801601a8698cb8d17a"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:8d927d042c0ef04607ee7822828b208ab045867d20477ec6593d612156798547"}, + {file = "pydantic_core-2.14.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5a1570875eb0d1479fb2270ed80c88c231aaaf68b0c3f114f35e7fb610435e4f"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cb2fd3ab67558eb16aecfb4f2db4febb4d37dc74e6b8613dc2e7160fb58158a9"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a7991f25b98038252363a03e6a9fe92e60fe390fda2631d238dc3b0e396632f8"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b45b7be9f99991405ecd6f6172fb6798908a8097106ae78d5cc5cc15121bad9"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:51506e7652a2ef1d1cf763c4b51b972ff4568d1dddc96ca83931a6941f5e6389"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:66dc0e63349ec39c1ea66622aa5c2c1f84382112afd3ab2fa0cca4fb01f7db39"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:8e17f0c3ba4cb07faa0038a59ce162de584ed48ba645c8d05a5de1e40d4c21e7"}, + {file = "pydantic_core-2.14.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d983222223f63e323a5f497f5b85e211557a5d8fb670dc88f343784502b466ba"}, + {file = "pydantic_core-2.14.1.tar.gz", hash = "sha256:0d82a6ee815388a362885186e431fac84c7a06623bc136f508e9f88261d8cadb"}, +] + [[package]] name = "pyflakes" version = "3.1.0" @@ -1647,6 +1907,64 @@ files = [ {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] +[[package]] +name = "pygeoapi" +version = "0.16.dev0" +git = "https://github.com/geopython/pygeoapi.git" +ref = "de1a7d93eeb492c2b51908e9875a61074b7eab6b" +revision = "de1a7d93eeb492c2b51908e9875a61074b7eab6b" +summary = "pygeoapi provides an API to geospatial data" +dependencies = [ + "Babel", + "Flask", + "PyYAML", + "SQLAlchemy<2.0.0", + "click", + "filelock", + "importlib-metadata", + "jinja2", + "jsonschema", + "pydantic", + "pygeofilter", + "pygeoif", + "pyproj", + "python-dateutil", + "pytz", + "rasterio", + "requests", + "shapely<2.0", + "tinydb", + "typing-extensions", + "unicodecsv", +] + +[[package]] +name = "pygeofilter" +version = "0.2.1" +summary = "pygeofilter is a pure Python parser implementation of OGC filtering standards" +dependencies = [ + "dateparser", + "lark<1.0", + "pygeoif>=1.0.0", +] +files = [ + {file = "pygeofilter-0.2.1-py2.py3-none-any.whl", hash = "sha256:6cbfd46edefee421cae6d338942a0f4f8bbb00f1a6d979914420a300aa0845a6"}, + {file = "pygeofilter-0.2.1.tar.gz", hash = "sha256:cafc961a5cab5f2836605a43b82b05e799500223d19d2d8d8acb85ba263e954c"}, +] + +[[package]] +name = "pygeoif" +version = "1.1.1" +requires_python = ">=3.7" +summary = "A basic implementation of the __geo_interface__" +dependencies = [ + "typing-extensions", +] +files = [ + {file = "pygeoif-1.1.1-py3-none-any.whl", hash = "sha256:c98dd9db1022c9002950d128a37b53bb17d972239f92871687e28958c4c088b0"}, + {file = "pygeoif-1.1.1.tar.gz", hash = "sha256:5b3cc057adde1a0bf50a3dcb5b160172261861a4f4bdde6ee6eb663773c4fe33"}, +] + [[package]] name = "pygeometa" version = "0.15.3" @@ -1748,6 +2066,16 @@ files = [ {file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"}, ] +[[package]] +name = "pyparsing" +version = "3.1.1" +requires_python = ">=3.6.8" +summary = "pyparsing module - Classes and methods to define and execute parsing grammars" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + [[package]] name = "pyproj" version = "3.6.1" @@ -1903,6 +2231,38 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "rasterio" +version = "1.3.9" +requires_python = ">=3.8" +summary = "Fast and direct raster I/O for use with Numpy and SciPy" +dependencies = [ + "affine", + "attrs", + "certifi", + "click-plugins", + "click>=4.0", + "cligj>=0.5", + "numpy", + "setuptools", + "snuggs>=1.4.1", +] +files = [ + {file = "rasterio-1.3.9-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:04247da9f4002587ac2bec967c3a72f63fc0e6654101c06850bae3d8131b700d"}, + {file = "rasterio-1.3.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c9edce37b70f4cd4be5d3f5d314877e3130aeebb612120405cd28f83fe200865"}, + {file = "rasterio-1.3.9-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:fd6a850a37840ba590ddcf7ff90ba007b1e231b04434d8b4ac5ce0f746ada91a"}, + {file = "rasterio-1.3.9-cp310-cp310-win_amd64.whl", hash = "sha256:0c83156a44f8fda11876ff9f2ff1b602d7e7434447f7d621353f2929cefb1bf1"}, + {file = "rasterio-1.3.9-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:0172dbd80bd9adc105ec2c9bd207dbd5519ea06b438a4d965c6290ae8ed6ff9f"}, + {file = "rasterio-1.3.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ea5b42597d85868ee88c750cc33f2ae729e1b5e3fe28f99071f39e1417bf1c0"}, + {file = "rasterio-1.3.9-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:be9b343bd08245df22115775dc9513c912afb4134d832662fa165d70cb805c34"}, + {file = "rasterio-1.3.9-cp311-cp311-win_amd64.whl", hash = "sha256:06d53e2e0885f039f960beb7c861400b92ea3e0e5abc2c67483fb56b1e5cbc13"}, + {file = "rasterio-1.3.9-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:a34bb9eef67b7896e2dfb39e10ba6372f9894226fb790bd7a46f5748f205b7d8"}, + {file = "rasterio-1.3.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:67b144b9678f9ad4cf5f2c3f455cbc6a7166c0523179249cee8f2e2c57d76c5b"}, + {file = "rasterio-1.3.9-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:99b72fccb702a921f43e56a4507b4cafe2a9196b478b993b98e82ec6851916d7"}, + {file = "rasterio-1.3.9-cp312-cp312-win_amd64.whl", hash = "sha256:6777fad3c31eb3e5da0ccaa28a032ad07c20d003bcd14f8bc13e16ca2f62348c"}, + {file = "rasterio-1.3.9.tar.gz", hash = "sha256:fc6d0d290492fa1a5068711cfebb21cc936968891b7ed9da0690c8a7388885c5"}, +] + [[package]] name = "rcssmin" version = "1.1.2" @@ -2128,35 +2488,26 @@ files = [ [[package]] name = "shapely" -version = "2.0.2" -requires_python = ">=3.7" -summary = "Manipulation and analysis of geometric objects" -dependencies = [ - "numpy>=1.14", -] -files = [ - {file = "shapely-2.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6ca8cffbe84ddde8f52b297b53f8e0687bd31141abb2c373fd8a9f032df415d6"}, - {file = "shapely-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:baa14fc27771e180c06b499a0a7ba697c7988c7b2b6cba9a929a19a4d2762de3"}, - {file = "shapely-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36480e32c434d168cdf2f5e9862c84aaf4d714a43a8465ae3ce8ff327f0affb7"}, - {file = "shapely-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef753200cbffd4f652efb2c528c5474e5a14341a473994d90ad0606522a46a2"}, - {file = "shapely-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a41ff4323fc9d6257759c26eb1cf3a61ebc7e611e024e6091f42977303fd3a"}, - {file = "shapely-2.0.2-cp310-cp310-win32.whl", hash = "sha256:72b5997272ae8c25f0fd5b3b967b3237e87fab7978b8d6cd5fa748770f0c5d68"}, - {file = "shapely-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:34eac2337cbd67650248761b140d2535855d21b969d76d76123317882d3a0c1a"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b0c052709c8a257c93b0d4943b0b7a3035f87e2d6a8ac9407b6a992d206422f"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2d217e56ae067e87b4e1731d0dc62eebe887ced729ba5c2d4590e9e3e9fdbd88"}, - {file = "shapely-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94ac128ae2ab4edd0bffcd4e566411ea7bdc738aeaf92c32a8a836abad725f9f"}, - {file = "shapely-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa3ee28f5e63a130ec5af4dc3c4cb9c21c5788bb13c15e89190d163b14f9fb89"}, - {file = "shapely-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:737dba15011e5a9b54a8302f1748b62daa207c9bc06f820cd0ad32a041f1c6f2"}, - {file = "shapely-2.0.2-cp311-cp311-win32.whl", hash = "sha256:45ac6906cff0765455a7b49c1670af6e230c419507c13e2f75db638c8fc6f3bd"}, - {file = "shapely-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:dc9342fc82e374130db86a955c3c4525bfbf315a248af8277a913f30911bed9e"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:06f193091a7c6112fc08dfd195a1e3846a64306f890b151fa8c63b3e3624202c"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eebe544df5c018134f3c23b6515877f7e4cd72851f88a8d0c18464f414d141a2"}, - {file = "shapely-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7e92e7c255f89f5cdf777690313311f422aa8ada9a3205b187113274e0135cd8"}, - {file = "shapely-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be46d5509b9251dd9087768eaf35a71360de6afac82ce87c636990a0871aa18b"}, - {file = "shapely-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5533a925d8e211d07636ffc2fdd9a7f9f13d54686d00577eeb11d16f00be9c4"}, - {file = "shapely-2.0.2-cp312-cp312-win32.whl", hash = "sha256:084b023dae8ad3d5b98acee9d3bf098fdf688eb0bb9b1401e8b075f6a627b611"}, - {file = "shapely-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:ea84d1cdbcf31e619d672b53c4532f06253894185ee7acb8ceb78f5f33cbe033"}, - {file = "shapely-2.0.2.tar.gz", hash = "sha256:1713cc04c171baffc5b259ba8531c58acc2a301707b7f021d88a15ed090649e7"}, +version = "1.8.5.post1" +requires_python = ">=3.6" +summary = "Geometric objects, predicates, and operations" +files = [ + {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d048f93e42ba578b82758c15d8ae037d08e69d91d9872bca5a1895b118f4e2b0"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99ab0ddc05e44acabdbe657c599fdb9b2d82e86c5493bdae216c0c4018a82dee"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a2f0da0109e81e0c101a2b4cd8412f73f5f299e7b5b2deaf64cd2a100ac118"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6fe855e7d45685926b6ba00aaeb5eba5862611f7465775dacd527e081a8ced6d"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec14ceca36f67cb48b34d02d7f65a9acae15cd72b48e303531893ba4a960f3ea"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a2b2a65fa7f97115c1cd989fe9d6f39281ca2a8a014f1d4904c1a6e34d7f25"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-win32.whl", hash = "sha256:21776184516a16bf82a0c3d6d6a312b3cd15a4cabafc61ee01cf2714a82e8396"}, + {file = "Shapely-1.8.5.post1-cp310-cp310-win_amd64.whl", hash = "sha256:a354199219c8d836f280b88f2c5102c81bb044ccea45bd361dc38a79f3873714"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:783bad5f48e2708a0e2f695a34ed382e4162c795cb2f0368b39528ac1d6db7ed"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a23ef3882d6aa203dd3623a3d55d698f59bfbd9f8a3bfed52c2da05a7f0f8640"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab38f7b5196ace05725e407cb8cab9ff66edb8e6f7bb36a398e8f73f52a7aaa2"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d086591f744be483b34628b391d741e46f2645fe37594319e0a673cc2c26bcf"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4728666fff8cccc65a07448cae72c75a8773fea061c3f4f139c44adc429b18c3"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-win32.whl", hash = "sha256:84010db15eb364a52b74ea8804ef92a6a930dfc1981d17a369444b6ddec66efd"}, + {file = "Shapely-1.8.5.post1-cp311-cp311-win_amd64.whl", hash = "sha256:48dcfffb9e225c0481120f4bdf622131c8c95f342b00b158cdbe220edbbe20b6"}, + {file = "Shapely-1.8.5.post1.tar.gz", hash = "sha256:ef3be705c3eac282a28058e6c6e5503419b250f482320df2172abcbea642c831"}, ] [[package]] @@ -2169,6 +2520,19 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "snuggs" +version = "1.4.7" +summary = "Snuggs are s-expressions for Numpy" +dependencies = [ + "numpy", + "pyparsing>=2.1.6", +] +files = [ + {file = "snuggs-1.4.7-py3-none-any.whl", hash = "sha256:988dde5d4db88e9d71c99457404773dabcc7a1c45971bfbe81900999942d9f07"}, + {file = "snuggs-1.4.7.tar.gz", hash = "sha256:501cf113fe3892e14e2fee76da5cd0606b7e149c411c271898e6259ebde2617b"}, +] + [[package]] name = "soupsieve" version = "2.5" @@ -2179,6 +2543,26 @@ files = [ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] +[[package]] +name = "sqlalchemy" +version = "1.4.50" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +summary = "Database Abstraction Library" +dependencies = [ + "greenlet!=0.4.17; python_version >= \"3\" and (platform_machine == \"aarch64\" or (platform_machine == \"ppc64le\" or (platform_machine == \"x86_64\" or (platform_machine == \"amd64\" or (platform_machine == \"AMD64\" or (platform_machine == \"win32\" or platform_machine == \"WIN32\"))))))", +] +files = [ + {file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00665725063692c42badfd521d0c4392e83c6c826795d38eb88fb108e5660e5"}, + {file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85292ff52ddf85a39367057c3d7968a12ee1fb84565331a36a8fead346f08796"}, + {file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d0fed0f791d78e7767c2db28d34068649dfeea027b83ed18c45a423f741425cb"}, + {file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db4db3c08ffbb18582f856545f058a7a5e4ab6f17f75795ca90b3c38ee0a8ba4"}, + {file = "SQLAlchemy-1.4.50-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14b0cacdc8a4759a1e1bd47dc3ee3f5db997129eb091330beda1da5a0e9e5bd7"}, + {file = "SQLAlchemy-1.4.50-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fb9cb60e0f33040e4f4681e6658a7eb03b5cb4643284172f91410d8c493dace"}, + {file = "SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cb501d585aa74a0f86d0ea6263b9c5e1d1463f8f9071392477fd401bd3c7cc"}, + {file = "SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a7a66297e46f85a04d68981917c75723e377d2e0599d15fbe7a56abed5e2d75"}, + {file = "SQLAlchemy-1.4.50.tar.gz", hash = "sha256:3b97ddf509fc21e10b09403b5219b06c5b558b27fc2453150274fa4e70707dbf"}, +] + [[package]] name = "sqlparse" version = "0.4.4" @@ -2222,6 +2606,16 @@ files = [ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, ] +[[package]] +name = "tinydb" +version = "4.8.0" +requires_python = ">=3.7,<4.0" +summary = "TinyDB is a tiny, document oriented database optimized for your happiness :)" +files = [ + {file = "tinydb-4.8.0-py3-none-any.whl", hash = "sha256:30c06d12383d7c332e404ca6a6103fb2b32cbf25712689648c39d9a6bd34bd3d"}, + {file = "tinydb-4.8.0.tar.gz", hash = "sha256:6dd686a9c5a75dfa9280088fd79a419aefe19cd7f4bd85eba203540ef856d564"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -2312,6 +2706,27 @@ files = [ {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] +[[package]] +name = "tzlocal" +version = "5.2" +requires_python = ">=3.8" +summary = "tzinfo object for the local timezone" +dependencies = [ + "tzdata; platform_system == \"Windows\"", +] +files = [ + {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"}, + {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"}, +] + +[[package]] +name = "unicodecsv" +version = "0.14.1" +summary = "Python2's stdlib csv module is nice, but it doesn't support unicode. This module is a drop-in replacement which *does*." +files = [ + {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, +] + [[package]] name = "urllib3" version = "1.26.18" @@ -2421,3 +2836,13 @@ files = [ {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] + +[[package]] +name = "zipp" +version = "3.17.0" +requires_python = ">=3.8" +summary = "Backport of pathlib-compatible object wrapper for zip files" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] diff --git a/pyproject.toml b/pyproject.toml index d4dbe57..2d4f8b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -162,6 +162,7 @@ dependencies = [ "pygeometa", "django-lifecycle", "gunicorn>=21.2.0", + "pygeoapi @ git+https://github.com/geopython/pygeoapi.git@de1a7d93eeb492c2b51908e9875a61074b7eab6b", ] requires-python = ">=3.10" name = ""