<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samuel Adekoya</title>
    <description>The latest articles on DEV Community by Samuel Adekoya (@parselfinger).</description>
    <link>https://dev.to/parselfinger</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F269719%2F174d449d-b561-4040-8667-9a76165ae47b.jpeg</url>
      <title>DEV Community: Samuel Adekoya</title>
      <link>https://dev.to/parselfinger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/parselfinger"/>
    <language>en</language>
    <item>
      <title>Asynchronous Tasks with Django and GCP Cloud Tasks</title>
      <dc:creator>Samuel Adekoya</dc:creator>
      <pubDate>Sun, 31 Jan 2021 16:53:54 +0000</pubDate>
      <link>https://dev.to/parselfinger/asynchronous-tasks-with-django-and-gcp-cloud-tasks-448n</link>
      <guid>https://dev.to/parselfinger/asynchronous-tasks-with-django-and-gcp-cloud-tasks-448n</guid>
      <description>&lt;p&gt;When building web applications, it is good practice to execute long-running tasks outside the HTTP request/response cycle.&lt;/p&gt;

&lt;p&gt;For most Python web applications, &lt;a href="https://docs.celeryproject.org/en/stable/getting-started/first-steps-with-celery.html" rel="noopener noreferrer"&gt;Celery&lt;/a&gt; is the most commonly used tool for handling asynchronous task execution. However, for an application hosted on Google App Engine (GAE), Celery might be overkill, since GAE ships with cloud tasks; a fully managed service that allows you to manage the execution, dispatch and delivery of a large number of distributed tasks.&lt;/p&gt;

&lt;p&gt;In this article, we are going to look at how to configure cloud tasks to handle asynchronous tasks in a Django app hosted on GAE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Google Cloud Platform Account&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/python/django/appengine" rel="noopener noreferrer"&gt;A django app hosted on google app engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/sdk/docs/install" rel="noopener noreferrer"&gt;Google Cloud SDK Installed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Billing enabled for your GCP account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enable Cloud Tasks For Your Project
&lt;/h2&gt;

&lt;p&gt;Let's start by enabling the cloud tasks API. From your GCP project page, navigate to the sidebar and look for cloud tasks under the tools section then enable the API for your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd8geawh0nz86t4u2738g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd8geawh0nz86t4u2738g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create A Queue
&lt;/h2&gt;

&lt;p&gt;Now that we have cloud tasks enabled, let's create a queue. You can think of a queue as a waiting area for tasks waiting to be executed. In your terminal, create a queue called "example queue" using the following gcloud command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gcloud tasks queues create example-queue


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;wait for the queue to initialize and then run the following command to verify that it was created succesfully&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

gcloud tasks queues describe example-queue


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should see an output similar to this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

name: projects/[project_name]/locations/[location]/queues/[QUEUE_ID]
purgeTime: '2020-12-04T10:07:54.059449Z'
rateLimits:
  maxBurstSize: 100
  maxConcurrentDispatches: 1000
  maxDispatchesPerSecond: 500.0
retryConfig:
  maxAttempts: 100
  maxBackoff: 3600s
  maxDoublings: 16
  minBackoff: 0.100s
stackdriverLoggingConfig:
  samplingRatio: 1.0
state: RUNNING


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Include your queue configuration in your project's settings.py file&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#settings.py


PROJECT_NAME = # your gcp project name
QUEUE_REGION = # your gcp region
QUEUE_ID = example_queue


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Setup a task
&lt;/h2&gt;

&lt;p&gt;In your app directory, create a new file called &lt;em&gt;cloud_tasks.py&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import json

from django.conf import settings

from google.cloud import tasks_v2beta3

client = tasks_v2beta3.CloudTasksClient()

def send_task(url, http_method='POST', payload=None):
    """ Send task to be executed """

    # construct the queue
    parent = client.queue_path(settings.PROJECT_NAME, 
             settings.QUEUE_REGION, queue=settings.QUEUE_ID)

    # construct the request body
    task = {
        'app_engine_http_request': {
            'http_method': http_method,
            'relative_uri': url
        }
    }

    if isinstance(payload, dict):
        # convert dict to JSON string
        payload = json.dumps(payload)

    if payload is not None:
        # The API expects a payload of type bytes
        converted_payload = payload.encode()

        # Add the payload to the request body
        task['app_engine_http_request']['body'] = 
        converted_payload

    # use the client to build and send the task
    response = client.create_task(parent=parent, task=task)

    return response


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we created a function that creates a task by making a post request to a URL endpoint that runs the task in the background.&lt;/p&gt;

&lt;p&gt;in your views.py file and include the following&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import time
from .cloud_tasks import send_task

def create_task(request):
    """ A simple view that triggers the task """
    task = "Example Task"
    send_task(url="/task/", payload=task)
    return JsonResponse({'message': "task created"})


def task_view(request):
    """ Processes a task """
    payload = request.body.decode('utf-8')
    time.sleep(60)
    print(f"{payload} is completed")


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the same directory, create a  &lt;em&gt;urls.py&lt;/em&gt; file&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;from django.urls import path&lt;br&gt;
from .views import create_task, task_view&lt;br&gt;
urlpatterns = [&lt;br&gt;
path("", create_task, name="create_task"),&lt;br&gt;
path("/task/", task_view, name="task_view")&lt;/p&gt;

&lt;p&gt;]&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Putting it all together&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Deploy your application on GAE and navigate to the home route to trigger the &lt;em&gt;create_task&lt;/em&gt; view. Next, navigate to the cloud tasks service page in GCP. You should see a queue (example-queue) with a task awaiting completion in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we looked at how to configure cloud tasks to handle long-running tasks for a Django application hosted on GAE.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>googlecloud</category>
    </item>
  </channel>
</rss>
