You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

oauth2client报KeyError: '_module'错误的原因与修复方法咨询

KeyError: '_module' When Using OAuth2Client with Google Sheets API

Hey there, let's break down this error and fix it step by step!

What's Causing This KeyError?

The root issue here is a wrong credential loading approach. You're using a Google Service Account JSON key file, but trying to load it with oauth2client.file.Storage—this class is designed specifically for handling user OAuth2 authorization credentials (like files containing refresh tokens from browser-based logins). Service account JSON has a completely different structure, and it doesn't include the _module field that Storage expects, hence the KeyError.

Is This a Module Bug?

Absolutely not! This is a classic usage mistake. The oauth2client library's Storage and ServiceAccountCredentials are built for distinct scenarios:

  • Storage: For storing long-term credentials from user-facing OAuth2 flows (e.g., desktop apps requiring user login)
  • ServiceAccountCredentials: For server-to-server authorization (no user interaction needed, perfect for background scripts or scheduled tasks like your weather tracker)

How to Fix This?

We'll refactor the credential loading logic to use the correct service account workflow, and also clean up your JSON parsing (regex is unreliable for this use case).

Modified Full Code

import requests, gspread, time
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime

def temperature():
    # Define API scopes
    scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
    
    # Load service account credentials directly (no Storage needed)
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        'Singapore-Weather-84def2be176a.json',
        scope
    )
    
    # Authorize and access the Google Sheet
    gc = gspread.authorize(credentials)
    wks = gc.open('Singapore Weather').sheet1
    
    # Fetch weather data and access values directly from JSON (no regex!)
    r = requests.get('https://api.darksky.net/forecast/b02b5107a2c9c27deaa3bc1876bcee81/1.312914,%20103.780257')
    current_data = r.json()['currently']
    
    temperature = current_data['temperature']
    apparent_temp = current_data['apparentTemperature']
    cloud_cover = current_data['cloudCover'] * 100
    timenow = datetime.now()
    
    # Append data to the sheet
    wks.append_row([str(timenow), temperature, apparent_temp, cloud_cover])

while True:
    temperature()
    time.sleep(3597)

Key Changes Explained

  1. Removed Storage & httplib2 code: Service accounts don't require Storage—we load the JSON key directly with from_json_keyfile_name.
  2. Replaced regex with direct JSON access: Regex breaks easily if the API's JSON structure changes (e.g., field order, whitespace). Direct key access is far more reliable.
  3. Simplified authorization flow: gspread.authorize() accepts ServiceAccountCredentials directly, so we don't need manual HTTP authorization or credential refreshes.

Extra Notes

  • Make sure your service account email is added as an editor to the "Singapore Weather" Google Sheet (use the Share button in the Sheet to grant access). Without this, you'll get permission errors.
  • Double-check that the Singapore-Weather-84def2be176a.json file is in the same directory as your script, or use an absolute file path.

内容的提问来源于stack exchange,提问作者jso8910

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:22:32