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.

    1. Edit the application level urls.py file.

 

    1. 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'),   
      ]

 

    1. Edit the wl.py view file.

 

    1. Add an import for an HttpResponse:from django.http import HttpResponse

 

    1. 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") 

 

    1. Edit the page template file.

 

    1. 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>

 

    1. 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>

 

    1. Add page holders for the language and classification that is returned:       <div>           <span id="id_language"></span>

                 -

                 <span id="id_classification"></span>

              </div>

       

 

    1. 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>

 

    1. Create a new application level directory named \static\js. Then, in this directory create the file services.js. 

 

    1. 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();

      }

 

    1. 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

        });

 

    1. 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');

      }

 

  1. 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: