Skip to content
This repository was archived by the owner on Feb 1, 2024. It is now read-only.

Commit 9d022f7

Browse files
arithmetic1728andrewsgdpebotmichaelawyuellenevans
authored
docs: add samples from python-docs-samples/tasks (#36)
* Add samples for Cloud Tasks [(#1068)](GoogleCloudPlatform/python-docs-samples#1068) * Add samples for Cloud Tasks * Respond to tasks sample review * Update app engine queues samples * Address review feedback * Address review issues and convert pull queue sample to not use API key auth * Reform pull queues to match appengine queues changes to auth, command line input, readme * flake8 and fix comment * Fix Tasks sample test issues. * Remove queue.yaml, now unused * Add required flag on certain arguments to command-line tools * Auto-update dependencies. [(#1116)](GoogleCloudPlatform/python-docs-samples#1116) * Auto-update dependencies. [(#1133)](GoogleCloudPlatform/python-docs-samples#1133) * Auto-update dependencies. * Fix missing http library Change-Id: I99faa600f2f3f1f50f57694fc9835d7f35bda250 * Update Task Queue samples for beta * Use full import to get client * Auto-update dependencies. [(#1186)](GoogleCloudPlatform/python-docs-samples#1186) * Auto-update dependencies. [(#1217)](GoogleCloudPlatform/python-docs-samples#1217) * Added "Open in Cloud Shell" buttons to README files [(#1254)](GoogleCloudPlatform/python-docs-samples#1254) * Add comments and region tags to Cloud Tasks samples [(#1271)](GoogleCloudPlatform/python-docs-samples#1271) * Standardize on CamelCase, reword confusing endpoint name [(#1288)](GoogleCloudPlatform/python-docs-samples#1288) * Auto-update dependencies. [(#1309)](GoogleCloudPlatform/python-docs-samples#1309) * Rename pull to lease and fix name/parent confusion [(#1311)](GoogleCloudPlatform/python-docs-samples#1311) * Updated region tags for pull queue samples [(#1329)](GoogleCloudPlatform/python-docs-samples#1329) * Auto-update dependencies. [(#1320)](GoogleCloudPlatform/python-docs-samples#1320) * Auto-update dependencies. [(#1355)](GoogleCloudPlatform/python-docs-samples#1355) * Auto-update dependencies. [(#1359)](GoogleCloudPlatform/python-docs-samples#1359) * Auto-update dependencies. * Update Cloud Tasks Samples [(#1529)](GoogleCloudPlatform/python-docs-samples#1529) * passing create task * Passing tests * updates to region tags * update region tags [(#1532)](GoogleCloudPlatform/python-docs-samples#1532) * update Tasks Sample for App Engine [(#1541)](GoogleCloudPlatform/python-docs-samples#1541) * update gcloud command for creating queues * deploys and runs * update license * passing tests * Fix run command [(#1563)](GoogleCloudPlatform/python-docs-samples#1563) * Updated library for TTS GA [(#1552)](GoogleCloudPlatform/python-docs-samples#1552) * update gcloud command for Cloud Tasks [(#1566)](GoogleCloudPlatform/python-docs-samples#1566) * update gcloud command * update pull queue command * update pull queue command * Update Cloud Tasks Push Queue Sample [(#1698)](GoogleCloudPlatform/python-docs-samples#1698) * deleted pull queues * updated samples * fix dependency versions * [Cloud Tasks] Move samples to new folder [(#2114)](GoogleCloudPlatform/python-docs-samples#2114) * Move samples to keep consistent with other langauges * Ad system tests as well * [Cloud Tasks] Add task with authentication sample [(#2113)](GoogleCloudPlatform/python-docs-samples#2113) * Add task with authentication sample * Fix linting * Fix linting * Fix spacing * Update tests with service account * Move samples and update READMEs * Update version and linting * Update task sample comments [(#2156)](GoogleCloudPlatform/python-docs-samples#2156) * Update task comments * Update readme * Update queue name * update gcloud [(#2208)](GoogleCloudPlatform/python-docs-samples#2208) * Add protobuf dep and install instructions [(#2250)](GoogleCloudPlatform/python-docs-samples#2250) * Add Migration Guide Snippets for Cloud Tasks [(#2316)](GoogleCloudPlatform/python-docs-samples#2316) * Migration guide * remove app and update migraitonn * snippets for migration guide - tests added * lint * remove print statements * Styling changes * Travis trigger * Update create_http_task.py [(#2187)](GoogleCloudPlatform/python-docs-samples#2187) Updates `create_http_task.py` to have missing `in_seconds` variable * Adds updates for samples profiler ... vision [(#2439)](GoogleCloudPlatform/python-docs-samples#2439) * Update Cloud Tasks library version [(#2516)](GoogleCloudPlatform/python-docs-samples#2516) * Update to new library * update library version * Adds Task name while creating Task [(#2543)](GoogleCloudPlatform/python-docs-samples#2543) * Task Name in Creating HTTP Task with Token [(#2700)](GoogleCloudPlatform/python-docs-samples#2700) * chore(deps): update dependency google-cloud-tasks to v1.5.0 [(#3168)](GoogleCloudPlatform/python-docs-samples#3168) * chore(deps): update dependency googleapis-common-protos to v1.51.0 [(#3171)](GoogleCloudPlatform/python-docs-samples#3171) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [googleapis-common-protos](https://togithub.com/googleapis/googleapis) | minor | `==1.6.0` -> `==1.51.0` | --- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * Simplify noxfile setup. [(#2806)](GoogleCloudPlatform/python-docs-samples#2806) * chore(deps): update dependency requests to v2.23.0 * Simplify noxfile and add version control. * Configure appengine/standard to only test Python 2.7. * Update Kokokro configs to match noxfile. * Add requirements-test to each folder. * Remove Py2 versions from everything execept appengine/standard. * Remove conftest.py. * Remove appengine/standard/conftest.py * Remove 'no-sucess-flaky-report' from pytest.ini. * Add GAE SDK back to appengine/standard tests. * Fix typo. * Roll pytest to python 2 version. * Add a bunch of testing requirements. * Remove typo. * Add appengine lib directory back in. * Add some additional requirements. * Fix issue with flake8 args. * Even more requirements. * Readd appengine conftest.py. * Add a few more requirements. * Even more Appengine requirements. * Add webtest for appengine/standard/mailgun. * Add some additional requirements. * Add workaround for issue with mailjet-rest. * Add responses for appengine/standard/mailjet. Co-authored-by: Renovate Bot <[email protected]> * Remove dependency googleapis-common-protos [(#3955)](GoogleCloudPlatform/python-docs-samples#3955) * Update dependency googleapis-common-protos to v1.52.0 * Update requirements.txt * Update requirements.txt * Update requirements.txt Co-authored-by: Bu Sun Kim <[email protected]> * Replace GCLOUD_PROJECT with GOOGLE_CLOUD_PROJECT. [(#4022)](GoogleCloudPlatform/python-docs-samples#4022) * [tasks] testing: use fixtures for the queue [(#4049)](GoogleCloudPlatform/python-docs-samples#4049) fixes #4045 fixes #4044 I don't know why these tests started to fail, but anyways we'd better use fixtures and temporary queues. * add python snippets and tests for creating, listing, and deleting queues [(#4012)](GoogleCloudPlatform/python-docs-samples#4012) * add python snippets and tests for creating, listing, and deleting queues * fix grammar * update licenses * apply suggested fixes and format with black * refine delete_queue_test with fixture for setup * utilize fixtures and match format of create_http_task_test * utilize fixtures in list_queues_test and create_queue_test * make create_queue_test call the right function * still attempt to delete queue after test runs in case of failure * attempt to delete queue in case of failure, using try/except approach * add print when NotFound is caught * fix import Co-authored-by: Averi Kitsch <[email protected]> Co-authored-by: Takashi Matsuo <[email protected]> * docs(tasks): service_account_email parameter example [(#4183)](GoogleCloudPlatform/python-docs-samples#4183) * docs(tasks): serviceAccountEmail parameter example * docs(tasks): parameter name camel => snake case * docs(tasks): comment order = function param order * chore(deps): update dependency pytest to v5.4.3 [(#4279)](GoogleCloudPlatform/python-docs-samples#4279) * chore(deps): update dependency pytest to v5.4.3 * specify pytest for python 2 in appengine Co-authored-by: Leah Cole <[email protected]> * Update dependency pytest to v6 [(#4390)](GoogleCloudPlatform/python-docs-samples#4390) * tasks: added json content-type request [(#4473)](GoogleCloudPlatform/python-docs-samples#4473) - added json payload compatibility - fix imports and code block used on https://cloud.google.com/tasks/docs/creating-http-target-tasks#python ## Description Fixes #<ISSUE-NUMBER> Note: It's a good idea to open an issue first for discussion. ## Checklist - [ ] I have followed [Sample Guidelines from AUTHORING_GUIDE.MD](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md) - [ ] README is updated to include [all relevant information](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md#readme-file) - [ ] **Tests** pass: `nox -s py-3.6` (see [Test Environment Setup](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md#test-environment-setup)) - [ ] **Lint** pass: `nox -s lint` (see [Test Environment Setup](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md#test-environment-setup)) - [ ] These samples need a new **API enabled** in testing projects to pass (let us know which ones) - [ ] These samples need a new/updated **env vars** in testing projects set to pass (let us know which ones) - [ ] Please **merge** this PR for me once it is approved. - [ ] This sample adds a new sample directory, and I updated the [CODEOWNERS file](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/.github/CODEOWNERS) with the codeowners for this sample * docs: add samples from python-docs-samples/tasks * chore: update templates Co-authored-by: Andrew Gorcester <[email protected]> Co-authored-by: Andrew Gorcester <[email protected]> Co-authored-by: DPE bot <[email protected]> Co-authored-by: michaelawyu <[email protected]> Co-authored-by: ellenevans <[email protected]> Co-authored-by: Averi Kitsch <[email protected]> Co-authored-by: michaelawyu <[email protected]> Co-authored-by: Noah Negrey <[email protected]> Co-authored-by: Alex Voorhees <[email protected]> Co-authored-by: Gus Class <[email protected]> Co-authored-by: Sarath Kaul <[email protected]> Co-authored-by: Sarath Kaul <[email protected]> Co-authored-by: WhiteSource Renovate <[email protected]> Co-authored-by: Kurtis Van Gent <[email protected]> Co-authored-by: Bu Sun Kim <[email protected]> Co-authored-by: Takashi Matsuo <[email protected]> Co-authored-by: Aaron Johnson <[email protected]> Co-authored-by: Adam Ross <[email protected]> Co-authored-by: Leah Cole <[email protected]> Co-authored-by: Joab Leite S. Neto <[email protected]>
1 parent a88e42b commit 9d022f7

30 files changed

+1709
-27
lines changed

.github/CODEOWNERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Code owners file.
2+
# This file controls who is tagged for review for any given pull request.
3+
#
4+
# For syntax help see:
5+
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
6+
7+
8+
/samples/**/*.py @averikitsch @googleapis/python-samples-owners

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pip-log.txt
4646
# Built documentation
4747
docs/_build
4848
bigquery/docs/generated
49+
docs.metadata
4950

5051
# Virtual environment
5152
env/
@@ -57,4 +58,4 @@ system_tests/local_test_setup
5758

5859
# Make sure a generated file isn't accidentally committed.
5960
pylintrc
60-
pylintrc.test
61+
pylintrc.test

.kokoro/build.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@ python3.6 -m pip uninstall --yes --quiet nox-automation
3636
python3.6 -m pip install --upgrade --quiet nox
3737
python3.6 -m nox --version
3838

39-
python3.6 -m nox
39+
# If NOX_SESSION is set, it only runs the specified session,
40+
# otherwise run all the sessions.
41+
if [[ -n "${NOX_SESSION:-}" ]]; then
42+
python3.6 -m nox -s "${NOX_SESSION:-}"
43+
else
44+
python3.6 -m nox
45+
fi

.kokoro/docker/docs/Dockerfile

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright 2020 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+
from ubuntu:20.04
16+
17+
ENV DEBIAN_FRONTEND noninteractive
18+
19+
# Ensure local Python is preferred over distribution Python.
20+
ENV PATH /usr/local/bin:$PATH
21+
22+
# Install dependencies.
23+
RUN apt-get update \
24+
&& apt-get install -y --no-install-recommends \
25+
apt-transport-https \
26+
build-essential \
27+
ca-certificates \
28+
curl \
29+
dirmngr \
30+
git \
31+
gpg-agent \
32+
graphviz \
33+
libbz2-dev \
34+
libdb5.3-dev \
35+
libexpat1-dev \
36+
libffi-dev \
37+
liblzma-dev \
38+
libreadline-dev \
39+
libsnappy-dev \
40+
libssl-dev \
41+
libsqlite3-dev \
42+
portaudio19-dev \
43+
redis-server \
44+
software-properties-common \
45+
ssh \
46+
sudo \
47+
tcl \
48+
tcl-dev \
49+
tk \
50+
tk-dev \
51+
uuid-dev \
52+
wget \
53+
zlib1g-dev \
54+
&& add-apt-repository universe \
55+
&& apt-get update \
56+
&& apt-get -y install jq \
57+
&& apt-get clean autoclean \
58+
&& apt-get autoremove -y \
59+
&& rm -rf /var/lib/apt/lists/* \
60+
&& rm -f /var/cache/apt/archives/*.deb
61+
62+
63+
COPY fetch_gpg_keys.sh /tmp
64+
# Install the desired versions of Python.
65+
RUN set -ex \
66+
&& export GNUPGHOME="$(mktemp -d)" \
67+
&& echo "disable-ipv6" >> "${GNUPGHOME}/dirmngr.conf" \
68+
&& /tmp/fetch_gpg_keys.sh \
69+
&& for PYTHON_VERSION in 3.7.8 3.8.5; do \
70+
wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \
71+
&& wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \
72+
&& gpg --batch --verify python-${PYTHON_VERSION}.tar.xz.asc python-${PYTHON_VERSION}.tar.xz \
73+
&& rm -r python-${PYTHON_VERSION}.tar.xz.asc \
74+
&& mkdir -p /usr/src/python-${PYTHON_VERSION} \
75+
&& tar -xJC /usr/src/python-${PYTHON_VERSION} --strip-components=1 -f python-${PYTHON_VERSION}.tar.xz \
76+
&& rm python-${PYTHON_VERSION}.tar.xz \
77+
&& cd /usr/src/python-${PYTHON_VERSION} \
78+
&& ./configure \
79+
--enable-shared \
80+
# This works only on Python 2.7 and throws a warning on every other
81+
# version, but seems otherwise harmless.
82+
--enable-unicode=ucs4 \
83+
--with-system-ffi \
84+
--without-ensurepip \
85+
&& make -j$(nproc) \
86+
&& make install \
87+
&& ldconfig \
88+
; done \
89+
&& rm -rf "${GNUPGHOME}" \
90+
&& rm -rf /usr/src/python* \
91+
&& rm -rf ~/.cache/
92+
93+
RUN wget -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' \
94+
&& python3.7 /tmp/get-pip.py \
95+
&& python3.8 /tmp/get-pip.py \
96+
&& rm /tmp/get-pip.py
97+
98+
CMD ["python3.7"]

.kokoro/docker/docs/fetch_gpg_keys.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# Copyright 2020 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# A script to fetch gpg keys with retry.
17+
# Avoid jinja parsing the file.
18+
#
19+
20+
function retry {
21+
if [[ "${#}" -le 1 ]]; then
22+
echo "Usage: ${0} retry_count commands.."
23+
exit 1
24+
fi
25+
local retries=${1}
26+
local command="${@:2}"
27+
until [[ "${retries}" -le 0 ]]; do
28+
$command && return 0
29+
if [[ $? -ne 0 ]]; then
30+
echo "command failed, retrying"
31+
((retries--))
32+
fi
33+
done
34+
return 1
35+
}
36+
37+
# 3.6.9, 3.7.5 (Ned Deily)
38+
retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
39+
0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
40+
41+
# 3.8.0 (Łukasz Langa)
42+
retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
43+
E3FF2839C048B25C084DEBE9B26995E310250568
44+
45+
#

.kokoro/docs/common.cfg

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ action {
1111
gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
1212

1313
# Use the trampoline script to run in docker.
14-
build_file: "python-tasks/.kokoro/trampoline.sh"
14+
build_file: "python-tasks/.kokoro/trampoline_v2.sh"
1515

1616
# Configure the docker image for kokoro-trampoline.
1717
env_vars: {
1818
key: "TRAMPOLINE_IMAGE"
19-
value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
19+
value: "gcr.io/cloud-devrel-kokoro-resources/python-lib-docs"
2020
}
2121
env_vars: {
2222
key: "TRAMPOLINE_BUILD_FILE"
@@ -28,6 +28,23 @@ env_vars: {
2828
value: "docs-staging"
2929
}
3030

31+
env_vars: {
32+
key: "V2_STAGING_BUCKET"
33+
value: "docs-staging-v2-staging"
34+
}
35+
36+
# It will upload the docker image after successful builds.
37+
env_vars: {
38+
key: "TRAMPOLINE_IMAGE_UPLOAD"
39+
value: "true"
40+
}
41+
42+
# It will always build the docker image.
43+
env_vars: {
44+
key: "TRAMPOLINE_DOCKERFILE"
45+
value: ".kokoro/docker/docs/Dockerfile"
46+
}
47+
3148
# Fetch the token needed for reporting release status to GitHub
3249
before_action {
3350
fetch_keystore {

.kokoro/docs/docs-presubmit.cfg

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Format: //devtools/kokoro/config/proto/build.proto
2+
3+
env_vars: {
4+
key: "STAGING_BUCKET"
5+
value: "gcloud-python-test"
6+
}
7+
8+
env_vars: {
9+
key: "V2_STAGING_BUCKET"
10+
value: "gcloud-python-test"
11+
}
12+
13+
# We only upload the image in the main `docs` build.
14+
env_vars: {
15+
key: "TRAMPOLINE_IMAGE_UPLOAD"
16+
value: "false"
17+
}

.kokoro/publish-docs.sh

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,16 @@ set -eo pipefail
1818
# Disable buffering, so that the logs stream through.
1919
export PYTHONUNBUFFERED=1
2020

21-
cd github/python-tasks
22-
23-
# Remove old nox
24-
python3.6 -m pip uninstall --yes --quiet nox-automation
21+
export PATH="${HOME}/.local/bin:${PATH}"
2522

2623
# Install nox
27-
python3.6 -m pip install --upgrade --quiet nox
28-
python3.6 -m nox --version
24+
python3 -m pip install --user --upgrade --quiet nox
25+
python3 -m nox --version
2926

3027
# build docs
3128
nox -s docs
3229

33-
python3 -m pip install gcp-docuploader
34-
35-
# install a json parser
36-
sudo apt-get update
37-
sudo apt-get -y install software-properties-common
38-
sudo add-apt-repository universe
39-
sudo apt-get update
40-
sudo apt-get -y install jq
30+
python3 -m pip install --user gcp-docuploader
4131

4232
# create metadata
4333
python3 -m docuploader create-metadata \
@@ -52,4 +42,23 @@ python3 -m docuploader create-metadata \
5242
cat docs.metadata
5343

5444
# upload docs
55-
python3 -m docuploader upload docs/_build/html --metadata-file docs.metadata --staging-bucket docs-staging
45+
python3 -m docuploader upload docs/_build/html --metadata-file docs.metadata --staging-bucket "${STAGING_BUCKET}"
46+
47+
48+
# docfx yaml files
49+
nox -s docfx
50+
51+
# create metadata.
52+
python3 -m docuploader create-metadata \
53+
--name=$(jq --raw-output '.name // empty' .repo-metadata.json) \
54+
--version=$(python3 setup.py --version) \
55+
--language=$(jq --raw-output '.language // empty' .repo-metadata.json) \
56+
--distribution-name=$(python3 setup.py --name) \
57+
--product-page=$(jq --raw-output '.product_documentation // empty' .repo-metadata.json) \
58+
--github-repository=$(jq --raw-output '.repo // empty' .repo-metadata.json) \
59+
--issue-tracker=$(jq --raw-output '.issue_tracker // empty' .repo-metadata.json)
60+
61+
cat docs.metadata
62+
63+
# upload docs
64+
python3 -m docuploader upload docs/_build/html/docfx_yaml --metadata-file docs.metadata --destination-prefix docfx --staging-bucket "${V2_STAGING_BUCKET}"

0 commit comments

Comments
 (0)