为什么Google API无法连接并超时

1 投票
1 回答
39 浏览
提问于 2025-04-13 02:20

我正在尝试使用API密钥,它确实可以在树莓派上拍照,但在发送照片到云端硬盘时却卡住了,我不太明白为什么。

注意:为了保护隐私,我把密钥和ID去掉了,但我确实有正确的信息在那儿。

import os
import pickle
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from picamera import PiCamera
from time import sleep
from datetime import datetime

API_KEY = "key"
FOLDER_ID = "ID"

def authenticate_drive():
    service = build('drive', 'v3', developerKey=API_KEY)
    return service

def take_picture(service):
    now = datetime.now()
    date_string = now.strftime("%m_%d_%y_%H%M")
    file_path = os.path.join(os.path.dirname(__file__), 'camera', 'pics_new', 'pic%s.jpg' % date_string)
    
    with PiCamera() as camera:
        camera.resolution = (2592, 1944)
        camera.framerate = 20

        sleep(3)
        camera.capture(file_path)
        prPeriwinkle("TAKE PICTURE", datetime.now().strftime("%H:%M:%S"))
        
        prNeonPink("Sending to Drive", datetime.now().strftime("%H:%M:%S"))
        
        # Upload the picture to Google Drive
        file_metadata = {'name': os.path.basename(file_path), 'parents': [FOLDER_ID]}
        media = MediaFileUpload(file_path, mimetype='image/jpeg')
        file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

        print("Uploaded to Google Drive")

def main():
    service = authenticate_drive()
    take_picture(service)

if __name__ == '__main__':
    main()

过了一会儿,它输出了这个信息:
sock.connect((self.host, self.port))
socket.timeout: 超时

我已经尝试解决这个问题很长时间了,但还是搞不定。

我试着用谷歌API的API密钥把照片上传到云端硬盘,但在发送照片时又卡住了。

1 个回答

0

API 密钥只能让你访问公开的数据。

你不能仅凭 API 密钥进行上传操作,这需要一个私人账户,也就是需要使用 oauth2 来连接用户账户。

Oauth2

def build_service(credentials, scope, user_token):
    creds = None

    if os.path.exists(user_token):
        creds = Credentials.from_authorized_user_file(user_token, scope)

    # If there are no (valid) user credentials available, prompt the user to 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, scope)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open(user_token, 'w') as token:
            token.write(creds.to_json())
    try:
        return build('drive', 'v3', credentials=creds)
    except HttpError as error:
        # TODO(developer) - any errors returned.
        print(f'An error occurred: {error}')

撰写回答