Skip to content

Commit aa0d4ca

Browse files
averikitschbusunkim96
authored andcommitted
Add Cloud Scheduler sample [(#1968)](GoogleCloudPlatform/python-docs-samples#1968)
* scheduler sample * scheduler tutorial draft * create and delete requests completed * updated region tag * update error * fix linting * Update styling * Update license * Update license * Update license * Update license
1 parent 0747892 commit aa0d4ca

File tree

7 files changed

+218
-0
lines changed

7 files changed

+218
-0
lines changed

packages/google-cloud-scheduler/samples/snippets/README.md

Whitespace-only changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START cloud_scheduler_python_yaml]
16+
runtime: python37
17+
service: my-service
18+
# [END cloud_scheduler_python_yaml]
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the 'License');
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an 'AS IS' BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
def create_scheduler_job(project_id, location_id, service_id):
17+
"""Create a job with an App Engine target via the Cloud Scheduler API"""
18+
# [START cloud_scheduler_create_job]
19+
from google.cloud import scheduler
20+
21+
# Create a client.
22+
client = scheduler.CloudSchedulerClient()
23+
24+
# TODO(developer): Uncomment and set the following variables
25+
# project_id = 'PROJECT_ID'
26+
# location_id = 'LOCATION_ID'
27+
# service_id = 'my-service'
28+
29+
# Construct the fully qualified location path.
30+
parent = client.location_path(project_id, location_id)
31+
32+
# Construct the request body.
33+
job = {
34+
'app_engine_http_target': {
35+
'app_engine_routing': {
36+
'service': service_id
37+
},
38+
'relative_uri': '/log_payload',
39+
'http_method': 'POST',
40+
'body': 'Hello World'.encode()
41+
},
42+
'schedule': '* * * * *',
43+
'time_zone': 'America/Los_Angeles'
44+
}
45+
46+
# Use the client to send the job creation request.
47+
response = client.create_job(parent, job)
48+
49+
print('Created job: {}'.format(response.name))
50+
# [END cloud_scheduler_create_job]
51+
return response
52+
53+
54+
def delete_scheduler_job(project_id, location_id, job_id):
55+
"""Delete a job via the Cloud Scheduler API"""
56+
# [START cloud_scheduler_delete_job]
57+
from google.cloud import scheduler
58+
from google.api_core.exceptions import GoogleAPICallError
59+
60+
# Create a client.
61+
client = scheduler.CloudSchedulerClient()
62+
63+
# TODO(developer): Uncomment and set the following variables
64+
# project_id = 'PROJECT_ID'
65+
# location_id = 'LOCATION_ID'
66+
# job_id = 'JOB_ID'
67+
68+
# Construct the fully qualified job path.
69+
job = client.job_path(project_id, location_id, job_id)
70+
71+
# Use the client to send the job deletion request.
72+
try:
73+
client.delete_job(job)
74+
print("Job deleted.")
75+
except GoogleAPICallError as e:
76+
print("Error: %s" % e)
77+
# [END cloud_scheduler_delete_job]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2019 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
import create_job
18+
19+
TEST_PROJECT_ID = os.getenv('GCLOUD_PROJECT')
20+
TEST_LOCATION = os.getenv('LOCATION_ID', 'us-central1')
21+
22+
23+
def test_create_job(capsys):
24+
create_result = create_job.create_scheduler_job(
25+
TEST_PROJECT_ID, TEST_LOCATION, 'my-service')
26+
out, _ = capsys.readouterr()
27+
assert 'Created job:' in out
28+
29+
job_name = create_result.name.split('/')[-1]
30+
create_job.delete_scheduler_job(TEST_PROJECT_ID, TEST_LOCATION, job_name)
31+
32+
out, _ = capsys.readouterr()
33+
assert 'Job deleted.' in out
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2019 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""App Engine app to serve as an endpoint for Cloud Scheduler samples."""
16+
17+
# [START cloud_scheduler_app]
18+
from flask import Flask, request
19+
20+
app = Flask(__name__)
21+
22+
23+
# Define relative URI for job endpoint
24+
@app.route('/log_payload', methods=['POST'])
25+
def example_task_handler():
26+
"""Log the job payload."""
27+
payload = request.get_data(as_text=True) or '(empty payload)'
28+
print('Received job with payload: {}'.format(payload))
29+
return 'Printed job payload: {}'.format(payload)
30+
# [END cloud_scheduler_app]
31+
32+
33+
@app.route('/')
34+
def hello():
35+
"""Basic index to verify app is serving."""
36+
return 'Hello World!'
37+
38+
39+
if __name__ == '__main__':
40+
# This is used when running locally. Gunicorn is used to run the
41+
# application on Google App Engine. See entrypoint in app.yaml.
42+
app.run(host='127.0.0.1', port=8080, debug=True)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2019 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import pytest
16+
17+
18+
@pytest.fixture
19+
def app():
20+
import main
21+
main.app.testing = True
22+
return main.app.test_client()
23+
24+
25+
def test_index(app):
26+
r = app.get('/')
27+
assert r.status_code == 200
28+
29+
30+
def test_log_payload(capsys, app):
31+
payload = 'test_payload'
32+
33+
r = app.post('/log_payload', data=payload)
34+
assert r.status_code == 200
35+
36+
out, _ = capsys.readouterr()
37+
assert payload in out
38+
39+
40+
def test_empty_payload(capsys, app):
41+
r = app.post('/log_payload')
42+
assert r.status_code == 200
43+
44+
out, _ = capsys.readouterr()
45+
assert 'empty payload' in out
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Flask==1.0.2
2+
gunicorn==19.9.0
3+
google-cloud-scheduler==0.1.0

0 commit comments

Comments
 (0)