Add support for the django framework (#630)
* Add initial support with a django skeleton project * Start the django server from pygeoapi configuration and push to settings * Add views to django routes * fixed flake8 problems * added jobs endpoints * added EDR endpoints * renamed jobs endpoints and functions * fixed flake8 * Bump django version to support 3 and 4 * Fix api request instance Fix api request instance * fixed stac catalog path request * fixed problem with static * get parameters from django requests * Add sample project for django application * Fix flake8 errors * added documentation for Django downstream project Co-authored-by: Luca Delucchi <lucadeluge@gmail.com> Co-authored-by: Krishna Lodha <krishnaglodha@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6faad638c2
commit
98bfdd5cf2
@@ -114,3 +114,5 @@ ENV/
|
||||
*.code-workspace
|
||||
|
||||
.DS_Store
|
||||
|
||||
pygeoapi/django_pygeoapi/sample_project/db.sqlite3
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
.. _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.
|
||||
@@ -23,6 +23,7 @@ pygeoapi |release| documentation
|
||||
configuration
|
||||
administration
|
||||
running
|
||||
downstream
|
||||
running-with-docker
|
||||
tour
|
||||
openapi
|
||||
|
||||
@@ -0,0 +1,880 @@
|
||||
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
|
||||
|
||||
@@ -43,6 +43,7 @@ def cli():
|
||||
@cli.command()
|
||||
@click.option('--flask', 'server', flag_value="flask", default=True)
|
||||
@click.option('--starlette', 'server', flag_value="starlette")
|
||||
@click.option('--django', 'server', flag_value="django")
|
||||
@click.pass_context
|
||||
def serve(ctx, server):
|
||||
"""Run the server with different daemon type (--flask is the default)"""
|
||||
@@ -55,8 +56,11 @@ def serve(ctx, server):
|
||||
from pygeoapi.starlette_app import serve as serve_starlette
|
||||
ctx.forward(serve_starlette)
|
||||
ctx.invoke(serve_starlette)
|
||||
elif server == "django":
|
||||
from pygeoapi.django_app import main as serve_django
|
||||
ctx.invoke(serve_django)
|
||||
else:
|
||||
raise click.ClickException('--flask/--starlette is required')
|
||||
raise click.ClickException('--flask/--starlette/--django is required')
|
||||
|
||||
|
||||
cli.add_command(config)
|
||||
|
||||
+24
-11
@@ -276,6 +276,8 @@ class APIRequest:
|
||||
self._path_info = request.scope['path'].strip('/')
|
||||
elif hasattr(request.headers, 'environ'):
|
||||
self._path_info = request.headers.environ['PATH_INFO'].strip('/')
|
||||
elif hasattr(request, 'path_info'):
|
||||
self._path_info = request.path_info
|
||||
|
||||
# Extract locale from params or headers
|
||||
self._raw_locale, self._locale = self._get_locale(request.headers,
|
||||
@@ -309,17 +311,22 @@ class APIRequest:
|
||||
# Set data from Flask request
|
||||
api_req._data = request.data
|
||||
elif hasattr(request, 'body'):
|
||||
try:
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
# Set data from Starlette request after async
|
||||
# coroutine completion
|
||||
# TODO: this now blocks, but once Flask v2 with async support
|
||||
# has been implemented, with_data() can become async too
|
||||
loop = asyncio.get_event_loop()
|
||||
api_req._data = loop.run_until_complete(request.body())
|
||||
except ModuleNotFoundError:
|
||||
LOGGER.error("Module nest-asyncio not found")
|
||||
if "django" in str(request.__class__):
|
||||
# Set data from Django request
|
||||
api_req._data = request.body
|
||||
else:
|
||||
try:
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
# Set data from Starlette request after async
|
||||
# coroutine completion
|
||||
# TODO:
|
||||
# this now blocks, but once Flask v2 with async support
|
||||
# has been implemented, with_data() can become async too
|
||||
loop = asyncio.get_event_loop()
|
||||
api_req._data = loop.run_until_complete(request.body())
|
||||
except ModuleNotFoundError:
|
||||
LOGGER.error("Module nest-asyncio not found")
|
||||
return api_req
|
||||
|
||||
@staticmethod
|
||||
@@ -337,6 +344,12 @@ class APIRequest:
|
||||
elif hasattr(request, 'query_params'):
|
||||
# Return ImmutableMultiDict from Starlette request
|
||||
return request.query_params
|
||||
elif hasattr(request, 'GET'):
|
||||
# Return QueryDict from Django GET request
|
||||
return request.GET
|
||||
elif hasattr(request, 'POST'):
|
||||
# Return QueryDict from Django GET request
|
||||
return request.POST
|
||||
LOGGER.debug('No query parameters found')
|
||||
return {}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def config():
|
||||
from pygeoapi.util import yaml_load
|
||||
|
||||
if not os.environ.get('PYGEOAPI_CONFIG'):
|
||||
raise RuntimeError('PYGEOAPI_CONFIG environment variable not set')
|
||||
|
||||
with open(os.environ.get('PYGEOAPI_CONFIG'), encoding='utf8') as fh:
|
||||
CONFIG = yaml_load(fh)
|
||||
|
||||
return CONFIG
|
||||
|
||||
|
||||
def main():
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_pygeoapi.settings')
|
||||
django_app_path = Path(os.path.dirname(__file__))
|
||||
try:
|
||||
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?"
|
||||
) 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')}"]
|
||||
sys.path.append(str(django_app_path))
|
||||
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample_project.settings')
|
||||
try:
|
||||
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?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,275 @@
|
||||
# =================================================================
|
||||
#
|
||||
# Authors: Tom Kralidis <tomkralidis@gmail.com>
|
||||
#
|
||||
# Copyright (c) 2020 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.
|
||||
#
|
||||
# =================================================================
|
||||
|
||||
server:
|
||||
bind:
|
||||
host: 0.0.0.0
|
||||
port: 8000
|
||||
url: http://localhost:8000/sample-project
|
||||
mimetype: application/json; charset=UTF-8
|
||||
encoding: utf-8
|
||||
gzip: false
|
||||
languages:
|
||||
# First language is the default language
|
||||
- en-US
|
||||
- fr-CA
|
||||
# cors: true
|
||||
pretty_print: true
|
||||
limit: 10
|
||||
# templates:
|
||||
# path: /path/to/Jinja2/templates
|
||||
# static: /path/to/static/folder # css/js/img
|
||||
map:
|
||||
url: https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
||||
attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
|
||||
# manager:
|
||||
# name: TinyDB
|
||||
# connection: /tmp/pygeoapi-process-manager.db
|
||||
# output_dir: /tmp/
|
||||
# ogc_schemas_location: /opt/schemas.opengis.net
|
||||
|
||||
logging:
|
||||
level: ERROR
|
||||
#logfile: /tmp/pygeoapi.log
|
||||
|
||||
metadata:
|
||||
identification:
|
||||
title:
|
||||
en: pygeoapi default instance
|
||||
fr: instance par défaut de pygeoapi
|
||||
description:
|
||||
en: pygeoapi provides an API to geospatial data
|
||||
fr: pygeoapi fournit une API aux données géospatiales
|
||||
keywords:
|
||||
en:
|
||||
- geospatial
|
||||
- data
|
||||
- api
|
||||
fr:
|
||||
- géospatiale
|
||||
- données
|
||||
- api
|
||||
keywords_type: theme
|
||||
terms_of_service: https://creativecommons.org/licenses/by/4.0/
|
||||
url: https://example.org
|
||||
license:
|
||||
name: CC-BY 4.0 license
|
||||
url: https://creativecommons.org/licenses/by/4.0/
|
||||
provider:
|
||||
name: Organization Name
|
||||
url: https://pygeoapi.io
|
||||
contact:
|
||||
name: Lastname, Firstname
|
||||
position: Position Title
|
||||
address: Mailing Address
|
||||
city: City
|
||||
stateorprovince: Administrative Area
|
||||
postalcode: Zip or Postal Code
|
||||
country: Country
|
||||
phone: +xx-xxx-xxx-xxxx
|
||||
fax: +xx-xxx-xxx-xxxx
|
||||
email: you@example.org
|
||||
url: Contact URL
|
||||
hours: Mo-Fr 08:00-17:00
|
||||
instructions: During hours of service. Off on weekends.
|
||||
role: pointOfContact
|
||||
|
||||
resources:
|
||||
obs:
|
||||
type: collection
|
||||
title: Observations
|
||||
description: My cool observations
|
||||
keywords:
|
||||
- observations
|
||||
- monitoring
|
||||
context:
|
||||
- datetime: https://schema.org/DateTime
|
||||
- vocab: https://example.com/vocab#
|
||||
stn_id: "vocab:stn_id"
|
||||
value: "vocab:value"
|
||||
links:
|
||||
- type: text/csv
|
||||
rel: canonical
|
||||
title: data
|
||||
href: https://github.com/mapserver/mapserver/blob/branch-7-0/msautotest/wxs/data/obs.csv
|
||||
hreflang: en-US
|
||||
- type: text/csv
|
||||
rel: alternate
|
||||
title: data
|
||||
href: https://raw.githubusercontent.com/mapserver/mapserver/branch-7-0/msautotest/wxs/data/obs.csv
|
||||
hreflang: en-US
|
||||
extents:
|
||||
spatial:
|
||||
bbox: [-180,-90,180,90]
|
||||
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
|
||||
temporal:
|
||||
begin: 2000-10-30T18:24:39Z
|
||||
end: 2007-10-30T08:57:29Z
|
||||
providers:
|
||||
- type: feature
|
||||
name: CSV
|
||||
data: tests/data/obs.csv
|
||||
id_field: id
|
||||
geometry:
|
||||
x_field: long
|
||||
y_field: lat
|
||||
|
||||
lakes:
|
||||
type: collection
|
||||
title:
|
||||
en: Large Lakes
|
||||
fr: Grands Lacs
|
||||
description:
|
||||
en: lakes of the world, public domain
|
||||
fr: lacs du monde, domaine public
|
||||
keywords:
|
||||
en:
|
||||
- lakes
|
||||
- water bodies
|
||||
fr:
|
||||
- lacs
|
||||
- plans d'eau
|
||||
links:
|
||||
- type: text/html
|
||||
rel: canonical
|
||||
title: information
|
||||
href: http://www.naturalearthdata.com/
|
||||
hreflang: en-US
|
||||
extents:
|
||||
spatial:
|
||||
bbox: [-180,-90,180,90]
|
||||
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
|
||||
temporal:
|
||||
begin: 2011-11-11T11:11:11Z
|
||||
end: null # or empty (either means open ended)
|
||||
providers:
|
||||
- type: feature
|
||||
name: GeoJSON
|
||||
data: tests/data/ne_110m_lakes.geojson
|
||||
id_field: id
|
||||
title_field: name
|
||||
|
||||
gdps-temperature:
|
||||
type: collection
|
||||
title: Global Deterministic Prediction System sample
|
||||
description: Global Deterministic Prediction System sample
|
||||
keywords:
|
||||
- gdps
|
||||
- global
|
||||
extents:
|
||||
spatial:
|
||||
bbox: [-180,-90,180,90]
|
||||
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
|
||||
links:
|
||||
- type: text/html
|
||||
rel: canonical
|
||||
title: information
|
||||
href: https://eccc-msc.github.io/open-data/msc-data/nwp_gdps/readme_gdps_en
|
||||
hreflang: en-CA
|
||||
providers:
|
||||
- type: coverage
|
||||
name: rasterio
|
||||
data: tests/data/CMC_glb_TMP_TGL_2_latlon.15x.15_2020081000_P000.grib2
|
||||
options:
|
||||
DATA_ENCODING: COMPLEX_PACKING
|
||||
format:
|
||||
name: GRIB
|
||||
mimetype: application/x-grib2
|
||||
|
||||
test-data:
|
||||
type: stac-collection
|
||||
title: pygeoapi test data
|
||||
description: pygeoapi test data
|
||||
keywords:
|
||||
- poi
|
||||
- portugal
|
||||
links:
|
||||
- type: text/html
|
||||
rel: canonical
|
||||
title: information
|
||||
href: https://github.com/geopython/pygeoapi/tree/master/tests/data
|
||||
hreflang: en-US
|
||||
extents:
|
||||
spatial:
|
||||
bbox: [-180,-90,180,90]
|
||||
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
|
||||
providers:
|
||||
- type: stac
|
||||
name: FileSystem
|
||||
data: tests/data
|
||||
file_types:
|
||||
- .gpkg
|
||||
- .sqlite
|
||||
- .csv
|
||||
- .grib2
|
||||
- .tif
|
||||
- .shp
|
||||
|
||||
canada-metadata:
|
||||
type: collection
|
||||
title:
|
||||
en: Open Canada sample data
|
||||
fr: Exemple de donn\u00e9es Canada Ouvert
|
||||
description:
|
||||
en: Sample metadata records from open.canada.ca
|
||||
fr: Exemples d'enregistrements de m\u00e9tadonn\u00e9es sur ouvert.canada.ca
|
||||
keywords:
|
||||
en:
|
||||
- canada
|
||||
- open data
|
||||
fr:
|
||||
- canada
|
||||
- donn\u00e9es ouvertes
|
||||
links:
|
||||
- type: text/html
|
||||
rel: canonical
|
||||
title: information
|
||||
href: https://open.canada.ca/en/open-data
|
||||
hreflang: en-CA
|
||||
- type: text/html
|
||||
rel: alternate
|
||||
title: informations
|
||||
href: https://ouvert.canada.ca/fr/donnees-ouvertes
|
||||
hreflang: fr-CA
|
||||
extents:
|
||||
spatial:
|
||||
bbox: [-180,-90,180,90]
|
||||
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
|
||||
providers:
|
||||
- type: record
|
||||
name: TinyDBCatalogue
|
||||
data: tests/data/open.canada.ca/sample-records.tinydb
|
||||
id_field: externalId
|
||||
time_field: recordCreated
|
||||
title_field: title
|
||||
|
||||
hello-world:
|
||||
type: process
|
||||
processor:
|
||||
name: HelloWorld
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for sample_project project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample_project.settings')
|
||||
|
||||
application = get_asgi_application()
|
||||
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
Django settings for sample_project project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 3.2.12.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/3.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/3.2/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from pygeoapi.django_app import config
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-um1sc7k4ovzdhp2r3kwz#%ta-l+kn$grk&9#7_(a0f)q$6u_ra' # noqa
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
|
||||
|
||||
|
||||
# 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 = 'sample_project.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 = 'sample_project.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', # noqa
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', # noqa
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # noqa
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', # noqa
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/3.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/3.2/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# pygeoapi
|
||||
PYGEOAPI_CONFIG = config()
|
||||
@@ -0,0 +1,24 @@
|
||||
"""sample_project URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/3.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.contrib import admin
|
||||
from django.urls import path, include
|
||||
|
||||
from pygeoapi.django_pygeoapi import urls as pygeoapi_urls
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('sample-project/', include(pygeoapi_urls)),
|
||||
]
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for sample_project 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/3.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sample_project.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
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()
|
||||
@@ -0,0 +1,150 @@
|
||||
"""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)
|
||||
@@ -0,0 +1,449 @@
|
||||
"""Integration module for Django"""
|
||||
from typing import Tuple, Dict, Mapping, Optional
|
||||
from django.conf import settings
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from pygeoapi.api import API
|
||||
from pygeoapi.openapi import get_oas
|
||||
|
||||
|
||||
def landing_page(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
OGC API landing page endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
|
||||
:returns: Django HTTP Response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "landing_page")
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def openapi(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
OpenAPI endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
|
||||
:returns: Django HTTP Response
|
||||
"""
|
||||
|
||||
openapi_config = get_oas(settings.PYGEOAPI_CONFIG)
|
||||
response_ = _feed_response(request, "openapi", openapi_config)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def conformance(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
OGC API conformance endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
|
||||
:returns: Django HTTP Response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "conformance")
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collections(
|
||||
request: HttpRequest,
|
||||
collection_id: Optional[str] = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API collections endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP Response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "describe_collections", collection_id)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_queryables(
|
||||
request: HttpRequest,
|
||||
collection_id: Optional[str] = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API collections queryables endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP Response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request, "get_collection_queryables", collection_id
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_items(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API collections items endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request,
|
||||
"get_collection_items",
|
||||
collection_id,
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_item(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
item_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API collections items endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
:param item_id: item identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request, "get_collection_item", collection_id, item_id
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_coverage(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Coverages coverage endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request, "get_collection_coverage", collection_id
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_coverage_domainset(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Coverages coverage domainset endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request, "get_collection_coverage_domainset", collection_id
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_coverage_rangetype(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Coverages coverage rangetype endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request, "get_collection_coverage_rangetype", collection_id
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_tiles(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Tiles collection tiles endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "get_collection_tiles", collection_id)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_tiles_metadata(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
tileMatrixSetId: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Tiles collection tiles metadata endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
:param tileMatrixSetId: identifier of tile matrix set
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request,
|
||||
"get_collection_tiles_metadata",
|
||||
collection_id,
|
||||
tileMatrixSetId,
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def collection_item_tiles(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
tileMatrixSetId: str,
|
||||
tileMatrix: str,
|
||||
tileRow: str,
|
||||
tileCol: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Tiles collection tiles data endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param collection_id: collection identifier
|
||||
:param tileMatrixSetId: identifier of tile matrix set
|
||||
:param tileMatrix: identifier of {z} matrix index
|
||||
:param tileRow: identifier of {y} matrix index
|
||||
:param tileCol: identifier of {x} matrix index
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(
|
||||
request,
|
||||
"get_collection_tiles_metadata",
|
||||
collection_id,
|
||||
tileMatrixSetId,
|
||||
tileMatrix,
|
||||
tileRow,
|
||||
tileCol,
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def processes(
|
||||
request: HttpRequest,
|
||||
process_id: Optional[str] = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Processes description endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param process_id: process identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "describe_processes", process_id)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def jobs(
|
||||
request: HttpRequest,
|
||||
job_id: Optional[str] = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Jobs endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param process_id: process identifier
|
||||
:param job_id: job identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
response_ = _feed_response(request, "get_jobs", job_id)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def job_results(
|
||||
request: HttpRequest,
|
||||
job_id: Optional[str] = None,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Job result endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param job_id: job identifier
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
response_ = _feed_response(request, "get_job_result", job_id)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def job_results_resource(
|
||||
request: HttpRequest,
|
||||
process_id: str,
|
||||
job_id: str,
|
||||
resource: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - Job result resource endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param job_id: job identifier
|
||||
:param resource: job resource
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
response_ = _feed_response(
|
||||
request,
|
||||
"get_job_result_resource",
|
||||
job_id,
|
||||
resource
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def get_collection_edr_query(
|
||||
request: HttpRequest,
|
||||
collection_id: str,
|
||||
instance_id: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
OGC API - EDR endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param job_id: job identifier
|
||||
:param resource: job resource
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
query_type = request.path.split('/')[-1]
|
||||
response_ = _feed_response(
|
||||
request,
|
||||
"get_collection_edr_query",
|
||||
collection_id,
|
||||
instance_id,
|
||||
query_type
|
||||
)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def stac_catalog_root(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
STAC root endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "get_stac_root")
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def stac_catalog_path(
|
||||
request: HttpRequest,
|
||||
path: str,
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
STAC path endpoint
|
||||
|
||||
:request Django HTTP Request
|
||||
:param path: path
|
||||
|
||||
:returns: Django HTTP response
|
||||
"""
|
||||
|
||||
response_ = _feed_response(request, "get_stac_path", path)
|
||||
response = _to_django_response(*response_)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def stac_catalog_search(request: HttpRequest) -> HttpResponse:
|
||||
pass
|
||||
|
||||
|
||||
def _feed_response(
|
||||
request: HttpRequest, api_definition: str, *args, **kwargs
|
||||
) -> Tuple[Dict, int, str]:
|
||||
"""Use pygeoapi api to process the input request"""
|
||||
api_ = API(settings.PYGEOAPI_CONFIG)
|
||||
api = getattr(api_, api_definition)
|
||||
return api(request, *args, **kwargs)
|
||||
|
||||
|
||||
def _to_django_response(
|
||||
headers: Mapping,
|
||||
status_code: int,
|
||||
content: str,
|
||||
) -> HttpResponse:
|
||||
"""Convert API payload to a django response"""
|
||||
response = HttpResponse(content, status=status_code)
|
||||
for key, value in headers.items():
|
||||
response[key] = value
|
||||
return response
|
||||
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
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()
|
||||
@@ -0,0 +1,2 @@
|
||||
Django <= 4, > 3
|
||||
pydantic
|
||||
Reference in New Issue
Block a user