NU IT
Northwestern University Information Technology
MorphAdorner Northwestern
 
MorphAdorner Server: Accessing the server programmatically

How the MorphAdorner Server operates

MorphAdorner Server, or MAServer for short, is an HTTP-based server which exposes MorphAdorner facilities over the web. Communication with the server takes place using ordinary HTTP protocol GET, POST and OPTIONS requests. The input format for all services is sent to the server encoded as an HTML form. Most services return output in one of four selectable formats: JSON, XML, HTML, or plain text. The remaining services which accept XML files as input only return XML files as output.

MAServer is written using the Restlet web framework.

MAServer can be accessed using an ordinary web browser or via custom programs. Any programming language can be used as long as it supports sending HTML form data to the server over HTTP, and can receive responses over HTTP.

The simplest way to access the server is to use forms in plain web pages. Sample web forms appear on the page defining the service parameters for each service.

Common features of the services

All of the services support cross-origin resource sharing (CORS). This means you can access the services from a JavaScript script running on any client system. Most web browsers issued the past few years support CORS, allowing you to use dynamic scripting (Ajax) to access MAServer and embed the results in web pages dynamically.

Support of GET versus POST

All of the plain text services allow access using either HTTP GET or POST. POST is better when the amount of text to process is larger than a few hundred characters, as some systems do not handle large amounts of text through a GET request.

The TEI XML services that accept files as input or output only work with POST requests.

Media format of service responses

The plain text services can generate responses in four different formats.

  • Plain utf-8 text. This is convenient if you want the results in a simple text format.
  • HTML. This is convenient if you want to embed the results in a web page -- for example, if you intend to display the results using Ajax calls from a Javascript program.
  • JSON. This is convenient for access from script languages like Python.
  • XML. This is convenient if you want to postprocess the results using XSLT scripts.

The TEI XML services always generate responses in XML format. The response may optionally be sent as an attached file, which is the most convenient response format when the request is submitted from a plain web form.

Using WADL to view the service query parameters

You may also access the WADL (web application description language) definitions for all the services using a web browser. Start the local version of the MAServer server using the runmaserver.bat (Windows) or runmaserver script (Unix and Mac OS X). Then open the following site in your web browser:

http://localhost:8182/?method=options

The WADL for an individual service can be retrieved using

http://localhost:8182/servicename?method=options

and replacing "servicename" with the name of the MAServer service for which you want the documentation. For example, the WADL for the lemmatizer service can be retrieved with:

http://localhost:8182/lemmatizer?method=options

If your system provides the curl utility, you can retrieve the XML formatted WADL descriptions for all services using curl in a console/terminal window as follows:

curl http://localhost:8182/?method=options

You can retrieve the WADL XML for a particular service -- say the lemmatizer service -- as follows:

curl http://localhost:8182/lemmatizer?method=options

You can also retrieve the WADL descriptions from a remotely installed MAServer installation by replacing "localhost:8182" with the server name and server port of the remote server. Examples:

http://myremotehost.com/maserver/?method=options
http://myremotehost.com/maserver/lemmatizer/?method=options

Replace "myremotehost.com" with the name (and optionally the port number) of your remote MAServer instance.

Accessing the server from a web page

The simplest way to access the server is using an ordinary web form on a web page. Following are two examples: using the plain-text Lemmatizer service, and using the TEI XML tokenizer service.

Example: accessing the Lemmatizer service

Here is a sample form for accessing the Lemmatizer service using a POST request. You must replace "myremotehost.com" in the form action= parameter with the name of your MorphAdorner server.

<form accept-charset="UTF-8" method="post"
      action="http://myremotehost.com/maserver/lemmatizer"
      target="_blank"
      name="lemmatizer">
