Make your new functionality available as a REST service
Now that you created a function that both translates and classifies, you will make that function available as a REST API.
-
- Edit the application level urls.py file.
- Edit the application level urls.py file.
-
- Add the route to the new url – process:
# -*- coding: utf-8 -*-
from django.conf.urls import include, url
from .views import wl
urlpatterns = [
url(r'^lang$', wl.index, name='langhome'),
url(r'^process$', wl.process, name='apiprocess'),
url(r'^converse$', wl.converse, name='apiconversation'),
]
- Add the route to the new url – process:
-
- Edit the wl.py view file.
- Edit the wl.py view file.
-
- Add an import for an HttpResponse:
from django.http import HttpResponse
- Add an import for an HttpResponse:
-
- Write the API function:
@csrf_exempt
def process(request):
targetlang = 'en'
classification = {"className":"unknown"}
results = {}
theData = {"error":"If you see this message then something has gone badly wrong"}
validRequest = False
logger.info("Checking request method")
if request.method == "GET":
logger.info("Request is a GET")
data = "Hard coded string to test that API is returning something"
validRequest = True
if request.method == "POST":
logger.info("Request is a POST")
form = Form_language(request.POST)
if form.is_valid():
data = form.cleaned_data['txtdata']
logger.info("Text to be processed is %s " % data)
validRequest = True
else:
logger.info("The form is not valid")
if validRequest:
del theData["error"]
try:
primarylang = theData['language'] = identifyLanguage(data)["language"]
logger.info('checking languages')
if targetlang != primarylang:
logger.info('checking translation support')
supportedModels = checkForTranslation(primarylang, targetlang)
if supportedModels:
englishTxt = performTranslation(data, primarylang, targetlang)
classification = classifyTheText(englishTxt)
else:
classification = classifyTheText(data)
theData['classification'] = classification['className']
except WatsonException as err:
theData['error'] = err;
else:
theData['error'] = "The form data is invalid";
results["results"] = theData
return HttpResponse(json.dumps(results), content_type="application/json")
This function checks for GET methods. If a GET is sent to the API, then a dummy hardcoded response is sent. This can be changed into an error message, but it’s better to start with the GET method because a GET method is easier to test for that a POST method.
if request.method == "GET":
logger.info("Request is a GET")
data = "Hard coded string to test that API is returning something"
validRequest = True
Then, it tests for a POST method. This function is expecting its input in the form of a POST method, and it will use the same form as shown previously to extract the input fields.
if request.method == "POST":
logger.info("Request is a POST")
form = Form_language(request.POST)
if form.is_valid():
data = form.cleaned_data['txtdata']
logger.info("Text to be processed is %s " % data)
validRequest = True
else:
logger.info("The form is not valid")
If the form is valid, then both language identification and natural language classification can be involved.
if validRequest:
del theData["error"]
try:
primarylang = theData['language'] = identifyLanguage(data)["language"]
if targetlang != primarylang:
supportedModels = checkForTranslation(primarylang, targetlang)
if supportedModels:
englishTxt = performTranslation(data, primarylang, targetlang)
classification = classifyTheText(englishTxt)
else:
classification = classifyTheText(data)
theData['classification'] = classification['className']
except WatsonException as err:
theData['error'] = err;
else:
theData['error'] = "The form data is invalid";
Return the response as JSON data:
results["results"] = theData
return HttpResponse(json.dumps(results), content_type="application/json")
- Write the API function:
-
- Edit the page template file.
- Edit the page template file.
-
- Add a button that when clicked, the event calls the JavaScript function onProcessClick. It is passed the URL for the API as a parameter:
<button class="rowselector" onclick="javascript:onProcessClick('{% url 'watsonlang:apiprocess' %}')">
As REST Call
</button>
- Add a button that when clicked, the event calls the JavaScript function onProcessClick. It is passed the URL for the API as a parameter:
-
- Because your application now requires JavaScript, add the following line to the top of the page.
<div id="no-script"class="bg-info">This application needs JavaScript enabled in your browser!</div>
- Because your application now requires JavaScript, add the following line to the top of the page.
-
- Add page holders for the language and classification that is returned:
<div>
<span id="id_language"></span>
-
<span id="id_classification"></span>
</div>
- Add page holders for the language and classification that is returned:
-
- At the bottom (still inside the body), add a link to the jQuery CDN and to a new JavaScript file named services.js:
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="/static/js/services.js"></script>
</body>
- At the bottom (still inside the body), add a link to the jQuery CDN and to a new JavaScript file named services.js:
-
- Create a new application level directory named \static\js. Then, in this directory create the file services.js.
- Create a new application level directory named \static\js. Then, in this directory create the file services.js.
-
- In the services.js file, add lines to check whether JavaScript is supported. If it is supported, remove the warning message from the page:
$(document).ready(function() {
javascriptCheck();
});
function javascriptCheck() {
// if javascript is enabled on the browser then can remove the warning message
$('#no-script').remove();
}
- In the services.js file, add lines to check whether JavaScript is supported. If it is supported, remove the warning message from the page:
-
- Add the OnProcessClick function that is invoked when the API button on the page is clicked.
function onProcessClick(urlForAPI){
console.log('Will be Processing REST API ', urlForAPI);
$('#id_language').text('');
$('#id_classification').text('');
$('#id_errormessagefromserver').text('Service has been invoked, waiting for response');
var ajaxData = "txtdata=" + $('#id_txtdata').val();
$.ajax({
type: 'POST',
url: urlForAPI,
data: ajaxData,
success: processOK,
error: processNotOK
});
- Add the OnProcessClick function that is invoked when the API button on the page is clicked.
-
- Add the error return function:
function processNotOK() {
// There was a problem in the request
console.log('REST API call failed');
$('#id_errormessagefromserver').text('Service has failed');
}
- Add the error return function:
- Try using the client by clicking the As REST Call button.
You can also use the URL directly. The GET method will return a classification on the hardcoded test.
You will not be able to test the POST API in this way because it requires that you to send form data with fields that map to the form being used. In an earlier lab, you created the following form:class Form_language(forms.Form):
txtdata = forms.CharField(required=True, label="Text to Process", widget=forms.Textarea)
To test the POST API, you will need a REST client that will allow you to send the form data in the structure that the API is expecting, for example, using Postman as the REST client to test the POST API: