From 3914ca807df5ec959af7c91f75aa723107e9f316 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20H=C3=B6ffner?= <info@sebastian-hoeffner.de>
Date: Wed, 10 Oct 2018 17:53:01 +0200
Subject: [PATCH] Updating the README to reflect the latest changes.

---
 README.md | 304 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 266 insertions(+), 38 deletions(-)

diff --git a/README.md b/README.md
index e291582..724b324 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,17 @@
 # Web OpenCCG
 
-This repository builds a small nginx-webserver and python wrapper around OpenCCG using the GUM-space ontology, ready to run inside a docker container.
+This repository builds a small [nginx](https://nginx.org/)-webserver and python wrapper around [OpenCCG](http://openccg.sourceforge.net/) using the [GUM-space ontology](http://www.diaspace.uni-bremen.de/cgi-bin/twiki/view/DiaSpace/ReSources.html), ready to run inside a [docker](https://www.docker.com/) container.
 
 After an initial `docker-compose up`, the service can be queried using a simple POST request, e.g. using curl:
 
-    $ curl --data "The yellow robot under the table." localhost:8080
-    {"sentence": "the yellow robot under the table", "number": 1, "parses": {"np": "(@w2:slm-Robot(slm-Robot ^ <det>the ^ <ident>specific ^ <quant>singular) ^ @x2:gs-SpatialLocating( <gs-locatum>w2:slm-Robot ^ <gs-placement>(x1:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w3:gs-UnderProjectionExternal ^ slm-Under) ^ <gs-relatum>(w5:slm-Table ^ slm-Table ^ <det>the ^ <ident>specific ^ <quant>singular))) ^ @x3:gum-ColorPropertyAscription( <concrete>true ^ <domain>w2:slm-Robot ^ <range>(w1:slm-Yellow ^ yellow ^ <concrete>true)))"}}
+    $ curl --data "Take the cup." localhost
+    {"version": "1.1.0", "application": "web-openccg", "uuid": "5fbcbc0d-c75e-4278-aa85-37a745847ae8", "sentence": "take the cup", "parses": {"smain": "@x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking))", "smain/0": "@x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking))", "smain/.r": "@x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking))", "smain/.r/0": "@x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking))"}, "http_status": 200, "json_parses": {"smain": {"nominal": "x1:gum-OrientationChange", "roles": [{"type": "mood", "target": "imp"}, [{"type": "gs-direction", "target": {"variable": "x2:gs-GeneralizedLocation", "roles": {"type": "gs-hasSpatialModality", "target": {"variable": "w2:slm-Cup", "roles": [{"entity": "cup"}, {"type": "det", "target": "the"}, {"type": "ident", "target": "specific"}, {"type": "quant", "target": "singular"}]}}}}, {"type": "gum-processInConfiguration", "target": {"variable": "w0:slm-Moving", "roles": {"entity": "slm-Taking"}}}]]}, "smain/0": {"nominal": "x1:gum-OrientationChange", "roles": [{"type": "mood", "target": "imp"}, [{"type": "gs-direction", "target": {"variable": "x2:gs-GeneralizedLocation", "roles": {"type": "gs-hasSpatialModality", "target": {"variable": "w2:slm-Cup", "roles": [{"entity": "cup"}, {"type": "det", "target": "the"}, {"type": "ident", "target": "specific"}, {"type": "quant", "target": "singular"}]}}}}, {"type": "gum-processInConfiguration", "target": {"variable": "w0:slm-Taking", "roles": {"entity": "slm-Taking"}}}]]}, "smain/.r": {"nominal": "x1:gs-AffectingDirectedMotion", "roles": [{"type": "mood", "target": "imperative"}, [{"type": "gs-route", "target": "x2"}, [{"type": "gum-actee", "target": {"variable": "w2:slm-Cup", "roles": [{"entity": "cup"}, {"type": "det", "target": "the"}, {"type": "ident", "target": "specific"}, {"type": "quant", "target": "singular"}]}}, {"type": "gum-processInConfiguration", "target": {"variable": "w0:slm-Moving", "roles": {"entity": "slm-Taking"}}}]]]}, "smain/.r/0": {"nominal": "x1:gs-AffectingDirectedMotion", "roles": [{"type": "mood", "target": "imperative"}, [{"type": "gs-route", "target": "x2"}, [{"type": "gum-actee", "target": {"variable": "w2:slm-Cup", "roles": [{"entity": "cup"}, {"type": "det", "target": "the"}, {"type": "ident", "target": "specific"}, {"type": "quant", "target": "singular"}]}}, {"type": "gum-processInConfiguration", "target": {"variable": "w0:slm-Taking", "roles": {"entity": "slm-Taking"}}}]]]}}}
 
 Or, as an example, using Python [requests](http://docs.python-requests.org/en/master/):
 
 ```python
 import requests
-print(requests.post('http://localhost:8080', data={'sentence': 'The yellow robot under the table.'}).json())
+print(requests.post('http://localhost', data={'sentence': 'Take the cup.'}).json())
 ```
 
 Note that is is not production ready, as it is really slow and not optimized:
@@ -20,56 +20,284 @@ Instead of keeping one (or multiple) instances of OpenCCG running to query them
 
 ## Usage
 
+### Querying
+
+To query the service visually, just open your browser at [http://localhost/gui](http://localhost/gui).
+Otherwise, use curl, wget, or e.g. python requests to query web-openccg via the command line or your application.
+
+If your client allows to build your request body manually, like curl, just put the sentence inside:
+
+    curl --data "Take the cup." localhost
+
+However, many high level frameworks like python requests usually use a
+key-value mechanism for post data. In this case, use the key `sentence`:
+
+    requests.post('http://localhost', data={'sentence': 'Take the cup.'})
+
+
 ### Response format
 
-The response is a JSON object and contains four fields:
+The response is a JSON object and always contains these fields:
+
+- `version`: The JSON object version.
+- `application`: Always "web-openccg", this is useful if you aggregate parses from different services.
+- `uuid`: A unique ID for this response. This will only be useful if you plan to integrate the tool somehow.
+- `http_status`: The HTTP status from the request.
+
+If a sentence was provided during the request, these fields are present:
 
 - `sentence`: The cleaned input sentence (all lowercase, punctuation removed, ...).
-- `number`: The number of possible parses as determined from OpenCCG.
+
+If at least one successful parse exists, the these fields are included:
 - `parses`: A dictionary of parse-identifiers (e.g. "np") to actual parses as OpenCCG outputs them.
-- `http_status`: The HTTP status from the request.
+- `json_parses`: A version of the OpenCCG outputs in a flat JSON. This is produced via a custom grammer for [TatSu](https://github.com/neogeny/TatSu), with some post-processing to keep the JSON hierarchy flat (TatSu creates right-deep trees).
+
+*Note:* The keys are shared between `parses` and `json_parses`, thus you can easily lookup the original output for a JSON parse and vice-versa.
 
-Thus, an example response for the sentence "The yellow robot under the table." is:
+If an error occurs, the error field is present:
+- `error`: An error description.
+
+An example response for the sentence "Take the cup." is:
 
 ```json
-{"sentence": "the yellow robot under the table",
- "number": 1,
- "parses": {"np": "(@w2:slm-Robot(slm-Robot ^ <det>the ^ <ident>specific ^ <quant>singular) ^ @x2:gs-SpatialLocating( <gs-locatum>w2:slm-Robot ^ <gs-placement>(x1:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w3:gs-UnderProjectionExternal ^ slm-Under) ^ <gs-relatum>(w5:slm-Table ^ slm-Table ^ <det>the ^ <ident>specific ^ <quant>singular))) ^ @x3:gum-ColorPropertyAscription( <concrete>true ^ <domain>w2:slm-Robot ^ <range>(w1:slm-Yellow ^ yellow ^ <concrete>true)))"},
- "http_status": 200}
+{
+    "version": "1.1.0",
+    "application": "web-openccg",
+    "uuid": "f25875d6-b137-4fc3-93c3-8dc9b4958595",
+    "sentence": "take the cup",
+    "parses": {
+        "smain": "@x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking))",
+        "smain/0": "@x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking))",
+        "smain/.r": "@x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking))",
+        "smain/.r/0": "@x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking))"
+    },
+    "http_status": 200,
+    "json_parses": {
+        "smain": {
+            "nominal": "x1:gum-OrientationChange",
+            "roles": [
+                {
+                    "type": "mood",
+                    "target": "imp"
+                },
+                [
+                    {
+                        "type": "gs-direction",
+                        "target": {
+                            "variable": "x2:gs-GeneralizedLocation",
+                            "roles": {
+                                "type": "gs-hasSpatialModality",
+                                "target": {
+                                    "variable": "w2:slm-Cup",
+                                    "roles": [
+                                        {
+                                            "entity": "cup"
+                                        },
+                                        {
+                                            "type": "det",
+                                            "target": "the"
+                                        },
+                                        {
+                                            "type": "ident",
+                                            "target": "specific"
+                                        },
+                                        {
+                                            "type": "quant",
+                                            "target": "singular"
+                                        }
+                                    ]
+                                }
+                            }
+                        }
+                    },
+                    {
+                        "type": "gum-processInConfiguration",
+                        "target": {
+                            "variable": "w0:slm-Moving",
+                            "roles": {
+                                "entity": "slm-Taking"
+                            }
+                        }
+                    }
+                ]
+            ]
+        },
+        "smain/0": {
+            "nominal": "x1:gum-OrientationChange",
+            "roles": [
+                {
+                    "type": "mood",
+                    "target": "imp"
+                },
+                [
+                    {
+                        "type": "gs-direction",
+                        "target": {
+                            "variable": "x2:gs-GeneralizedLocation",
+                            "roles": {
+                                "type": "gs-hasSpatialModality",
+                                "target": {
+                                    "variable": "w2:slm-Cup",
+                                    "roles": [
+                                        {
+                                            "entity": "cup"
+                                        },
+                                        {
+                                            "type": "det",
+                                            "target": "the"
+                                        },
+                                        {
+                                            "type": "ident",
+                                            "target": "specific"
+                                        },
+                                        {
+                                            "type": "quant",
+                                            "target": "singular"
+                                        }
+                                    ]
+                                }
+                            }
+                        }
+                    },
+                    {
+                        "type": "gum-processInConfiguration",
+                        "target": {
+                            "variable": "w0:slm-Taking",
+                            "roles": {
+                                "entity": "slm-Taking"
+                            }
+                        }
+                    }
+                ]
+            ]
+        },
+        "smain/.r": {
+            "nominal": "x1:gs-AffectingDirectedMotion",
+            "roles": [
+                {
+                    "type": "mood",
+                    "target": "imperative"
+                },
+                [
+                    {
+                        "type": "gs-route",
+                        "target": "x2"
+                    },
+                    [
+                        {
+                            "type": "gum-actee",
+                            "target": {
+                                "variable": "w2:slm-Cup",
+                                "roles": [
+                                    {
+                                        "entity": "cup"
+                                    },
+                                    {
+                                        "type": "det",
+                                        "target": "the"
+                                    },
+                                    {
+                                        "type": "ident",
+                                        "target": "specific"
+                                    },
+                                    {
+                                        "type": "quant",
+                                        "target": "singular"
+                                    }
+                                ]
+                            }
+                        },
+                        {
+                            "type": "gum-processInConfiguration",
+                            "target": {
+                                "variable": "w0:slm-Moving",
+                                "roles": {
+                                    "entity": "slm-Taking"
+                                }
+                            }
+                        }
+                    ]
+                ]
+            ]
+        },
+        "smain/.r/0": {
+            "nominal": "x1:gs-AffectingDirectedMotion",
+            "roles": [
+                {
+                    "type": "mood",
+                    "target": "imperative"
+                },
+                [
+                    {
+                        "type": "gs-route",
+                        "target": "x2"
+                    },
+                    [
+                        {
+                            "type": "gum-actee",
+                            "target": {
+                                "variable": "w2:slm-Cup",
+                                "roles": [
+                                    {
+                                        "entity": "cup"
+                                    },
+                                    {
+                                        "type": "det",
+                                        "target": "the"
+                                    },
+                                    {
+                                        "type": "ident",
+                                        "target": "specific"
+                                    },
+                                    {
+                                        "type": "quant",
+                                        "target": "singular"
+                                    }
+                                ]
+                            }
+                        },
+                        {
+                            "type": "gum-processInConfiguration",
+                            "target": {
+                                "variable": "w0:slm-Taking",
+                                "roles": {
+                                    "entity": "slm-Taking"
+                                }
+                            }
+                        }
+                    ]
+                ]
+            ]
+        }
+    }
+}
 ```
 
 
-### Querying OpenCCG
+### Changing the port
+
+Most webservices use port 80 as a default port, and so does web-openccg.
 
-The [OpenCCG](http://openccg.sourceforge.net/) service allows to parse sentences using the English [CCG grammar](https://www.sfbtr8.spatial-cognition.de/en/project/interaction/i5-diaspace/resources/index.html) based on the [Generalized Upper Model](https://www.sfbtr8.spatial-cognition.de/en/project/interaction/i1-ontospace/research/gum-20-30/index.html) by the SFB/TR 8 Spatial Cognition.
+To change the port, adjust the docker-compose file and change the port line
+from `"80:80"` to your port on the left side (but keep the 80 on the right), so
+for example to set up the service on Port 9043, you would change it to
+`"9043:80"`.
 
-It is wrapped into a small web app which can either be queried using a post request (e.g. using curl or wget), or used with a crude GUI:
 
-    $ curl --data "The yellow robot under the table." localhost:8080
-    {"sentence": "the yellow robot under the table", "number": 1, "parses": {"np": "(@w2:slm-Robot(slm-Robot ^ <det>the ^ <ident>specific ^ <quant>singular) ^ @x2:gs-SpatialLocating( <gs-locatum>w2:slm-Robot ^ <gs-placement>(x1:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w3:gs-UnderProjectionExternal ^ slm-Under) ^ <gs-relatum>(w5:slm-Table ^ slm-Table ^ <det>the ^ <ident>specific ^ <quant>singular))) ^ @x3:gum-ColorPropertyAscription( <concrete>true ^ <domain>w2:slm-Robot ^ <range>(w1:slm-Yellow ^ yellow ^ <concrete>true)))"}}
+## Development
 
-When using the GUI (open your browser at [http://localhost:8080](http://localhost:8080)), the response is more human readable:
+Although not necessarily needed, I use a pipenv for local development to be
+able to compile the grammar to a parser using TatSu.
+I rely on [when-changed](https://github.com/joh/when-changed) to trigger
+automatic builds:
 
-    "the yellow robot under the table": 1 parse found.
+    when-changed OpenCCG.ebnf make
 
-    Parse: np :
-      (@w2:slm-Robot(slm-Robot ^
-                    <det>the ^
-                    <ident>specific ^
-                    <quant>singular) ^ @x2:gs-SpatialLocating(
-                             <gs-locatum>w2:slm-Robot ^
-                             <gs-placement>(x1:gs-GeneralizedLocation ^
-                                            <gs-hasSpatialModality>(w3:gs-UnderProjectionExternal ^ slm-Under) ^
-                                            <gs-relatum>(w5:slm-Table ^ slm-Table ^
-                                                         <det>the ^
-                                                         <ident>specific ^
-                                                         <quant>singular))) ^ @x3:gum-ColorPropertyAscription(
-                                      <concrete>true ^
-                                      <domain>w2:slm-Robot ^
-                                      <range>(w1:slm-Yellow ^ yellow ^
-                                              <concrete>true)))
+To start the development docker container, use the Makefile:
 
-### Changing the port
+    make run
 
-Many webservices use port 8080 as a default port.
-To change the port of this software, adjust the docker-compose file and change the port line from `"8080:80"` to your port on the left side (but keep the 80 in tact), so for example to set up the service on Port 9043, you would change it to `"9043:80"`.
+The development server binds to port 5000 and uses the
+[flask](http://flask.pocoo.org/) debug environment. Additionally, the docker
+container started with `make run` binds the app directory
+so that flask's reloading works properly.
-- 
GitLab