Working with command-line tools - curl and httpie

We will start composing and sending HTTP requests with the curl and HTTPie command-line tools, which we introduced in Chapter 1, Developing RESTful APIs and Microservices with Flask 1.0.2, in the section named Working with command-line tools - curl and httpie. Make sure you read this section before executing the next examples.

Whenever we compose HTTP requests with the command line, we will use two versions of the same command: the first one with HTTPie and the second one with curl. This way, you will be able to use the most convenient for you.

Make sure you leave the Tornado 5.1.1 development server running. Don't close the Terminal or Command Prompt that is running this development server. Open a new Terminal in macOS or Linux, or a Command Prompt in Windows, activate the virtual environment we have been using, and run the following command. We will compose and send an HTTP PATCH request to turn on the hexacopter and set its motor speed to 50 RPMs. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1101.txt file:

    http PATCH ":8888/hexacopters/1" motor_speed_in_rpm=50

The following is the equivalent curl command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1102.txt file:

 curl -iX PATCH -H "Content-Type: application/json" -d '{"motor_speed_in_rpm":50}' "localhost:8888/hexacopters/1"
  

The previous commands will compose and send the HTTP request PATCH http://localhost:8888/hexacopters/1 with the following JSON key-value pair:

{  
   "motor_speed_in_rpm": 50 
} 

The request specifies /hexacopters/1, and therefore Tornado will iterate over the list of tuples with regular expressions and request classes, and will match the '/hexacopters/([0-9]+)' regular expression. Tornado will create an instance of the HexacopterHandler class and run the HexacopterHandler.patch method with 1 as the value for the id argument.

As the HTTP verb for the request is PATCH, Tornado calls the patch method. If the hexacopter's speed is successfully set, the method returns an HTTP 200 OK status code and the key-value pairs with the speed and status for the recently updated hexacopter serialized to JSON in the response body. The following lines show an example response for the HTTP request:

    HTTP/1.1 200 OK
    Content-Length: 48
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 30 Oct 2018 17:01:06 GMT
    Server: TornadoServer/5.1.1
    
    {
        "is_turned_on": true, 
        "motor_speed_in_rpm": 50
    }
  

Now, we will write a command to compose and send an HTTP GET request to retrieve the status and the motor speed for the hexacopter. Run the following command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1103.txt file:

    http ":8888/hexacopters/1"

The following is the equivalent curl command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1104.txt file:

    curl -iX GET -H "localhost:8888/hexacopters/1"

The previous commands will compose and send the following HTTP request: GET http://localhost:8888/hexacopters/1. The request specifies /hexacopters/1, and therefore it will match the '/hexacopters/([0-9]+)' regular expression and run the HexacopterHandler.get method with 1 as the value for the id argument. As the HTTP verb for the request is GET, Tornado calls the get method. The method retrieves the hexacopter's status and generates a JSON response with the key-value pairs.

The following lines show an example response for the HTTP request. The first lines show the HTTP response headers, including the status (200 OK) and the content type (application/json). After the HTTP response headers, we can see the details for the hexacopter's status in the JSON response:

    HTTP/1.1 200 OK
    Content-Length: 48
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 30 Oct 2018 17:06:10 GMT
    Etag: "172316bfc38ea5a04857465b888cff65c72a228c"
    Server: TornadoServer/5.1.1
    
    {
        "is_turned_on": true, 
        "motor_speed_in_rpm": 50
    }
  

After we run the two requests, we will see the following lines in the window that is running the Tornado HTTP server. The output shows the results of executing the print statements that describe when the code started setting or retrieving information, and when it finished:

    I've started setting the hexacopter's motor speed
    I've finished setting the hexacopter's motor speed
    I've started retrieving the hexacopter's status
    I've finished retrieving the hexacopter's status

The different methods we coded in the request handler classes end up calling time.sleep to simulate the operations taking some time with the hexacopter. In this case, our code is running with a synchronous execution, and therefore each time we compose and send a request, the Tornado server is blocked until the operation with the hexacopter finishes and the method sends the response. We will create a new version of this API that will use an asynchronous execution later, and will understand the advantages of Tornado's non-blocking features. However, first, we will understand how the synchronous version of the API works.