<table cellpadding="0" cellspacing="5">
<tr>
<td><strong>Spelling:</strong></td>
<td><input type="text" name="spelling" size="20" value="" /></td>
</tr>
<tr>
<td>
<td><input type="checkbox" name="standardize" value="true" checked="checked" />Standardize spelling</td>
</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><strong>Primary word class:</strong></td>
<td>
<select name="wordClass">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td><strong>Secondary word class:</strong></td>
<td>
<select name="wordClass2">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td valign="top">
<strong>
Lexicon:</strong>
</td>
<td>
<input type="radio" name="corpusConfig" value="eme">Early Modern English</input><br />
<input type="radio" name="corpusConfig" value="ece">Eighteen Century English</input><br />
<input type="radio" name="corpusConfig" value="ncf" checked="checked">Nineteenth Century Fiction</input>
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td valign="top">
<strong>Results format:</strong>
</td>
<td>
<input type="radio" name="media" value="json">JSON format</input><br />
<input type="radio" name="media" value="xml" checked="checked">XML format</input><br />
<input type="radio" name="media" value="html">HTML format</input><br />
<input type="radio" name="media" value="text">Text format</input>
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>
<input type="submit" name="lemmatize" value="Lemmatize" />
</td>
</tr>
</table>
</form>

After the user fills out the form and selects the Lemmatize button, the results will be returned in the selected format onto a new web page.

Example: accessing the Lemmatizer service using Javascript and Ajax

We can modify the form above slightly to demonstrate accessing the server and inserting the results into a <div> on the same page. We use the jQuery library to provide the Javascript and Ajax access. The jQuery libraries (jquery-1.10.1.min.js and jquery.form.min.js) should be inserted in the <head> section of the web page. We also add a custom function ajaxifyForm stored in ajaxify.js which wraps the JQuery functions to convert a standard web form into an Ajax compatible form.

<script src="jquery-1.10.1.min.js" type="text/javascript">
</script>
<script src="jquery.form.min.js" type="text/javascript">
</script>
<script src="ajaxify.js" type="text/javascript">
</script>

The contents of ajaxify.js is:

function ajaxifyForm( formID )
{
    var options =
    {
        target: '#results',           // Target element to be updated with
                                      // server response.
        error:
           function( xhr, textStatus, errorThrown )
           {
              $('#results').empty().append( "<strong>Error:</strong>&nbsp;" );
              $('#results').append(
                  "Server returned error code " + xhr.status + ": " );
              $('#results').append( textStatus + ": " + errorThrown );
           }
    };
                                      // Bind to the form's submit event.
    $( "#" + formID ).submit
    (
        function()
        {
                                      // Inside event callbacks 'this' is
                                      // the DOM element so wrap it in a
                                      // jQuery object and then invoke
                                      // ajaxSubmit.
            $(this).ajaxSubmit( options );
                                      // Return false to prevent standard
                                      // browser submit and page
                                      // navigation.
            return false;
        }
    );
}

The lemmatizer request form is essentially the same as the plain web form except that we force selection of the HTML result type using a hidden input form field. This is so we can insert the HTML results directly into the "results" div element.

<input type="hidden" name="media" value="html" />

Following the end of the form definition we add a jQuery script request which converts the form into an Ajax request using the ajaxifyForm we defined above. We then add a <div> with the name "result" which will hold the HTML formatted results return by the server.

<script type="text/javascript">
    $(document).ready( ajaxifyForm( 'lemmatizer' ) );
<div id="results" name="results" class="results">
</div>

After the user fills out the form and selects the Lemmatize button, the results will be returned in the results div below the form.

Here is the entire sample web page for requesting an "ajaxified" lemmatization. Again, you must replace "myremotehost.com" in the form action= parameter with the name of your MorphAdorner server.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Access Lemmatizer Service using Javascript/Ajax</title>
<script src="jquery-1.10.1.min.js" type="text/javascript">
</script>
<script src="jquery.form.min.js" type="text/javascript">
</script>
<script src="ajaxify.js" type="text/javascript">
</script>
</head>
<body>
<form accept-charset="UTF-8" method="post"
      action="http://myremotehost.com/maserver/lemmatizer"
      name="lemmatizer" id="lemmatizer">
