end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Re: google drive api for python を使用した ocr

https://end0tknr.hateblo.jp/entry/20230223/1677142182

以前、上記entryを記載しましたが、 google_drive_ocr for python の影響でしょうか、 以下のようなエラーが表示されるようになりました。

google.auth.exceptions.RefreshError: ('deleted_client:
  The OAuth client was deleted.',
 {'error': 'deleted_client',
 'error_description': 'The OAuth client was deleted.'})

なので、 https://qiita.com/makaishi2/items/b0537413161d57335107 を写経しました。

2023/5/10追記

以下のscriptでは、 InstalledAppFlow.from_client_secrets_file(client_secret.json) で認証した結果を token.json というファイルにcacheしますが、 どうやら、上記のエラーは、token.json の有効期限切れが原因だったようです。

なので、token.json ファイルを削除することで解消します。

#!/usr/bin/python
# -*- coding: utf-8 -*-
# c.f.
# https://qiita.com/makaishi2/items/b0537413161d57335107
# https://laboratory.kazuuu.net/character-recognition-in-python-using-google-drive-ocr

import io
import os.path
import matplotlib.pyplot as plt
from PIL import Image
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from googleapiclient.http import MediaIoBaseDownload

SCOPES           = ['https://www.googleapis.com/auth/drive.file']
MIME_TYPE        = 'application/vnd.google-apps.document'
APPLICATION_NAME = 'ipa-google-drive-api-client'
client_secrets_file = "client_secret.json"
res_encode = "utf-8"

def main():
    input_file = "CAD_DATAS/sample_img.png"
    
    service = get_service()
    output = read_ocr(service, input_file, "ja")
    print(output)

    
def read_ocr(service,input_file,lang):
    # ローカルファイルの定義
    media_body = MediaFileUpload(input_file, mimetype=MIME_TYPE, resumable=True)

    newfile = 'output.pdf' # Google Drive上のfile名

    # creat関数でupload実行し、同時にOCR読み取り
    output = service.files().create(
        body={'name':newfile,'mimeType':MIME_TYPE},
        media_body=media_body,
        ocrLanguage=lang, ).execute()

    ## text file download
    
    request = service.files().export_media(fileId=output['id'],
                                           mimeType = "text/plain")
    output_path = 'output.txt' # 出力 text file名

    fh = io.FileIO(output_path, "wb")
    downloader = MediaIoBaseDownload(fh, request)
    
    done = False
    while done is False:
        status, done = downloader.next_chunk()

    # Google Drive上のfile削除
    service.files().delete(fileId=output['id']).execute()
 
    # textの取得
    with open(output_path,encoding=res_encode) as f:
        mylist = f.read().splitlines()[1:]
    return mylist
        
    
def get_service():
    # credentialの取得
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    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(
                client_secrets_file, SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
        
    # serviceの取得
    service = build('drive', 'v3', credentials=creds) 
    return service
    
if __name__ == '__main__':
    main()