Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker extension #46

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
PyWPS demo with docker support
==============================
Clone pywps-flask, install libraries, build docker image (due to GDAL compiling lasts quite long)::
Install Docker. For detailed instruction see Docker `docs <https://docs.docker.com/install/linux/docker-ce/ubuntu/>`_.
Check if Docker-engine is running.::

$ pip3 install -r requirements.txt
$ cd pywps-flask/docker/alpine/flask
$ docker build -t pywps_container .
$ sudo apt install docker-ce
$ sudo systemctl status docker

Clone pywps-flask, switch to docker_extension branch::

$ git clone https://github.com/lazaa32/pywps-flask.git
$ git checkout docker_extension
lazaa32 marked this conversation as resolved.
Show resolved Hide resolved

Clone pywps and OWSLib::
Install libraries, build docker image (due to GDAL compiling lasts quite long)::

$ git clone https://github.com/lazaa32/pywps.git
$ git clone https://github.com/lazaa32/OWSLib.git
$ pip3 install -r requirements.txt
$ cd pywps-flask/docker/isolation
lazaa32 marked this conversation as resolved.
Show resolved Hide resolved
$ docker build -t pywps .

Set PYTHONPATH::
Check ``pywps.cfg``, set mode to ``docker`` and docker image name to ``pywps``::

$ export PYTHONPATH=$PYTHONPATH:$PWD/OWSLib:$PWD/pywps
mode=docker
docker_img=pywps

Run server::

python3 demo.py
$ cd pywps-flask
$ python3 demo.py

Send example POST request::

$ curl -X POST -d @static/requests/execute_buffer_async_reference.xml http://localhost:5000/wps

You should get response with ``ProcessAccepted`` status code. During execution check whether a container was created::

$ docker ps -a


PyWPS example service
Expand Down
30 changes: 15 additions & 15 deletions docker/isolation/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,24 @@ RUN apk update && apk add --no-cache \
libxslt-dev \
linux-headers \
expat \
expat-dev
expat-dev \
g++ \
libstdc++ \
make \
swig


RUN apk --update --no-cache add g++ libstdc++ make swig

# Xerces
RUN wget http://www.apache.org/dist/xerces/c/3/sources/xerces-c-${XERCES_VERSION}.tar.gz -O /tmp/xerces-c-${XERCES_VERSION}.tar.gz && \
tar xvf /tmp/xerces-c-${XERCES_VERSION}.tar.gz -C /tmp && \
cd /tmp/xerces-c-${XERCES_VERSION} && \
./configure --prefix=/opt/xerces && \
make -j $PROCESSOR_N && \
make install

# Geos
RUN apk add --no-cache \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/testing \
geos \
geos-dev

#Compiling Xerces
RUN wget http://www.apache.org/dist/xerces/c/3/sources/xerces-c-${XERCES_VERSION}.tar.gz -O /tmp/xerces-c-${XERCES_VERSION}.tar.gz && \
tar xvf /tmp/xerces-c-${XERCES_VERSION}.tar.gz -C /tmp && \
cd /tmp/xerces-c-${XERCES_VERSION} && \
LDFLAGS="-s" ./configure --prefix=/usr/local/src/xerces && \
make -j $PROCESSOR_N install

# Install GDAL
RUN wget http://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz -O /tmp/gdal.tar.gz && \
tar xzf /tmp/gdal.tar.gz -C /tmp && \
Expand All @@ -47,12 +46,13 @@ RUN cd /tmp/gdal-${GDAL_VERSION}/swig/python \
&& python3 setup.py build \
&& python3 setup.py install

