Skip to content

Commit ee0d786

Browse files
glasntleahecole
andauthored
Add new django tutorial (#4869)
* Cloud Run with Django tutorial * Cloud Run with Django tutorial * black, .env file update * Document Dockerfile, add PYTHONUNBUFFERED * Document cloudmigrate.yaml * Formatiting * Bump django, remove mysql * Update secretmanager * Update pinned dependencies * ensure path is set correctly with api update * format * Generalise cloudmigrate file * update service default * add tests * Update CODEOWNERS * Licence headers * Remove envvar declaration * cleanup readme * Fix import names, region tags * black * Cloud Run with Django tutorial * black, .env file update * Document Dockerfile, add PYTHONUNBUFFERED * Document cloudmigrate.yaml * Formatiting * Bump django, remove mysql * Update secretmanager * Update pinned dependencies * ensure path is set correctly with api update * format * Generalise cloudmigrate file * update service default * add tests * Update CODEOWNERS * Licence headers * Remove envvar declaration * cleanup readme * Fix import names, region tags * black * black * Format YAML * bump dependencies * Update var names, remove sql instance creation * PR Feedback * Debug failing command * Remove IAM calls - possible permissions issues * debug * force local settings if in nox/test * add IDs to cloud build * Update region tags * Get instance name from envvar * Make secrets dynamic, optionally overload names by envvar * Remove create/destroy of static setting * Consolidate envvars * fix region tags * lint, import error * Testing instance name is fqdn, need just name for gcloud sql calls * Ensure project specified on gcloud calls * set project when using gsutil * order of flags in gsutil matters * ensure all subprocesses include project causes issues otherwise * Add and remove more project tags * Update comments * match on exact project name, not substring * lint * Can't hide the settings name in the setting itself 🧐 * big oof * migrations require __init__.py to be detected * Bump overnight patch * Debug 503 * Service requires custom settings envvar * attempt fixing local tests * lint * revert accidental appengine change * envvars * ohno * wrong varname * Update run/django/noxfile_config.py Co-authored-by: Leah E. Cole <[email protected]> * Add licence header * Formatting * black * Add typehinting, remove debugging * ⚠️ noxfile change - add typehints * ⚠️ noxfile change - fix method signature * ⚠️ noxfile change - fix nox session type * ⚠️ noxfile change - import order * hadolint Dockerfile * revert hadolint * Add linking * Remove gcloudignore * Testing: i have a theory this is why tests started failing Co-authored-by: Leah E. Cole <[email protected]>
1 parent cc92681 commit ee0d786

26 files changed

+1029
-9
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
/profiler/**/*.py @kalyanac @GoogleCloudPlatform/python-samples-owners
5555
/pubsub/**/*.py @anguillanneuf @hongalex @GoogleCloudPlatform/python-samples-owners
5656
/run/**/*.py @averikitsch @grant @GoogleCloudPlatform/python-samples-owners
57+
/run/django/**/*.py @glasnt @GoogleCloudPlatform/python-samples-owners
5758
/scheduler/**/*.py @averikitsch @GoogleCloudPlatform/python-samples-owners
5859
/spanner/**/*.py @larkee @GoogleCloudPlatform/python-samples-owners
5960
/speech/**/*.py @telpirion @sirtorry @GoogleCloudPlatform/python-samples-owners

noxfile-template.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import os
1818
from pathlib import Path
1919
import sys
20+
from typing import Callable, Dict, List, Optional
2021

2122
import nox
2223

@@ -68,7 +69,7 @@
6869
TEST_CONFIG.update(TEST_CONFIG_OVERRIDE)
6970

7071

71-
def get_pytest_env_vars():
72+
def get_pytest_env_vars() -> Dict[str, str]:
7273
"""Returns a dict for pytest invocation."""
7374
ret = {}
7475

@@ -98,7 +99,7 @@ def get_pytest_env_vars():
9899
#
99100

100101

101-
def _determine_local_import_names(start_dir):
102+
def _determine_local_import_names(start_dir: str) -> List[str]:
102103
"""Determines all import names that should be considered "local".
103104
104105
This is used when running the linter to insure that import order is
@@ -136,7 +137,7 @@ def _determine_local_import_names(start_dir):
136137

137138

138139
@nox.session
139-
def lint(session):
140+
def lint(session: nox.sessions.Session) -> None:
140141
if not TEST_CONFIG['enforce_type_hints']:
141142
session.install("flake8", "flake8-import-order")
142143
else:
@@ -156,7 +157,7 @@ def lint(session):
156157
#
157158

158159
@nox.session
159-
def blacken(session):
160+
def blacken(session: nox.sessions.Session) -> None:
160161
session.install("black")
161162
python_files = [path for path in os.listdir(".") if path.endswith(".py")]
162163

@@ -171,7 +172,7 @@ def blacken(session):
171172
PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"]
172173

173174

174-
def _session_tests(session, post_install=None):
175+
def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None:
175176
"""Runs py.test for a particular project."""
176177
if os.path.exists("requirements.txt"):
177178
session.install("-r", "requirements.txt")
@@ -197,7 +198,7 @@ def _session_tests(session, post_install=None):
197198

198199

199200
@nox.session(python=ALL_VERSIONS)
200-
def py(session):
201+
def py(session: nox.sessions.Session) -> None:
201202
"""Runs py.test for a sample using the specified version of Python."""
202203
if session.python in TESTED_VERSIONS:
203204
_session_tests(session)
@@ -212,9 +213,10 @@ def py(session):
212213
#
213214

214215

215-
def _get_repo_root():
216+
def _get_repo_root() -> Optional[str]:
216217
""" Returns the root folder of the project. """
217-
# Get root of this repository. Assume we don't have directories nested deeper than 10 items.
218+
# Get root of this repository.
219+
# Assume we don't have directories nested deeper than 10 items.
218220
p = Path(os.getcwd())
219221
for i in range(10):
220222
if p is None:
@@ -230,7 +232,7 @@ def _get_repo_root():
230232

231233
@nox.session
232234
@nox.parametrize("path", GENERATED_READMES)
233-
def readmegen(session, path):
235+
def readmegen(session: nox.sessions.Session, path: str) -> None:
234236
"""(Re-)generates the readme for a sample."""
235237
session.install("jinja2", "pyyaml")
236238
dir_ = os.path.dirname(path)

run/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This directory contains samples for [Google Cloud Run](https://cloud.run). [Clou
1515
|[Cloud Pub/Sub][pubsub] | Handling Pub/Sub push messages | [<img src="https://storage.googleapis.com/cloudrun/button.svg" alt="Run on Google Cloud" height="30">][run_button_pubsub] |
1616
|[Cloud SQL (MySQL)][mysql] | Use MySQL with Cloud Run | - |
1717
|[Cloud SQL (Postgres)][postgres] | Use Postgres with Cloud Run | - |
18+
|[Django][django] | Deploy Django on Cloud Run | - |
1819

1920
For more Cloud Run samples beyond Python, see the main list in the [Cloud Run Samples repository](https://github.com/GoogleCloudPlatform/cloud-run-samples).
2021

@@ -109,6 +110,7 @@ for more information.
109110
[pubsub]: pubsub/
110111
[mysql]: ../cloud-sql/mysql/sqlalchemy
111112
[postgres]: ../cloud-sql/postgres/sqlalchemy
113+
[django]: django/
112114
[run_button_helloworld]: https://deploy.cloud.run/?git_repo=https://github.com/knative/docs&dir=docs/serving/samples/hello-world/helloworld-python
113115
[run_button_pubsub]: https://deploy.cloud.run/?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&dir=run/pubsub
114116
[testing]: https://cloud.google.com/run/docs/testing/local#running_locally_using_docker_with_access_to_services

run/django/.gcloudignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env

run/django/Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
# Use an official lightweight Python image.
16+
# https://hub.docker.com/_/python
17+
FROM python:3.8-slim
18+
19+
ENV APP_HOME /app
20+
WORKDIR $APP_HOME
21+
22+
# Removes output stream buffering, allowing for more efficient logging
23+
ENV PYTHONUNBUFFERED 1
24+
25+
# Install dependencies
26+
COPY requirements.txt .
27+
RUN pip install --no-cache-dir -r requirements.txt
28+
29+
# Copy local code to the container image.
30+
COPY . .
31+
32+
# Run the web service on container startup. Here we use the gunicorn
33+
# webserver, with one worker process and 8 threads.
34+
# For environments with multiple CPU cores, increase the number of workers
35+
# to be equal to the cores available.
36+
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 mysite.wsgi:application

run/django/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Getting started with Django on Cloud Run
2+
3+
[![Open in Cloud Shell][shell_img]][shell_link]
4+
5+
[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png
6+
[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=run/django/README.md
7+
8+
This repository is an example of how to run a [Django](https://www.djangoproject.com/)
9+
app on Google Cloud Run (fully managed).
10+
11+
The Django application used in this tutorial is the [Writing your first Django app](https://docs.djangoproject.com/en/3.0/#first-steps), after completing [Part 1](https://docs.djangoproject.com/en/3.0/intro/tutorial01/) and [Part 2](https://docs.djangoproject.com/en/3.0/intro/tutorial02/).
12+
13+
14+
# Tutorial
15+
See our [Running Django on Cloud Run (fully managed)](https://cloud.google.com/python/django/run) tutorial for instructions for setting up and deploying this sample application.

run/django/cloudmigrate.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
steps:
16+
- id: "build image"
17+
name: "gcr.io/cloud-builders/docker"
18+
args: ["build", "-t", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}", "."]
19+
20+
- id: "push image"
21+
name: "gcr.io/cloud-builders/docker"
22+
args: ["push", "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"]
23+
24+
- id: "apply migrations"
25+
name: "gcr.io/google-appengine/exec-wrapper"
26+
args:
27+
[
28+
"-i",
29+
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
30+
"-s",
31+
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
32+
"-e",
33+
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
34+
"--",
35+
"python",
36+
"manage.py",
37+
"migrate",
38+
]
39+
40+
- id: "collect static"
41+
name: "gcr.io/google-appengine/exec-wrapper"
42+
args:
43+
[
44+
"-i",
45+
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
46+
"-s",
47+
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
48+
"-e",
49+
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
50+
"--",
51+
"python",
52+
"manage.py",
53+
"collectstatic",
54+
"--no-input",
55+
]
56+
57+
substitutions:
58+
_INSTANCE_NAME: django-instance
59+
_REGION: us-central1
60+
_SERVICE_NAME: polls-service
61+
_SECRET_SETTINGS_NAME: django-settings
62+
63+
images:
64+
- "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"

0 commit comments

Comments
 (0)