Running tests to check that throttling policies work as expected

Before Django runs the main body of a class-based view, it performs the checks for each throttle class specified in the throttle classes settings. In the drones and pilots-related views, we wrote code that overrides the default settings.

If a single throttle check fails, the code will raise a Throttled exception and Django won't execute the main body of the view. The cache is responsible for storing previous request information for throttling checking.

Now, we can launch Django's development server to compose and send HTTP requests to understand how the configured throttling rules, combined with all the previous configurations, work. Execute any of the following two commands based on your needs to access the API in other devices or computers connected to your LAN. Remember that we analyzed the difference between them in Chapter 3, Creating API Views, in the Launching Django's development server section.

    python manage.py runserver
    python manage.py runserver 0.0.0.0:8000

After we run any of the previous commands, the development server will start listening at port 8000.

Now, we will compose and send the following HTTP GET request without authentication credentials to retrieve the first page of the competitions four times:

    http :8000/competitions/

We can also use the features of the shell in macOS or Linux to run the previous command four times with just a single line with a bash shell. The command is compatible with a Cygwin terminal in Windows. We must take into account that we will see all the results one after the other and we will have to scroll to understand what happened with each execution:

    for i in {1..4}; do http :8000/competitions/; done;

The following line allows you to run the command four times with a single line in Windows PowerShell:

    1..4 | foreach { http :8000/competitions/ }

The following is the equivalent curl command that we must execute four times:

    curl -iX GET localhost:8000/competitions/

The following is the equivalent curl command that is executed four times with a single line in a bash shell in a macOS or Linux, or a Cygwin terminal in Windows:

    for i in {1..4}; do curl -iX GET localhost:8000/competitions/; done;

The following is the equivalent curl command that is executed four times with a single line in Windows PowerShell:

    1..4 | foreach { curl -iX GET localhost:8000/competitions/ }

The Django REST framework won't process the request number 4. The AnonRateThrottle class is configured as one of the default throttle classes and its throttle settings specify a maximum of 3 requests per hour. Hence, we will receive an HTTP 429 Too many requests status code in the response header and a message indicating that the request was throttled and the time in which the server will be able to process an additional request. The value for the Retry-After key in the response header provides the number of seconds that we must wait until the next request: 2347. The following lines show a sample response. Notice that the number of seconds might be different in your configuration:

    HTTP/1.0 429 Too Many Requests
    Allow: GET, POST, HEAD, OPTIONS
    Content-Length: 71
    Content-Type: application/json
    Date: Thu, 30 Nov 2017 03:07:28 GMT
    Retry-After: 2347
    Server: WSGIServer/0.2 CPython/3.6.2
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "detail": "Request was throttled. Expected available in 2347 seconds."
    }

Now, we will compose and send the following HTTP GET request with authentication credentials to retrieve the first page of the competitions four times. We will use the superuser we created in the previous chapter. Remember to replace djangosuper with the name you used for the superuser and passwordforsuper with the password you configured for this user as shown here:

    http -a "djangosuper":"passwordforsuper" :8000/competitions/

In a Linux, macOS or a Cygwin terminal, we can run the previous command four times with the following single line:

    for i in {1..4}; do http -a "djangosuper":"passwordforsuper" :8000/competitions/; done;

The following line allows you to run the command four times with a single line in Windows PowerShell.

    1..4 | foreach { http -a "djangosuper":"passwordforsuper" :8000/competitions/ }
  

The following is the equivalent curl command that we must execute four times:

    curl --user 'djangosuper':'passwordforsuper' -iX GET localhost:8000/competitions/
  

The following is the equivalent curl command that we can execute four times in a Linux, macOS or a Cygwin terminal with a single line:

    for i in {1..4}; do curl --user "djangosuper":"passwordforsuper" -iX GET localhost:8000/competitions/; done;
  

The following is the equivalent curl command that is executed four times with a single line in Windows PowerShell:

    1..4 | foreach { curl --user "djangosuper":"passwordforsuper" -iX GET localhost:8000/competitions/ }
  

In this case, Django will process the request number 4 because we have composed and sent 4 authenticated requests with the same user. The UserRateThrottle class is configured as one of the default throttle classes and its throttle settings specify 10 requests per hour. We still have 6 requests before we accumulate the maximum number of requests per hour.

If we compose and send the same request 7 times more, we will accumulate 11 requests and we will will receive an HTTP 429 Too many requests status code in the response header, a message indicating that the request was throttled and the time in which the server will be able to process an additional request after the last execution.

Now, we will compose and send the following HTTP GET request without authentication credentials to retrieve the first page of the drones collection 20 times:

    http :8000/drones/

We can use the features of the shell in macOS or Linux to run the previous command 20 times with just a single line with a bash shell. The command is compatible with a Cygwin terminal in Windows:

    for i in {1..20}; do http :8000/drones/; done;

The following line allows you to run the command 20 times with a single line in Windows PowerShell:

    1..21 | foreach { http :8000/drones/ }
  

The following is the equivalent curl command that we must execute 20 times:

    curl -iX GET localhost:8000/drones/

The following is the equivalent curl command that is executed 20 times with a single line in a bash shell in macOS or Linux, or a Cygwin terminal in Windows:

    for i in {1..21}; do curl -iX GET localhost:8000/drones/; done;

The following is the equivalent curl command that is executed 20 times with a single line in Windows PowerShell:

    1..20 | foreach { curl -iX GET localhost:8000/drones/ }

The Django REST framework will process the 20 requests. The DroneList class has its throttle_scope class attribute set to 'drones' and uses the ScopedRateThrottle class to accumulate the requests in the specified scope. The 'drones' scope is configured to accept a maximum of 20 requests per hour, and therefore, if we make another request with the same non-authenticated user and this request accumulates in the same scope, the request will be throttled.

Now, we will compose and send an HTTP GET request to retrieve the details for a drone. Make sure you replace 1 for any existing drone ID value that was listed in the results for the previous requests:

    http :8000/drones/1

The following is the equivalent curl command:

    curl -iX GET localhost:8000/drones/1

The Django REST framework won't process this request. The request ends up routed to the DroneDetail class. The DroneDetail class has its throttle_scope class attribute set to 'drones' and uses the ScopedRateThrottle class to accumulate the requests in the specified scope. Thus, both the DroneList and the DroneDetail class accumulate in the same scope. The new request from the same non-authenticated user becomes the request number 21 for the 'drones' scope that is configured to accept a maximum of 20 requests per hour, and therefore, we will receive an HTTP 429 Too many requests status code in the response header and a message indicating that the request was throttled and the time in which the server will be able to process an additional request. The value for the Retry-After key in the response header provides the number of seconds that we must wait until the next request: 3138. The following lines show a sample response. Notice that the number of seconds might be different in your configuration:

    HTTP/1.0 429 Too Many Requests
    Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
    Content-Length: 71
    Content-Type: application/json
    Date: Mon, 04 Dec 2017 03:55:14 GMT
    Retry-After: 3138
    Server: WSGIServer/0.2 CPython/3.6.2
    Vary: Accept, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "detail": "Request was throttled. Expected available in 3138 seconds."
    }
Throttling rules are extremely important to make sure that users don't abuse our RESTful Web Service and that we keep control of the resources that are being used to process incoming requests. We should never put a RESTful Web Service in production without a clear configuration for throttling rules.
..................Content has been hidden....................

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