It is easy to get service accounts working with App Engine's app_devserver.py
- once you know how.
On the way there, you might have pulled out all your hair following one documentation dead end after another, trying to piece together the right information.
Here are the steps you need to take, in exact order, to get this working. Once you follow these steps, you'll be able to use service accounts in local development, so that you can interact with Google APIs (e.g.: Spreadsheet, Calendar) in a way that is consistent with the deployment environment on App Engine.
In order to follow the instructions, you'll be better off using the latest UI for Google Cloud projects. Older interfaces (such as the dedicated App Engine dashboard) have things in different places, under different names, etc. It is a world of pain there.
Also note that I've tested this on several 1.9.x releases of App Engine; I can't confirm the behaviour of earlier releases.
-
Ensure you have Google's API client installed and available.
pip install google-api-python-client
-
Add pycrypto to libraries in your app.yaml
libraries:
- name: pycrypto version: latest
-
Go to cloud.google.com, and:
- go to the main dashboard for your particular project
- go to APIS & AUTH > Credentials > Create new Client ID > Service Account > Create Client ID
-
After completing 3, a new Service Account client will appear with your other credentials, and a json file will be downloaded automatically. You do not need this JSON file. Instead:
- click "Generate new P12 key" under your new Service Account.
This will download another key, not surprisingly, with a .p12 suffix.
-
Now the .p12 key needs to be converted to .pem format - the format that App Engine's devserver requires. The code snippet below assumes the working directory is the location of the .p12 key. The .p12 key is called "secret.p12", the password for the key is "notasecret", and the output file is "secret.pem".
cat secret.p12 | openssl pkcs12 -nodes -nocerts -passin pass:notasecret | openssl rsa > secret.pem
-
Now, take note of the email adddress of the service account you just created, and the path to the .pem file you just created. Run your devserver with these, like so:
dev_appserver.py --appidentity_email_address {EMAIL_ADDRESS} --appidentity_private_key_path {PATH_TO_KEY} {PATH_TO_CODE}
-
When the development server is run with these flags, and the values are valid, service accounts can be used in development. Here is a short example, using AppAssertionCredentials to authorize
gspread
: a pleasant-to-use client for the Google Spreadsheet APIfrom somewhere import config from oauth2client import appengine import gspread
scope = config['SERVICE_ACCOUNT']['scopes']['spreadsheets']
credentials = appengine.AppAssertionCredentials(scope=scope)
client = gspread.authorize(credentials)
This example assumes configuration values are available via the config
dict.
See any other examples in Google's API documentation for different implementations.
The point here being, that however you implement your code, if it works in production, it will also now work in development if you run dev_appserver.py with the correct appidentity flags.