<table cellpadding="0" cellspacing="5">
<tr>
<td><strong>Spelling:</strong></td>
<td><input type="text" name="spelling" size="20" value="" /></td>
</tr>
<tr>
<td>
<td><input type="checkbox" name="standardize" value="true" checked="checked" />Standardize spelling<br />
<input type="hidden" name="media" value="html" />
</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><strong>Primary word class:</strong></td>
<td>
<select name="wordClass">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td><strong>Secondary word class:</strong></td>
<td>
<select name="wordClass2">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td valign="top">
<strong>
Lexicon:</strong>
</td>
<td>
<input type="radio" name="corpusConfig" value="eme">Early Modern English</input><br />
<input type="radio" name="corpusConfig" value="ece">Eighteen Century English</input><br />
<input type="radio" name="corpusConfig" value="ncf" checked="checked">Nineteenth Century Fiction</input>
</td>
</tr>
<tr>
<td>
<input type="submit" name="lemmatize" value="Lemmatize" />
</td>
</tr>
</table>
</form>
<script type="text/javascript">
    $(document).ready( ajaxifyForm( 'lemmatizer' ) );
</script>
<div id="results" name="results">
</div>
</body>
</html>

Example: accessing the Lemmatizer service using an iframe

Some users may elect to turn off JavaScript in their browsers. In this case the Ajax solution above will not work. An alternative is to display the results of the query in an internal frame or iframe.

The lemmatizer request form is once again mostly the same as the plain web form except that we force selection of the HTML result type using a hidden input form field and set the name of an iframe as the target to receive the lemmatizer results using target=. The main downside of the iframe solution is that the results may display in a different style than the rest of the text on the page. The seamless option on the iframe definition is intended to correct this, but few browsers support this yet.

The iframe approach is also useful if you want to embed a MorphAdorner server facility into another web page over which you may not have full control. For example, you can use the iframe approach to add a MorphAdorner lemmatizer form to a WordPress blog posting.

Here is a sample form for requesting an iframe version of lemmatization. The iframe target element which receives the lemmatization results is named "resultsiframe". Again, you must replace "myremotehost.com" in the form action= parameter with the name of your MorphAdorner server.

<form accept-charset="UTF-8" method="post"
      action="http://myremotehost.com/maserver/lemmatizer"
      target="resultsiframe"
      name="lemmatizer">
<table cellpadding="0" cellspacing="5">
<tr>
<td><strong>Spelling:</strong></td>
<td><input type="text" name="spelling" size="20" value="" /></td>
</tr>
<tr>
<td>
<td><input type="checkbox" name="standardize" value="true" checked="checked" />Standardize spelling</td>
<input type="hidden" name="media" value="html" />
</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><strong>Primary word class:</strong></td>
<td>
<select name="wordClass">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td><strong>Secondary word class:</strong></td>
<td>
<select name="wordClass2">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td valign="top">
<strong>
Lexicon:</strong>
</td>
<td>
<input type="radio" name="corpusConfig" value="eme">Early Modern English</input><br />
<input type="radio" name="corpusConfig" value="ece">Eighteen Century English</input><br />
<input type="radio" name="corpusConfig" value="ncf" checked="checked">Nineteenth Century Fiction</input>
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>
<input type="submit" name="lemmatize" value="Lemmatize" />
</td>
</tr>
</table>
</form>
<iframe id="resultsiframe" name="resultsiframe" frameborder="0"
        width="100%" scrolling="auto" seamless="true" height="500px"
        frameborder="0"
        >
</iframe>

Using an iframe as a fallback when JavaScript is not enabled

We can combine the Ajax/JavaScript and iframe approaches. If JavaScript is enabled, we use the Ajax approach. If JavaScript is not enabled, we fallback to the iframe approach. The <noscript> block which defines the iframe is only used if JavaScript is disabled or not supported. This combined approach works in the majority of modern web browsers.

