ChemSpider webservices in Perl

ChemSpider is an authoritative resource of chemical information, now part of the Royal Society of Chemistry‘s provision. One of the nice features for the programmer is ChemSpider’s range of webservices. These allow you to convert between file formats and search for information without the need to use one of the chemical data function libraries out there (see here for a list).

Perl is a great language, often overlooked these days in favour of more ‘modern’ alternatives such as Ruby or Python. One of the advantages of Perl is that there is a huge resource of books, free libraries and example code available. A free Windows version of Perl can be downloaded from ActiveState. It’s usually installed as part of a Linux distribution by default. Not sure about the Mac. Since most webservers run a version of Linux, that means Perl can be used as part of a website, allowing rich web applications to be developed.

When it comes to writing webservice clients in Perl, the first port of call is SOAP::Lite. This appears to do the trick at first sight, but I found it was difficult to use.

Here is the information ChemSpider expects to receive for its SMILESToInChI service…

POST /InChI.asmx HTTP/1.1
Host: www.chemspider.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.chemspider.com/SMILESToInChI"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <SMILESToInChI xmlns="http://www.chemspider.com/">
      <smiles>string</smiles>
    </SMILESToInChI>
  </soap:Body>
</soap:Envelope>

OK, that doesn’t look too hard, but to get SOAP::Lite to generate this was a real pain. Then I stumbled upon a blog by Robert Price which saved the day. So to cut a long story short, here’s the Perl code to convert a SMILES string to an InChI.

#!/bin/perl
use SOAP::Lite on_action => sub {sprintf '"%s%s"', @_};
my $smiles='CCO';
my $service = SOAP::Lite -> uri('http://www.chemspider.com/')
-> proxy('http://www.chemspider.com/InChi.asmx');
my $inchi = $service->call(SOAP::Data->name('SMILESToInChI')->attr({xmlns => 'http://www.chemspider.com/'})
=>  SOAP::Data->name('smiles')->value($smiles)->type(''))->result();
print "SMILES = $smiles\n";
print "InChI = $inchi\n";

For more complicated webservices, and to debug what is being sent and received, I recommend reading Robert’s article.

Leave a Reply

Your email address will not be published. Required fields are marked *