Uploading, Downloading, and Managing a Go App

The App Engine Go SDK includes the goapp deploy command for uploading your app to App Engine.

The App Engine Go SDK includes a second command for interacting with App Engine named appcfg.py. You can use this command to upload new versions of the code, configuration and static files for your app to App Engine. You can also use the command to manage datastore indexes and download log data.

Note: If you created your project using the Google Developers Console, your project has a title and an ID. In the instructions that follow, the project title and ID can be used wherever an application title and ID are mentioned. They are the same thing.

  1. Uploading the app
  2. Updating indexes
  3. Deleting unused indexes
  4. Updating Task Queue configuration
  5. Updating the dispatch file
  6. Updating the DoS protection configuration
  7. Managing scheduled tasks
  8. Downloading source code
  9. Downloading logs
  10. Using an HTTP proxy
  11. Password-less login with OAuth2
  12. Command line arguments

Uploading the app

The simplest way to upload application files is to run goapp deploy from within the root directory of your application. The root directory should contain the app.yaml file for the application.

goapp deploy

Alternatively, you can provide the location of your application's root directory as an additional argument. For help using the tool, run goapp help deploy for a full description of its options.

goapp deploy wraps the appcfg.py python tool provided in the SDK. You can also invoke this tool directly if you need greater control over the deployment:

appcfg.py update myapp/
Like goapp deploy, appcfg.py gets the application ID from the app.yaml file, and prompts you for the email address and password of your Google account. After successfully signing in with your account, appcfg.py stores a "cookie" so that it does not need to prompt for a password on subsequent attempts.

You can specify the email address on the command line using the --email option. You cannot specify the password as a command line option.

appcfg.py --email=Albert.Johnson@example.com update myapp/

If you factor your application into Modules you can specify one or more yaml files for your modules in the update command.

cd myapp
appcfg.py update main/app.yaml mod1/mod1.yaml mod2/mod2.yaml

Updating indexes

When you upload an application using appcfg.py update, the update includes the app's index.yaml file. If the index.yaml file defines an index that doesn't exist yet on App Engine, App Engine creates the new index. Depending on how much data is already in the datastore that needs to be mentioned in the new index, the process of creating the index may take a while. If the app performs a query that requires an index that hasn't finished building yet, the query will raise an exception.

To prevent this, you must ensure that the new version of the app that requires a new index is not the live version of the application until the indexes finish building. One way to do this is to give the app a new version number in app.yaml whenever you add or change an index in index.yaml. The app is uploaded as a new version, and does not become the default version automatically. When your indexes have finished building, you change the default version to the new one using the "Versions" section of the Admin Console.

Another way to ensure that new indexes are built before the new app goes live is to upload the index.yaml configuration separately before uploading the app. To upload only the index configuration for an app, use the following command:

appcfg.py update_indexes myapp/

You can check the status of the app's indexes from the "Indexes" section of the Admin Console.

Deleting unused indexes

When you change or remove an index from index.yaml, the original index is not deleted from App Engine automatically. This gives you the opportunity to leave an older version of the app running while new indexes are being built, or to revert to the older version immediately if a problem is discovered with a newer version.

When you are sure that old indexes are no longer needed, you can delete them from App Engine using the following command:

appcfg.py vacuum_indexes myapp/

This command deletes all indexes for the app that are not mentioned in the local version of index.yaml.

Updating Task Queue configuration

To update the task queue configuration, use the appcfg.py update_queues command. Note that you specify the directory that contains queue.yaml, not the file:

appcfg.py update_queues myapp/

If you update a module by performing the appcfg.py update command on a directory that contains an app.yaml file and a queue.yaml file, the task queue configuration will be uploaded as well.

Updating the dispatch file

To update the dispatch file, use the appcfg.py update_dispatch command. Note that you specify the directory that contains dispatch.yaml, not the file:

appcfg.py update_dispatch myapp/

Be sure that all the modules mentioned in the file have been uploaded before using this command.

If you update a module by performing the appcfg.py update command on a directory that contains an app.yaml file and a dispatch.yaml file, the dispatch file will be uploaded as well.

Updating the DoS protection configuration

To update the DoS protection, use the appcfg.py update_dos command. Note that you specify the directory that contains dos.yaml, not the file:

appcfg.py update_dos myapp/

If you update a module by performing the appcfg.py update command on a directory that contains an app.yaml file and a dos.yaml file, the DoS protection configuration will be uploaded as well.

Managing scheduled tasks

App Engine supports scheduled tasks (known as cron jobs). You specify these in a file called cron.yaml.

To update the cron job configuration, use the appcfg.py update_cron command. Note that you specify the directory that contains cron.yaml, not the file:

appcfg.py update_cron myapp/

The command displays a summary of the scheduled task configuration, and the expected times of the next few runs. For more on cron jobs, see the Cron Jobs documentation.

If you run the appcfg.py update specifying a directory that contains an app.yaml file and a cron.yaml file, the cron job configuration will be updated as well.

Downloading source code

You can download an application's source code by running appcfg.py with the download_app action in the Go SDK command-line tool:

appcfg.py download_app -A <your_app_id> -V <your_app_version> <output-dir>

Output like the following results if the command is successful:

Getting file list...
Email: <admin-id>@example.com
Password for <admin-id>@example.com:
Fetching files...
Getting files...

[1/5] request.py
[2/5] login.py
[3/5] static/screen.css
[4/5] static/print.css
[5/5] images/bird.png

Only the developer who uploaded the code and the application owner(s) can download it. If anyone other than these parties attempts to download the app, they'll see an error message like the following:

Fetching file list...
Email: user@example.com
Password for user@example.com:
Error 403: --- begin server output ---
You do not have permission to download this app version.
--- end server output ---

If you are listed as an owner or a developer for an application, you can permanently disable code downloads from the Versions screen in your development web server. On that page, click permanently prohibit code downloads:

Downloading logs

App Engine maintains a log of messages that your application emits through methods on appengine.Context. App Engine also records each request in the log. Each log level has a fixed buffer size that controls the amount of log information you can access. Normally, you use logging features more at lower log levels; thus, the time window is smaller for log events at these levels. You can browse your app's logs of the last 90 days from the "Logs" section of the Admin Console.

If you wish to perform more detailed analysis of your application's logs, you can download the log data to a file on your computer. To download logs to a file named mylogs.txt, use the following command:

appcfg.py request_logs myapp/ mylogs.txt

By default, the command downloads log messages from the current calendar day (since midnight Pacific Time) with a log level of INFO or higher (omitting DEBUG level messages). The command overwrites the local log file. You can adjust the number of days, the minimum log level, and whether to overwrite or append to the local log file using command-line options. See below for more information on these options.

You can limit the log messages that are downloaded to just those emitted during request on a given domain name using the --vhost=... option. You can use this to download the logs for your live app using a Google Apps domain or http://your_app_id.appspot.com, excluding log messages emitted by versions you are testing on URLs such as http://2.latest.your_app_id.appspot.com. Or you can use it to download just the log messages for a given test domain.

There are many options for the request_logs command. You can view them all by typing:

appcfg.py help request_logs

Using an HTTP proxy

If you are running appcfg.py behind an HTTP proxy, you must tell appcfg.py the name of the proxy. To set an HTTP proxy for appcfg.py, set the http_proxy and https_proxy environment variables.

Using Windows (in Command Prompt):

set HTTP_PROXY=http://cache.mycompany.com:3128
set HTTPS_PROXY=http://cache.mycompany.com:3128
appcfg.py update myapp

Using the command line in Mac OS X (in Terminal) or Linux:

export http_proxy="http://cache.mycompany.com:3128"
appcfg.py update myapp

Password-less Login with OAuth2

If you don't want to enter your login credentials, you can use an OAuth2 token instead. This token gives access to App Engine, but not to other parts of your Google account; if your Google account uses two-factor authentication, you'll find this especially convenient. You can store this token to permanently log in on this machine.

To set this up, use the --oauth2 option. (Or, if your browser is on a different machine, perhaps because you're shelled into it, pass --noauth_local_webserver --oauth2.) This will store your OAuth2 credentials in your home directory in a file called .appcfg_oauth2_tokens. If you don't want to permanently log in by storing your OAuth2 token on disk, also use the --no_cookies option.

appcfg.py --oauth2 update myapp/

A page will appear in your web browser prompting you for authentication. (If you used the --noauth_local_webserver option, then appcfg.py will instead show you a URL to copy/paste into your browser.) Log in if necessary. The page will ask whether you wish to give appcfg access. Click OK. (If you used the --noauth_local_webserver option, then you will be given a token that you will need to supply to the prompt from appcfg.py.)

appcfg.py continues:

Authentication successful.
Scanning files on local disk.
...more of the usual output...

From now on, when you run appcfg.py --oauth2, it uses the saved authentication token.

If you have some automated application managment, you might want appcfg.py to run non-interactively. To use OAuth2 without interacting with the script, you can pass the --oauth2_refresh_token to appcfg.py:

appcfg.py --oauth2_refresh_token=token update myapp/

To get a refresh token, you can look for a .appcfg_oauth2_tokens file in your home directory on a machine where you have set up OAuth2. This file is in JSON format; you want the refresh_token value.

Command line arguments

The appcfg.py command takes a set of options, an action, and arguments for the action.

The App Engine SDK is updated frequently, and this list of arguments may not be current. Type appcfg.py help to see the list of all available actions, and appcfg.py help <action> for details on a particular action.

appcfg.py [options] update <app-directory>|<files...>

If you specify a directory, it must contain an app.yaml file and all of the other files required by the app (or module that the app.yaml file defines). If the directory contains any global application settings files (index.yaml, queues.yaml, dispatch.yaml, dos.yaml, cron.yaml) they will also be uploaded. Note that if there are other module configuration files in the directory they will not be uploaded. You'll need to specify them using update with a file list.

The update action creates or updates the app version named in the app.yaml file at the top level of the directory. It follows symlinks and recursively uploads all files to the server. Temporary or source control files (e.g. foo~, .svn/*) are skipped.

Use the files argument to upload one or more yaml files that define modules. No other types of yaml files can appear in the command line. Only the specified modules will be updated.

The following option applies to update:

Maximum size of a file to upload (in bytes).
appcfg.py help <action>
Prints a help message about the given action, then quits.
appcfg.py [options] cron_info <app-directory>
Displays information about the scheduled task (cron) configuration, including the expected times of the next few executions. By default, displays the times of the next 5 runs. You can modify the number of future run times displayed with the --num_runs=... option.
appcfg.py download_app -A <app_id> -V <version><output-dir>

Retrieves the most current version of your application's code using the following options:

The application ID (required).

The current application version. May be one of the following:

  • hi-V major.minor – Specifies the exact version specified.
  • -V major – Specifies the latest major version.
  • Omitted entirely – Returns the current default version, if one exists

The directory where you wish to save the files (required).

appcfg.py [options] request_logs <app-directory> <output-file>

Retrieves log data for the application running on App Engine. output-file is the name of the file to create, replace or append (if the --append flag is set). If output-file is a hyphen (-), the log data is printed to the console. The following options apply to request_logs:

The number of days of log data to retrieve, ending on the current date at midnight UTC. A value of 0 retrieves all available logs. If --append is given, then the default is 0, otherwise the default is 1.
The latest date of log data to return, in the form YYYY-MM-DD. The default is today. The --num_days option counts backwards from the end date.
The minimum log level for the log messages to retrieve. The value is a number corresponding to the log level: 4 for CRITICAL, 3 for ERROR, 2 for WARNING, 1 for INFO, 0 for DEBUG. All messages at the given log level and above will be retrieved. Default is 1 (INFO).

Append the fetched data to the output file, starting with the first log line not already present in the file. Running this action once a day with --append results in a file containing all log data.

The default is to overwrite the output file. Does not apply if output-file is - (printing to the console).


If present, limits the log messages downloaded to just those emitted by requests for a given domain name. For instance, --vhost=example.com will download just the log messages for the live app at the Google Apps domain example.com, excluding any log messages emitted by a new version being tested at http://2.latest.your_app_id.appspot.com. Similarly, --vhost=2.latest.your_app_id.appspot.com downloads just the logs for the test version, excluding the live version.

The value is a regular expression that matches the Host header of the incoming requests. Note that the pattern is case sensitive, even though domain names usually are not.


Include the domain name for each request (the Host request header) in the request log data, as an additional field.

appcfg.py [options] rollback <app-directory>
Undoes a partially completed update for the given application. You can use this if an update was interrupted, and the command is reporting that the application cannot be updated due to a lock.
appcfg.py [options] set_default_version <app-directory>
Sets the default (serving) version of the app. By default, the serving version is set to the version specified in app.yaml, unless you specify another with the --version option.
appcfg.py [options] migrate_traffic <app-directory>
Implements traffic migration. Dynamically re-routes traffic from the current default (serving) version of the app to the the version specified in the app.yaml. Traffic is gradually moved from the old to the new version. Once all traffic is being sent to the new version, sets the default (serving) version of the app to the version specified in the app.yaml.
appcfg.py [options] update_cron <app-directory>
Updates the schedule task (cron) configuration for the app, based on the cron.yaml file.
appcfg.py [options] update_dos <app-directory>
Updates the DoS Protection configuration for the app, based on the dos.yaml file.
appcfg.py [options] update_indexes <app-directory>
Updates datastore indexes in App Engine to include newly added indexes. If a new version of your application requires an additional index definition that was added to index.yaml, you can update your index definitions in App Engine prior to uploading the new version of your application. Running this action a few hours prior to uploading your new application version will give the indexes time to build and be serving when the application is deployed.
appcfg.py [options] update_queues <app-directory>
Updates the task queue configuration for the app, based on the queue.yaml file.
appcfg.py [options] update_dispatch <app-directory>
Updates the dispatch for the app, based on the dispatch.yaml file.
appcfg.py [options] start_module_version <app-directory>

Start the specified module version.

Use the --module and --version options to override the settings in the app.yaml file.

appcfg.py [options] stop_module_version <app-directory>

Stop the specified module version.

Use the --module and --version options to override the settings in the app.yaml file.

appcfg.py [options] vacuum_indexes <app-directory>
Deletes unused datastore indexes in App Engine. If an index definition is removed from index.yaml, the index is not deleted automatically when the application is uploaded because it may be in use by another version of the application. Run this action when all old indexes are no longer needed.

The appcfg.py command accepts the following options for all actions:

The application ID to use. By default, this is derived from the application: line in the app.yaml file in the application directory. If --application is specified, it overrides the ID in app.yaml for this action.
The email address of the Google account of an administrator for the application, for actions that require signing in. If omitted and no cookie is stored from a previous use of the command, the command will prompt for this value.
Force deletion of unused indexes. By default, uploading an app does not delete unused indexes from the server, even if they do not appear in the index.yaml file.
The hostname of the local machine for use with remote procedure calls.
A maximum size of files to upload, as a number of bytes. Files larger than this size will not be uploaded. The default is 10485760. The server currently enforces a maximum file size of 10,485,760 bytes, so increasing this value will not have any effect.
The name of the module to use. By default, this is derived from the module: line in the app.yaml file in the application directory. If --module is specified, it overrides the value in app.yaml for this action.
Do not store the administrator sign-in credentials. Prompt for a password every time (or go through the OAuth2 flow if the --oauth2 options is used).
Print many messages about what the command is doing. This is mostly useful when working with the App Engine team to troubleshoot an upload issue.
Don't use the web browser to display web pages for authentication. This is useful for OAuth2 authentication if you're remotely logged on to a machine. This flag only applies for OAuth2.
Use OAuth2 authentication instead of password-based authentication.
Use an OAuth2 refresh token to authenticate instead of password-based authentication or a stored token.
If given, the tool accepts the Google account password in stdin instead of prompting for it interactively. This allows you to invoke the tool from a script without putting your password on the command line.
Do not print messages when successful.
The App Engine server hostname. The default is appengine.google.com.
Print messages about what the command is doing.
The version ID to use. By default, this is derived from the version: line in the app.yaml file in the application directory. If --version is specified, it overrides the version ID in app.yaml for this action.