Google Search Console Python Import

Turning Your Google Search Console API Python File Into an Importable

Now that you know how to make requests to the Google Search Console API using Python, you’re probably well on your way to automating a lot of tasks and analyzing a lot of SEO data at scale!

If you’re anything like me, you’ve been copying and pasting the same codes from the API Connection and the API Requests into all of the scripts you’ve been writing. That’s a perfectly fine way to do it, but there’s a simpler way! I’m going to teach you how to write the scripts we’ve learned in previous articles and set them up in your directories in a way that will allow us to import the file and use the functions (we’ll be defining them here) to execute your requests.

What I won’t be showing you here is how to create a package that you can install via pip. Although we will be creating a large portion of what we need to in order to make a pip-installable package, that is a more advanced method and is beyond the scope of this article.

Creating Importable Python Script

I won’t spend much time on the individual components of this since I’ve covered them in previous articles, but I will be including every piece of the puzzle here.

The first step is that we are going to import our modules and define the function to authorize our API just like we did in the Connecting to the Google Search Console API with Python article.

# Import Modules
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials


# Define function to get authorization
def gsc_auth(scopes):
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', scopes)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', scopes)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    service = build('searchconsole', 'v1', credentials=creds)

    return service

That should look very familiar to you if you’ve been following the previous articles.

The next thing we’re going to do is turn each of the four reports we went over in the Google Search Console Python API Requests article into functions that we can call. I personally find it difficult to remember exactly which functions to chain together for each one without a reference, so I like to turn them into functions with arguments for everything we’ll need to make the requests.

# Define List of Sites Function
def get_sites(service):
    return service.sites().list().execute()


# Define List of Sitemaps Function
def get_sitemaps(service, property_uri):
    return service.sitemaps().list(siteUrl=property_uri).execute()


# Define Query Execution Function
def query_gsc(service, property_uri, request):
    return service.searchanalytics().query(siteUrl=property_uri, body=request).execute()


# Define Inspect URL Function
def inspect_url(service, request):
    return service.urlInspection().index().inspect(body=request).execute()

This is the general gist of the script. However, as someone likely starting out in Python, you might run this code and say, “This script doesn’t actually do anything.” And you’re kinda right. We’ll want to test to make sure these functions are working.

scopes = ['https://www.googleapis.com/auth/webmasters']
service = gsc_auth(scopes)
gsc_sites = get_sites(service)
gsc_sitemaps = get_sitemaps(service, 'sc-domain:shortautomaton.com')

sa_request = {
    "startDate": "2022-03-01",
    "endDate": "2022-03-15",
    "dimensions": [
        "QUERY",
        "PAGE"
    ],
    "rowLimit": 10
}

gsc_search_analytics = query_gsc(service, 'sc-domain:shortautomaton.com', sa_request)

inspect_request = {
    "siteUrl": "sc-domain:shortautomaton.com",
    "inspectionUrl": "https://www.shortautomaton.com/",
}

gsc_inspect = inspect_url(service, inspect_request)

I’m not going to bother showing you the output of these since we covered them in the other article. You can trust that these are working properly.

But we’re not finished. If we were to leave this as it is and import the script into another script, it will run the whole thing and we don’t want that because we don’t need to re-run our test every time. We could just delete it out, I suppose, but the best way to handle this is using an IF statement. You might have seen one like it before. Check it out.

if __name__ == '__main__':
    scopes = ['https://www.googleapis.com/auth/webmasters']
    service = gsc_auth(scopes)
    gsc_sites = get_sites(service)
    gsc_sitemaps = get_sitemaps(service, 'sc-domain:shortautomaton.com')

    sa_request = {
        "startDate": "2022-03-01",
        "endDate": "2022-03-15",
        "dimensions": [
            "QUERY",
            "PAGE"
        ],
        "rowLimit": 10
    }

    gsc_search_analytics = query_gsc(service, 'sc-domain:shortautomaton.com', sa_request)

    inspect_request = {
        "siteUrl": "sc-domain:shortautomaton.com",
        "inspectionUrl": "https://www.shortautomaton.com/",
    }

    gsc_inspect = inspect_url(service, inspect_request)

I’ll try to keep this simple. Under the hood, every script gets assigned a __name__ attribute at the time it is called upon. The script file you are running is assigned the __name__ “__main__”. Any imported scripts will be named differently.