Here is the entire sample web page for requesting an Ajaxified lemmatization result with a fallback to an iframe version when JavaScript is not enabled. As before, you must replace "myremotehost.com" in the form action= parameter with the name of your MorphAdorner server.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Access Lemmatizer Service using Javascript/Ajax</title>
<script src="jquery-1.10.1.min.js" type="text/javascript">
</script>
<script src="jquery.form.min.js" type="text/javascript">
</script>
<script src="ajaxify.js" type="text/javascript">
</script>
</head>
<body>
<form accept-charset="UTF-8" method="post"
      action="http://myremotehost.com/maserver/lemmatizer"
      target="resultsiframe"
      name="lemmatizer" id="lemmatizer">
<table cellpadding="0" cellspacing="5">
<tr>
<td><strong>Spelling:</strong></td>
<td><input type="text" name="spelling" size="20" value="" /></td>
</tr>
<tr>
<td>
<td><input type="checkbox" name="standardize" value="true" checked="checked" />Standardize spelling<br />
<input type="hidden" name="media" value="html" />
</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><strong>Primary word class:</strong></td>
<td>
<select name="wordClass">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td><strong>Secondary word class:</strong></td>
<td>
<select name="wordClass2">
<option value="" selected="selected"></option>
<option value="adjective">adjective</option>
<option value="adverb">adverb</option>
<option value="compound">compound</option>
<option value="conjunction">conjunction</option>
<option value="infinitive-to">infinitive-to</option>
<option value="noun">noun</option>
<option value="noun-possessive">noun-possessive</option>
<option value="preposition">preposition</option>
<option value="pronoun">pronoun</option>
<option value="pronoun-possessive">pronoun-possessive</option>
<option value="pronoun-possessive-determiner">pronoun-possessive-determiner</option>
<option value="verb">verb</option>
</select>
</td>
</tr>
<tr>
<td valign="top">
<strong>
Lexicon:</strong>
</td>
<td>
<input type="radio" name="corpusConfig" value="eme">Early Modern English</input><br />
<input type="radio" name="corpusConfig" value="ece">Eighteen Century English</input><br />
<input type="radio" name="corpusConfig" value="ncf" checked="checked">Nineteenth Century Fiction</input>
</td>
</tr>
<tr>
<td>
<input type="submit" name="lemmatize" value="Lemmatize" />
</td>
</tr>
</table>
</form>
<script type="text/javascript">
    $(document).ready( ajaxifyForm( 'lemmatizer' ) );
</script>
<noscript>
<iframe id="resultsiframe" name="resultsiframe" frameborder="0"
        width="100%" scrolling="auto" seamless="true" height="500px"
        frameborder="0"
        >
</iframe>
</noscript>
<div id="results" name="results">
</div>
</body>
</html>

Example: accessing the Tokenize TEI file service

Here is a sample form for accessing the TEI XML tokenizer service using a POST request. You must replace "myremotehost.com" in the form action= parameter with the name of your MorphAdorner server.

<form accept-charset="UTF-8" method="post"
      action="http://myremotehost.com/maserver/teitokenizer"
      target="_blank"
      enctype="multipart/form-data" name="teitokenizer">
<table cellpadding="0" cellspacing="5">
<tr>
<td>
<strong>TEI XML file:</strong>
</td>
<td>
<input type="file" name="teifile" size="50">
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="checkbox" name="resultsAsAttachedFile" value="true"
       checked="checked"/>
Send results as attached file
</td>
</tr>
<tr>
<td valign="top">
<strong>
Lexicon:</strong>
</td>
<td>
<input type="radio" name="corpusConfig" value="eme">Early Modern English</input><br />
<input type="radio" name="corpusConfig" value="ece">Eighteen Century English</input><br />
<input type="radio" name="corpusConfig" value="ncf" checked="checked">Nineteenth Century Fiction</input>
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
<td>
&nbsp;
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="tokenize" value="Tokenize" />
</td>
</tr>
</table>
</form>

