Skip to content

Commit

Permalink
Updated configs for pygeoapi 0.18.0 and added Docker setup
Browse files Browse the repository at this point in the history
- unpin pygeoapi version; use master
- Updated README with docker setup
- Add docker-compose setup
  • Loading branch information
Kevin Ngai committed Oct 21, 2024
1 parent b75a345 commit 9a3ec64
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 5 deletions.
86 changes: 86 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
###################################################################
#
# Author: Kevin Ngai <[email protected]>
#
# Copyright (c) 2024 Kevin Ngai
#
# 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.
#
###################################################################

# Development stage
FROM ubuntu:jammy AS develop-stage

# Default environment variables if none are passed in
ARG PYGEOAPI_GITREPO=https://github.com/geopython/pygeoapi.git
ARG WOUDC_EXTCSV_GITREPO=https://github.com/woudc/woudc-extcsv.git
ARG BASEDIR=/data/web/woudc-api-nightly

ENV BASEDIR=$BASEDIR
ENV APPDIR=$BASEDIR/woudc-api

WORKDIR $BASEDIR

# Set environment to avoid interactive prompts during apt-get install
ENV DEBIAN_FRONTEND=noninteractive

# Set up the repository mirror for faster package retrieval
RUN sed -i 's/http:\/\/archive.ubuntu.com\/ubuntu\//mirror:\/\/mirrors.ubuntu.com\/mirrors.txt/g' /etc/apt/sources.list

# Install build dependencies
RUN apt-get update && \
apt-get install -y software-properties-common && \
add-apt-repository ppa:gcpp-kalxas/wmo && \
add-apt-repository ppa:ubuntugis/ppa && apt-get update && \
apt-get install -y python3 python3-pip python3-flask git curl unzip && \
# pygeoapi install
git clone $PYGEOAPI_GITREPO -b master --depth=1 && \
cd pygeoapi && \
pip3 install -r requirements.txt && \
pip3 install . && \
cd .. && \
# woudc-extcsv install
git clone $WOUDC_EXTCSV_GITREPO -b master --depth=1 && \
cd woudc-extcsv && \
pip3 install . && \
cd ..

# Copy application code
COPY . $APPDIR

# Install application dependencies and woudc-api (including elasticsearch and elasticsearch-dsl from requirements.txt)
RUN cd woudc-api && \
pip3 install -r $APPDIR/requirements.txt && \
pip3 install gunicorn gevent && \
pip3 install .

