Generating an OAuth token for Airtable using Python

I have code that successfully generates a Google API OAuth2 token using the google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file method, which opens a browser and saves the token to a file for API interactions.

from google_auth_oauthlib.flow import InstalledAppFlow

def obtain_credentials():
    credentials = None
    if os.path.exists(TOKEN_FILE):
        credentials = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_FILE, SCOPES)
            credentials = flow.run_local_server(port=0)
        with open(TOKEN_FILE, 'w') as token:
            token.write(credentials.to_json())
    return credentials

The CREDENTIALS_FILE is a JSON file obtained from the Google OAuth console. However, Airtable offers OAuth without a straightforward credentials file. I’ve compiled the necessary parameters into a JSON file, but Google’s code isn’t functioning.

Here are the parameters I used:

{"installed": {
  "client_id":"****",
  "auth_uri":"https://airtable.com/oauth2/v1/authorize",
  "token_uri":"https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
  "client_secret":"*****",
  "redirect_uris":["http://localhost"]}}

I encountered an error from Airtable even though my client ID is accurate, and http://localhost is valid as per Google’s setup. The method from_client_secrets_file utilizes a local webserver on a random port, but it doesn’t permit port specification.

I’ve tested multiple OAuth2 libraries without success, often requiring me to manually copy and paste redirect URLs causing errors. Below is some code that progresses further:

from oauthlib.oauth2 import WebApplicationClient
from requests_oauthlib import OAuth2Session
import secrets
import base64
import hashlib

def create_pkce_pair():
    code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b"=").decode('utf-8')
    code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).rstrip(b"=").decode('utf-8')
    return code_verifier, code_challenge

def execute():
    client_id = '****'
    redirect_uri = 'https://localhost:8080/'
    scope = ['schema.bases:read']

    code_verifier, code_challenge = create_pkce_pair()
    client = WebApplicationClient(client_id)
    oauth_session = OAuth2Session(client=client, redirect_uri=redirect_uri, scope=scope)

    auth_url, state = oauth_session.authorization_url(
        url='https://airtable.com/oauth2/v1/authorize',
        code_challenge_method="S256",
        code_challenge=code_challenge
    )

    print("Visit this URL to authorize:", auth_url)
    redirect_response = input('Paste the full redirect URL here: ')

    token_url = "https://api.airtable.com/oauth/token"
    token = oauth_session.fetch_token(
        token_url=token_url,
        authorization_response=redirect_response,
        client_secret=None,
        code_verifier=code_verifier)

    print("Access token achieved:", token)

if __name__ == '__main__':
    execute()

The code redirects to a localhost:8080 URL that is unresponsive, requiring a manual paste of the redirect URL into the console. The following error arises:


 oauthlib.oauth2.rfc6749.errors.CustomOAuth2Error: ({'type': 'INVALID_API_VERSION'})

I’m uncertain how to define the API version. I need assistance to resolve this issue by either: 1) Determining a suitable redirect_uri for Airtable compatible with the Google library, or 2) Correctly specifying the API version for the OAuth2Session request.

I’ve encountered similar issues when doing OAuth flows. Specifically for Airtable, ensure that your API call includes the correct endpoint version. Instead of hardcoded URLs, it might help to make the token_uri and other URLs in your JSON dynamic based on the API version you intend to use.

In your case, ensuring the URL and API version compatibility can be achieved by verifying that the endpoint you’re connecting to allows for the expected OAuth flow. If Airtable needs a custom version, make sure you explore their API documentation for the current supported OAuth flow or API version.

Also, confirm if the client_secret or any other credentials provided by Airtable need to be included differently than Google’s setup, sometimes seen in cases of missing or incorrect credentials handling. If you are stuck, validating the settings on your Airtable developer account or using their community threads can be very helpful for changes.

It seens like Airtable’s OAuth2 flow doesn’t always play nice with the google oauth method. One solution might be using a dedicated library for OAuth that gives you more control, like requests-oauthlib. Also, don’t forget to check if the api version error comes from an endpoint URL mismatch in their documentation.