Code class: Calling a RESTful web service from Instant JChem

news · 6 years ago
by Tim Dudgeon

Data is increasingly becoming available through web services nowadays, and REST is becoming dominant mostly due to its extreme simplicity. This post shows how you can call an external RESTful web service from IJC.

The example uses the ChEMBL REST web services. This is a nice example to use as it deals with chemistry, and is a public service, not needing authentication so we can keep the example simple. See here for more about the ChEMBL web services: https://www.ebi.ac.uk/chembldb/index.php/ws

The example script runs a similarity search for a structure you specify against the web service and inserts the resulting structures into an IJC database. They key part that we concentrate on here is how to call the web service and process the response.

Calling a web service in Groovy is really simple, thanks to the HttpBuilder library. But this is not part of IJC so we need to make if available from our script. We do this using Groovy’s Grape function which allows us to ‘Grab’ external libraries from a Maven or Ivy repository. All we need is one line of code to do this and then we can import the RESTClient class: [groovy firstline="15"] @Grab(group = 'org.codehaus.groovy.modules.http-builder', module = 'http-builder', version = '0.5.2') import groovyx.net.http.RESTClient [/groovy]

In this example we hard code the query and the similarity threshold into the script. In a later blog we’ll look at how to do this better.

[groovy firstline="19"] String query = 'COC(=O)[C@@H]1[C@H]2CC[C@@H](C[C@@H]1OC(=O)C1=CC=CC=C1)N2C' String similarity = '90' // similarity score as a percent. [/groovy]

Now for the interesting part. How to call the web service and handle the response. This is the meat of how the web service call is performed. On line 37 we create the rest client, on line 42 we make the GET request using the query structure and similarity score defined earlier and then in lines 44 - 61 we handle the response with some very basic error handling.

[groovy firstline="37"] def client = new RESTClient('https://www.ebi.ac.uk/chemblws/') // build the query and execute the GET operation String path = "compounds/similarity/$query/$similarity" println "Performing GET for $path" def resp = client.get(path: path) println "Processing..." if (resp.status == 200) { … } else { // something went wrong with the web service call println "ERROR: code=$resp.status" } [/groovy]

Lines 45-57 of the above example is where we would process the results. Lets look at that part now

[groovy firstline="45"] println "Response OK" def data = resp.data // iterate through each result int count = 0 data.compound.each { cpd -> count++ String mol = cpd.smiles String id = cpd.chemblId println "Loading $id -> $mol" // perform the update def updateInfo = edp.insert([(structF.id):mol, (chemblF.id):id], null, envRW) } println "Processed $count results" [/groovy]

This is where the HttpBuilder really comes into its own. It handles the ugly XML response and wraps it up in a Groovy friendly way allowing us to access the XML elements and attributes using ‘dot notation’. So whilst the web service returns ugly XML like this (and this is greatly simplified compared with what you actually see!):

<list>
    <compound>
        <chemblId>CHEMBL127026</chemblId>
       <smiles>CN1C2CCC1C(C(C2)OC(=O)c3ccccc3)C(=O)Oc4ccccc4</smiles>
   </compound>
</list>

we can just access the bits we want like this:

data.compound.each { cpd ->
    String mol = cpd.smiles
    String id = cpd.chemblId
}

So simple! Once we’ve grabbed what we want we insert it into the IJC entity on line 10. This is standard IJC API stuff that we won’t cover here.

So that’s all there is to it. Of course this is a very simplified version, and in future posts we’ll cover how to improve this and make it more user friendly and useful. The full script can be found here: Full_script.zip

To run it follow the instructions at the top of the script.