Can't see Drive SDK in Google App Engine console - google-app-engine

I've created a project and was following tutorials to enable Drive API and Drive SDK but Drive SDK isn't showing in console. Snapshot of console is added below:

You can use Google API such as Google Drive, Calendar etc. in Google App Engine(GAE). Unfortunately, they are not directly linked but you can use google-api-python-client library (which you have to install).
You can follow the Python Quickstart to start the integration with GAE and Google APIs.
Here is the following code given in the answer from the previous SO question:
import httplib2
from apiclient import discovery
credentials = get_credentials() #Your function to request / access stored credentials
#Authorise access to Drive using the user's credentials
http = credentials.authorise(httplib2.Http())
#The service object is the gateway to your API functions
service = discovery.build('drive', 'v2', http=http)
#Run your requests using the service object. e.g. list first 10 files:
results = service.files().list(maxResults=10).execute()
# ... etc ... Do something with results
Also include from the SO question is the API reference for the Google Drive.
I hope this helps you. :)

Related

Production App on Google App Engine suddenly lost access to Google Cloud Storage

Our production app (python 2.7 standard environment) running on Google App Engine suddenly lost permissions to write (create objects) on Google Cloud Storage, without any change in the code on our side.
The code is able to create new buckets, but not new objects within them.
It seems that the default app engine service account is not granted the permission.
Needless to say, the service account has the Storage Object Creator role, as well as the Editor role on the project level.
Strangely, the exact same code running on the test environment project, continues to work perfectly.
We are using the api client library to obtain credentials, like so:
from oauth2client.appengine import AppAssertionCredentials
from apiclient.discovery import build as discovery_build
credentials = AppAssertionCredentials(scope=scope)
http = credentials.authorize(httplib2.Http())
service = discovery_build('storage', 'v1', http=http)
And then using the service to make the api call.
All calls to create objects are suddenly failing with the message:
"Anonymous caller does not have storage.objects.create access to /"
Any ideas what could suddenly have gone wrong ??
This turned up to be an issue with Google Cloud Storage (GCS).
A payed support ticket was opened, after approximately 90 hours, a rollback was made by Google GCS engineers which solved the issue, however, the root cause of the issue was not found or reported.
Very troubling that a production app can be affected this way for such a long time and eventually there is no explanation.

Google Cloud Functions http request only by Google App Engine

I have a nodejs app deployed on Google App Engine, which trigger http cloud functions, thought simple http call (using axios) to get data from Google Cloud Sql.
Everyone that will use the site will be able to see the http request and to replicate it.
What is the best way to secure my google cloud functions to be called only from google app engine?
The best way is to deploy a private function.
When you deploy your function with the cli use the --no-allow-unauthenticated param. This feature is in Beta
On the console, you can't you when you deploy your function. However, you can delete the access to all user in the functions list page
Click on the function line (not the name of the function, the line)
Show the info panel in the upper right corner
Delete allUsers from the cloud function invoker.
Now authorize only AppEngine to access to your function
In the console, at the same place (Function Invoker), add the AppEngine default service account : #appspot.gserviceaccount.com
With the cli, use this command
gcloud beta functions add-iam-policy-binding <Your Function Name> \
--member='serviceAccount:<your project id>#appspot.gserviceaccount.com' \
--role='roles/cloudfunctions.invoker'
Now only the user/service account with the role cloudfunctions.invoker could invoke your function.
I feel the post mentioned by #Denis T does mention options for your scenario. Since you commented it does not work for your scenario, did you consider restricting access to Cloud Function to only the App Engine default service account? How to do this is mentioned in the answer quoted by Denis.

How to call Google Talent Solution api from Google App Engine (Python)

