Skip to content

Commit e24ef40

Browse files
committed
Reorganize the appengine Flex directory. Copy appengine/flexible to appengine/flexible_python37_and_earlier. Move appengine/flexible_ubuntu to appengine/flexible_python38_and_later. We can not remove appengine/flexible yet because our user guide still points to it.
1 parent 6549228 commit e24ef40

File tree

153 files changed

+4398
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+4398
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## Google App Engine Flexible Environment Python Samples
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=appengine/flexible/README.md
7+
8+
These are samples for using Python on Google App Engine Flexible Environment. These samples are typically referenced from the [docs](https://cloud.google.com/appengine/docs).
9+
10+
See our other [Google Cloud Platform github repos](https://github.com/GoogleCloudPlatform) for sample applications and
11+
scaffolding for other frameworks and use cases.
12+
13+
## Run Locally
14+
15+
Some samples have specific instructions. If there is a README in the sample folder, please refer to it for any additional steps required to run the sample.
16+
17+
In general, the samples typically require:
18+
19+
1. Install the [Google Cloud SDK](https://cloud.google.com/sdk/), including the [gcloud tool](https://cloud.google.com/sdk/gcloud/), and [gcloud app component](https://cloud.google.com/sdk/gcloud-app).
20+
21+
2. Setup the gcloud tool. This provides authentication to Google Cloud APIs and services.
22+
23+
```
24+
gcloud init
25+
```
26+
27+
3. Clone this repo.
28+
29+
```
30+
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
31+
cd python-docs-samples/appengine/flexible
32+
```
33+
34+
4. Open a sample folder, create a virtualenv, install dependencies, and run the sample:
35+
36+
```
37+
cd hello-world
38+
virtualenv env
39+
source env/bin/activate
40+
pip install -r requirements.txt
41+
python main.py
42+
```
43+
44+
5. Visit the application at [http://localhost:8080](http://localhost:8080).
45+
46+
47+
## Deploying
48+
49+
Some samples in this repositories may have special deployment instructions. Refer to the readme in the sample directory.
50+
51+
1. Use the [Google Developers Console](https://console.developer.google.com) to create a project/app id. (App id and project id are identical)
52+
53+
2. Setup the gcloud tool, if you haven't already.
54+
55+
```
56+
gcloud init
57+
```
58+
59+
3. Use gcloud to deploy your app.
60+
61+
```
62+
gcloud app deploy
63+
```
64+
65+
4. Congratulations! Your application is now live at `your-app-id.appspot.com`
66+
67+
## Contributing changes
68+
69+
* See [CONTRIBUTING.md](../CONTRIBUTING.md)
70+
71+
## Licensing
72+
73+
* See [LICENSE](../LICENSE)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Google Analytics Measurement Protocol sample for Google App Engine Flexible
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=appengine/flexible/analytics/README.md
7+
8+
This sample demonstrates how to use the [Google Analytics Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/v1/) (or any other SQL server) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine).
9+
10+
## Setup
11+
12+
Before you can run or deploy the sample, you will need to do the following:
13+
14+
1. Create a Google Analytics Property and obtain the Tracking ID.
15+
16+
2. Update the environment variables in in ``app.yaml`` with your Tracking ID.
17+
18+
## Running locally
19+
20+
Refer to the [top-level README](../README.md) for instructions on running and deploying.
21+
22+
You will need to set the following environment variables via your shell before running the sample:
23+
24+
$ export GA_TRACKING_ID=[your Tracking ID]
25+
$ python main.py
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2021 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+
runtime: python
16+
env: flex
17+
entrypoint: gunicorn -b :$PORT main:app
18+
19+
runtime_config:
20+
python_version: 3
21+
22+
#[START gae_flex_analytics_env_variables]
23+
env_variables:
24+
GA_TRACKING_ID: your-tracking-id
25+
#[END gae_flex_analytics_env_variables]
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright 2015 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+
# [START gae_flex_analytics_track_event]
16+
import logging
17+
import os
18+
19+
from flask import Flask
20+
import requests
21+
22+
23+
app = Flask(__name__)
24+
25+
26+
# Environment variables are defined in app.yaml.
27+
GA_TRACKING_ID = os.environ['GA_TRACKING_ID']
28+
29+
30+
def track_event(category, action, label=None, value=0):
31+
data = {
32+
'v': '1', # API Version.
33+
'tid': GA_TRACKING_ID, # Tracking ID / Property ID.
34+
# Anonymous Client Identifier. Ideally, this should be a UUID that
35+
# is associated with particular user, device, or browser instance.
36+
'cid': '555',
37+
't': 'event', # Event hit type.
38+
'ec': category, # Event category.
39+
'ea': action, # Event action.
40+
'el': label, # Event label.
41+
'ev': value, # Event value, must be an integer
42+
'ua': 'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14'
43+
}
44+
45+
response = requests.post(
46+
'https://www.google-analytics.com/collect', data=data)
47+
48+
# If the request fails, this will raise a RequestException. Depending
49+
# on your application's needs, this may be a non-error and can be caught
50+
# by the caller.
51+
response.raise_for_status()
52+
53+
54+
@app.route('/')
55+
def track_example():
56+
track_event(
57+
category='Example',
58+
action='test action')
59+
return 'Event tracked.'
60+
61+
62+
@app.errorhandler(500)
63+
def server_error(e):
64+
logging.exception('An error occurred during a request.')
65+
return """
66+
An internal error occurred: <pre>{}</pre>
67+
See logs for full stacktrace.
68+
""".format(e), 500
69+
70+
71+
if __name__ == '__main__':
72+
# This is used when running locally. Gunicorn is used to run the
73+
# application on Google App Engine. See entrypoint in app.yaml.
74+
app.run(host='127.0.0.1', port=8080, debug=True)
75+
# [END gae_flex_analytics_track_event]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2016 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 re
16+
17+
import pytest
18+
import responses
19+
20+
21+
@pytest.fixture
22+
def app(monkeypatch):
23+
monkeypatch.setenv('GA_TRACKING_ID', '1234')
24+
25+
import main
26+
27+
main.app.testing = True
28+
return main.app.test_client()
29+
30+
31+
@responses.activate
32+
def test_tracking(app):
33+
responses.add(
34+
responses.POST,
35+
re.compile(r'.*'),
36+
body='{}',
37+
content_type='application/json')
38+
39+
r = app.get('/')
40+
41+
assert r.status_code == 200
42+
assert 'Event tracked' in r.data.decode('utf-8')
43+
44+
assert len(responses.calls) == 1
45+
request_body = responses.calls[0].request.body
46+
assert 'tid=1234' in request_body
47+
assert 'ea=test+action' in request_body
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pytest==7.0.1
2+
responses==0.17.0; python_version < '3.7'
3+
responses==0.20.0; python_version > '3.6'
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Flask==2.1.0; python_version > '3.6'
2+
Flask==2.0.3; python_version < '3.7'
3+
gunicorn==20.1.0
4+
requests[security]==2.27.1
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Python Google Cloud Datastore sample for Google App Engine Flexible Environment
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=appengine/flexible/datastore/README.md
7+
8+
This sample demonstrates how to use [Google Cloud Datastore](https://cloud.google.com/datastore/) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine).
9+
10+
## Setup
11+
12+
Before you can run or deploy the sample, you will need to enable the Cloud Datastore API in the [Google Developers Console](https://console.developers.google.com/project/_/apiui/apiview/datastore/overview).
13+
14+
## Running locally
15+
16+
Refer to the [top-level README](../README.md) for instructions on running and deploying.
17+
18+
When running locally, you can use the [Google Cloud SDK](https://cloud.google.com/sdk) to provide authentication to use Google Cloud APIs:
19+
20+
$ gcloud init
21+
22+
Starting your application:
23+
24+
$ python main.py
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright 2021 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+
runtime: python
16+
env: flex
17+
entrypoint: gunicorn -b :$PORT main:app
18+
19+
runtime_config:
20+
python_version: 3
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright 2015 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 datetime
16+
import logging
17+
import socket
18+
19+
from flask import Flask, request
20+
from google.cloud import datastore
21+
22+
23+
app = Flask(__name__)
24+
25+
26+
def is_ipv6(addr):
27+
"""Checks if a given address is an IPv6 address."""
28+
try:
29+
socket.inet_pton(socket.AF_INET6, addr)
30+
return True
31+
except socket.error:
32+
return False
33+
34+
35+
# [START gae_flex_datastore_app]
36+
@app.route('/')
37+
def index():
38+
ds = datastore.Client()
39+
40+
user_ip = request.remote_addr
41+
42+
# Keep only the first two octets of the IP address.
43+
if is_ipv6(user_ip):
44+
user_ip = ':'.join(user_ip.split(':')[:2])
45+
else:
46+
user_ip = '.'.join(user_ip.split('.')[:2])
47+
48+
entity = datastore.Entity(key=ds.key('visit'))
49+
entity.update({
50+
'user_ip': user_ip,
51+
'timestamp': datetime.datetime.now(tz=datetime.timezone.utc)
52+
})
53+
54+
ds.put(entity)
55+
query = ds.query(kind='visit', order=('-timestamp',))
56+
57+
results = []
58+
for x in query.fetch(limit=10):
59+
try:
60+
results.append('Time: {timestamp} Addr: {user_ip}'.format(**x))
61+
except KeyError:
62+
print("Error with result format, skipping entry.")
63+
64+
output = 'Last 10 visits:\n{}'.format('\n'.join(results))
65+
66+
return output, 200, {'Content-Type': 'text/plain; charset=utf-8'}
67+
# [END gae_flex_datastore_app]
68+
69+
70+
@app.errorhandler(500)
71+
def server_error(e):
72+
logging.exception('An error occurred during a request.')
73+
return """
74+
An internal error occurred: <pre>{}</pre>
75+
See logs for full stacktrace.
76+
""".format(e), 500
77+
78+
79+
if __name__ == '__main__':
80+
# This is used when running locally. Gunicorn is used to run the
81+
# application on Google App Engine. See entrypoint in app.yaml.
82+
app.run(host='127.0.0.1', port=8080, debug=True)

0 commit comments

Comments
 (0)