The following screenshot shows two Terminal windows side by side on macOS. The Terminal window on the left-hand side is running the Tornado HTTP server and displays the messages printed in the methods that process the HTTP requests. The Terminal window on the right-hand side is running http commands to generate the HTTP requests. It is a good idea to use a similar configuration to check the output while we compose and send the HTTP requests:

Now, we will write a command to compose and send an HTTP request to retrieve a hexacopter that doesn't exist. Remember that we just have one hexacopter in our drone. Run the following command to try to retrieve the status for a hexacopter with an invalid id. We must make sure that the utilities display the headers as part of the response to see the returned status code. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1105.txt file:

    http ":8888/hexacopters/5"

The following is the equivalent curl command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1106.txt file:

    curl -iX GET "localhost:8888/hexacopters/5"

The previous commands will compose and send the following HTTP request: GET http://localhost:8888/hexacopters/5. The request is the same as the previous one we have analyzed, with a different number for the id parameter. The server will run the HexacopterHandler.get method with 5 as the value for the id argument. The id is not equal to 1, and therefore the code will return an HTTP 404 Not Found status code. The following lines show an example header response for the HTTP request:

    HTTP/1.1 404 Not Found
    Content-Length: 0
    Content-Type: text/html; charset=UTF-8
    Date: Tue, 30 Oct 2018 17:22:13 GMT
    Server: TornadoServer/5.1.1

Now, we will write a command to compose and send an HTTP GET request to retrieve the altitude from the altimeter included in the drone, expressed in meters. Run the following command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1107.txt file:

    http ":8888/altimeters/1?unit=meters"

The following is the equivalent curl command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1108.txt file:

    curl -iX GET -H "localhost:8888/altimeters/1?unit=meters"

The previous commands will compose and send the following HTTP request: GET http://localhost:8888/altimeters/1?unit=meters. The request specifies /altimeters/1, and therefore it will match the '/altimeters/([0-9]+)' regular expression and run the AltimeterHandler.get method with 1 as the value for the id argument. As the HTTP verb for the request is GET, Tornado calls the get method. The method will retrieve the value for the unit query parameter, retrieve the altimeter's altitude in feet, convert it to meters, and generate a JSON response with the key-value pairs.

The following lines show an example response for the HTTP request:

    HTTP/1.1 200 OK
    Content-Length: 49
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 30 Oct 2018 17:35:59 GMT
    Etag: "e6bef0812295935473bbef8883a144a7740d4838"
    Server: TornadoServer/5.1.1
    
    {
        "altitude": 126.7968, 
        "unit": "meters"
    }
  

Now, we will write a command to compose and send an HTTP GET request to retrieve the altitude from the altimeter included in the drone, expressed in the default unit: feet. Run the following command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1109.txt file:

    http ":8888/altimeters/1" 

The following is the equivalent curl command. The code file for the sample is included in the restful_python_2_10_01 folder, in the Tornado01/cmd/cmd1110.txt file:

    curl -iX GET -H "localhost:8888/altimeters/1"

The previous commands will compose and send the following HTTP request: GET http://localhost:8888/altimeters/1. The request specifies /altimeters/1, and therefore it will match the '/altimeters/([0-9]+)' regular expression and run the AltimeterHandler.get method with 1 as the value for the id argument. As the HTTP verb for the request is GET, Tornado calls the get method. In this case, there is no unit query parameter, and therefore the method will retrieve the altimeter's altitude in feet and generate a JSON response with the key-value pairs.

The following lines show an example response for the HTTP request:

    HTTP/1.1 200 OK
    Content-Length: 33
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 30 Oct 2018 17:38:58 GMT
    Etag: "985cc8ce1bddf8a96b2a06a76d14faaa5bc03c9b"
    Server: TornadoServer/5.1.1
    
    {
        "altitude": 263, 
        "unit": "feet"
    }
  
Notice that the altitude value is a random number generated each time we require it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.5.239