blob: 89954e3f9dba59513108622ae0eddd29c34d799f [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2020 The Chromium Authors
Copybara854996b2021-09-07 19:36:02 +00002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""A helper module for interfacing with google cloud tasks.
5
6This module wraps Gooogle Cloud Tasks, link to its documentation:
7https://googleapis.dev/python/cloudtasks/1.3.0/gapic/v2/api.html
8"""
9
10from __future__ import absolute_import
11from __future__ import division
12from __future__ import print_function
13
14import logging
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010015import six
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020016from six.moves import urllib
Copybara854996b2021-09-07 19:36:02 +000017
18from google.api_core import exceptions
19from google.api_core import retry
20
21import settings
22
23if not settings.unit_test_mode:
24 import grpc
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010025 from google.cloud import tasks_v2
26 from google.cloud.tasks_v2.services import cloud_tasks
Copybara854996b2021-09-07 19:36:02 +000027
28_client = None
29# Default exponential backoff retry config for enqueueing, not to be confused
30# with retry config for dispatching, which exists per queue.
31_DEFAULT_RETRY = retry.Retry(initial=.1, maximum=1.6, multiplier=2, deadline=10)
32
33
34def _get_client():
35 # type: () -> tasks.CloudTasksClient
36 """Returns a cloud tasks client."""
37 global _client
38 if not _client:
39 if settings.local_mode:
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010040 transport = cloud_tasks.transports.CloudTasksGrpcTransport(
Copybara854996b2021-09-07 19:36:02 +000041 channel=grpc.insecure_channel(settings.CLOUD_TASKS_EMULATOR_ADDRESS))
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010042 _client = tasks_v2.CloudTasksClient(transport=transport)
Copybara854996b2021-09-07 19:36:02 +000043 else:
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010044 _client = tasks_v2.CloudTasksClient()
Copybara854996b2021-09-07 19:36:02 +000045 return _client
46
47
48def create_task(task, queue='default', **kwargs):
49 # type: (Union[dict, tasks.types.Task], str, **Any) ->
50 # tasks.types.Task
51 """Tries and catches creating a cloud task.
52
53 This exposes a simplied task creation interface by wrapping
54 tasks.CloudTasksClient.create_task; see its documentation:
55 https://googleapis.dev/python/cloudtasks/1.5.0/gapic/v2/api.html#google.cloud.tasks_v2.CloudTasksClient.create_task
56
57 Args:
58 task: A dict or Task describing the task to add.
59 queue: A string indicating name of the queue to add task to.
60 kwargs: Additional arguments to pass to cloud task client's create_task
61
62 Returns:
63 Successfully created Task object.
64
65 Raises:
66 AttributeError: If input task is malformed or missing attributes.
67 google.api_core.exceptions.GoogleAPICallError: If the request failed for any
68 reason.
69 google.api_core.exceptions.RetryError: If the request failed due to a
70 retryable error and retry attempts failed.
71 ValueError: If the parameters are invalid.
72 """
73 client = _get_client()
74
75 parent = client.queue_path(
76 settings.app_id, settings.CLOUD_TASKS_REGION, queue)
77 target = task.get('app_engine_http_request').get('relative_uri')
78 kwargs.setdefault('retry', _DEFAULT_RETRY)
79 logging.info('Enqueueing %s task to %s', target, parent)
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010080 return client.create_task(parent=parent, task=task, **kwargs)
Copybara854996b2021-09-07 19:36:02 +000081
82
83def generate_simple_task(url, params):
84 # type: (str, dict) -> dict
85 """Construct a basic cloud tasks Task for an appengine handler.
86 Args:
87 url: Url path that handles the task.
88 params: Url query parameters dict.
89
90 Returns:
91 Dict representing a cloud tasks Task object.
92 """
93 return {
94 'app_engine_http_request':
95 {
96 'relative_uri': url,
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010097 'body': six.ensure_binary(urllib.parse.urlencode(params)),
Copybara854996b2021-09-07 19:36:02 +000098 'headers': {
99 'Content-type': 'application/x-www-form-urlencoded'
100 }
101 }
102 }