update Django integration (#971)

* update Django integration

* address PR comments
This commit is contained in:
Tom Kralidis
2022-08-30 16:41:48 -04:00
committed by GitHub
parent 98bfdd5cf2
commit 199a1fc612
27 changed files with 649 additions and 1320 deletions
+1 -2
View File
@@ -114,5 +114,4 @@ ENV/
*.code-workspace
.DS_Store
pygeoapi/django_pygeoapi/sample_project/db.sqlite3
examples/django/sample_project/db.sqlite3
@@ -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 <https://github.com/xmunoz/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 <https://dev.socrata.com/docs/app-tokens.html>` to Socrata.
an `app token <https://dev.socrata.com/docs/app-tokens.html>` to Socrata.
.. code-block:: yaml
-103
View File
@@ -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 <https://www.djangoproject.com/>`_ 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.
-1
View File
@@ -23,7 +23,6 @@ pygeoapi |release| documentation
configuration
administration
running
downstream
running-with-docker
tour
openapi
+21
View File
@@ -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
+91
View File
@@ -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`
-880
View File
@@ -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
+2 -2
View File
@@ -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
View File
+28
View File
@@ -0,0 +1,28 @@
# =================================================================
#
# Authors: Tom Kralidis <tomkralidis@gmail.com>
#
# 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.
#
# =================================================================
+168
View File
@@ -0,0 +1,168 @@
# =================================================================
#
# Authors: Francesco Bartoli <francesco.bartoli@geobeyond.it>
# Luca Delucchi <lucadeluge@gmail.com>
# Krishna Lodha <krishnaglodha@gmail.com>
# Tom Kralidis <tomkralidis@gmail.com>
#
# 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()
+185
View File
@@ -0,0 +1,185 @@
# =================================================================
#
# Authors: Francesco Bartoli <francesco.bartoli@geobeyond.it>
# Luca Delucchi <lucadeluge@gmail.com>
# Krishna Lodha <krishnaglodha@gmail.com>
# Tom Kralidis <tomkralidis@gmail.com>
#
# 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/<str:collection_id>',
views.collections,
name='collection-detail',
),
path(
'collections/<str:collection_id>/queryables/',
views.collection_queryables,
name='collection-queryables',
),
path(
'collections/<str:collection_id>/items/',
views.collection_items,
name='collection-items',
),
path(
'collections/<str:collection_id>/items/<str:item_id>',
views.collection_item,
name='collection-item',
),
path(
'collections/<str:collection_id>/coverage/',
views.collection_coverage,
name='collection-coverage',
),
path(
'collections/<str:collection_id>/coverage/domainset/',
views.collection_coverage_domainset,
name='collection-coverage-domainset',
),
path(
'collections/<str:collection_id>/coverage/rangetype/',
views.collection_coverage_rangetype,
name='collection-coverage-rangetype',
),
path(
'collections/<str:collection_id>/tiles/',
views.collection_tiles,
name='collection-tiles',
),
path(
'collections/<str:collection_id>/tiles/<str:tileMatrixSetId>/metadata',
views.collection_tiles_metadata,
name='collection-tiles-metadata',
),
path(
'collections/<str:collection_id>/tiles/\
<str:tileMatrixSetId>/<str:tile_matrix>/<str:tileRow>/<str:tileCol>',
views.collection_item_tiles,
name='collection-item-tiles',
),
path(
'collections/<str:collection_id>/position',
views.get_collection_edr_query,
name='collection-edr-position',
),
path(
'collections/<str:collection_id>/area',
views.get_collection_edr_query,
name='collection-edr-area',
),
path(
'collections/<str:collection_id>/cube',
views.get_collection_edr_query,
name='collection-edr-cube',
),
path(
'collections/<str:collection_id>/trajectory',
views.get_collection_edr_query,
name='collection-edr-trajectory',
),
path(
'collections/<str:collection_id>/corridor',
views.get_collection_edr_query,
name='collection-edr-corridor',
),
path(
'collections/<str:collection_id>/instances/<str:instance_id>/position',
views.get_collection_edr_query,
name='collection-edr-instance-position',
),
path(
'collections/<str:collection_id>/instances/<str:instance_id>/area',
views.get_collection_edr_query,
name='collection-edr-instance-area',
),
path(
'collections/<str:collection_id>/instances/<str:instance_id>/cube',
views.get_collection_edr_query,
name='collection-edr-instance-cube',
),
path(
'collections/<str:collection_id>/instances/<str:instance_id>/trajectory', # noqa
views.get_collection_edr_query,
name='collection-edr-instance-trajectory',
),
path(
'collections/<str:collection_id>/instances/<str:instance_id>/corridor',
views.get_collection_edr_query,
name='collection-edr-instance-corridor',
),
path('processes/', views.processes, name='processes'),
path('processes/<str:process_id>', views.processes, name='process-detail'),
path('jobs/', views.jobs, name='jobs'),
path('jobs/<str:job_id>', views.jobs, name='job'),
path(
'jobs/<str:job_id>/results/',
views.job_results,
name='job-results',
),
path(
'jobs/<str:job_id>/results/<str:resource>',
views.job_results_resource,
name='job-results-resource',
),
path('stac/', views.stac_catalog_root, name='stac-catalog-root'),
path('stac/<str:path>', 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)
@@ -1,3 +1,38 @@
# =================================================================
#
# Authors: Francesco Bartoli <francesco.bartoli@geobeyond.it>
# Luca Delucchi <lucadeluge@gmail.com>
# Krishna Lodha <krishnaglodha@gmail.com>
# Tom Kralidis <tomkralidis@gmail.com>
#
# 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
+51
View File
@@ -0,0 +1,51 @@
# =================================================================
#
# Authors: Francesco Bartoli <francesco.bartoli@geobeyond.it>
# Luca Delucchi <lucadeluge@gmail.com>
# Krishna Lodha <krishnaglodha@gmail.com>
# Tom Kralidis <tomkralidis@gmail.com>
#
# 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()
+44 -10
View File
@@ -1,8 +1,41 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
# =================================================================
#
# Authors: Francesco Bartoli <francesco.bartoli@geobeyond.it>
# Luca Delucchi <lucadeluge@gmail.com>
# Krishna Lodha <krishnaglodha@gmail.com>
# Tom Kralidis <tomkralidis@gmail.com>
#
# 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)
-133
View File
@@ -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()
-150
View File
@@ -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/<str:collection_id>",
views.collections,
name="collection-detail",
),
path(
"collections/<str:collection_id>/queryables/",
views.collection_queryables,
name="collection-queryables",
),
path(
"collections/<str:collection_id>/items/",
views.collection_items,
name="collection-items",
),
path(
"collections/<str:collection_id>/items/<str:item_id>",
views.collection_item,
name="collection-item",
),
path(
"collections/<str:collection_id>/coverage/",
views.collection_coverage,
name="collection-coverage",
),
path(
"collections/<str:collection_id>/coverage/domainset/",
views.collection_coverage_domainset,
name="collection-coverage-domainset",
),
path(
"collections/<str:collection_id>/coverage/rangetype/",
views.collection_coverage_rangetype,
name="collection-coverage-rangetype",
),
path(
"collections/<str:collection_id>/tiles/",
views.collection_tiles,
name="collection-tiles",
),
path(
"collections/<str:collection_id>/tiles/<str:tileMatrixSetId>/metadata",
views.collection_tiles_metadata,
name="collection-tiles-metadata",
),
path(
"collections/<str:collection_id>/tiles/\
<str:tileMatrixSetId>/<str:tile_matrix>/<str:tileRow>/<str:tileCol>",
views.collection_item_tiles,
name="collection-item-tiles",
),
path(
"collections/<str:collection_id>/position",
views.get_collection_edr_query,
name="collection-edr-position",
),
path(
"collections/<str:collection_id>/area",
views.get_collection_edr_query,
name="collection-edr-area",
),
path(
"collections/<str:collection_id>/cube",
views.get_collection_edr_query,
name="collection-edr-cube",
),
path(
"collections/<str:collection_id>/trajectory",
views.get_collection_edr_query,
name="collection-edr-trajectory",
),
path(
"collections/<str:collection_id>/corridor",
views.get_collection_edr_query,
name="collection-edr-corridor",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/position",
views.get_collection_edr_query,
name="collection-edr-instance-position",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/area",
views.get_collection_edr_query,
name="collection-edr-instance-area",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/cube",
views.get_collection_edr_query,
name="collection-edr-instance-cube",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/trajectory", # noqa
views.get_collection_edr_query,
name="collection-edr-instance-trajectory",
),
path(
"collections/<str:collection_id>/instances/<str:instance_id>/corridor",
views.get_collection_edr_query,
name="collection-edr-instance-corridor",
),
path("processes/", views.processes, name="processes"),
path("processes/<str:process_id>", views.processes, name="process-detail"),
path("jobs/", views.jobs, name="jobs"),
path("jobs/<str:job_id>", views.jobs, name="job"),
path(
"jobs/<str:job_id>/results/",
views.job_results,
name="job-results",
),
path(
"jobs/<str:job_id>/results/<str:resource>",
views.job_results_resource,
name="job-results-resource",
),
path("stac/", views.stac_catalog_root, name="stac-catalog-root"),
path("stac/<str:path>", 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)
-16
View File
@@ -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()
+1 -1
View File
@@ -1,2 +1,2 @@
Django <= 4, > 3
Django <= 4, > 3.2.12
pydantic