Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6e9ab2e

Browse filesBrowse files
dinagravesleahecole
andcommitted
"Hello Broken" python sample (GoogleCloudPlatform#2618)
* Hello broken python sample * Updating README * Updating test file * Fixing README nits * Fixing README link * Updating test instructions in README and moving region tag * Noxfile change to signal only python 3 tests Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com>
1 parent 6e8425c commit 6e9ab2e
Copy full SHA for 6e9ab2e

File tree

Expand file treeCollapse file tree

6 files changed

+213
-0
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+213
-0
lines changed

‎noxfile.py

Copy file name to clipboardExpand all lines: noxfile.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ def _setup_appengine_sdk(session):
175175
or sample.startswith("./functions/")
176176
or sample.startswith("./bigquery/pandas-gbq-migration")
177177
or sample.startswith("./run/system-package")
178+
or sample.startswith("./run/hello-broken")
178179
)
179180
]
180181
NON_GAE_STANDARD_SAMPLES_PY2 = sorted(

‎run/hello-broken/Dockerfile

Copy file name to clipboard
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
# Use the official Python image.
16+
# https://hub.docker.com/_/python
17+
FROM python:3.7
18+
19+
# Copy application dependency manifests to the container image.
20+
# Copying this separately prevents re-running pip install on every code change.
21+
COPY requirements.txt .
22+
23+
# Install production dependencies.
24+
RUN pip install -r requirements.txt
25+
26+
# Copy local code to the container image.
27+
ENV APP_HOME /app
28+
WORKDIR $APP_HOME
29+
COPY . .
30+
31+
# Run the web service on container startup.
32+
# Use gunicorn webserver with one worker process and 8 threads.
33+
# For environments with multiple CPU cores, increase the number of workers
34+
# to be equal to the cores available.
35+
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 main:app

‎run/hello-broken/README.md

Copy file name to clipboard
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Cloud Run Broken Sample
2+
3+
This sample presents broken code in need of troubleshooting. View [improved](main.py#L43) for a more stable implementation.
4+
5+
Troubleshoot this code by following the [Local Container Troubleshooting Tutorial](http://cloud.google.com/run/docs/tutorials/local-troubleshooting).
6+
7+
[![Run in Google Cloud][run_img]][run_link]
8+
9+
[run_img]: https://storage.googleapis.com/cloudrun/button.svg
10+
[run_link]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&cloudshell_working_dir=run/hello-broken
11+
12+
## Build
13+
14+
```
15+
docker build --tag hello-broken:python .
16+
```
17+
18+
## Run Locally
19+
20+
```
21+
docker run --rm -p 9090:8080 hello-broken:python
22+
```
23+
24+
## Test
25+
26+
```
27+
nox -s "py36(sample='./run/hello-broken')"
28+
```
29+
30+
_Note: you may need to install `nox` using `pip install nox`._
31+
32+
## Deploy
33+
34+
```sh
35+
# Set an environment variable with your GCP Project ID
36+
export GOOGLE_CLOUD_PROJECT=<PROJECT_ID>
37+
38+
# Submit a build using Google Cloud Build
39+
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-broken
40+
41+
# Deploy to Cloud Run
42+
gcloud run deploy hello-broken \
43+
--image gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-broken
44+
```
45+
46+
47+
For more details on how to work with this sample read the [Python Cloud Run Samples README](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/run)

‎run/hello-broken/main.py

Copy file name to clipboard
+72Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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 run_broken_service]
16+
from flask import Flask
17+
import json
18+
import os
19+
import sys
20+
21+
app = Flask(__name__)
22+
23+
24+
@app.route("/", methods=["GET"])
25+
def index():
26+
print("hello: received request.")
27+
28+
# [START run_broken_service_problem]
29+
NAME = os.getenv("NAME")
30+
31+
if not NAME:
32+
print("Environment validation failed.")
33+
raise Exception("Missing required service parameter.")
34+
# [END run_broken_service_problem]
35+
36+
# Flush the stdout to avoid log buffering.
37+
sys.stdout.flush()
38+
39+
return f"Hello {NAME}"
40+
# [END run_broken_service]
41+
42+
43+
@app.route("/improved", methods=["GET"])
44+
def improved():
45+
print("hello: received request.")
46+
47+
# [START run_broken_service_upgrade]
48+
NAME = os.getenv("NAME")
49+
50+
if not NAME:
51+
NAME = "World"
52+
error_message = {
53+
"severity": "WARNING",
54+
"message": f"NAME not set, default to {NAME}",
55+
}
56+
print(json.dumps(error_message))
57+
# [END run_broken_service_upgrade]
58+
59+
# Flush the stdout to avoid log buffering.
60+
sys.stdout.flush()
61+
62+
return f"Hello {NAME}"
63+
64+
65+
# [START run_broken_service]
66+
if __name__ == "__main__":
67+
PORT = int(os.getenv("PORT")) if os.getenv("PORT") else 8080
68+
69+
# This is used when running locally. Gunicorn is used to run the
70+
# application on Cloud Run. See entrypoint in Dockerfile.
71+
app.run(host="127.0.0.1", port=PORT, debug=True)
72+
# [END run_broken_service]

‎run/hello-broken/main_test.py

Copy file name to clipboard
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
import os
16+
import pytest
17+
import main
18+
19+
20+
@pytest.fixture
21+
def client():
22+
main.app.testing = True
23+
return main.app.test_client()
24+
25+
26+
def test_broken_handler(client):
27+
with pytest.raises(Exception) as e:
28+
client.get("/")
29+
30+
assert "Missing required service parameter" in str(e.value)
31+
32+
33+
def test_broken_handler_with_env_variable(client):
34+
os.environ["NAME"] = "Foo"
35+
r = client.get("/")
36+
37+
assert r.data.decode() == "Hello Foo"
38+
assert r.status_code == 200
39+
40+
41+
def test_improved_handler_no_env_variable(client):
42+
os.environ["NAME"] = ""
43+
r = client.get("/improved")
44+
45+
assert r.data.decode() == "Hello World"
46+
assert r.status_code == 200
47+
48+
49+
def test_improved_handler_with_env_variable(client):
50+
os.environ["NAME"] = "Foo"
51+
r = client.get("/improved")
52+
53+
assert r.data.decode() == "Hello Foo"
54+
assert r.status_code == 200

‎run/hello-broken/requirements.txt

Copy file name to clipboard
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Flask==1.1.1
2+
pytest==5.3.0; python_version > "3.0"
3+
pytest==4.6.6; python_version < "3.0"
4+
gunicorn==19.9.0

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.