Skip to content
This repository has been archived by the owner on May 25, 2020. It is now read-only.

API Interface

NickRuiz edited this page Nov 3, 2010 · 9 revisions

Serverland Web API

The serverland web API lives at dashboard/api/.

All URLs (e.g., dashboard/api/requests/) can optionally specify what format they would like to receive responses in. Requesting that returned data be formatted in JSON, for example, looks like dashboard/api/json/requests/. Other options are yaml or xml. The default return format is json.

All requests made to the web API must be authenticated. This is accomplished using a short web API access key, which can be generated and assigned to a user in the admin interface. Keys are 8-digit hex codes that uniquely identify a user. The key should be sent to the server in the token field.

Querying all worker servers

The following GET request will return a list of all worker servers known to the serverland server:

curl -s http://lns-87005.sb.dfki.de:8383/dashboard/api/workers/?token=53d92161

On success, the server returns 200 with output like the following:

[
     {
         "is_busy": false, 
         "language_pairs": [
             [
                 "eng", 
                 "fre"
             ], 
             [
                 "fre", 
                 "eng"
             ]
         ], 
         "is_alive": true, 
         "shortname": "dummy1", 
         "description": "dummy worker"
     },
     {
         "is_busy": true, 
         "language_pairs": [
             [
                 "por", 
                 "deu"
             ], 
             [
                 "deu", 
                 "por"
             ]
         ], 
         "is_alive": true, 
         "shortname": "dummy2", 
         "description": "dummy worker"
     }   
 ]

Querying a specific worker server

A specific worker server can be queried using the worker server’s shortname:

curl -s http://lns-87005.sb.dfki.de:8383/dashboard/api/workers/dummy1/?token=53d92161

On success, the server returns 200 with output similar to:

{
     "is_busy": false, 
     "language_pairs": [
         [
             "eng", 
             "fre"
         ], 
         [
             "fre", 
             "eng"
         ]
     ], 
     "is_alive": true, 
     "shortname": "dummy1", 
     "description": "dummy worker"
 }

Querying all translation requests

This request will return a list of all translation requests:

curl -s http://lns-87005.sb.dfki.de:8383/dashboard/api/requests/?token=53d92161

On success, the server returns 200 with output similar to:

[
     {
         "created": "2010-08-27 05:19:45", 
         "worker": "dummy1", 
         "owner": "wroberts", 
         "request_id": "c9d64f85f6e447fa877002f0c099f790", 
         "ready": true, 
         "shortname": "fluffy2"
     }, 
     {
         "created": "2010-08-27 14:27:34", 
         "worker": "dummy1", 
         "owner": "wroberts", 
         "request_id": "2a633a9156b34e2e870e79a3b968a558", 
         "ready": true, 
         "shortname": "fluffy3"
     }, 
     {
         "created": "2010-08-27 15:32:28", 
         "worker": "dummy1", 
         "owner": "wroberts", 
         "request_id": "4c697840b3fa4c60923777113a15b3c1", 
         "ready": false, 
         "shortname": "fluffy21"
     }
 ]

Querying a specific translation request

Specific translation requests can be queried using either the translation request’s shortname or its request_id:

curl -s http://lns-87005.sb.dfki.de:8383/dashboard/api/requests/fluffy21/?token=53d92161

On success, the server returns 200 and output similar to:

{
     "created": "2010-08-27 15:32:28", 
     "worker": "dummy1", 
     "owner": "wroberts", 
     "request_id": "4c697840b3fa4c60923777113a15b3c1", 
     "ready": false, 
     "shortname": "fluffy21"
 }

Creating a translation request

Translation requests can be created on the server using an HTTP POST request. To create a new translation request, one must specify the fields shortname, worker (using either the worker’s shortname or id number), source_language and target_language (both set to a supported three-letter ISO 639 code in lower case), and a file object attached to the source_text field.