# Cleanup unnecessary packages and files
RUN apt-get remove --purge -y git && \
apt-get clean && \
apt autoremove -y && \
rm -rf /var/lib/apt/lists/*

# Permission fix (mark as executable)
RUN chmod +x $APPDIR/entrypoint.sh

# Start entrypoint.sh
ENTRYPOINT ["/data/web/woudc-api-nightly/woudc-api/entrypoint.sh"]
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ curl -O http://schemas.opengis.net/SCHEMAS_OPENGIS_NET.zip && unzip ./SCHEMAS_OP
# optional for development: clone pygeoapi codebase and install
git clone https://github.com/geopython/pygeoapi.git
cd pygeoapi
git checkout tags/0.16.1
pip3 install -r requirements.txt
python3 setup.py install
cd ..
Expand Down Expand Up @@ -73,6 +72,32 @@ curl http://localhost:5000 # redirect to WOUDC data services pages
curl http://localhost:5000/oapi # OGC API endpoint
```

#### Docker

Docker commands:
```bash
# build
docker build -t woudc-api .

# run container
docker run -d --name woudc-api -p 6080:6080 woudc-api
```

Docker compose commands:
```bash
# build
docker compose -f docker-compose.yml build

# take down container
docker compose -f docker-compose.yml down

# ensure container is removed
docker container rm -f woudc-api-nightly

# run container
docker compose -f docker-compose.yml up -d
```

### Development

```bash
Expand Down
4 changes: 3 additions & 1 deletion deploy/default/woudc-api-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ server:
basepath: /
mimetype: application/json; charset=UTF-8
encoding: utf-8
language: en-CA
languages:
- en-CA
- fr-CA
# cors: true
pretty_print: true
limit: 500
Expand Down
57 changes: 57 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
###################################################################
#
# Author: Tom Kralidis <[email protected]>
#
# Copyright (c) 2023 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.
#
###################################################################

services:
woudc-api:
image: woudc/woudc-api:nightly
container_name: woudc-api-nightly
restart: unless-stopped
build:
context: .
args:
BASEDIR: /data/web/woudc-api-nightly
network_mode: host
environment:
WOUDC_API_BIND_HOST: 0.0.0.0
WOUDC_API_BIND_PORT: 6080
WOUDC_API_URL: ${WOUDC_API_URL} # sourced from ~/.profile or local.env
WOUDC_API_ES_USERNAME: ${WOUDC_API_ES_USERNAME} # sourced from ~/.profile or local.env
WOUDC_API_ES_PASSWORD: ${WOUDC_API_ES_PASSWORD} # sourced from ~/.profile or local.env
WOUDC_API_ES_URL: https://${WOUDC_API_ES_USERNAME}:${WOUDC_API_ES_PASSWORD}@localhost:9200
WOUDC_API_ES_INDEX_PREFIX: ${WOUDC_API_ES_INDEX_PREFIX}
WOUDC_API_OGC_SCHEMAS_LOCATION: /data/web/woudc-api-nightly/schemas.opengis.net
PYGEOAPI_CONFIG: /data/web/woudc-api-nightly/woudc-api/deploy/default/woudc-api-config.yml
PYGEOAPI_OPENAPI: /data/web/woudc-api-nightly/woudc-api/deploy/default/woudc-api-openapi.yml
ports:
- "6080:6080"

networks:
default:
name: woudc_network
driver: bridge
112 changes: 112 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/bash
###################################################################
#
# Author: Kevin Ngai <[email protected]>
#
# Copyright (c) 2024 Kevin Ngai
#
# 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.
#
###################################################################

echo "START /entrypoint.sh"

set -e # Exit on error

# Default env variables
BASEDIR=${BASEDIR:-/data/web/woudc-api-nightly}
APPDIR=${APPDIR:-$BASEDIR/woudc-api}
WOUDC_API_URL=${WOUDC_API_URL}
PYGEOAPI_CONFIG=${PYGEOAPI_CONFIG}
PYGEOAPI_OPENAPI=${PYGEOAPI_OPENAPI}

# Gunicorn env settings with defaults
CONTAINER_NAME="woudc-api-nightly"
CONTAINER_HOST=${CONTAINER_HOST:-0.0.0.0}
CONTAINER_PORT=${CONTAINER_PORT:-6080}
WSGI_WORKERS=${WSGI_WORKERS:-4}
WSGI_WORKER_TIMEOUT=${WSGI_WORKER_TIMEOUT:-6000}
WSGI_WORKER_CLASS=${WSGI_WORKER_CLASS:-gevent}

# What to invoke: default is to run gunicorn server
entry_cmd=${1:-run}

# Shorthand (bash) commands
function error() {
echo "ERROR: $@"
}
function log() {
echo "$(date +'%Y-%m-%d %H:%M:%S') - $*"
}

# Signal trapping for graceful shutdown
trap 'log "Shutting down..."; exit 0' SIGTERM

log "Generating schemas.opengis.net..."
cd ${BASEDIR}
mkdir -p schemas.opengis.net
if ! curl -O http://schemas.opengis.net/SCHEMAS_OPENGIS_NET.zip; then
error "Failed to download schemas.opengis.net ZIP"
exit 1
fi
if ! unzip -o ./SCHEMAS_OPENGIS_NET.zip "ogcapi/*" -d schemas.opengis.net; then
error "Failed to unzip schemas.opengis.net"
exit 1
fi
rm -f ./SCHEMAS_OPENGIS_NET.zip

# woudc-api configuration
log "Configuring woudc-api configurations..."
sed -i 's^# cors: true^cors: true^' "${PYGEOAPI_CONFIG}"

log "Generating woudc-api-openapi.yml with PYGEOAPI_CONFIG=${PYGEOAPI_CONFIG} and PYGEO_API_OPENAPI=${PYGEOAPI_OPENAPI}..."
log "Creating backup of default woudc-api-openapi.yml as: ${PYGEOAPI_OPENAPI}-backup"
cp "${PYGEOAPI_OPENAPI}" "${PYGEOAPI_OPENAPI}-backup"
if ! pygeoapi openapi generate "${PYGEOAPI_CONFIG}" --output-file "${PYGEOAPI_OPENAPI}"; then
error "OpenAPI document could not be generated ERROR"
log "Reverting back to using the default OpenAPI document that was backed up..."
# cp "${DEFAULT_PYGEOAPI_OPENAPI}" "${PYGEOAPI_OPENAPI}"
cp "${PYGEOAPI_OPENAPI}-backup" "${PYGEOAPI_OPENAPI}"
rm "${PYGEOAPI_OPENAPI}-backup"
fi
sed -i "s#http://schemas.opengis.net#$WOUDC_API_URL/schemas#g" "${PYGEOAPI_OPENAPI}"

log "OpenAPI document generated. Continuing woudc-api start up..."

case ${entry_cmd} in
run)
log "Start gunicorn name=${CONTAINER_NAME} on ${CONTAINER_HOST}:${CONTAINER_PORT} with ${WSGI_WORKERS} workers"
exec gunicorn --workers "${WSGI_WORKERS}" \
--worker-class="${WSGI_WORKER_CLASS}" \
--timeout "${WSGI_WORKER_TIMEOUT}" \
--name="${CONTAINER_NAME}" \
--bind "${CONTAINER_HOST}:${CONTAINER_PORT}" \
--reload \
--reload-extra-file "${PYGEOAPI_CONFIG}" \
pygeoapi.flask_app:APP
;;
*)
error "unknown command arg: must be 'run'"
;;
esac

log "END /entrypoint.sh"
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ elasticsearch
elasticsearch-dsl
flask
woudc-extcsv>=0.5.0
pygeoapi==0.16.1
pygeoapi
4 changes: 2 additions & 2 deletions woudc_api/provider/elasticsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(self, provider_def):
self.title_field = provider_def.get('title_field')
self.properties = provider_def.get('properties', [])
self.file_types = provider_def.get('file_types', [])
self.fields = {}
self._fields = {}
self.filename = None

# for coverage providers
Expand Down Expand Up @@ -123,7 +123,7 @@ def __init__(self, provider_def):

LOGGER.debug('Grabbing field information')
try:
self.fields = self.get_fields()
self._fields = self.get_fields()
except exceptions.NotFoundError as err:
LOGGER.error(err)
raise ProviderQueryError(err)

0 comments on commit 9a3ec64

Please sign in to comment.