As a result, when we are checking if the __name__ is equal to "__main__", we are basically asking if the script we are calling is the “home” script as opposed to an imported script. If it is, we run everything indented under it, just like a regular IF statement. This allows us to run our tests on the script without running the tests when it is imported. Cool stuff, right?

A quick note, I’m calling them tests, but as you become a more advanced developer, testing can mean something pretty different. That’s well beyond the scope of this article, so don’t sweat it for now.

Go ahead and save this file as gsc_api.py in a folder of your choice. In the same folder, add your credentials.json file.

Full Code for gsc_api.py

# Import Modules
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials


# Define function to get authorization
def gsc_auth(scopes):
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', scopes)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', scopes)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    service = build('searchconsole', 'v1', credentials=creds)

    return service


# Define List of Sites Function
def get_sites(service):
    return service.sites().list().execute()


# Define List of Sitemaps Function
def get_sitemaps(service, property_uri):
    return service.sitemaps().list(siteUrl=property_uri).execute()


# Define Query Execution Function
def query_gsc(service, property_uri, request):
    return service.searchanalytics().query(siteUrl=property_uri, body=request).execute()


# Define Inspect URL Function
def inspect_url(service, request):
    return service.urlInspection().index().inspect(body=request).execute()


if __name__ == '__main__':
    scopes = ['https://www.googleapis.com/auth/webmasters']
    service = gsc_auth(scopes)
    gsc_sites = get_sites(service)
    gsc_sitemaps = get_sitemaps(service, 'sc-domain:shortautomaton.com')

    sa_request = {
        "startDate": "2022-03-01",
        "endDate": "2022-03-15",
        "dimensions": [
            "QUERY",
            "PAGE"
        ],
        "rowLimit": 10
    }

    gsc_search_analytics = query_gsc(service, 'sc-domain:shortautomaton.com', sa_request)

    inspect_request = {
        "siteUrl": "sc-domain:shortautomaton.com",
        "inspectionUrl": "https://www.shortautomaton.com/",
    }

    gsc_inspect = inspect_url(service, inspect_request)

Importing gsc_api.py Into Another Script

Within the Same Folder

In the same folder, create a new script. I called it proof_of_importability.py. Very original.

Now your folder might look something like this:

  • folder
    • credentials.json
    • gsc_api.py
    • proof_of_importability.py

You might also have a token.json in there, if you’ve tested gsc_api.py.

Depending on your IDE, this might become super obvious immediately that it works. Just for fun, let’s write some code.

import gsc_api

scopes = ['https://www.googleapis.com/auth/webmasters']

service = gsc_api.gsc_auth(scopes)

sites = gsc_api.get_sites(service)

verified_sites = [site['siteUrl'] for site in sites['siteEntry']
                  if site['permissionLevel'] != 'siteUnverifiedUser']

print('\n'.join(verified_sites))

And let’s run it. Provided you followed along with this correctly, you should get something like this:

"https://www.shortautomaton.com/"
"http://www.shortautomaton.com/"
"https://shortautomaton.com/"
"http://shortautomaton.com/"
"sc-domain:shortautomaton.com"

Within a Child/Descendant Folder

This also works if you create a gsc_api_module folder with gsc_api.py in it.

So now your directory structure might look like this:

  • folder
    • gsc_api_module
      • gsc_api.py
      • credentials.json
    • proof_of_importability.py

We’re going to slightly change proof_of_importability.py with the code below.

from gsc_api_module import gsc_api

scopes = ['https://www.googleapis.com/auth/webmasters']

service = gsc_api.gsc_auth(scopes)

sites = gsc_api.get_sites(service)

verified_sites = [site['siteUrl'] for site in sites['siteEntry']
                  if site['permissionLevel'] != 'siteUnverifiedUser']

print('\n'.join(verified_sites))

Go ahead and run it. You should see the same output as before.

Other Importing Methods

There are ways to import from a parent or ancestor folder tree, but it is nowhere near as straightforward. To keep this guide as useful as possible for beginners, I’m not going to cover those. They involved importing other modules to set directories to the PATH programmatically with built-in modules. It’s a headache. At that point, you’re better off creating a Python package to install via pip, which, as I mentioned at the beginning, I also won’t be covering.

As a final tip, I prefer using the second method. With the second method, I can just copy and paste the entire folder to the various folders I do my work. This keeps my credentials and token files with them as well while also reducing the clutter for the code I’m working in.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top