After the user fills out the form and selects the Tokenize button, the tokenized TEI file will be returned either as an attached file (if the "Send results as attached file" option is selected) or as an XML stream (on a separate web page). In many cases it may be simplest to force the selection of the "Send results as attached file" option.

Accessing the server from a Java program

You can access the MorphAdorner Server using any programming language which supports access to remote servers using the HTTP protocol. However, since MAServer is written using the Restlet framework, it is convenient to use the Restlet libraries to access the server from a Java program.

Example: accessing the Lemmatizer service from a Java program

Here is a simple Java program which accesses the Lemmatizer service using the Restlet libraries. As an example, we will request the lemma form of the obsolete spelling "strykynge" using the Early Modern English corpus.

import org.restlet.*;
import org.restlet.resource.*;
import edu.northwestern.at.morphadorner.server.*;
public class trylemmatizer
{
    public static void main( String[] args )
    {
                                //    Create lemmatizer client resource. 
        ClientResource resource    =
            new ClientResource
            (
                "http://myremotehost.com/maserver/lemmatizer"
            );
                                //    Add query parameters. 
        resource.addQueryParameter( "spelling" , "strykynge" );
        resource.addQueryParameter( "corpusConfig" , "eme" );
        resource.addQueryParameter( "wordClass" , "verb" );
        resource.addQueryParameter( "standardize" , "true" );
        resource.addQueryParameter( "media" , "xml" );
                                //    Get result from server. 
        try
        {
            LemmatizerResult result    = resource.get( LemmatizerResult.class );
                                //    Display resultant lemma. 
            System.out.println( "lemma: " + result.lemma );
        }
        catch ( Exception e )
        {
            System.out.println( "Error: " + e.getMessage() );
        }
    }
}

We create a Restlet client resource, add the service parameters, and perform an HTTP GET request. We request the results to be returned as XML because Restlet can automtically convert the XML to a Java object -- in this case, a LemmatizerResult object. We then display the resultant lemma value from the LemmatizerResult object, or display an error message if the server returns an error.

Example: accessing the Tokenize TEI file service

This example demonstrates sending a TEI XML file to the server for tokenization using a POST request. We request the tokenized output as XML, store it in a generic Representation object, and pull out the tokenized text from the Representation using the getText method. We then display the tokenized text or an error message, if any, from the server.

import org.restlet.*;
import org.restlet.ext.html.*;
import org.restlet.data.*;
import org.restlet.representation.*;
import org.restlet.resource.*;
import edu.northwestern.at.morphadorner.server.*;
public class tryteitokenizer
{
    public static void main( String[] args )
    {
                                //    Create client resource. 
        ClientResource resource    =
            new ClientResource
            (
                "http://myremotehost.com/maserver/teitokenizer"
            );
                                //    Create form with query parameters. 
        FormDataSet form    = new FormDataSet();
        form.setMultipart( true );
        form.getEntries().add( new FormData( "corpusConfig" , "ncf" ) );
        form.getEntries().add( new FormData( "media" , "xml" ) );
        form.getEntries().add(
            new FormData( "resultsAsAttachedFile" , "false" ) );
        FileRepresentation file    =
            new FileRepresentation(
                "j:/marylamb.xml" , MediaType.APPLICATION_XML );
        form.getEntries().add( new FormData(" teifile" , file ) );
                                //    Get result XML from server. 
        try
        {
            Representation result    = resource.post( form );
            System.out.println( result.getText() );
        }
        catch ( Exception e )
        {
            System.out.println( "Error: " + e.getMessage() );
        }
    }
}
Home
 
Announcements and News
 
Documentation
 
Download MorphAdorner
 
Glossary
 
Helpful References
 
Licenses
 
Server
 
Talks
 
Tech Talk