ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Google Drive API 사용하기
    Tech 2020. 8. 16. 22:22
    반응형

    Google Drive API


    오늘은 Google Drive API를 사용해서 다수의 파일을 업로드하려 한다. 그냥 구글 드라이브 페이지에서 Drag&Drop하면 쉽게 되는데 왜 굳이 API를 사용하냐고? 파일 건 수가 18만 건 정도되니까 웹브라우저가 버티질 못 하고 오류가 나는 상황이 발생했기 때문이다.

     

    사실, 크롤링한 이미지를 OCR을 통해 텍스트를 추출하는 과정을 진행하고 있었는데, 생각지도 못 한 난관을 만나게 되었다. 바로, 맥북 프로에서는 'GPU 연산을 가능'하게 해 주는 CUDA가 지원되지 않다는 것이다. 파일을 로컬에 보관하고, 바로 구현된 OCR 모델로 처리하려 했는데. 불가능하게 되었다. 그래서 Google에서 제공해 주는, Colab으로 넘어가서 코드를 실행하고자 하였고. 이를 위해서 크롤링한 다수의 이미지를 드라이브에 업로드 하는 작업이 필요했다.

    * Google Colab에서 무료 런타임 환경으로 GPU를 제공해준다.

     

    - 엔비디아, 맥 OS에 대한 CUDA 지원 중단

     

    엔비디아, 맥 OS에 대한 CUDA 지원 중단 > 하드웨어 뉴스 | 퀘이사존

    오역이 있을 수 있으니 자세한 건 원문을 참고하시기 바라며  오역과 중복 글일 경우 지적해주시면 감사하겠습니다. 엔비디아, 맥 OS에 대한 CUDA 지원 중단 다음 CUDA 릴리스는 macOS에서 지원되지

    quasarzone.com

    Google Drive API는 어떻게 사용할까?


    매번 Google의 API 문서를 살펴볼 때마다 느끼는 것이지만, 보기가 조금.. 어려운 것 같다. 다른 바쁜 일들을 하느라 업데이트를 안 해주는 것 같다. 무튼, 이런 API를 제공해주는 것만으로도 감사해야할 일이긴 하다.

     

    1) Google APIs에 Drive용 애플리케이션 등록하기

     

    첫 번째로 해줘야할 작업은, Google Drive용 애플리케이션을 등록해주는 작업이다. 요기를 클릭해 들어가면, 절차에 따라 Google Drive API용 애플리케이션을 등록해주면 된다.

     

    1-1) 프로젝트 만들기 선택 후 해당 프로젝트로 이동하기

    1-2) 프로젝트 화면 → 사용자 인증 정보 → OAuth 클라이언트 ID 만들기

     

    2) Google Drive API를 Python으로 사용하기

     

    아래의 내용은, Google Drive API 공식 문서에 나와있는 내용이다. 보다 상세한 내용을 알고 싶다면, 다음 페이지로 이동하길 권장한다. 우선, Google Client Library를 설치해야하는데, 설치는 다음과 같다.

    pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

    이후, 퀵스타트 샘플 코드를 살펴보고 실행시켜 보도록 하자. 퀵스타트 샘플 코드를 실행하기 위해서는 우선 credential.json 파일이 필요하다. 해당 파일은, 처음 인증 정보를 생성할 때 다운로드 된 파일이며, [client_secret_......json] 이라는 파일명을 가지고 있을 것이다. 만약 해당 파일을 지웠다면,  프로젝트 → 사용자 인증 정보 → OAuth 2.0 클라이언트 ID를 확인해 보면 다시 다운로드할 수 있으니 다시 다운로드 받도록 하자.

     

    또 참고할 점은 'SCOPE'인데, 해당 값을 통해서 권한의 정도를 바꿀 수 있다. 현재는 'www.googleapis.com/auth/drive'로 Google Drive에 대한, See/Edit/Create/Delete 등 모든 권한을 부여할 수 있는 권한으로 설정되어 있다. 추후에 보다 적은 권한을 부여하려면, 해당 페이지를 살펴보고 변경해주면 된다. 예를 들어, 객체 메타 데이터에 대한 읽기 권한만 주고 싶으면 'https://www.googleapis.com/auth/drive.metadata.readonly'로 변경해주면 된다.

    from __future__ import print_function
    import pickle
    import os.path
    from googleapiclient.discovery import build
    from google_auth_oauthlib.flow import InstalledAppFlow
    from google.auth.transport.requests import Request
    
    # If modifying these scopes, delete the file token.pickle.
    SCOPES = ['https://www.googleapis.com/auth/drive']
    
    def main():
        """Shows basic usage of the Drive v3 API.
        Prints the names and ids of the first 10 files the user has access to.
        """
        creds = None
        # The file token.pickle stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token.pickle'):
            with open('token.pickle', 'rb') as token:
                creds = pickle.load(token)
        # If there are no (valid) credentials available, let the user 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.json', SCOPES)
                creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token.pickle', 'wb') as token:
                pickle.dump(creds, token)
    
        service = build('drive', 'v3', credentials=creds)
    
        # Call the Drive v3 API
        results = service.files().list(
            pageSize=10, fields="nextPageToken, files(id, name)").execute()
        items = results.get('files', [])
    
        if not items:
            print('No files found.')
        else:
            print('Files:')
            for item in items:
                print(u'{0} ({1})'.format(item['name'], item['id']))
    
    if __name__ == '__main__':
        main()

     

    자, 이제 실행시켜보면, 아래와 같은 화면의 창이 켜질 것이다. 그런 다음에 사용하려는 계정을 클릭하고, 생성한 프로젝트가 해당 계정 드라이브에 대한 권한을 얻을 수 있도록 한다. 이후 권한을 승인한다면, token.pickle이라는 파일이 생성될 것이고, 유효기간이 지나거나 어떠한 권한/데이터 들이 변경되지 않는 한 다음부터는 로그인하고 권한 승인할 필요 없이 곧바로 실행될 것이다. 그리고 결과적으로는, 위의 코드에 따라 드라이브 내의 10개의 파일 목록이 고유 ID와 함께 프린트 될 것이다.

    드라이브 내 파일을 읽는 것 말고도, 로컬 내 파일을 업로드할 수도 있다.

    # 단순 파일 업로드
    file_metadata = {'name' : name}
    ## mimeType을 설정해주어야 하지만, 웬만한 파일들은 자동으로 생성해준다.
    media = MediaFileUpload('/path', resumable = True)
    file = service.files().create(body = file_metadata, media_body=media, fields='id').execute()
    
    # 특정 폴더 내 파일 업로드
    ## parents에 업로드할 파일의 상위 폴더의 ID를 넣어주면 해당 폴더 안으로 업로드 된다.
    file_metadata = {'name' : name, 'parents' : ['folder id']}
    media = MediaFileUpload('/path', resumable = True)
    file = service.files().create(body = file_metadata, media_body=media, fields='id').execute()

    폴더의 ID는, 구글 드라이브에서 해당 폴더에 들어가 주소창을 확인해 보면 다음과 같은 링크가 나온다. 'https://drive.google.com/drive/u/0/folders/<folder id>' 해당 링크에서 가장 마지막 부분에 있는 것이 폴더의 ID인데, 해당 ID를 복사해 가져와 parents에 붙여 넣어주면 된다. 

     

    결론


    Python 이외에도 Node/Java 등등 사용할 수 있게 해주었기에 나름 쓸만하다. 하지만, 많은 양의 데이터를 업로드할 때 웹처럼 무한 로딩이나 튕기지는 않으나. 업로드 속도가 살짝 아쉬운 것 같다. 약 200kb의 파일을 업로드하는데 약 3~5초 정도의 시간이 소요되었기 때문이다. 이건 뭐, 네트워크 속도 문제이거나, Google Drive 유료 버전(?)을 이용하지 않아서일 것 같다. *스토리지 용량 외에 속도 이슈를 해결해줄 유료버전이 있는 지는 모르겠다. 또, 파일(분할압축?)을 압축한다던가, 이미지 파일의 용량(섬네일화 등등)을 줄이던가 해서 근본적인 속도 이슈를 해결할 수도?

    반응형

    댓글

Designed by Tistory.