Add section on using displaCy in a web app
@@ -315,3 +315,61 @@ p
'ents': [{'start': 4, 'end': 10, 'label': 'ORG'}],
'title': None
}
+
++h(2, "webapp") Using displaCy in a web application
+
+p
+ | If you want to use the visualizers as part of a web application, for
+ | example to create something like our
+ | #[+a(DEMOS_URL + "/displacy") online demo], it's not recommended to
+ | simply wrap and serve the displaCy renderer. Instead, you should only
+ | rely on the server to perform spaCy's processing capabilities, and use
+ | #[+a(gh("displacy")) displaCy.js] to render the JSON-formatted output.
+
++aside("Why not return the HTML by the server?")
+ | It's certainly possible to just have your server return the markup.
+ | But outputting raw, unsanitised HTML is risky and makes your app vulnerable to
+ | #[+a("https://en.wikipedia.org/wiki/Cross-site_scripting") cross-site scripting]
+ | (XSS). All your user needs to do is find a way to make spaCy return one
+ | token #[code &lt;script src="malicious-code.js"&gt;&lt;script&gt;].
+ | Instead of relying on the server to render and sanitize HTML, you
+ | can do this on the client in JavaScript. displaCy.js creates
+ | the SVG markup as DOM nodes and will never insert raw HTML.
+
+p
+ | The #[code parse_deps] function takes a #[code Doc] object and returns
+ | a dictionary in a format that can be rendered by displaCy.
+
++code("Example").
+ import spacy
+ from spacy import displacy
+
+ nlp = spacy.load('en')
+
+ def displacy_service(text):
+ doc = nlp(text)
+ return displacy.parse_deps(doc)
+
+p
+ | Using a library like #[+a("https://falconframework.org/") Falcon] or
+ | #[+a("http://www.hug.rest/") Hug], you can easily turn the above code
+ | into a simple REST API that receives a text and returns a JSON-formatted
+ | parse. In your front-end, include #[+a(gh("displacy")) displacy.js] and
+ | initialise it with the API URL and the ID or query selector of the
+ | container to render the visualisation in, e.g. #[code '#displacy'] for
+ | #[code &lt;div id="displacy"&gt;].
+
++code("script.js", "javascript").
+ var displacy = new displaCy('http://localhost:8080', {
+ container: '#displacy'
+ })
+
+ function parse(text) {
+ displacy.parse(text);
+ }
+
+p
+ | When you call #[code parse()], it will make a request to your API,
+ | receive the JSON-formatted parse and render it in your container. To
+ | create an interactive experience, you could trigger this function by
+ | a button and read the text from an #[code &lt;input&gt;] field.