curl -s -F "token=53d92161" -F "shortname=fluffy123" \
    -F "worker=dummy1" -F "source_language=eng" -F "target_language=fre" \
    -F "[email protected]" \
    http://lns-87005.sb.dfki.de:8383/dashboard/api/requests/

On success, the server returns 201 and a representation of the object created:

{
     "created": "2010-08-27 20:24:58", 
     "worker": "dummy1", 
     "owner": "wroberts", 
     "request_id": "68518b8df7cf4f0993687af0268e8212", 
     "ready": false, 
     "shortname": "fluffy123"
 }

Deleting a translation request

To delete a given translation request, one sends an HTTP DELETE request to the object-specific URI (see Querying a specific translation request, above). Either the translation request’s shortname or request_id may be used to identify which object to delete.

curl -s -X DELETE http://lns-87005.sb.dfki.de:8383/dashboard/api/requests/fluffy123/?token=53d92161

On success, the server returns 204. Subsequent calls will result in response code 410 (GONE).

Fetching translation results

It is possible to download translation results using the web API; this call is exactly the same as querying translation requests, but sent to api/results instead of api/requests. The translation results will be included in the results field of the returned object.

curl -s http://lns-87005.sb.dfki.de:8383/dashboard/api/results/fluffy2/?token=53d92161

On success, the server returns 200, with output similar to the following:

{    "created": "2010-08-27 05:19:45", 
     "worker": "dummy1", 
     "owner": "wroberts", 
     "result": "FILE CONTENTS HERE ..."
     "request_id": "c9d64f85f6e447fa877002f0c099f790", 
     "ready": true, 
     "shortname": "fluffy2"
 }

Using the API interface from Python code

Below is a Python script showing use of the API interface from inside Python code:

import httplib2
import json
import mimetools
import pprint

http = httplib2.Http()
BASE_URL = 'http://lns-87005.sb.dfki.de:8383/dashboard/api/'
TOKEN = '53d92161'

# query the server for workers
response = http.request ( BASE_URL + 'workers/?token={}'.format(TOKEN),
                          method='GET' )
print 'workers:'
print response[0].status, response[0].reason
if response[0].status == 200:
    pprint.pprint(json.loads(response[1]))
print

# query the server for translation requests
response = http.request ( BASE_URL + 'requests/?token={}'.format(TOKEN),
                          method='GET' )
print 'requests:'
print response[0].status, response[0].reason
if response[0].status == 200:
    pprint.pprint(json.loads(response[1]))
print

# submit a new translation request: multipart/form-data
contents = {}
contents['token'] = TOKEN
contents['shortname'] = 'fluffy1234'
contents['worker'] = 'dummy1'
contents['source_language'] = 'eng'
contents['target_language'] = 'fre'
file_name = 'howto.txt'
with open(file_name) as f:
    file_lines = f.read().split('\n')
CRLF = '\r\n'
boundary = '-----' + mimetools.choose_boundary() + '-----'
body = []
for (key,value) in contents.items():
    body.append ( '--' + boundary )
    body.append('Content-Disposition: form-data; name="{}"'.format(key) )
    body.append('')
    body.append(value)
body.append ( '--' + boundary )
body.append ( 'Content-Disposition: form-data; ' +
              'name="source_text"; ' +
              'filename="{}"'.format(file_name) )
body.append('Content-Type: text/plain')
body.append('')
body.extend(file_lines)
body.append ( '--' + boundary )
body.append('')
body = CRLF.join(body)
content_type = 'multipart/form-data; boundary={}'.format(boundary)
header = {'Content-type': content_type, 'Content-length': str(len(body))}

response = http.request(BASE_URL + 'requests/',
                        method='POST', body=body, headers=header)
print 'create new request:'
print response[0].status, response[0].reason
if response[0].status == 201:
    pprint.pprint(json.loads(response[1]))
print

# delete a translation request
response = http.request ( BASE_URL +
                          'requests/fluffy1234/?token={}'.format(TOKEN),
                          method='DELETE' )
print 'delete request:'
print response[0].status, response[0].reason
print

The script will give output similar to the following on success:

workers:
200 OK
{'description': 'dummy worker',
 'is_alive': True,
 'is_busy': False,
 'language_pairs': [['eng', 'fre'], ['fre', 'eng']],
 'shortname': 'dummy1'}

requests:
200 OK
[]

create new request:
201 CREATED
{'created': '2010-09-02 16:15:35',
 'owner': 'wroberts',
 'ready': False,
 'request_id': '28a197b25ee4499698a3ec04b7811709',
 'shortname': 'fluffy1234',
 'worker': 'dummy1'}

delete request:
204 NO CONTENT

Using the API interface via XML-RPC

The dashboard API also includes an adapter server which will translate XML-RPC calls into HTTP requests to the REST backend. The XML-RPC server can be found in the dashboard API directory, and takes as parameters the hostname and port number to bind to, and the URL of the dashboard API which it will wrap. It can be started with something like this:

python xmlrpcserver.py localhost 6666 http://0.0.0.0:8383/mt-serverland

The dashboard API can then be driven using XML-RPC calls. The following code demonstrates this functionality:

import xmlrpclib

s = xmlrpclib.ServerProxy('http://0.0.0.0:6666')

TOKEN = '53d92161'

# print list of worker servers
print 'workers:'
print s.list_workers(TOKEN)
print

# print details on a particular worker server
print 'worker = dummy1:'
print s.list_workers(TOKEN, 'dummy1')
print

# print details on a particular worker server
print 'worker = badshortname:'
try:
    print s.list_workers(TOKEN, 'badshortname')
except xmlrpclib.Fault, e:
    print e
print

# print list of request objects
print 'requests:'
print s.list_requests(TOKEN)
print

# print details on a particular request object
print 'request = fluffy123:'
print s.list_requests(TOKEN, 'fluffy123')
print

# create a translation request
file_name = 'howto.txt'
with open(file_name) as f:
    file_contents = f.read()
print 'create request:'
print s.create_translation(TOKEN,
                           'fluffy12345',
                           'dummy1',
                           'eng',
                           'fre',
                           file_name,
                           file_contents)
print

# delete a translation request
print 'delete request = fluffy12345:'
print s.delete_translation(TOKEN, 'fluffy12345')
print

# fetch results
print 'fetch results on request = fluffy123:'
print s.list_results(TOKEN, 'fluffy123')
print

This code will give output similar to the following:

workers:
{'is_alive': True, 'language_pairs': [['eng', 'fre'], ['fre', 'eng']],
 'shortname': 'dummy1', 'description': 'dummy worker', 'is_busy': False}

worker = dummy1:
{'is_alive': True, 'language_pairs': [['eng', 'fre'], ['fre', 'eng']],
 'shortname': 'dummy1', 'description': 'dummy worker', 'is_busy': False}

worker = badshortname:
<Fault 1: "<type 'exceptions.Exception'>:NOT FOUND">

requests:
{'created': '2010-09-08 15:54:35', 'worker': 'dummy1', 'owner': 'wroberts',
 'request_id': '0c25ad42d0ea492490fe85514957e64f', 'ready': True,
 'shortname': 'fluffy123'}

request = fluffy123:
{'created': '2010-09-08 15:54:35', 'worker': 'dummy1', 'owner': 'wroberts',
 'request_id': '0c25ad42d0ea492490fe85514957e64f', 'ready': True,
 'shortname': 'fluffy123'}

create request:
{'created': '2010-09-08 16:09:34', 'worker': 'dummy1', 'owner': 'wroberts',
 'request_id': '3c007983a7a743428340ce0d8f49d991', 'ready': False,
 'shortname': 'fluffy12345'}

delete request = fluffy12345:
True

fetch results on request = fluffy123:
{'created': '2010-09-08 15:54:35', 'worker': 'dummy1', 'owner': 'wroberts',
 'result': 'RESULT_TEXT', 'request_id': '0c25ad42d0ea492490fe85514957e64f',
 'ready': True, 'shortname': 'fluffy123'}