Difference between revisions of "Web API"

From ISFDB
Jump to navigation Jump to search
(→‎getpub.cgi: Replaced the example with one that has PubSeries data)
m (headings and source tags)
Line 1: Line 1:
=Introduction=
+
==Introduction==
 
 
 
The ISFDB currently provides 2 web APIs: getpub.cgi which is used to obtain publication metadata, and submission.cgi which is used to submit data to the ISFDB. There are currently no methods for obtaining author, title, series, or awards information from the ISFDB.
 
The ISFDB currently provides 2 web APIs: getpub.cgi which is used to obtain publication metadata, and submission.cgi which is used to submit data to the ISFDB. There are currently no methods for obtaining author, title, series, or awards information from the ISFDB.
  
=License Keys=
+
==License Keys==
 
+
Since registration is required to edit the ISFDB, the web API enforces that policy. Submitting data to the ISFDB requires a registered user ID, as well as a license key which is your password for accessing the web API. If you are logged into the ISFDB, a license key can be generated by visiting http://www.isfdb.org/cgi-bin/edit/keygen.cgi and clicking on '''[Generate New Key]'''. For data submissions this key must appear within a '''LicenseKey''' XML tag following the '''Submitter''' tag.
Since registration is required to edit the ISFDB, the web API enforces that policy. Submitting data to the ISFDB requires a registered user ID, as well as a license key which is your password for accessing the web API. If you are logged into the ISFDB, a license key can be generated by visiting [http://www.isfdb.org/cgi-bin/edit/keygen.cgi http://www.isfdb.org/cgi-bin/edit/keygen.cgi] and clicking on '''[Generate New Key]'''. For data submissions this key must appear within a '''LicenseKey''' XML tag following the '''Submitter''' tag.
 
 
 
=getpub.cgi=
 
  
 +
==getpub.cgi==
 
The getpub.cgi application takes an ISBN for an argument, and returns an XML structure containing the metadata for that particular publication. If more than one publication is associated with that particular ISBN, multiple records will be generated. The '''Records''' tag indicates the number of records found, followed by some number of '''Publication''' records. A license key is not required to use this API. The URL for getpub.cgi should appear as follows:
 
The getpub.cgi application takes an ISBN for an argument, and returns an XML structure containing the metadata for that particular publication. If more than one publication is associated with that particular ISBN, multiple records will be generated. The '''Records''' tag indicates the number of records found, followed by some number of '''Publication''' records. A license key is not required to use this API. The URL for getpub.cgi should appear as follows:
  
  http://www.isfdb.org/cgi-bin/rest/getpub.cgi?0439176832
+
http://www.isfdb.org/cgi-bin/rest/getpub.cgi?0439176832
  
 
Example XML returned via call to getpub.cgi:
 
Example XML returned via call to getpub.cgi:
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="iso-8859-1" ?>
 +
<ISFDB>
 +
<Records>1</Records>
 +
<Publications>
 +
  <Publication>
 +
    <Record>325837</Record>
 +
    <Title>The Winchester Horror</Title>
 +
    <Authors>
 +
      <Author>William F. Nolan</Author>
 +
    </Authors>
 +
    <Year>1998-00-00</Year>
 +
    <Isbn>1881475530</Isbn>
 +
    <Publisher>Cemetery Dance Publications</Publisher>
 +
    <PubSeries>Cemetery Dance Novella</PubSeries>
 +
    <PubSeriesNum>6</PubSeriesNum>
 +
    <Price>$30.00</Price>
 +
    <Pages>111</Pages>
 +
    <Binding>hc</Binding>
 +
    <Type>CHAPTERBOOK</Type>
 +
    <Tag>THWNCHSTRH1998</Tag>
 +
    <CoverArtists>
 +
      <Artist>Eric Powell</Artist>
 +
    </CoverArtists>
 +
    <Note>Hardcover Limited Edition of 450 signed and numbered copies bound in full-cloth and Smyth sewn</Note>
 +
  </Publication>
 +
</Publications>
 +
</ISFDB>
 +
</source>
  
<?xml version="1.0" encoding="iso-8859-1" ?>
+
===Example python script utilizing getpub.cgi===
<ISFDB>
 
  <Records>1</Records>
 
  <Publications>
 
    <Publication>
 
      <Record>325837</Record>
 
      <Title>The Winchester Horror</Title>
 
      <Authors>
 
        <Author>William F. Nolan</Author>
 
      </Authors>
 
      <Year>1998-00-00</Year>
 
      <Isbn>1881475530</Isbn>
 
      <Publisher>Cemetery Dance Publications</Publisher>
 
      <PubSeries>Cemetery Dance Novella</PubSeries>
 
      <PubSeriesNum>6</PubSeriesNum>
 
      <Price>$30.00</Price>
 
      <Pages>111</Pages>
 
      <Binding>hc</Binding>
 
      <Type>CHAPTERBOOK</Type>
 
      <Tag>THWNCHSTRH1998</Tag>
 
      <CoverArtists>
 
        <Artist>Eric Powell</Artist>
 
      </CoverArtists>
 
      <Note>Hardcover Limited Edition of 450 signed and numbered copies bound in full-cloth and Smyth sewn</Note>
 
    </Publication>
 
  </Publications>
 
</ISFDB>
 
 
 
==Example python script utilizing getpub.cgi==
 
 
 
 
Although getpub.cgi can be invoked via a browser, a more practical application is to invoke the URL via a programming interface, parsing the result with an XML parser, and then doing something of use with the resulting data. The following example shows the python code needed to obtain the XML data; it does not show an example of parsing the XML:  
 
Although getpub.cgi can be invoked via a browser, a more practical application is to invoke the URL via a programming interface, parsing the result with an XML parser, and then doing something of use with the resulting data. The following example shows the python code needed to obtain the XML data; it does not show an example of parsing the XML:  
 +
<source lang="python">
 +
import httplib
  
  <source lang="python">
+
host = "www.isfdb.org"
  
  import httplib
+
def GetXml(isbn):
 
+
      webservice = httplib.HTTP(host)
  host = "www.isfdb.org"
+
      command = '/cgi-bin/rest/getpub.cgi?%s' % isbn
 
+
      webservice.putrequest("GET", command)
  def GetXml(isbn):
+
      webservice.putheader("Host", host)
        webservice = httplib.HTTP(host)
+
      webservice.putheader("User-Agent", "Wget/1.9+cvs-stable (Red Hat modified)")
        command = '/cgi-bin/rest/getpub.cgi?%s' % isbn
+
      webservice.endheaders()
        webservice.putrequest("GET", command)
+
      errcode, errmsg, headers = webservice.getreply()
        webservice.putheader("Host", host)
+
      if errcode != 200:
        webservice.putheader("User-Agent", "Wget/1.9+cvs-stable (Red Hat modified)")
+
              resp = webservice.getfile()
        webservice.endheaders()
+
              print "Error:", errmsg
        errcode, errmsg, headers = webservice.getreply()
+
              print "Resp:", resp.read()
        if errcode != 200:
+
              resp.close()
                resp = webservice.getfile()
+
              return ''
                print "Error:", errmsg
+
      else:
                print "Resp:", resp.read()
+
              resp = webservice.getfile()
                resp.close()
+
              raw = resp.read()
                return ''
+
              resp.close()
        else:
+
              index = raw.find('<?xml')
                resp = webservice.getfile()
+
              return raw[index:]
                raw = resp.read()
+
</source>
                resp.close()
 
                index = raw.find('<?xml')
 
                return raw[index:]
 
  </source>
 
 
 
==Error Conditions==
 
  
 +
===Error Conditions===
 
In the event of an error condition, getpub.cgi will return an XML structure with the number of records found set to zero:
 
In the event of an error condition, getpub.cgi will return an XML structure with the number of records found set to zero:
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="iso-8859-1" ?>
 +
<ISFDB>
 +
  <Records>0</Records>
 +
  <Publications>
 +
  </Publications>
 +
</ISFDB>
 +
</source>
  
<source lang="xml">
+
==submission.cgi==
<?xml version="1.0" encoding="iso-8859-1" ?>
 
<ISFDB>
 
  <Records>0</Records>
 
  <Publications>
 
  </Publications>
 
</ISFDB>
 
</source>
 
 
 
=submission.cgi=
 
 
 
 
The submission.cgi application allows a remote user to post data to the ISFDB. Any of the data payloads defined in the [[Data Submission Formats]] article are accepted. The format of the XML data is identical to that used for local submissions, with the exception that the user's license key must be inserted after the '''Submitter''' tag. The user's registered login name should be contained within the '''Submitter''' tag, and the user's current license key should be contained with the '''LicenseKey''' tag. The URL for submission.cgi should appear as follows:
 
The submission.cgi application allows a remote user to post data to the ISFDB. Any of the data payloads defined in the [[Data Submission Formats]] article are accepted. The format of the XML data is identical to that used for local submissions, with the exception that the user's license key must be inserted after the '''Submitter''' tag. The user's registered login name should be contained within the '''Submitter''' tag, and the user's current license key should be contained with the '''LicenseKey''' tag. The URL for submission.cgi should appear as follows:
  
  http://www.isfdb.org/cgi-bin/rest/submission.cgi
+
http://www.isfdb.org/cgi-bin/rest/submission.cgi
  
 
Submissions are placed in the moderator queue as with an ISFDB edit, and are not integrated into the database until a moderator approves it. As such it is important that you not flood the moderator queue with hundreds of submissions. In general you should only post no more than 20 submissions per session, until they are cleared out by a moderator.
 
Submissions are placed in the moderator queue as with an ISFDB edit, and are not integrated into the database until a moderator approves it. As such it is important that you not flood the moderator queue with hundreds of submissions. In general you should only post no more than 20 submissions per session, until they are cleared out by a moderator.
  
An example submission XML payload follows, with the LicenseKey x'd out and the http section of the Image x'd out to prevent the image from loading here:
+
An example submission XML payload follows, with the LicenseKey x'd out:
 
+
<source lang="xml">
<source lang="xml">
+
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml version="1.0" encoding="iso-8859-1" ?>
+
<NewPub>
  <NewPub>
+
  <Submitter>Dissembler</Submitter>
    <Submitter>Dissembler</Submitter>
+
  <LicenseKey>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</LicenseKey>
    <LicenseKey>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</LicenseKey>
+
  <Isbn>1575661292</Isbn>
    <Isbn>1575661292</Isbn>
+
  <Subject>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Subject>
    <Subject>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Subject>
+
  <Title>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Title>
    <Title>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Title>
+
  <Year>1997-01-01</Year>
    <Year>1997-01-01</Year>
+
  <Price>$14.95</Price>
    <Price>$14.95</Price>
+
  <Publisher>Kensington</Publisher>
    <Publisher>Kensington</Publisher>
+
  <PubSeries>Time Romances</PubSeries>
    <PubSeries>Time Romances</PubSeries>
+
  <PubSeriesNum>17</PubSeriesNum>
    <PubSeriesNum>17</PubSeriesNum>
+
  <Pages>432</Pages>
    <Pages>432</Pages>
+
  <Authors>
    <Authors>
+
    <Author>Jennifer Roberson</Author>
      <Author>Jennifer Roberson</Author>
+
  </Authors>
    </Authors>
+
  <Binding>tp</Binding>
    <Binding>tp</Binding>
+
  <PubType>NOVEL</PubType>
    <PubType>NOVEL</PubType>
+
  <Image>http://ecx.images-amazon.com/images/I/519xedh9nrL._SL500_.jpg</Image>
    <Image>xxxx://ecx.images-amazon.com/images/I/519xedh9nrL._SL500_.jpg</Image>
+
  <Note>Pre-release data generated by Dissembler from Amazon.com website on 2008-5-8</Note>
    <Note>Pre-release data generated by Dissembler from Amazon.com website on 2008-5-8</Note>
+
</NewPub>
  </NewPub>
+
</source>
  </source>
 
 
 
==Example python script utilizing submission.cgi==
 
  
 +
===Example python script utilizing submission.cgi===
 
The submission.cgi application uses the http POST method, so it can not be invoked via a web browser. Once a proper XML payload has been constructed as described above, a connection needs to be made to the ISFDB web server, and the appropriate http header needs to be sent, including content type and length information. This example below shows how this can be implemented in python:
 
The submission.cgi application uses the http POST method, so it can not be invoked via a web browser. Once a proper XML payload has been constructed as described above, a connection needs to be made to the ISFDB web server, and the appropriate http header needs to be sent, including content type and length information. This example below shows how this can be implemented in python:
 +
<source lang="python">
 +
import httplib
  
  <source lang="python">
+
host = "www.isfdb.org"
  
  import httplib
+
def SendXml(xmlmsg):
 
+
      webservice = httplib.HTTP(host)
  host = "www.isfdb.org"
+
      webservice.putrequest("POST", "/cgi-bin/rest/submission.cgi")
 
+
      webservice.putheader("Host", host)
  def SendXml(xmlmsg):
+
      webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
        webservice = httplib.HTTP(host)
+
      webservice.putheader("Content-length", "%d" % len(xmlmsg))
        webservice.putrequest("POST", "/cgi-bin/rest/submission.cgi")
+
      webservice.endheaders()
        webservice.putheader("Host", host)
+
      webservice.send(xmlmsg)
        webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
 
        webservice.putheader("Content-length", "%d" % len(xmlmsg))
 
        webservice.endheaders()
 
        webservice.send(xmlmsg)
 
 
 
        errcode, errmsg, headers = webservice.getreply()
 
        if errcode != 200:
 
                resp = webservice.getfile()
 
                print "Error:", errmsg
 
        else:
 
                resp = webservice.getfile()
 
        resp.close()
 
  </source>
 
  
==Error Conditions==
+
      errcode, errmsg, headers = webservice.getreply()
 +
      if errcode != 200:
 +
              resp = webservice.getfile()
 +
              print "Error:", errmsg
 +
      else:
 +
              resp = webservice.getfile()
 +
      resp.close()
 +
</source>
  
 +
===Error Conditions===
 
In the event of an error condition, submission.cgi will return an XML structure with a Status of FAIL (success will return OK). The cause of the error can be found within the Error tag:
 
In the event of an error condition, submission.cgi will return an XML structure with a Status of FAIL (success will return OK). The cause of the error can be found within the Error tag:
 
+
<source lang="xml">
<source lang="xml">
+
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml version="1.0" encoding="iso-8859-1" ?>
+
<ISFDB>
<ISFDB>
+
  <Status>FAIL</Status>
  <Status>FAIL</Status>
+
  <Error>Bad XML data</Error>
  <Error>Bad XML data</Error>
+
</ISFDB>
</ISFDB>
+
</source>
</source>
 

Revision as of 08:22, 9 August 2012

Introduction

The ISFDB currently provides 2 web APIs: getpub.cgi which is used to obtain publication metadata, and submission.cgi which is used to submit data to the ISFDB. There are currently no methods for obtaining author, title, series, or awards information from the ISFDB.

License Keys

Since registration is required to edit the ISFDB, the web API enforces that policy. Submitting data to the ISFDB requires a registered user ID, as well as a license key which is your password for accessing the web API. If you are logged into the ISFDB, a license key can be generated by visiting http://www.isfdb.org/cgi-bin/edit/keygen.cgi and clicking on [Generate New Key]. For data submissions this key must appear within a LicenseKey XML tag following the Submitter tag.

getpub.cgi

The getpub.cgi application takes an ISBN for an argument, and returns an XML structure containing the metadata for that particular publication. If more than one publication is associated with that particular ISBN, multiple records will be generated. The Records tag indicates the number of records found, followed by some number of Publication records. A license key is not required to use this API. The URL for getpub.cgi should appear as follows:

http://www.isfdb.org/cgi-bin/rest/getpub.cgi?0439176832

Example XML returned via call to getpub.cgi:

<?xml version="1.0" encoding="iso-8859-1" ?>
<ISFDB>
 <Records>1</Records>
 <Publications>
   <Publication>
     <Record>325837</Record>
     <Title>The Winchester Horror</Title>
     <Authors>
       <Author>William F. Nolan</Author>
     </Authors>
     <Year>1998-00-00</Year>
     <Isbn>1881475530</Isbn>
     <Publisher>Cemetery Dance Publications</Publisher>
     <PubSeries>Cemetery Dance Novella</PubSeries>
     <PubSeriesNum>6</PubSeriesNum>
     <Price>$30.00</Price>
     <Pages>111</Pages>
     <Binding>hc</Binding>
     <Type>CHAPTERBOOK</Type>
     <Tag>THWNCHSTRH1998</Tag>
     <CoverArtists>
       <Artist>Eric Powell</Artist>
     </CoverArtists>
     <Note>Hardcover Limited Edition of 450 signed and numbered copies bound in full-cloth and Smyth sewn</Note>
   </Publication>
 </Publications>
</ISFDB>

Example python script utilizing getpub.cgi

Although getpub.cgi can be invoked via a browser, a more practical application is to invoke the URL via a programming interface, parsing the result with an XML parser, and then doing something of use with the resulting data. The following example shows the python code needed to obtain the XML data; it does not show an example of parsing the XML:

import httplib

host = "www.isfdb.org"

def GetXml(isbn):
      webservice = httplib.HTTP(host)
      command = '/cgi-bin/rest/getpub.cgi?%s' % isbn
      webservice.putrequest("GET", command)
      webservice.putheader("Host", host)
      webservice.putheader("User-Agent", "Wget/1.9+cvs-stable (Red Hat modified)")
      webservice.endheaders()
      errcode, errmsg, headers = webservice.getreply()
      if errcode != 200:
              resp = webservice.getfile()
              print "Error:", errmsg
              print "Resp:", resp.read()
              resp.close()
              return ''
      else:
              resp = webservice.getfile()
              raw = resp.read()
              resp.close()
              index = raw.find('<?xml')
              return raw[index:]

Error Conditions

In the event of an error condition, getpub.cgi will return an XML structure with the number of records found set to zero:

<?xml version="1.0" encoding="iso-8859-1" ?>
<ISFDB>
  <Records>0</Records>
  <Publications>
  </Publications>
</ISFDB>

submission.cgi

The submission.cgi application allows a remote user to post data to the ISFDB. Any of the data payloads defined in the Data Submission Formats article are accepted. The format of the XML data is identical to that used for local submissions, with the exception that the user's license key must be inserted after the Submitter tag. The user's registered login name should be contained within the Submitter tag, and the user's current license key should be contained with the LicenseKey tag. The URL for submission.cgi should appear as follows:

http://www.isfdb.org/cgi-bin/rest/submission.cgi

Submissions are placed in the moderator queue as with an ISFDB edit, and are not integrated into the database until a moderator approves it. As such it is important that you not flood the moderator queue with hundreds of submissions. In general you should only post no more than 20 submissions per session, until they are cleared out by a moderator.

An example submission XML payload follows, with the LicenseKey x'd out:

<?xml version="1.0" encoding="iso-8859-1" ?>
 <NewPub>
   <Submitter>Dissembler</Submitter>
   <LicenseKey>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</LicenseKey>
   <Isbn>1575661292</Isbn>
   <Subject>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Subject>
   <Title>Lady of the Glen: A Novel of 17th-Century Scotland and the Massacre of Glencoe</Title>
   <Year>1997-01-01</Year>
   <Price>$14.95</Price>
   <Publisher>Kensington</Publisher>
   <PubSeries>Time Romances</PubSeries>
   <PubSeriesNum>17</PubSeriesNum>
   <Pages>432</Pages>
   <Authors>
     <Author>Jennifer Roberson</Author>
   </Authors>
   <Binding>tp</Binding>
   <PubType>NOVEL</PubType>
   <Image>http://ecx.images-amazon.com/images/I/519xedh9nrL._SL500_.jpg</Image>
   <Note>Pre-release data generated by Dissembler from Amazon.com website on 2008-5-8</Note>
 </NewPub>

Example python script utilizing submission.cgi

The submission.cgi application uses the http POST method, so it can not be invoked via a web browser. Once a proper XML payload has been constructed as described above, a connection needs to be made to the ISFDB web server, and the appropriate http header needs to be sent, including content type and length information. This example below shows how this can be implemented in python:

import httplib

host = "www.isfdb.org"

def SendXml(xmlmsg):
      webservice = httplib.HTTP(host)
      webservice.putrequest("POST", "/cgi-bin/rest/submission.cgi")
      webservice.putheader("Host", host)
      webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
      webservice.putheader("Content-length", "%d" % len(xmlmsg))
      webservice.endheaders()
      webservice.send(xmlmsg)

      errcode, errmsg, headers = webservice.getreply()
      if errcode != 200:
              resp = webservice.getfile()
              print "Error:", errmsg
      else:
              resp = webservice.getfile()
      resp.close()

Error Conditions

In the event of an error condition, submission.cgi will return an XML structure with a Status of FAIL (success will return OK). The cause of the error can be found within the Error tag:

<?xml version="1.0" encoding="iso-8859-1" ?>
<ISFDB>
  <Status>FAIL</Status>
  <Error>Bad XML data</Error>
</ISFDB>