Skip to content

Commit 75106f5

Browse files
committed
Adding endpoints sample
1 parent ad7d75f commit 75106f5

10 files changed

+564
-0
lines changed

managed_vms/endpoints/.gitignore

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

managed_vms/endpoints/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Google Cloud Endpoints & App Engine Flexible Environment & Python
2+
3+
This sample demonstrates how to use Google Cloud Endpoints on Google App Engine Flexible Environment using Python.
4+
5+
This sample consists of two parts:
6+
7+
1. The backend
8+
2. The clients
9+
10+
## Running locally
11+
12+
### Running the backend
13+
14+
For more info on running Flexible applications locally, see [the getting started documentation](https://cloud.google.com/appengine/docs/managed-vms/python/hello-world).
15+
16+
Install all the dependencies:
17+
18+
$ virtualenv env
19+
$ source env/bin/activate
20+
$ pip install -r requirements.txt
21+
22+
Run the application:
23+
24+
$ python main.py
25+
26+
In your web browser, go to the following address: http://localhost:8080.
27+
28+
### Using the echo client
29+
30+
With the app running locally, you can execute the simple echo client using:
31+
32+
$ python clients/echo-client.py http://localhost:8080 APIKEY
33+
34+
The `APIKEY` doesn't matter as the endpoint proxy is not running to do authentication.
35+
36+
## Deploying to Google App Engine
37+
38+
Open the `swagger.yaml` file and in the `host` property, replace
39+
`YOUR-PROJECT-ID` with your project's ID.
40+
41+
Then, deploy the sample using `gcloud`:
42+
43+
gcloud preview app deploy app.yaml
44+
45+
Once deployed, you can access the application at https://YOUR-PROJECT-ID.appspot.com/.
46+
47+
### Using the echo client
48+
49+
With the project deployed, you'll need to create an API key to access the API.
50+
51+
1. Open the Credentials page of the API Manager in the [Cloud Console](https://console.cloud.google.com/apis/credentials).
52+
2. Click 'Create credentials'.
53+
3. Select 'API Key'.
54+
4. Choose 'Server Key'
55+
56+
With the API key, you can use the echo client to access the API:
57+
58+
$ python clients/echo-client.py https://YOUR-PROJECT-ID.appspot.com YOUR-API-KEY
59+
60+
### Using the JWT client.
61+
62+
The JWT client demonstrates how to use service accounts to authenticate to endpoints. To use the client, you'll need both an API key (as described in the echo client section) and a service account. To create a service account:
63+
64+
1. Open the Credentials page of the API Manager in the [Cloud Console](https://console.cloud.google.com/apis/credentials).
65+
2. Click 'Create credentials'.
66+
3. Select 'Service account key'.
67+
4. In the 'Select service account' dropdown, select 'Create new service account'.
68+
5. Choose 'JSON' for the key type.
69+
70+
To use the service account for authentication:
71+
72+
1. Update the `google_jwt`'s `x-jwks_uri` in `swagger.yaml` with your service account's email address.
73+
2. Redeploy your application.
74+
75+
Now you can use the JWT client to make requests to the API:
76+
77+
$ python clients/google-jwt-client.py https://YOUR-PROJECT-ID.appspot.com YOUR-API-KEY /path/to/service-account.json
78+
79+
### Using the ID Token client.
80+
81+
The ID Token client demonstrates how to use user credentials to authenticate to endpoints. To use the client, you'll need both an API key (as described in the echo client section) and a OAuth2 client ID. To create a client ID:
82+
83+
1. Open the Credentials page of the API Manager in the [Cloud Console](https://console.cloud.google.com/apis/credentials).
84+
2. Click 'Create credentials'.
85+
3. Select 'OAuth client ID'.
86+
4. Choose 'Other' for the application type.
87+
88+
To use the client ID for authentication:
89+
90+
1. Update the `/auth/info/googleidtoken`'s `audiences` in `swagger.yaml` with your client ID.
91+
2. Redeploy your application.
92+
93+
Now you can use the client ID to make requests to the API:
94+
95+
$ python clients/google-id-token-client.py https://YOUR-PROJECT-ID.appspot.com YOUR-API-KEY /path/to/client-id.json

managed_vms/endpoints/app.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
runtime: python
2+
vm: true
3+
entrypoint: gunicorn -b :$PORT main:app
4+
5+
runtime_config:
6+
python_version: 3
7+
8+
beta_settings:
9+
# Enable Google Cloud Endpoints API management.
10+
use_endpoints_api_management: true
11+
# Specify the Swagger API specification.
12+
endpoints_swagger_spec_file: swagger.yaml
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Example of calling a simple Google Cloud Endpoint API."""
18+
19+
import argparse
20+
21+
import requests
22+
from six.moves import urllib
23+
24+
25+
def make_request(host, api_key, message):
26+
"""Makes a request to the auth info endpoint for Google ID tokens."""
27+
url = urllib.parse.urljoin(host, 'echo')
28+
params = {
29+
'key': api_key
30+
}
31+
body = {
32+
'message': message
33+
}
34+
35+
response = requests.post(url, params=params, json=body)
36+
37+
response.raise_for_status()
38+
return response.text
39+
40+
41+
def main(host, api_key, message):
42+
response = make_request(host, api_key, message)
43+
print(response)
44+
45+
46+
if __name__ == '__main__':
47+
parser = argparse.ArgumentParser(
48+
description=__doc__,
49+
formatter_class=argparse.RawDescriptionHelpFormatter)
50+
parser.add_argument(
51+
'host', help='Your API host, e.g. https://your-project.appspot.com.')
52+
parser.add_argument(
53+
'api_key', help='Your API key.')
54+
parser.add_argument(
55+
'message',
56+
help='Message to echo.')
57+
58+
args = parser.parse_args()
59+
60+
main(args.host, args.api_key, args.message)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Example of calling a Google Cloud Endpoint API with an ID token obtained
18+
using the Google OAuth2 flow."""
19+
20+
import argparse
21+
22+
import oauth2client.client
23+
import oauth2client.tools
24+
import oauth2client.file
25+
import requests
26+
from six.moves import urllib
27+
28+
29+
def get_id_token(client_secrets_file, extra_args):
30+
storage = oauth2client.file.Storage('credentials.dat')
31+
credentials = storage.get()
32+
33+
if not credentials or credentials.invalid:
34+
flow = oauth2client.client.flow_from_clientsecrets(
35+
client_secrets_file, scope='email')
36+
credentials = oauth2client.tools.run_flow(
37+
flow, storage, flags=extra_args)
38+
39+
# The ID token is used by Cloud Endpoints, not the access token.
40+
id_token = credentials.token_response['id_token']
41+
42+
return id_token
43+
44+
45+
def make_request(host, api_key, id_token):
46+
"""Makes a request to the auth info endpoint for Google ID tokens."""
47+
url = urllib.parse.urljoin(host, '/auth/info/googleidtoken')
48+
params = {
49+
'key': api_key
50+
}
51+
headers = {
52+
'Authorization': 'Bearer {}'.format(id_token)
53+
}
54+
55+
response = requests.get(url, params=params, headers=headers)
56+
57+
response.raise_for_status()
58+
return response.text
59+
60+
61+
def main(host, api_key, client_secrets_file, extra_args):
62+
id_token = get_id_token(client_secrets_file, extra_args)
63+
response = make_request(host, api_key, id_token)
64+
print(response)
65+
66+
67+
if __name__ == '__main__':
68+
parser = argparse.ArgumentParser(
69+
description=__doc__,
70+
formatter_class=argparse.RawDescriptionHelpFormatter,
71+
parents=[oauth2client.tools.argparser])
72+
parser.add_argument(
73+
'host', help='Your API host, e.g. https://your-project.appspot.com.')
74+
parser.add_argument(
75+
'api_key', help='Your API key.')
76+
parser.add_argument(
77+
'client_secrets_file',
78+
help='The path to your OAuth2 client secrets file.')
79+
80+
args = parser.parse_args()
81+
82+
main(args.host, args.api_key, args.client_secrets_file, args)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Example of calling a Google Cloud Endpoint API with a JWT signed by
18+
a Google API Service Account."""
19+
20+
import argparse
21+
import time
22+
23+
import oauth2client.crypt
24+
from oauth2client.service_account import ServiceAccountCredentials
25+
import requests
26+
from six.moves import urllib
27+
28+
29+
def generate_jwt(service_account_file):
30+
"""Generates a signed JSON Web Token using a Google API Service Account."""
31+
credentials = ServiceAccountCredentials.from_json_keyfile_name(
32+
service_account_file)
33+
34+
now = int(time.time())
35+
36+
payload = {
37+
'iat': now,
38+
'exp': now + credentials.MAX_TOKEN_LIFETIME_SECS,
39+
# aud must match 'audience' in the security configuration in your
40+
# swagger spec. It can be any string.
41+
'aud': 'echo.endpoints.sample.google.com',
42+
# iss must match 'issuer' in the security configuration in your
43+
# swagger spec. It can be any string.
44+
'iss': 'jwt-client.endpoints.sample.google.com',
45+
# sub and email are mapped to the user id and email respectively.
46+
'sub': '12345678',
47+
'email': '[email protected]'
48+
}
49+
50+
signed_jwt = oauth2client.crypt.make_signed_jwt(
51+
credentials._signer, payload, key_id=credentials._private_key_id)
52+
53+
return signed_jwt
54+
55+
56+
def make_request(host, api_key, signed_jwt):
57+
"""Makes a request to the auth info endpoint for Google JWTs."""
58+
url = urllib.parse.urljoin(host, '/auth/info/googlejwt')
59+
params = {
60+
'key': api_key
61+
}
62+
headers = {
63+
'Authorization': 'Bearer {}'.format(signed_jwt)
64+
}
65+
66+
response = requests.get(url, params=params, headers=headers)
67+
68+
response.raise_for_status()
69+
return response.text
70+
71+
72+
def main(host, api_key, service_account_file):
73+
signed_jwt = generate_jwt(service_account_file)
74+
response = make_request(host, api_key, signed_jwt)
75+
print(response)
76+
77+
78+
if __name__ == '__main__':
79+
parser = argparse.ArgumentParser(
80+
description=__doc__,
81+
formatter_class=argparse.RawDescriptionHelpFormatter)
82+
parser.add_argument(
83+
'host', help='Your API host, e.g. https://your-project.appspot.com.')
84+
parser.add_argument(
85+
'api_key', help='Your API key.')
86+
parser.add_argument(
87+
'service_account_file',
88+
help='The path to your service account json file.')
89+
90+
args = parser.parse_args()
91+
92+
main(args.host, args.api_key, args.service_account_file)

managed_vms/endpoints/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width">
6+
<title>Endpoints Echo &amp; Auth Sample</title>
7+
</head>
8+
<body>
9+
<h1>Welcome to your Endpoints Sample</h1>
10+
<p>Congratulations on successfully setting up and deploying your Endpoints bookstore sample.</p>
11+
<p>Here are some helpful links:</p>
12+
<ul>
13+
<li><a href="/echo">Echo Sample</a> - a simple echo service.</li>
14+
<li><a href="/api-docs">Raw Swagger Spec</a> - a link to your <pre>swagger.json</pre>.</li>
15+
<li><a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a> - a documentation tool to explore your Swagger spec</li>
16+
<li><a href="https://console.cloud.google.com">Google Cloud Console</a> - manage your deployment</li>
17+
</ul>
18+
</body>
19+
</html>

0 commit comments

Comments
 (0)