From 199a1fc612ec66bcb2833af3a0beeacabdb086df Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Tue, 30 Aug 2022 16:41:48 -0400 Subject: [PATCH] update Django integration (#971) * update Django integration * address PR comments --- .gitignore | 3 +- .../data-publishing/ogcapi-features.rst | 4 +- docs/source/downstream.rst | 103 -- docs/source/index.rst | 1 - docs/source/running.rst | 21 + examples/django/sample_project/README.md | 91 ++ .../django}/sample_project/manage.py | 0 .../sample_project/pygeoapi-config.yml | 0 .../sample_project}/__init__.py | 0 .../sample_project/sample_project/asgi.py | 0 .../sample_project/sample_project/settings.py | 0 .../sample_project/sample_project/urls.py | 0 .../sample_project/sample_project/wsgi.py | 0 pygeoapi-openapi.yml | 880 ------------------ pygeoapi/api.py | 4 +- pygeoapi/db.sqlite3 | 0 pygeoapi/django_/__init__.py | 28 + pygeoapi/django_/settings.py | 168 ++++ pygeoapi/django_/urls.py | 185 ++++ .../{django_pygeoapi => django_}/views.py | 75 +- pygeoapi/django_/wsgi.py | 51 + pygeoapi/django_app.py | 54 +- .../sample_project/sample_project/__init__.py | 0 pygeoapi/django_pygeoapi/settings.py | 133 --- pygeoapi/django_pygeoapi/urls.py | 150 --- pygeoapi/django_pygeoapi/wsgi.py | 16 - requirements-django.txt | 2 +- 27 files changed, 649 insertions(+), 1320 deletions(-) delete mode 100644 docs/source/downstream.rst create mode 100644 examples/django/sample_project/README.md rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/manage.py (100%) rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/pygeoapi-config.yml (100%) rename {pygeoapi/django_pygeoapi => examples/django/sample_project/sample_project}/__init__.py (100%) rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/sample_project/asgi.py (100%) rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/sample_project/settings.py (100%) rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/sample_project/urls.py (100%) rename {pygeoapi/django_pygeoapi => examples/django}/sample_project/sample_project/wsgi.py (100%) delete mode 100644 pygeoapi-openapi.yml delete mode 100644 pygeoapi/db.sqlite3 create mode 100644 pygeoapi/django_/__init__.py create mode 100644 pygeoapi/django_/settings.py create mode 100644 pygeoapi/django_/urls.py rename pygeoapi/{django_pygeoapi => django_}/views.py (76%) create mode 100644 pygeoapi/django_/wsgi.py delete mode 100644 pygeoapi/django_pygeoapi/sample_project/sample_project/__init__.py delete mode 100644 pygeoapi/django_pygeoapi/settings.py delete mode 100644 pygeoapi/django_pygeoapi/urls.py delete mode 100644 pygeoapi/django_pygeoapi/wsgi.py diff --git a/.gitignore b/.gitignore index 97d8eef..a0b9c1f 100644 --- a/.gitignore +++ b/.gitignore @@ -114,5 +114,4 @@ ENV/ *.code-workspace .DS_Store - -pygeoapi/django_pygeoapi/sample_project/db.sqlite3 +examples/django/sample_project/db.sqlite3 diff --git a/docs/source/data-publishing/ogcapi-features.rst b/docs/source/data-publishing/ogcapi-features.rst index d2e60c2..85fccf4 100644 --- a/docs/source/data-publishing/ogcapi-features.rst +++ b/docs/source/data-publishing/ogcapi-features.rst @@ -105,7 +105,7 @@ specify the URL for the service layer in the ``data`` field. * ``id_field`` will often be ``OBJECTID``, ``objectid``, or ``FID``. * If the map or feature service is not shared publicly, the ``username`` and ``password`` fields can be set in the -configuration to authenticate into the service. + configuration to authenticate into the service. .. code-block:: yaml @@ -310,7 +310,7 @@ relies on `sodapy `. * ``resource_id`` is the 4x4 resource id pattern. * ``geom_field`` is required for bbox queries to work. * ``token`` is optional and can be included in the configuration to pass -an `app token ` to Socrata. + an `app token ` to Socrata. .. code-block:: yaml diff --git a/docs/source/downstream.rst b/docs/source/downstream.rst deleted file mode 100644 index 1957351..0000000 --- a/docs/source/downstream.rst +++ /dev/null @@ -1,103 +0,0 @@ -.. _downstream: - -Downstream Projects -======= - -Downstreaming `pygeoapi` project with various python frameworks. - ------------------- - -In this page, we'll demonstrate how to downstream `pygeoapi` project with various python frameworks. - - -Django -^^^^^^ - -Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Click `here `_ to read more about Django. - -In this section we create a sample django project and use `pygeoapi` package as a pluggable django application and serve all the capabilities of `pygeoapi` using Django. For the truly impatient developers, there is a Django `sample_project` in the source code. - -To create everything from scratch please follow these steps : - -- Create a Project folder and create a fresh virtual environment using your preferred tool. e.g. - -.. code-block:: bash - - python3 -m venv env - -Once created, activate it. - -- Install the following dependencies - -.. code-block:: bash - - pip install Django pygeoapi - -- Create a django project in a directory and cd into it. - -.. code-block:: python - - django-admin startproject sampleproject - cd /sampleproject - -- Download `pygeoapi-config.yml` using - -.. code-block:: bash - - curl -O https://raw.githubusercontent.com/geopython/pygeoapi/django_pygeoapi/sample_project/pygeoapi-config.yml - -and put it in the same folder at root level. - -- Set environment variable - -.. code-block:: bash - - export PYGEOAPI_CONFIG=pygeoapi-config.yml - export PYGEOAPI_OPENAPI=example-openapi.yml - -- Run `python manage.py collectstatic` to get all static files. -- Generate OpenAPI document using following `pygeoapi` command - -.. code-block:: bash - - pygeoapi openapi generate $PYGEOAPI_CONFIG --output-file $PYGEOAPI_OPENAPI - -- Update Django `sampleproject/settings.py` file as per following - -.. code-block:: python - - import os - from pygeoapi.django_app import config - - INSTALLED_APPS = [ - # other apps - .... - #pygeoapi app - 'pygeoapi' - ] - - # Put following setting after STATIC_URL - STATIC_ROOT = os.path.join( BASE_DIR / 'assets') - - # Specific pygeoapi setting - PYGEOAPI_CONFIG = config() - ... - -- Update Django `sampleproject/urls.py` file to run pygeoapi at e.g. `pga` path - -.. code-block:: python - - from django.contrib import admin - from django.urls import path, include - from pygeoapi.django_pygeoapi import urls - urlpatterns = [ - path('admin/', admin.site.urls), - path('pga/', include(urls)) # added here - ] - -- Update pygeoapi `pygeoapi-config.yml` file with following settings - -1. Update the `url` property under `server` in `pygeoapi-config.yml` accordingly to your django project url. e.g. In this case the path set is `pga` . -2. Update all data paths e.g. `tests/data/ne_110m_lakes.geojson` to match with the absolute path of the pygeoapi project directory. - -- Run Django project using `python manage.py runserver`. Once server starts, head over to `localhost:8000/pga` to see `pygeoapi` running. \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 0651f15..6194b36 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -23,7 +23,6 @@ pygeoapi |release| documentation configuration administration running - downstream running-with-docker tour openapi diff --git a/docs/source/running.rst b/docs/source/running.rst index b60bb7c..cbdd87b 100644 --- a/docs/source/running.rst +++ b/docs/source/running.rst @@ -181,6 +181,26 @@ is simple to run from the command, e.g: .. note:: Uvicorn is as easy to install as ``pip install uvicorn`` + +Django +^^^^^^ + +`Django`_ is a Python web framework that encourages rapid development and clean, pragmatic design. Assuming +a Django install/enabled application: + + +.. code-block:: bash + + pygeoapi serve --django + + +To integrate pygeoapi as part of another Django project in a pluggable way the truly impatient developers can +see `examples/django/sample_project/README.md` for a complete Django application. + +As a result, your Django application will be available at http://localhost:5000/ and pygeoapi will be available +at http://localhost:5000/oapi + + Summary ------- @@ -199,3 +219,4 @@ and modify accordingly. .. _`Gunicorn settings`: http://docs.gunicorn.org/en/stable/settings.html .. _`Uvicorn`: https://www.uvicorn.org .. _`mod_wsgi`: https://modwsgi.readthedocs.io +.. _`Django`: https://djangoproject.com diff --git a/examples/django/sample_project/README.md b/examples/django/sample_project/README.md new file mode 100644 index 0000000..40512ee --- /dev/null +++ b/examples/django/sample_project/README.md @@ -0,0 +1,91 @@ +# pygeoapi Django integration + +## Overview + +Django is a Python web framework that encourages rapid development and clean, pragmatic design. + +The pygeoapi and Django integration can be visualized as follows: + +> HTTP request <--> Django (`pygeoapi/django_app.py`) <--> pygeoapi API (`pygeoapi/api.py`) + +This directory contains a [sample Django project](https://djangoproject.com) demonstrating how to +integrate pygeoapi into your Django application. + +In this document we create a sample Django project and use pygeoapi as a pluggable, embedded application. + +## Integration pygeoapi with a Django project + +To create your Django application from scratch follow these steps: + +```bash + +# create a project directory and create a fresh virtual environment +python3 -m venv env +cd env +source bin/activate + +# install dependencies +pip install Django pygeoapi + +# create a Django project +django-admin startproject sampleproject +cd sampleproject + +# set pygeoapi environment variables +export PYGEOAPI_CONFIG=`pwd`/pygeoapi-config.yml +export PYGEOAPI_OPENAPI=`pwd`/example-openapi.yml + +# Django: collect all static assets/files +python3 manage.py collectstatic + +# generate OpenAPI document +pygeoapi openapi generate $PYGEOAPI_CONFIG --output-file $PYGEOAPI_OPENAPI +``` + +Update `settings.py`: + +```python + +import os +from pygeoapi.django_app import config + +INSTALLED_APPS = [ + # other apps + .... + #pygeoapi app + 'pygeoapi' +] + +# Put following setting after STATIC_URL +STATIC_ROOT = os.path.join( BASE_DIR / 'assets') + +# Specific pygeoapi setting +PYGEOAPI_CONFIG = config() + ... +``` + +Update `urls.py` to run pygeoapi at e.g. `oapi` path + +```python + +from django.contrib import admin +from django.urls import path, include +from pygeoapi.django_pygeoapi import urls +urlpatterns = [ + path('admin/', admin.site.urls), + path('oapi/', include(urls)) # added here +] +``` + +Update `pygeoapi-config.yml` as follows: + +- set the `server.url` property according to your Django application URL (e.g. in this case the path set is `oapi`) +- set all data paths (e.g. `tests/data/ne_110m_lakes.geojson`) to match with the absolute path of the project directory + +Finally, run your Django project: + +```bash +python3 manage.py runserver`. Once server starts, head over to `localhost:8000/oapi` to see `pygeoapi` running. +``` + +At this point you can go your Django / pygeoapi project at `http://localhost:8000/oapi` diff --git a/pygeoapi/django_pygeoapi/sample_project/manage.py b/examples/django/sample_project/manage.py similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/manage.py rename to examples/django/sample_project/manage.py diff --git a/pygeoapi/django_pygeoapi/sample_project/pygeoapi-config.yml b/examples/django/sample_project/pygeoapi-config.yml similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/pygeoapi-config.yml rename to examples/django/sample_project/pygeoapi-config.yml diff --git a/pygeoapi/django_pygeoapi/__init__.py b/examples/django/sample_project/sample_project/__init__.py similarity index 100% rename from pygeoapi/django_pygeoapi/__init__.py rename to examples/django/sample_project/sample_project/__init__.py diff --git a/pygeoapi/django_pygeoapi/sample_project/sample_project/asgi.py b/examples/django/sample_project/sample_project/asgi.py similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/sample_project/asgi.py rename to examples/django/sample_project/sample_project/asgi.py diff --git a/pygeoapi/django_pygeoapi/sample_project/sample_project/settings.py b/examples/django/sample_project/sample_project/settings.py similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/sample_project/settings.py rename to examples/django/sample_project/sample_project/settings.py diff --git a/pygeoapi/django_pygeoapi/sample_project/sample_project/urls.py b/examples/django/sample_project/sample_project/urls.py similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/sample_project/urls.py rename to examples/django/sample_project/sample_project/urls.py diff --git a/pygeoapi/django_pygeoapi/sample_project/sample_project/wsgi.py b/examples/django/sample_project/sample_project/wsgi.py similarity index 100% rename from pygeoapi/django_pygeoapi/sample_project/sample_project/wsgi.py rename to examples/django/sample_project/sample_project/wsgi.py diff --git a/pygeoapi-openapi.yml b/pygeoapi-openapi.yml deleted file mode 100644 index e00b19d..0000000 --- a/pygeoapi-openapi.yml +++ /dev/null @@ -1,880 +0,0 @@ -components: - parameters: - f: - description: The optional f parameter indicates the output format which the - server shall provide as part of the response document. The default format - is GeoJSON. - explode: false - in: query - name: f - required: false - schema: - default: json - enum: - - json - - html - - jsonld - type: string - style: form - lang: - description: The optional lang parameter instructs the server return a response - in a certain language, if supported. If the language is not among the available - values, the Accept-Language header language will be used if it is supported. - If the header is missing, the default server language is used. Note that providers - may only support a single language (or often no language at all), that can - be different from the server language. Language strings can be written in - a complex (e.g. "fr-CA,fr;q=0.9,en-US;q=0.8,en;q=0.7"), simple (e.g. "de") - or locale-like (e.g. "de-CH" or "fr_BE") fashion. - in: query - name: lang - required: false - schema: - default: en-US - enum: - - en-US - - fr-CA - type: string - properties: - description: The properties that should be included for each feature. The parameter - value is a comma-separated list of property names. - explode: false - in: query - name: properties - required: false - schema: - items: - type: string - type: array - style: form - skipGeometry: - description: This option can be used to skip response geometries for each feature. - explode: false - in: query - name: skipGeometry - required: false - schema: - default: false - type: boolean - style: form - startindex: - description: The optional startindex parameter indicates the index within the - result set from which the server shall begin presenting results in the response - document. The first element has an index of 0 (default). - explode: false - in: query - name: startindex - required: false - schema: - default: 0 - minimum: 0 - type: integer - style: form - responses: - '200': - description: successful operation - Queryables: - content: - application/json: - schema: - $ref: '#/components/schemas/queryables' - description: successful queryables operation - default: - content: - application/json: - schema: - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/schemas/exception.yaml - description: Unexpected error - schemas: - queryable: - properties: - description: - description: a human-readable narrative describing the queryable - type: string - language: - default: - - en - description: the language used for the title and description - type: string - queryable: - description: the token that may be used in a CQL predicate - type: string - title: - description: a human readable title for the queryable - type: string - type: - description: the data type of the queryable - type: string - type-ref: - description: a reference to the formal definition of the type - format: url - type: string - required: - - queryable - - type - type: object - queryables: - properties: - queryables: - items: - $ref: '#/components/schemas/queryable' - type: array - required: - - queryables - type: object -info: - contact: - email: you@example.org - name: Organization Name - url: https://pygeoapi.io - description: pygeoapi provides an API to geospatial data - license: - name: CC-BY 4.0 license - url: https://creativecommons.org/licenses/by/4.0/ - termsOfService: https://creativecommons.org/licenses/by/4.0/ - title: pygeoapi default instance - version: 0.13.dev0 - x-keywords: - - geospatial - - data - - api -openapi: 3.0.2 -paths: - /: - get: - description: Landing page - operationId: getLandingPage - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/LandingPage - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Landing page - tags: - - server - /collections: - get: - description: Collections - operationId: getCollections - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Collections - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Collections - tags: - - server - /collections/canada-metadata: - get: - description: Sample metadata records from open.canada.ca - operationId: describeCanada-metadataCollection - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Collection - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Open Canada sample data metadata - tags: - - canada-metadata - /collections/canada-metadata/items: - get: - description: Sample metadata records from open.canada.ca - operationId: getCanada-metadataFeatures - parameters: - - &id001 - description: The optional f parameter indicates the output format which the - server shall provide as part of the response document. The default format - is GeoJSON. - explode: false - in: query - name: f - required: false - schema: - default: json - enum: - - json - - html - - jsonld - - csv - type: string - style: form - - &id002 - description: The optional lang parameter instructs the server return a response - in a certain language, if supported. If the language is not among the available - values, the Accept-Language header language will be used if it is supported. - If the header is missing, the default server language is used. Note that - providers may only support a single language (or often no language at all), - that can be different from the server language. Language strings can be - written in a complex (e.g. "fr-CA,fr;q=0.9,en-US;q=0.8,en;q=0.7"), simple - (e.g. "de") or locale-like (e.g. "de-CH" or "fr_BE") fashion. - in: query - name: lang - required: false - schema: - default: en-US - enum: - - en-US - - fr-CA - type: string - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/bbox - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/limit - - description: The properties that should be included for each feature. The - parameter value is a comma-separated list of property names. - explode: false - in: query - name: properties - required: false - schema: - items: - enum: - - recordCreated - - recordUpdated - - type - - title - - description - - contactPoint - - associations - - externalId - - themes - - q - type: string - type: array - style: form - - $ref: '#/components/parameters/skipGeometry' - - $ref: https://raw.githubusercontent.com/opengeospatial/ogcapi-records/master/core/openapi/parameters/sortby.yaml - - $ref: '#/components/parameters/startindex' - - $ref: https://raw.githubusercontent.com/opengeospatial/ogcapi-records/master/core/openapi/parameters/q.yaml - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/datetime - - explode: false - in: query - name: recordCreated - required: false - schema: - type: string - style: form - - explode: false - in: query - name: recordUpdated - required: false - schema: - type: string - style: form - - explode: false - in: query - name: type - required: false - schema: - type: string - style: form - - explode: false - in: query - name: title - required: false - schema: - type: string - style: form - - explode: false - in: query - name: description - required: false - schema: - type: string - style: form - - explode: false - in: query - name: contactPoint - required: false - schema: - type: string - style: form - - explode: false - in: query - name: associations - required: false - schema: - type: string - style: form - - explode: false - in: query - name: externalId - required: false - schema: - type: string - style: form - - explode: false - in: query - name: themes - required: false - schema: - type: string - style: form - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Features - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Open Canada sample data items - tags: - - canada-metadata - /collections/canada-metadata/items/{featureId}: - get: - description: Sample metadata records from open.canada.ca - operationId: getCanada-metadataFeature - parameters: - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/featureId - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Feature - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Open Canada sample data item by id - tags: - - canada-metadata - /collections/canada-metadata/queryables: - get: - description: Sample metadata records from open.canada.ca - operationId: getCanada-metadataQueryables - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: '#/components/responses/Queryables' - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Open Canada sample data queryables - tags: - - canada-metadata - /collections/gdps-temperature: - get: - description: Global Deterministic Prediction System sample - operationId: describeGdps-temperatureCollection - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Collection - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Global Deterministic Prediction System sample metadata - tags: - - gdps-temperature - /collections/gdps-temperature/coverage: - get: - description: Global Deterministic Prediction System sample - operationId: getGdps-temperatureCoverage - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Features - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Global Deterministic Prediction System sample coverage - tags: - - gdps-temperature - /collections/gdps-temperature/coverage/domainset: - get: - description: Global Deterministic Prediction System sample - operationId: getGdps-temperatureCoverageDomainSet - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: https://raw.githubusercontent.com/tomkralidis/ogcapi-coverages-1/fix-cis/yaml-unresolved/schemas/cis_1.1/domainSet.yaml - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Global Deterministic Prediction System sample coverage domain set - tags: - - gdps-temperature - /collections/gdps-temperature/coverage/rangetype: - get: - description: Global Deterministic Prediction System sample - operationId: getGdps-temperatureCoverageRangeType - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: https://raw.githubusercontent.com/tomkralidis/ogcapi-coverages-1/fix-cis/yaml-unresolved/schemas/cis_1.1/rangeType.yaml - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Global Deterministic Prediction System sample coverage range type - tags: - - gdps-temperature - /collections/lakes: - get: - description: lakes of the world, public domain - operationId: describeLakesCollection - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Collection - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Large Lakes metadata - tags: - - lakes - /collections/lakes/items: - get: - description: lakes of the world, public domain - operationId: getLakesFeatures - parameters: - - *id001 - - *id002 - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/bbox - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/limit - - description: The properties that should be included for each feature. The - parameter value is a comma-separated list of property names. - explode: false - in: query - name: properties - required: false - schema: - items: - enum: - - id - - scalerank - - name - - name_alt - - admin - - featureclass - type: string - type: array - style: form - - $ref: '#/components/parameters/skipGeometry' - - $ref: https://raw.githubusercontent.com/opengeospatial/ogcapi-records/master/core/openapi/parameters/sortby.yaml - - $ref: '#/components/parameters/startindex' - - explode: false - in: query - name: id - required: false - schema: - type: string - style: form - - explode: false - in: query - name: scalerank - required: false - schema: - type: string - style: form - - explode: false - in: query - name: name - required: false - schema: - type: string - style: form - - explode: false - in: query - name: name_alt - required: false - schema: - type: string - style: form - - explode: false - in: query - name: admin - required: false - schema: - type: string - style: form - - explode: false - in: query - name: featureclass - required: false - schema: - type: string - style: form - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Features - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Large Lakes items - tags: - - lakes - /collections/lakes/items/{featureId}: - get: - description: lakes of the world, public domain - operationId: getLakesFeature - parameters: - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/featureId - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Feature - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Large Lakes item by id - tags: - - lakes - /collections/lakes/queryables: - get: - description: lakes of the world, public domain - operationId: getLakesQueryables - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: '#/components/responses/Queryables' - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Large Lakes queryables - tags: - - lakes - /collections/obs: - get: - description: My cool observations - operationId: describeObsCollection - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Collection - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Observations metadata - tags: - - obs - /collections/obs/items: - get: - description: My cool observations - operationId: getObsFeatures - parameters: - - *id001 - - *id002 - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/bbox - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/limit - - description: The properties that should be included for each feature. The - parameter value is a comma-separated list of property names. - explode: false - in: query - name: properties - required: false - schema: - items: - enum: - - id - - stn_id - - datetime - - value - - lat - - long - type: string - type: array - style: form - - $ref: '#/components/parameters/skipGeometry' - - $ref: https://raw.githubusercontent.com/opengeospatial/ogcapi-records/master/core/openapi/parameters/sortby.yaml - - $ref: '#/components/parameters/startindex' - - explode: false - in: query - name: id - required: false - schema: - type: string - style: form - - explode: false - in: query - name: stn_id - required: false - schema: - type: string - style: form - - explode: false - in: query - name: datetime - required: false - schema: - type: string - style: form - - explode: false - in: query - name: value - required: false - schema: - type: string - style: form - - explode: false - in: query - name: lat - required: false - schema: - type: string - style: form - - explode: false - in: query - name: long - required: false - schema: - type: string - style: form - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Features - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Observations items - tags: - - obs - /collections/obs/items/{featureId}: - get: - description: My cool observations - operationId: getObsFeature - parameters: - - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/parameters/featureId - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/Feature - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Observations item by id - tags: - - obs - /collections/obs/queryables: - get: - description: My cool observations - operationId: getObsQueryables - parameters: - - *id001 - - *id002 - responses: - '200': - $ref: '#/components/responses/Queryables' - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '404': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/NotFound - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: Get Observations queryables - tags: - - obs - /conformance: - get: - description: API conformance definition - operationId: getConformanceDeclaration - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ConformanceDeclaration - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - '500': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/ServerError - summary: API conformance definition - tags: - - server - /openapi: - get: - description: This document - operationId: getOpenapi - parameters: - - $ref: '#/components/parameters/f' - - $ref: '#/components/parameters/lang' - - description: UI to render the OpenAPI document - explode: false - in: query - name: ui - required: false - schema: - default: swagger - enum: - - swagger - - redoc - type: string - style: form - responses: - '200': - $ref: '#/components/responses/200' - '400': - $ref: http://schemas.opengis.net/ogcapi/features/part1/1.0/openapi/ogcapi-features-1.yaml#/components/responses/InvalidParameter - default: - $ref: '#/components/responses/default' - summary: This document - tags: - - server - /processes: - get: - description: Processes - operationId: getProcesses - parameters: - - $ref: '#/components/parameters/f' - responses: - '200': - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/responses/ProcessList.yaml - default: - $ref: '#/components/responses/default' - summary: Processes - tags: - - server - /processes/hello-world: - get: - description: An example process that takes a name as input, and echoes it back - as output. Intended to demonstrate a simple process with a single literal - input. - operationId: describeHello-worldProcess - parameters: - - $ref: '#/components/parameters/f' - responses: - '200': - $ref: '#/components/responses/200' - default: - $ref: '#/components/responses/default' - summary: Get process metadata - tags: - - hello-world - /processes/hello-world/execution: - post: - description: An example process that takes a name as input, and echoes it back - as output. Intended to demonstrate a simple process with a single literal - input. - operationId: executeHello-worldJob - requestBody: - content: - application/json: - example: - inputs: - message: An optional message. - name: World - schema: - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/schemas/execute.yaml - description: Mandatory execute request JSON - required: true - responses: - '200': - $ref: '#/components/responses/200' - '201': - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/responses/ExecuteAsync.yaml - '404': - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/responses/NotFound.yaml - '500': - $ref: http://schemas.opengis.net/ogcapi/processes/part1/1.0/openapi/responses/ServerError.yaml - default: - $ref: '#/components/responses/default' - summary: Process Hello World execution - tags: - - hello-world - /stac: - get: - description: SpatioTemporal Asset Catalog - operationId: getStacCatalog - parameters: [] - responses: - '200': - $ref: '#/components/responses/200' - default: - $ref: '#/components/responses/default' - summary: SpatioTemporal Asset Catalog - tags: - - stac -servers: -- description: pygeoapi provides an API to geospatial data - url: http://localhost:5000 -tags: -- description: pygeoapi provides an API to geospatial data - externalDocs: - description: information - url: https://example.org - name: server -- description: SpatioTemporal Asset Catalog - name: stac -- description: My cool observations - name: obs -- description: lakes of the world, public domain - name: lakes -- description: Global Deterministic Prediction System sample - name: gdps-temperature -- description: Sample metadata records from open.canada.ca - name: canada-metadata -- description: An example process that takes a name as input, and echoes it back as - output. Intended to demonstrate a simple process with a single literal input. - name: hello-world - diff --git a/pygeoapi/api.py b/pygeoapi/api.py index 35ca548..705dac3 100644 --- a/pygeoapi/api.py +++ b/pygeoapi/api.py @@ -311,7 +311,7 @@ class APIRequest: # Set data from Flask request api_req._data = request.data elif hasattr(request, 'body'): - if "django" in str(request.__class__): + if 'django' in str(request.__class__): # Set data from Django request api_req._data = request.body else: @@ -326,7 +326,7 @@ class APIRequest: loop = asyncio.get_event_loop() api_req._data = loop.run_until_complete(request.body()) except ModuleNotFoundError: - LOGGER.error("Module nest-asyncio not found") + LOGGER.error('Module nest-asyncio not found') return api_req @staticmethod diff --git a/pygeoapi/db.sqlite3 b/pygeoapi/db.sqlite3 deleted file mode 100644 index e69de29..0000000 diff --git a/pygeoapi/django_/__init__.py b/pygeoapi/django_/__init__.py new file mode 100644 index 0000000..455138b --- /dev/null +++ b/pygeoapi/django_/__init__.py @@ -0,0 +1,28 @@ +# ================================================================= +# +# Authors: Tom Kralidis +# +# 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. +# +# ================================================================= diff --git a/pygeoapi/django_/settings.py b/pygeoapi/django_/settings.py new file mode 100644 index 0000000..5a09742 --- /dev/null +++ b/pygeoapi/django_/settings.py @@ -0,0 +1,168 @@ +# ================================================================= +# +# 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. +# +# ================================================================= + +""" +pygeoapi Django settings + +Generated by 'django-admin startproject' using Django 2.2.18. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + +import os +# pygeoapi specific +from pygeoapi.django_app import config + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = ')#cqm2jfato)gk((nm#%r7h&#n&aqy00_21pavfp=l8)4%cegb' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'django_.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'django_.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': + 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', # noqa + }, + { + 'NAME': + 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': + 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': + 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, 'static') +] +STATIC_ROOT = os.path.join(BASE_DIR, 'assets') +STATIC_URL = '/static/' + +# pygeoapi specific +PYGEOAPI_CONFIG = config() diff --git a/pygeoapi/django_/urls.py b/pygeoapi/django_/urls.py new file mode 100644 index 0000000..a37de2b --- /dev/null +++ b/pygeoapi/django_/urls.py @@ -0,0 +1,185 @@ +# ================================================================= +# +# 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. +# +# ================================================================= + +"""django_ URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" + +from django.urls import ( + path, +) +from django.conf import settings +from django.conf.urls.static import static + +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/', + views.collection_coverage_domainset, + name='collection-coverage-domainset', + ), + path( + 'collections//coverage/rangetype/', + views.collection_coverage_rangetype, + name='collection-coverage-rangetype', + ), + path( + 'collections//tiles/', + views.collection_tiles, + name='collection-tiles', + ), + 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//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//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' + ), +] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/pygeoapi/django_pygeoapi/views.py b/pygeoapi/django_/views.py similarity index 76% rename from pygeoapi/django_pygeoapi/views.py rename to pygeoapi/django_/views.py index 70b4ad7..855a30e 100644 --- a/pygeoapi/django_pygeoapi/views.py +++ b/pygeoapi/django_/views.py @@ -1,3 +1,38 @@ +# ================================================================= +# +# 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 typing import Tuple, Dict, Mapping, Optional from django.conf import settings @@ -15,7 +50,7 @@ def landing_page(request: HttpRequest) -> HttpResponse: :returns: Django HTTP Response """ - response_ = _feed_response(request, "landing_page") + response_ = _feed_response(request, 'landing_page') response = _to_django_response(*response_) return response @@ -31,7 +66,7 @@ def openapi(request: HttpRequest) -> HttpResponse: """ openapi_config = get_oas(settings.PYGEOAPI_CONFIG) - response_ = _feed_response(request, "openapi", openapi_config) + response_ = _feed_response(request, 'openapi', openapi_config) response = _to_django_response(*response_) return response @@ -46,7 +81,7 @@ def conformance(request: HttpRequest) -> HttpResponse: :returns: Django HTTP Response """ - response_ = _feed_response(request, "conformance") + response_ = _feed_response(request, 'conformance') response = _to_django_response(*response_) return response @@ -65,7 +100,7 @@ def collections( :returns: Django HTTP Response """ - response_ = _feed_response(request, "describe_collections", collection_id) + response_ = _feed_response(request, 'describe_collections', collection_id) response = _to_django_response(*response_) return response @@ -85,7 +120,7 @@ def collection_queryables( """ response_ = _feed_response( - request, "get_collection_queryables", collection_id + request, 'get_collection_queryables', collection_id ) response = _to_django_response(*response_) @@ -107,7 +142,7 @@ def collection_items( response_ = _feed_response( request, - "get_collection_items", + 'get_collection_items', collection_id, ) response = _to_django_response(*response_) @@ -131,7 +166,7 @@ def collection_item( """ response_ = _feed_response( - request, "get_collection_item", collection_id, item_id + request, 'get_collection_item', collection_id, item_id ) response = _to_django_response(*response_) @@ -152,7 +187,7 @@ def collection_coverage( """ response_ = _feed_response( - request, "get_collection_coverage", collection_id + request, 'get_collection_coverage', collection_id ) response = _to_django_response(*response_) @@ -173,7 +208,7 @@ def collection_coverage_domainset( """ response_ = _feed_response( - request, "get_collection_coverage_domainset", collection_id + request, 'get_collection_coverage_domainset', collection_id ) response = _to_django_response(*response_) @@ -194,7 +229,7 @@ def collection_coverage_rangetype( """ response_ = _feed_response( - request, "get_collection_coverage_rangetype", collection_id + request, 'get_collection_coverage_rangetype', collection_id ) response = _to_django_response(*response_) @@ -214,7 +249,7 @@ def collection_tiles( :returns: Django HTTP response """ - response_ = _feed_response(request, "get_collection_tiles", collection_id) + response_ = _feed_response(request, 'get_collection_tiles', collection_id) response = _to_django_response(*response_) return response @@ -237,7 +272,7 @@ def collection_tiles_metadata( response_ = _feed_response( request, - "get_collection_tiles_metadata", + 'get_collection_tiles_metadata', collection_id, tileMatrixSetId, ) @@ -269,7 +304,7 @@ def collection_item_tiles( response_ = _feed_response( request, - "get_collection_tiles_metadata", + 'get_collection_tiles_metadata', collection_id, tileMatrixSetId, tileMatrix, @@ -294,7 +329,7 @@ def processes( :returns: Django HTTP response """ - response_ = _feed_response(request, "describe_processes", process_id) + response_ = _feed_response(request, 'describe_processes', process_id) response = _to_django_response(*response_) return response @@ -313,7 +348,7 @@ def jobs( :returns: Django HTTP response """ - response_ = _feed_response(request, "get_jobs", job_id) + response_ = _feed_response(request, 'get_jobs', job_id) response = _to_django_response(*response_) return response @@ -331,7 +366,7 @@ def job_results( :returns: Django HTTP response """ - response_ = _feed_response(request, "get_job_result", job_id) + response_ = _feed_response(request, 'get_job_result', job_id) response = _to_django_response(*response_) return response @@ -354,7 +389,7 @@ def job_results_resource( """ response_ = _feed_response( request, - "get_job_result_resource", + 'get_job_result_resource', job_id, resource ) @@ -380,7 +415,7 @@ def get_collection_edr_query( query_type = request.path.split('/')[-1] response_ = _feed_response( request, - "get_collection_edr_query", + 'get_collection_edr_query', collection_id, instance_id, query_type @@ -399,7 +434,7 @@ def stac_catalog_root(request: HttpRequest) -> HttpResponse: :returns: Django HTTP response """ - response_ = _feed_response(request, "get_stac_root") + response_ = _feed_response(request, 'get_stac_root') response = _to_django_response(*response_) return response @@ -418,7 +453,7 @@ def stac_catalog_path( :returns: Django HTTP response """ - response_ = _feed_response(request, "get_stac_path", path) + response_ = _feed_response(request, 'get_stac_path', path) response = _to_django_response(*response_) return response diff --git a/pygeoapi/django_/wsgi.py b/pygeoapi/django_/wsgi.py new file mode 100644 index 0000000..0e69bdf --- /dev/null +++ b/pygeoapi/django_/wsgi.py @@ -0,0 +1,51 @@ +# ================================================================= +# +# 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. +# +# ================================================================= + +""" +WSGI config for django_ project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_.settings') + +application = get_wsgi_application() diff --git a/pygeoapi/django_app.py b/pygeoapi/django_app.py index 69f1b0c..2b3d805 100644 --- a/pygeoapi/django_app.py +++ b/pygeoapi/django_app.py @@ -1,8 +1,41 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" +# ================================================================= +# +# 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. +# +# ================================================================= + import os -import sys from pathlib import Path +import sys def config(): @@ -24,16 +57,17 @@ def main(): from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" + 'Couldn\'t import Django. Are you sure it\'s installed and ' + 'available on your PYTHONPATH environment variable? Did you ' + 'forget to activate a virtual environment?' ) from exc CONFIG = config() - sys.argv = [str(django_app_path / "django_app.py"), - "runserver", - f"{CONFIG['server']['bind'].get('host')}:" - f"{CONFIG['server']['bind'].get('port')}"] + + bind = f"{CONFIG['server']['bind']['host']}:{CONFIG['server']['bind']['port']}" # noqa + + sys.argv = [str(django_app_path / 'django_app.py'), 'runserver', bind] + sys.path.append(str(django_app_path)) execute_from_command_line(sys.argv) diff --git a/pygeoapi/django_pygeoapi/sample_project/sample_project/__init__.py b/pygeoapi/django_pygeoapi/sample_project/sample_project/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygeoapi/django_pygeoapi/settings.py b/pygeoapi/django_pygeoapi/settings.py deleted file mode 100644 index 000ddca..0000000 --- a/pygeoapi/django_pygeoapi/settings.py +++ /dev/null @@ -1,133 +0,0 @@ -""" -Django settings for django_pygeoapi project. - -Generated by 'django-admin startproject' using Django 2.2.18. - -For more information on this file, see -https://docs.djangoproject.com/en/2.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/2.2/ref/settings/ -""" - -import os -# pygeoapi specific -from pygeoapi.django_app import config - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = ")#cqm2jfato)gk((nm#%r7h&#n&aqy00_21pavfp=l8)4%cegb" - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = [ - "django.contrib.admin", - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.messages", - "django.contrib.staticfiles", -] - -MIDDLEWARE = [ - "django.middleware.security.SecurityMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", -] - -ROOT_URLCONF = "django_pygeoapi.urls" - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], - "APP_DIRS": True, - "OPTIONS": { - "context_processors": [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - ], - }, - }, -] - -WSGI_APPLICATION = "django_pygeoapi.wsgi.application" - - -# Database -# https://docs.djangoproject.com/en/2.2/ref/settings/#databases - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(BASE_DIR, "db.sqlite3"), - } -} - - -# Password validation -# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": - "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # noqa - }, - { - "NAME": - "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": - "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": - "django.contrib.auth.password_validation.NumericPasswordValidator", - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/2.2/topics/i18n/ - -LANGUAGE_CODE = "en-us" - -TIME_ZONE = "UTC" - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/2.2/howto/static-files/ - -STATICFILES_DIRS = [ - os.path.join(BASE_DIR, "static") -] -STATIC_ROOT = os.path.join(BASE_DIR, "assets") -STATIC_URL = "/static/" - -# pygeoapi specific -PYGEOAPI_CONFIG = config() diff --git a/pygeoapi/django_pygeoapi/urls.py b/pygeoapi/django_pygeoapi/urls.py deleted file mode 100644 index 29c1e3f..0000000 --- a/pygeoapi/django_pygeoapi/urls.py +++ /dev/null @@ -1,150 +0,0 @@ -"""django_pygeoapi URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/2.2/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" - -from django.urls import ( - path, -) -from django.conf import settings -from django.conf.urls.static import static - -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/", - views.collection_coverage_domainset, - name="collection-coverage-domainset", - ), - path( - "collections//coverage/rangetype/", - views.collection_coverage_rangetype, - name="collection-coverage-rangetype", - ), - path( - "collections//tiles/", - views.collection_tiles, - name="collection-tiles", - ), - 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//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//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" - ), -] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/pygeoapi/django_pygeoapi/wsgi.py b/pygeoapi/django_pygeoapi/wsgi.py deleted file mode 100644 index 3407543..0000000 --- a/pygeoapi/django_pygeoapi/wsgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -WSGI config for django_pygeoapi project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_pygeoapi.settings") - -application = get_wsgi_application() diff --git a/requirements-django.txt b/requirements-django.txt index efb1e80..ddf5380 100644 --- a/requirements-django.txt +++ b/requirements-django.txt @@ -1,2 +1,2 @@ -Django <= 4, > 3 +Django <= 4, > 3.2.12 pydantic