From 6090118ea0b3bd8b2304f7496811052d27b72d27 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Wed, 27 Jun 2018 16:40:30 -0700 Subject: [PATCH] update Tasks Sample for App Engine (#1541) * update gcloud command for creating queues * deploys and runs * update license * passing tests --- appengine/flexible/tasks/README.md | 40 +++++++++++---- appengine/flexible/tasks/app.yaml | 14 ++++++ .../tasks/create_app_engine_queue_task.py | 49 +++++++------------ .../create_app_engine_queue_task_test.py | 24 ++++----- appengine/flexible/tasks/main.py | 2 +- appengine/flexible/tasks/main_test.py | 2 +- appengine/flexible/tasks/requirements.txt | 6 +-- tasks/README.md | 2 +- 8 files changed, 76 insertions(+), 63 deletions(-) diff --git a/appengine/flexible/tasks/README.md b/appengine/flexible/tasks/README.md index ffab1069bd47..00353ceaca1a 100644 --- a/appengine/flexible/tasks/README.md +++ b/appengine/flexible/tasks/README.md @@ -34,7 +34,9 @@ To set up authentication, please refer to our To create a queue using the Cloud SDK, use the following gcloud command: - gcloud alpha tasks queues create-app-engine-queue my-appengine-queue +``` +gcloud alpha tasks queues create app-engine my-appengine-queue +``` Note: A newly created queue will route to the default App Engine service and version unless configured to do otherwise. @@ -43,17 +45,23 @@ version unless configured to do otherwise. Deploy the App Engine app with gcloud: - gcloud app deploy +``` +gcloud app deploy +``` Verify the index page is serving: - gcloud app browse +``` +gcloud app browse +``` The App Engine app serves as a target for the push requests. It has an endpoint `/log_payload` that reads the payload (i.e., the request body) of the HTTP POST request and logs it. The log output can be viewed with: - gcloud app logs read +``` +gcloud app logs read +``` ## Running the Samples @@ -61,12 +69,16 @@ Set environment variables: First, your project ID: - export PROJECT_ID=my-project-id +``` +export PROJECT_ID=my-project-id +``` Then the queue ID, as specified at queue creation time. Queue IDs already created can be listed with `gcloud alpha tasks queues list`. - export QUEUE_ID=my-appengine-queue +``` +export QUEUE_ID=my-appengine-queue +``` And finally the location ID, which can be discovered with `gcloud alpha tasks queues describe $QUEUE_ID`, with the location embedded in @@ -74,17 +86,25 @@ the "name" value (for instance, if the name is "projects/my-project/locations/us-central1/queues/my-appengine-queue", then the location is "us-central1"). - export LOCATION_ID=us-central1 +``` +export LOCATION_ID=us-central1 +``` Create a task, targeted at the `log_payload` endpoint, with a payload specified: - python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello +``` +python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello +``` Now view that the payload was received and verify the payload: - gcloud app logs read +``` +gcloud app logs read +``` Create a task that will be scheduled for a time in the future using the `--in_seconds` flag: - python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello --in_seconds=30 +``` +python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello --in_seconds=30 +``` diff --git a/appengine/flexible/tasks/app.yaml b/appengine/flexible/tasks/app.yaml index e5ac514e8b6e..8bc4a9bb9c8b 100644 --- a/appengine/flexible/tasks/app.yaml +++ b/appengine/flexible/tasks/app.yaml @@ -1,3 +1,17 @@ +# Copyright 2018 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + runtime: python env: flex entrypoint: gunicorn -b :$PORT main:app diff --git a/appengine/flexible/tasks/create_app_engine_queue_task.py b/appengine/flexible/tasks/create_app_engine_queue_task.py index b08e694e46c8..93c8df4e4cbc 100644 --- a/appengine/flexible/tasks/create_app_engine_queue_task.py +++ b/appengine/flexible/tasks/create_app_engine_queue_task.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. All Rights Reserved. +# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,62 +15,51 @@ from __future__ import print_function import argparse -import base64 import datetime -import json # [START cloud_tasks_appengine_create_task] def create_task(project, queue, location, payload=None, in_seconds=None): """Create a task for a given queue with an arbitrary payload.""" - import googleapiclient.discovery + from google.cloud import tasks_v2beta2 + from google.protobuf import timestamp_pb2 # Create a client. - client = googleapiclient.discovery.build('cloudtasks', 'v2beta2') + client = tasks_v2beta2.CloudTasksClient() # Construct the request body. - url = '/example_task_handler' - body = { - 'task': { - 'appEngineHttpRequest': { # Specify the type of request. - 'httpMethod': 'POST', - 'relativeUrl': url + task = { + 'app_engine_http_request': { # Specify the type of request. + 'http_method': 'POST', + 'relative_url': '/example_task_handler' } - } } - if payload is not None: - # The API expects base64 encoding of the payload, so encode the unicode - # `payload` object into a byte string and base64 encode it. - base64_encoded_payload = base64.b64encode(payload.encode()) - - # The request body object will be emitted in JSON, which requires - # unicode objects, so convert the byte string to unicode, still base64. - converted_payload = base64_encoded_payload.decode() + # The API expects a payload of type bytes. + converted_payload = payload.encode() # Add the payload to the request. - body['task']['appEngineHttpRequest']['payload'] = converted_payload + task['app_engine_http_request']['payload'] = converted_payload if in_seconds is not None: # Convert "seconds from now" into an rfc3339 datetime string. d = datetime.datetime.utcnow() + datetime.timedelta(seconds=in_seconds) - scheduled_time = d.isoformat('T') + 'Z' + + # Create Timestamp protobuf. + timestamp = timestamp_pb2.Timestamp() + timestamp.FromDatetime(d) # Add the rfc3339 datetime string to the request. - body['task']['scheduleTime'] = scheduled_time + task['schedule_time'] = timestamp # Construct the fully qualified queue name. - queue_name = 'projects/{}/locations/{}/queues/{}'.format( - project, location, queue) - - print('Sending task {}'.format(json.dumps(body))) + parent = client.queue_path(project, location, queue) # Use the client to build and send the task. - response = client.projects().locations().queues().tasks().create( - parent=queue_name, body=body).execute() + response = client.create_task(parent, task) - print('Created task {}'.format(response['name'])) + print('Created task {}'.format(response.name)) return response # [END cloud_tasks_appengine_create_task] diff --git a/appengine/flexible/tasks/create_app_engine_queue_task_test.py b/appengine/flexible/tasks/create_app_engine_queue_task_test.py index 491f30017022..bbafd7f415f9 100644 --- a/appengine/flexible/tasks/create_app_engine_queue_task_test.py +++ b/appengine/flexible/tasks/create_app_engine_queue_task_test.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,22 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock +import os import create_app_engine_queue_task -TEST_PROJECT = 'mock-project' -TEST_LOCATION = 'us-central1' -TEST_QUEUE = 'my-appengine-queue' +TEST_PROJECT_ID = os.getenv('GCLOUD_PROJECT') +TEST_LOCATION = os.getenv('TEST_QUEUE_LOCATION', 'us-central1') +TEST_QUEUE_NAME = os.getenv('TEST_QUEUE_NAME', 'my-appengine-queue') -@mock.patch('googleapiclient.discovery.build') -def test_create_task(build): - projects = build.return_value.projects.return_value - locations = projects.locations.return_value - create_function = locations.queues.return_value.tasks.return_value.create - execute_function = create_function.return_value.execute - execute_function.return_value = {'name': 'task_name'} - create_app_engine_queue_task.create_task( - TEST_PROJECT, TEST_QUEUE, TEST_LOCATION) - assert execute_function.called +def test_create_task(): + result = create_app_engine_queue_task.create_task( + TEST_PROJECT_ID, TEST_QUEUE_NAME, TEST_LOCATION) + assert TEST_QUEUE_NAME in result.name diff --git a/appengine/flexible/tasks/main.py b/appengine/flexible/tasks/main.py index 8b6c666d43cd..74b4e39d2e12 100644 --- a/appengine/flexible/tasks/main.py +++ b/appengine/flexible/tasks/main.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. +# Copyright 2018 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/appengine/flexible/tasks/main_test.py b/appengine/flexible/tasks/main_test.py index d47072d1c363..4c24d41eec57 100644 --- a/appengine/flexible/tasks/main_test.py +++ b/appengine/flexible/tasks/main_test.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2018 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/appengine/flexible/tasks/requirements.txt b/appengine/flexible/tasks/requirements.txt index 72a84ac29c4a..82c75bdfb684 100644 --- a/appengine/flexible/tasks/requirements.txt +++ b/appengine/flexible/tasks/requirements.txt @@ -1,6 +1,2 @@ Flask==0.12.2 -google-api-python-client==1.6.5 -google-auth==1.4.1 -google-auth-httplib2==0.0.3 -google-cloud-datastore==1.6.0 -gunicorn==19.7.1 +google-cloud-tasks==0.2.0 diff --git a/tasks/README.md b/tasks/README.md index ddba20decb21..182ee2cc3d3d 100644 --- a/tasks/README.md +++ b/tasks/README.md @@ -28,7 +28,7 @@ To set up authentication, please refer to our To create a queue using the Cloud SDK, use the following gcloud command: - gcloud alpha tasks queues create-pull-queue my-pull-queue + gcloud alpha tasks queues create pull my-pull-queue ## Running the Samples