I'd like to use the Google Talent Solution (GTS).
The set-up docs explain how to set-up an Standard Env App Engine project using a service account. I've enabled GTS in my App Engine project, enabled Data Logging and added a Service Account Token Creator to the App Engine default service account that was created when I enabled GTS - [app-id]#appspot.gserviceaccount.com.
I've read the docs for a Python AppEngine project but it uses a deprecated API oauth2client and I'm trying to use google_auth instead (I've installed and vendored google_api and google_auth.
In my vendor appengine_config.py:
from google.appengine.ext import vendor
import os
google_api_path = "%s%s" % (os.path.dirname(os.path.realpath(__file__)), '/applications/[app-id]/modules/google_api')
vendor.add(google_api_path)
google_auth = "%s%s" % (os.path.dirname(os.path.realpath(__file__)), '/applications/[app-id]/modules/google')
vendor.add(google_auth)
I installed google_auth into a directory named google. And in a directory path /applications/[app-id]/modules/ which works well with Web2py, a Python framework.
My code:
from google.auth import app_engine
credentials = app_engine.Credentials()
print(credentials.token)
Alas, credentials.token is None
In all this set-up, config and code, what have I missed?
Possibly because the oauth2client has been deprecated. From googleapis/oauth2client:
Note: oauth2client is now deprecated. No more features will be added to the libraries and the core team is turning down support. We
recommend you use google-auth and oauthlib. For more details
on the deprecation, see oauth2client deprecation.
But I see google-auth uses gRPC, which at least not long ago wasn't compatible with standard environment GAE apps, see GRPC and types import error in App Engine Datastore, so YMMV.
After making the changes (which I've added to my question) the calls work!
Because I'm using a Service Account credentials.token is None and I can proceed to call a Google Talent Solution to add, for example, companies.

Asserting identity to Google APIs with App Engine development server

I have a Golang app running on App Engine and I would like to call the Analytics API to process some metrics. Both on App Engine and on the development server.
This page describes the overall procedure using a service account for server-to-server communication and getting an access token using OAuth2. I would like to avoid doing this myself so I found Google APIs for Go and the following that describes how to do it for App Engine.
I have added the App Engine app's service account email to Google Analytics for read access.
I have played around with queries using the Query Explorer and that works great. I have even used the API Query URI from here that includes the proper access token and that works fine. That works fine with cURL or calling it through urlfetch on App Engine.
What I need is to get hold of an access token automatically on App Engine and also while using the development server.
In here is an example for URL shortener which a have modified to use the Analytics API instead.
client := http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(c, analytics.AnalyticsScope),
Base: &urlfetch.Transport{Context: c},
},
}
svc, err := analytics.New(&client)
if err != nil {
return nil, err
}
data, err := svc.Data.Ga.Get("...")
The response in the development server is 401 Invalid Credentials, authError.
Is this supposed to work like this or am I missing something?
UPDATE
So, the problem is half solved. It works fine now using the development server when I pass in the service account's email and .pem file. However, that very same service account that is in App Engine does not work with the above code!
googleapi: Error 403: User does not have any Google Analytics account., insufficientPermissions
User should be the service account that I already successfully use on the development server, so I don't really understand this problem. It's the exact same code on App Engine and on the development server as well.
Google Analytics is set up to have read access and I use the read-only API. And it already works on the development server so that should be fine.
What might be different that is the issue?
It is possible to provide the development server with the necessary information at start like here.
$ dev_appserver.py --appidentity_email_address email --appidentity_private_key_path file.pem
And for App Engine you need to not use this Service Account but the one with the app name:
app_name#appspot.gserviceaccount.com

OAuth: Starting a Google Compute Instance from within Google App Engine

I have a Google App Engine web app that runs the majority of my site. However, for certain functions, I need a linux machine. I would like my Google App Engine app to automatically spin-up a Google Compute Instance on certain events.
I understand that you can add Google Compute instances using the Compute Engine REST API. However, in order to access the Google Compute REST API, you need to get an access token using the OAuth2 authentication process.
How can I programmatically get an access token from within Google App Engine?
It seems that all of the authentication methods require a window to appear so you can type in your username and password, which is impractical from within Google App Engine.
Here is a complete example of using service accounts and App Engine cron tasks to stop instances after they've been running for a while:
(opposite of starting instances, but the authorization code will be the same)
https://github.com/GoogleCloudPlatform/compute-appengine-timeout-python
AppAssertionCredentials handles the access token using this code:
# Obtain App Engine AppAssertion credentials and authorize HTTP connection.
# https://developers.google.com/appengine/docs/python/appidentity/overview
credentials = AppAssertionCredentials(
scope='https://www.googleapis.com/auth/compute')
HTTP = credentials.authorize(httplib2.Http(memcache))
# Build object for the 'v1beta15' version of the GCE API.
# https://developers.google.com/compute/docs/reference/v1beta13/
compute = build('compute', 'v1beta15', http=HTTP)
You should be able to use the service account associated with your project to authenticate to the Compute Engine API and launch VMs.
Documentation on service accounts suggests that the following python code should fetch a service account token.
import httplib2
import discovery
from oauth2client.appengine import AppAssertionCredentials
...
credentials = AppAssertionCredentials(
scope='https://www.googleapis.com/auth/compute')
auth_http = credentials.authorize(httplib2.Http())
compute_service = discovery.build('compute', 'v1beta15', http=auth_http)
I'd thought that the Google I/O demo from this year where they built a video-sharing site was going to be available, but I don't see it on GitHub yet. There are a number of demos that use AppEngine to control GCE, but most of them seem to use the user's project and credentials, rather the app's own credentials.
Obviously, you probably don't want to spin up a VM on direct user input unless you've got a very large budget or some form of rate limiting in place, but it's quite helpful to spin up a VM now and then when you've got a lot of computation to do. (Transcoding, etc.)

Resources