From a173e2461eb282f1992ce8caa7921534ac0d2c95 Mon Sep 17 00:00:00 2001 From: averikitsch Date: Thu, 14 Mar 2019 12:34:46 -0700 Subject: [PATCH 1/7] Http push queue sample --- appengine/flexible/tasks/app.flexible.yaml | 20 +++ appengine/flexible/tasks/app.yaml | 9 +- appengine/flexible/tasks/create_http_task.py | 121 ++++++++++++++++++ .../flexible/tasks/create_http_task_test.py | 28 ++++ 4 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 appengine/flexible/tasks/app.flexible.yaml create mode 100644 appengine/flexible/tasks/create_http_task.py create mode 100644 appengine/flexible/tasks/create_http_task_test.py diff --git a/appengine/flexible/tasks/app.flexible.yaml b/appengine/flexible/tasks/app.flexible.yaml new file mode 100644 index 00000000000..dc20098c594 --- /dev/null +++ b/appengine/flexible/tasks/app.flexible.yaml @@ -0,0 +1,20 @@ +# Copyright 2019 Google LLC 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 + +runtime_config: + python_version: 3 diff --git a/appengine/flexible/tasks/app.yaml b/appengine/flexible/tasks/app.yaml index 8bc4a9bb9c8..620fcb3a3dc 100644 --- a/appengine/flexible/tasks/app.yaml +++ b/appengine/flexible/tasks/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. All Rights Reserved. +# Copyright 2019 Google LLC 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,9 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -runtime: python -env: flex -entrypoint: gunicorn -b :$PORT main:app - -runtime_config: - python_version: 3 +runtime: python37 diff --git a/appengine/flexible/tasks/create_http_task.py b/appengine/flexible/tasks/create_http_task.py new file mode 100644 index 00000000000..38e4a9c2a6e --- /dev/null +++ b/appengine/flexible/tasks/create_http_task.py @@ -0,0 +1,121 @@ +# Copyright 2019 Google LLC 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. + +from __future__ import print_function + +import argparse +import datetime + + +def create_http_task(project, + queue, + location, + url, + payload=None, + in_seconds=None): + # [START cloud_tasks_create_http_task] + """Create a task for a given queue with an arbitrary payload.""" + + from google.cloud import tasks + from google.protobuf import timestamp_pb2 + + # Create a client. + client = tasks.CloudTasksClient() + + # TODO(developer): Uncomment these lines and replace with your values. + # project = 'my-project-id' + # queue = 'my-appengine-queue' + # location = 'us-central1' + # payload = 'hello' + + # Construct the fully qualified queue name. + parent = client.queue_path(project, location, queue) + + # Construct the request body. + task = { + 'http_request': { # Specify the type of request. + 'http_method': 'POST', + 'url': url + } + } + if payload is not None: + # The API expects a payload of type bytes. + converted_payload = payload.encode() + + # Add the payload to the request. + task['http_request']['body'] = 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) + + # Create Timestamp protobuf. + timestamp = timestamp_pb2.Timestamp() + timestamp.FromDatetime(d) + + # Add the timestamp to the tasks. + task['schedule_time'] = timestamp + + # Use the client to build and send the task. + response = client.create_task(parent, task) + + print('Created task {}'.format(response.name)) + return response +# [END cloud_tasks_create_http_task] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=create_http_task.__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + + parser.add_argument( + '--project', + help='Project of the queue to add the task to.', + required=True, + ) + + parser.add_argument( + '--queue', + help='ID (short name) of the queue to add the task to.', + required=True, + ) + + parser.add_argument( + '--location', + help='Location of the queue to add the task to.', + required=True, + ) + + parser.add_argument( + '--url', + help='The full url path that the request will be sent to.', + required=True, + ) + + parser.add_argument( + '--payload', + help='Optional payload to attach to the push queue.' + ) + + parser.add_argument( + '--in_seconds', type=int, + help='The number of seconds from now to schedule task attempt.' + ) + + args = parser.parse_args() + + create_http_task( + args.project, args.queue, args.location, args.url, + args.payload, args.in_seconds) diff --git a/appengine/flexible/tasks/create_http_task_test.py b/appengine/flexible/tasks/create_http_task_test.py new file mode 100644 index 00000000000..d452fb771cf --- /dev/null +++ b/appengine/flexible/tasks/create_http_task_test.py @@ -0,0 +1,28 @@ +# Copyright 2019 Google LLC 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. + +import os + +import create_http_task + +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') + + +def test_create_task(): + url = 'https://' + TEST_PROJECT_ID + '.appspot.com/example_task_handler' + result = create_http_task.create_http_task( + TEST_PROJECT_ID, TEST_QUEUE_NAME, TEST_LOCATION, url) + assert TEST_QUEUE_NAME in result.name From 02e2b36a14ffac5dd594b8d461f5bd56330a16d9 Mon Sep 17 00:00:00 2001 From: averikitsch Date: Thu, 14 Mar 2019 12:35:12 -0700 Subject: [PATCH 2/7] Updates to requirements and license --- appengine/flexible/tasks/README.md | 13 +++++++++---- .../flexible/tasks/create_app_engine_queue_task.py | 6 +++--- .../tasks/create_app_engine_queue_task_test.py | 2 +- appengine/flexible/tasks/main.py | 2 +- appengine/flexible/tasks/main_test.py | 2 +- appengine/flexible/tasks/requirements.txt | 2 +- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/appengine/flexible/tasks/README.md b/appengine/flexible/tasks/README.md index b0bc11b8c78..e9f3702c927 100644 --- a/appengine/flexible/tasks/README.md +++ b/appengine/flexible/tasks/README.md @@ -1,4 +1,4 @@ -# Google Cloud Tasks App Engine Queue Samples +# Google Cloud Tasks Samples [![Open in Cloud Shell][shell_img]][shell_link] @@ -45,9 +45,14 @@ version unless configured to do otherwise. Deploy the App Engine app with gcloud: -``` -gcloud app deploy -``` +* To deploy to the Standard environment: + ``` + gcloud app deploy app.yaml + ``` +* To deploy to the Flexible environment: + ``` + gcloud app deploy app.flexible.yaml + ``` Verify the index page is serving: diff --git a/appengine/flexible/tasks/create_app_engine_queue_task.py b/appengine/flexible/tasks/create_app_engine_queue_task.py index 16642d23d9d..46c892a7130 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 2018 Google Inc. All Rights Reserved. +# Copyright 2019 Google LLC 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. @@ -22,11 +22,11 @@ def create_task(project, queue, location, payload=None, in_seconds=None): # [START cloud_tasks_appengine_create_task] """Create a task for a given queue with an arbitrary payload.""" - from google.cloud import tasks_v2beta3 + from google.cloud import tasks from google.protobuf import timestamp_pb2 # Create a client. - client = tasks_v2beta3.CloudTasksClient() + client = tasks.CloudTasksClient() # TODO(developer): Uncomment these lines and replace with your values. # project = 'my-project-id' 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 bbafd7f415f..39edff12993 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 2018 Google Inc. All Rights Reserved. +# Copyright 2019 Google LLC 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/main.py b/appengine/flexible/tasks/main.py index 74b4e39d2e1..5af1777595a 100644 --- a/appengine/flexible/tasks/main.py +++ b/appengine/flexible/tasks/main.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. +# Copyright 2019 Google LLC # # 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 4c24d41eec5..916f911241c 100644 --- a/appengine/flexible/tasks/main_test.py +++ b/appengine/flexible/tasks/main_test.py @@ -1,4 +1,4 @@ -# Copyright 2018 Google Inc. All Rights Reserved. +# Copyright 2019 Google LLC 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 d10a6bdd8aa..17f12a45c86 100644 --- a/appengine/flexible/tasks/requirements.txt +++ b/appengine/flexible/tasks/requirements.txt @@ -1,3 +1,3 @@ Flask==1.0.2 gunicorn==19.9.0 -google-cloud-tasks==0.4.0 +google-cloud-tasks==0.5.0 From b6248fecde7cba43e89627042f148206e2fb0ddf Mon Sep 17 00:00:00 2001 From: averikitsch Date: Thu, 14 Mar 2019 12:44:38 -0700 Subject: [PATCH 3/7] update comments --- appengine/flexible/tasks/README.md | 23 ++++++++++++++++---- appengine/flexible/tasks/create_http_task.py | 3 ++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/appengine/flexible/tasks/README.md b/appengine/flexible/tasks/README.md index e9f3702c927..718cf6a10c2 100644 --- a/appengine/flexible/tasks/README.md +++ b/appengine/flexible/tasks/README.md @@ -5,8 +5,8 @@ [shell_img]: http://gstatic.com/cloudssh/images/open-btn.png [shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=appengine/flexible/tasks/README.md -Sample command-line program for interacting with the Cloud Tasks API -using App Engine queues. +Sample command-line programs for interacting with the Cloud Tasks API +. App Engine queues push tasks to an App Engine HTTP target. This directory contains both the App Engine app to deploy, as well as the snippets to run @@ -94,14 +94,29 @@ location is "us-central1"). ``` export LOCATION_ID=us-central1 ``` - -Running the sample will create a task, targeted at the 'example_task_handler' +### Using App Engine Queues +Running the sample will create a task, targeted at the `/example_task_handler` endpoint, with a payload specified: ``` python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello ``` +### Using HTTP Push Queues + +Set an environment variable for the endpoint to your task handler. This is an +example url to send requests to the App Engine task handler: +``` +export URL=https://.appspot.com/example_task_handler +``` + +Running the sample will create a task and send the task to the specific URL +endpoint, with a payload specified: + +``` +python create_http_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --url=$URL --payload=hello +``` + Now view that the payload was received and verify the payload: ``` diff --git a/appengine/flexible/tasks/create_http_task.py b/appengine/flexible/tasks/create_http_task.py index 38e4a9c2a6e..19fdbbf49ee 100644 --- a/appengine/flexible/tasks/create_http_task.py +++ b/appengine/flexible/tasks/create_http_task.py @@ -37,6 +37,7 @@ def create_http_task(project, # project = 'my-project-id' # queue = 'my-appengine-queue' # location = 'us-central1' + # url = 'https://.appspot.com/example_task_handler' # payload = 'hello' # Construct the fully qualified queue name. @@ -46,7 +47,7 @@ def create_http_task(project, task = { 'http_request': { # Specify the type of request. 'http_method': 'POST', - 'url': url + 'url': url # The full url path that the task will be sent to. } } if payload is not None: From e6eca2291a0bc6907a34875f56c703e8e27b35d0 Mon Sep 17 00:00:00 2001 From: averikitsch Date: Mon, 25 Mar 2019 09:01:51 -0700 Subject: [PATCH 4/7] Update app.yaml --- appengine/flexible/tasks/app.flexible.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appengine/flexible/tasks/app.flexible.yaml b/appengine/flexible/tasks/app.flexible.yaml index dc20098c594..fdc2d9a1d4e 100644 --- a/appengine/flexible/tasks/app.flexible.yaml +++ b/appengine/flexible/tasks/app.flexible.yaml @@ -14,7 +14,7 @@ runtime: python env: flex -entrypoint: gunicorn -b :$PORT main:app +entrypoint: gunicorn -b :$PORT --threads=4 main:app runtime_config: python_version: 3 From 4cf79b306d0658ae3ef4faf7a6a1100e0238b60f Mon Sep 17 00:00:00 2001 From: averikitsch Date: Wed, 10 Apr 2019 09:30:08 -0700 Subject: [PATCH 5/7] update readme --- appengine/flexible/tasks/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/appengine/flexible/tasks/README.md b/appengine/flexible/tasks/README.md index 718cf6a10c2..303fbfcfcaf 100644 --- a/appengine/flexible/tasks/README.md +++ b/appengine/flexible/tasks/README.md @@ -122,10 +122,3 @@ Now view that the payload was received and verify the payload: ``` 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 -``` From 46a06878ea42a70308100d6d9f308346bff2a8ab Mon Sep 17 00:00:00 2001 From: averikitsch Date: Wed, 10 Apr 2019 09:47:42 -0700 Subject: [PATCH 6/7] fix versioning errors --- appengine/flexible/tasks/create_http_task.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appengine/flexible/tasks/create_http_task.py b/appengine/flexible/tasks/create_http_task.py index 19fdbbf49ee..9d303a2f571 100644 --- a/appengine/flexible/tasks/create_http_task.py +++ b/appengine/flexible/tasks/create_http_task.py @@ -27,11 +27,11 @@ def create_http_task(project, # [START cloud_tasks_create_http_task] """Create a task for a given queue with an arbitrary payload.""" - from google.cloud import tasks + from google.cloud import tasks_v2beta3 from google.protobuf import timestamp_pb2 # Create a client. - client = tasks.CloudTasksClient() + client = tasks_v2beta3.CloudTasksClient() # TODO(developer): Uncomment these lines and replace with your values. # project = 'my-project-id' From 426b01c9a4e679936101549bc37132798f2d64d4 Mon Sep 17 00:00:00 2001 From: averikitsch Date: Wed, 10 Apr 2019 09:55:32 -0700 Subject: [PATCH 7/7] linting error fixed --- appengine/flexible/tasks/create_http_task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appengine/flexible/tasks/create_http_task.py b/appengine/flexible/tasks/create_http_task.py index 9d303a2f571..6ff3a6a2cfa 100644 --- a/appengine/flexible/tasks/create_http_task.py +++ b/appengine/flexible/tasks/create_http_task.py @@ -47,7 +47,7 @@ def create_http_task(project, task = { 'http_request': { # Specify the type of request. 'http_method': 'POST', - 'url': url # The full url path that the task will be sent to. + 'url': url # The full url path that the task will be sent to. } } if payload is not None: