# Quickstart: Run a Search Console App in Python

This sample web app prints the list of sites that you can access, and the sitemaps,
if any, for each of those sites.

## Requirements

To run this program, you'll need:

- Access to the internet and a web browser, in order to authorize the sample app.
- A Google account with at least one website [verified](https://support.google.com/webmasters/answer/9008080) in Google Search Console.
- Python 3 and the [flask](https://github.com/pallets/flask) web application framework.

## Instructions

For this sample, you'll adapt the [OAuth 2.0 for Web Server Applications sample
application](https://developers.google.com/identity/protocols/oauth2/web-server#python).
This sample python app uses the flask web application framework to run a
web-based application that manages OAuth keys and calls a Google Cloud API. You
will adapt the linked sample to call the Search Console API and print out the
results in a web page.

Follow the setup instructions on the OAuth sample page linked above, and copy the
sample code, then modify the code as shown below. Specifically, follow the
setup instructions for your coding environment, setting up (or reusing) a project
that can access the Search Console API in the Google Cloud console, and generating credentials
for a web application.

You will use the [Complete code example](https://developers.google.com/identity/protocols/oauth2/web-server#example) **for
Python** as the source code for this sample.

Read *Modifications* below to see what changes you need to make to the linked
instructions.

If you need to access the Google API Python Client from a Google App Engine
project, you'll need to use a [service account](https://developers.google.com/identity/protocols/oauth2/service-account)
to manage your permissions.

## Modifications

When following the instructions on the linked Oauth2 sample page, make the
following changes:

1. Enable the Google Search Console API rather than the Drive API.
2. Copy the sample application at the end of the OAUth document linked above,
   and replace this

   ```
   SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
   API_SERVICE_NAME = 'drive'
   API_VERSION = 'v2'
   ```
   With this:

   ```
   SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
   API_SERVICE_NAME = 'searchconsole'
   API_VERSION = 'v1'
   ```

   <br />

3. Replace the body of the Python language
   [`test_api_request()`](https://developers.google.com/identity/protocols/oauth2/web-server#example)
   function with the following code:

   ```python
   @app.route('/test')
   def test_api_request():
     if 'credentials' not in flask.session:
       return flask.redirect('authorize')

     # Load credentials from the session.
     credentials = google.oauth2.credentials.Credentials(
         **flask.session['credentials'])

     # Retrieve list of properties in account
     search_console_service = googleapiclient.discovery.build(
         API_SERVICE_NAME, API_VERSION, credentials=credentials)
     site_list = search_console_service.sites().list().execute()

     # Filter for verified URL-prefix websites.
     verified_sites_urls = [s['siteUrl'] for s in site_list['siteEntry']
                           if s['permissionLevel'] != 'siteUnverifiedUser'
                           and s['siteUrl'].startswith('http')]

     # Print the sitemaps for all websites that you can access.
     results = '<!DOCTYPE html><html><body><table><tr><th>Verified site</th><th>Sitemaps</th></tr>'
     for site_url in verified_sites_urls:

       # Retrieve list of sitemaps submitted
       sitemaps = search_console_service.sitemaps().list(siteUrl=site_url).execute()
       results += '<tr><td>%s</td>' % (site_url)

       # Add a row with the site and the list of sitemaps
       if 'sitemap' in sitemaps:
         sitemap_list = "<br />".join([s['path'] for s in sitemaps['sitemap']])
       else:
         sitemap_list = "<i>None</i>"
       results += '<td>%s</td></tr>' % (sitemap_list)

     results += '</table></body></html>'

     # Save credentials back to session in case access token was refreshed.
     # ACTION ITEM: In a production app, you likely want to save these
     #              credentials in a persistent database instead.
     flask.session['credentials'] = credentials_to_dict(credentials)

     return results
   ```

   <br />

4. In our testing, we needed to manually set OAUTHLIB_INSECURE_TRANSPORT
   to 1 in the Bash environment: `export OAUTHLIB_INSECURE_TRANSPORT=1`.
   If you get errors about HTTPS required to run the sample app, try setting that
   variable.