Why Does Google API Not Connect and Times Out

42 views Asked by At

I am trying to use the API Key and it does take the picture on the Raspi but then gets stuck trying to send it to the Drive and I am unsure why.

Note: I took out the key and ID for privacy but I do actually have the proper info there

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()

After a while it out puts this:
sock.connect((self.host, self.port)) socket.timeout: timed out

I have been trying to solve this for some time and cannot figure it out

I tried using the API Key from Google API to upload pictures to the Drive but it gets stuck trying to send the picture.

1

There are 1 answers

3
Linda Lawton - DaImTo On

Api keys only give you access to public data.

You can't upload with an API key it requires private account to a user account use 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}')