RUN git clone https://github.com/geopython/pywps-flask.git
RUN rm -rf /var/cache/apk/*

RUN git clone https://github.com/lazaa32/pywps-flask.git

WORKDIR /pywps-flask
RUN pip3 install -r requirements.txt


EXPOSE 5000
ENTRYPOINT ["/usr/bin/python3", "demo.py","-a"]

Expand Down
8 changes: 4 additions & 4 deletions pywps.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ url=http://localhost:5000/wps
outputurl=http://localhost:5000/outputs/
outputpath=outputs
workdir=workdir
wd_inp_subdir=inputs
wd_out_subdir=outputs
maxprocesses=10
parallelprocesses=2
allowedinputpaths=/pywps-flask/data

[processing]
mode=docker
mode=default
port_min=5050
port_max=5070
docker_img=container
docker_img=pywps
dckr_inp_dir=/pywps-flask/data
dckr_out_dir=/pywps-flask/outputs
sleep_secs=5

[logging]
level=INFO
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Shapely
Werkzeug
SQLAlchemy
psutil
-e git+https://github.com/geopython/pywps.git@master#egg=pywps-master
docker
-e git+https://github.com/lazaa32/pywps.git@docker_extension#egg=pywps
2 changes: 1 addition & 1 deletion static/requests/execute_buffer_post_referenceoutput.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="true">
<wps:ResponseDocument status="true" storeExecuteResponse="true">
<wps:Output asReference="false">
<ows:Identifier>buff_out</ows:Identifier>
</wps:Output>
Expand Down
6 changes: 1 addition & 5 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,5 @@ def validate(url, schema, post_data=None):

schema = get_schema(schema)

if schema.validate(body_doc):
return True
else:
print(body)
return False
return schema.validate(body_doc)

50 changes: 46 additions & 4 deletions tests/test_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ def setUp(self):
def test_valid(self):
"POST Execute request"

validate(self.url, self.schema_url, self.request_data)

assert validate(self.url, self.schema_url, self.request_data)


#def test_valid_lineage(self):
Expand All @@ -70,7 +69,6 @@ def _get_response(self, request):

return response_doc


def test_sync(self):
request = self._get_request('http://localhost:5000/static/requests/execute_buffer_post.xml')
response = self._get_response(request)
Expand Down Expand Up @@ -100,7 +98,50 @@ def test_sync(self):
'wps:ComplexData/ogr:FeatureCollection',
namespaces=NAMESPACES))

def test_sync_reference(self):
request = self._get_request('http://localhost:5000/static/requests/execute_buffer_sync_reference.xml')
response = self._get_response(request)

self.assertEqual(
response.xpath('//wps:ExecuteResponse/wps:Process/ows:Identifier',
namespaces=NAMESPACES)[0].text, 'buffer')

self.assertEqual(
response.xpath(
'//wps:ExecuteResponse/wps:Status/wps:ProcessSucceeded',
namespaces=NAMESPACES)[0].text,
'PyWPS Process GDAL Buffer process finished')

self.assertEqual(len(response.xpath(
'//wps:ExecuteResponse/wps:ProcessOutputs/wps:Output',
namespaces=NAMESPACES)), 1)

self.assertEqual(response.xpath(
'//wps:ExecuteResponse/wps:ProcessOutputs/'
'wps:Output/wps:Reference',
namespaces=NAMESPACES)[0].get('mimeType'),
'application/gml+xml')

self.assertTrue(response.xpath(
'//wps:ExecuteResponse/wps:ProcessOutputs/wps:Output/'
'wps:Reference',
namespaces=NAMESPACES))

data_href = response.xpath(
'//wps:ExecuteResponse/wps:ProcessOutputs/wps:Output/'
'wps:Reference',
namespaces=NAMESPACES)[0].get('href')

data = self._get_request(data_href)
data_doc = etree.fromstring(data)

self.assertTrue(data_doc.xpath('//ogr:FeatureCollection',
namespaces=NAMESPACES))

def test_async(self):
"""
This test fails for Docker. Docker supports only referenced output in response.
"""
request = self._get_request('http://localhost:5000/static/requests/execute_buffer_async.xml')
response = self._get_response(request)

Expand Down Expand Up @@ -164,14 +205,15 @@ def test_async_reference(self):
data_href = status_doc.xpath(
'//wps:ExecuteResponse/wps:ProcessOutputs/wps:Output/'
'wps:Reference',
namespaces=NAMESPACES)[0].get('{http://www.w3.org/1999/xlink}href')
namespaces=NAMESPACES)[0].get('href')

data = self._get_request(data_href)
data_doc = etree.fromstring(data)

self.assertTrue(data_doc.xpath('//ogr:FeatureCollection',
namespaces=NAMESPACES))


def load_tests(loader=None, tests=None, pattern=None):
if not loader:
loader = unittest.TestLoader()
Expand Down