Python REST API Image

How to Create a Web Service with a Python REST API

Introduction

The REST or Representational state transfer concept is often used to design an application programming interface (API) for a web service. It is the prefereed method because it uses less bandwidth than its counterparts and is therefore well suited to large deployments.

In this tutorial we will use python to build a RESTful web service. This web service will be written in only 35 lines of code and will serve to demonstrate the effectiveness of using python in this way. The basic concept used to build it can easily be extended to create very complex applications.

Basic Concept

The basic idea here is that we will use the simple http server that comes with python to respond to a REST query. This is done by defining how our server should respond to an http GET request. Our definition will search the request for specific phrases and if any are found then specific actions are taken.

Our server will be simple and for the sake of demonstrating the concept we will make a server that can carry out two functions: square a number and multiply two numbers. The request will take the following formats:

To square a number the request would be:

http://_serverIP_/api/square/_number_

where _serverIP is the IP address of the server and _number_ is the number to be squared.

To multiply two numbers the request would be:

http://_serverIP_/api/square/_number1_/_number2_

where _serverIP is the IP address of the server and _number1_ and _number2_ are the two numbers to be multiplied.

These are trivial actions but the general concept can be extended to other more powerful and useful functions. Essentially you are getting the full power of python available to create your webservice or application.

See github for a more complex application that uses python to solve simultaneous equations entered through a web page.

Create the Python REST Web Service

Step 1

We will need to import SocketServer and SimpleHTTPServer to handle the http communications and re to handle the string matching and searching.

import SocketServer
import SimpleHTTPServer
import re

Step 2

Next we will define the port to use for our sever and the class that will handle any http requests made on our server.

PORT = 9090

class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
   def do_GET(self):
      if None != re.search('/api/square/*', self.path):
         num = float(self.path.split('/')[-1])
         self.send_response(200)
         self.send_header('Content-type','text/html')
         self.end_headers()
         self.wfile.write(str(num*num)) #call sample function here
         return

   if None != re.search('/api/mult/*', self.path):
      num1 = float(self.path.split('/')[-1])
      num2 = float(self.path.split('/')[-2])
      #This URL will trigger our sample function and send what it returns back to the browser
      self.send_response(200)
      self.send_header('Content-type','text/html')
      self.end_headers()
      self.wfile.write(str(num1*num2)) #call sample function here
      return

   else:
      #serve files, and directory listings by following self.path from
      #current working directory
      SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)

Code Overview

The class defined as CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler) is what will handle the http request made to our server.

The if None != re.search(‘/api/square/*’, self.path): statements will check if the URL submitted has strings that matched the pattern /api/square/. If this is the case then the commands under that if statement is executed.

These commands will first partion the url using the / as a delimiter and the get the last item in that list. This is done with the num = float(self.path.split(‘/’)[-1]) statement.

For example if the url is localhost:9090/api/square/5 then it would be split into [”, ‘api’, ‘square’, ’13’]. The [-1] would take the last item in this list, the ’13’, and the float will convert it into an actual number so the computer can do math with it.

The self.response(200) sends the proper web server response showing that all is OK.

The self.send_headers() sends the appropriate header so our browser knows what kind of data to expect, in this case regular web page data , i.e. HTML. It is followed by a self.end_headers().

The self.write sends the content. In our case it is simply the result of the action, the square of the number.

The multiply section follows a similar concept but the numbers are the last two elements in the list created by the split.

Step 3

Now we can start the server and let it run forever.

httpd = SocketServer.ThreadingTCPServer(('', PORT),CustomHandler)
print "serving at port", PORT
httpd.serve_forever()

The code is pretty self explanatory in what it is doing but for details as to how it works and other options you can view the original docs here.

Full Code

import SocketServer
import SimpleHTTPServer
import re

PORT = 9090

class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        if None != re.search('/api/square/*', self.path):
            num = float(self.path.split('/')[-1])
            print self.path.split('/')
            #This URL will trigger our sample function and send what it returns back to the browser
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write(str(num*num)) #call sample function here
            return
        if None != re.search('/api/mult/*', self.path):
            num1 = float(self.path.split('/')[-1])
            num2 = float(self.path.split('/')[-2])
            #This URL will trigger our sample function and send what it returns back to the browser
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write(str(num1*num2)) #call sample function here
            return
        else:
            #serve files, and directory listings by following self.path from
            #current working directory
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)

httpd = SocketServer.ThreadingTCPServer(('', PORT),CustomHandler)

print "serving at port", PORT
httpd.serve_forever()

Accessing the Python Rest Server

To access the server we now open a browser and type the appropriate URL in the bar.

For example what if we want to square 13, we would type

localhost:9090/api/square/13 in the address bar.

If everything went well the result should be:

Python Rest SS 1

As another example if we want to multiply 77 by 6 the url wuld be:

localhost:9090/api/mult/77/6

and the result would be:

Conclusion

A python REST server was presented that can serve as the basis for a python web service. This web service can allow for data gathering from a Raspberry Pi or similarly powerful and low cost computer to help form the internet of things. The application presented was simple but was more than adequate to demonstrate the basic concept. Please feel free to expand it and use this basic idea to create your own web service for whatever you can imagine.

If you found this helpful don’t forget to share with those you think may be interested. Happy coding :).