Major Study./Computer Science

Google Drive 파일 Linux 서버에서 다운로드

sosal 2023. 12. 23. 21:46
반응형

목표: Google Drive에 업로드 된 테라 단위의 파일을 서버에 받아야 하는 상황

 

Ubuntu 리눅스 서버 환경에서 Google Drive와의 동기화를 시도했으나, google-drive-ocamlfuse와 rclone을 사용하는 과정에서 여러 어려움이 있었습니다.

 

제 서버 환경은 GUI가 없어서, OAuth 인증 과정에서 리디렉션과 인증 코드 입력이 필요했습니다. google-drive-ocamlfuse의 경우, 서버 설정과 리디렉션 URI 문제가 복잡했으며, rclone도 비슷한 인증 과정을 요구했습니다.

 

아무튼, 정리하면 google-drive-ocamlfuse는 사용자 인증을 필요로 하는 OAuth 2.0을 기반으로 합니다. 이 방식은 일반적으로 사용자의 브라우저에서 Google 계정으로 로그인하고 액세스 권한을 부여하는 인터랙티브한 인증 과정을 거칩니다. 서버 환경에서 GUI가 없다면 이 과정이 복잡해질 수 있습니다. ㅠㅠ

 

이런 여러가지 제약으로, GUI가 없는 서버 환경에서의 Google Drive 동기화는 결국 실패했습니다. ㅠㅠ

 

 

 

Python을 활용한 Google Drive 접근하기

 

ocamlfuse 및 rclone과 달리, 인터랙티브한 인증과정을 거칠 필요 없이 오직 서버단에서, Google Cloud Console에서 생성한 서비스 계정관련 JSON 키 파일만 있으면, OAuth 인증을 수월하게 처리할 수 있습니다.

 

꼭 sync를 매번 맞춰야 하는 상황이 아니시라면, (저와 같이 단순히 파일을 엄청 받아야하는 상황이라면) 파이썬으로 이러한 문제를 해결하실 수 있습니다.

 

 

 

 

1. Google Cloud Console에서 API 키 가져오기

 

1) 구글 클라우드 콘솔에 접속합니다.

https://console.cloud.google.com/

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

 

 

2) Google Cloud console의 프로젝트를 생성하거나, 이미 있는 프로젝트를 선택합니다.

 

 

3) IAM 및 관리자 에 들어갑니다.

 

 

 

4) IAM 및 관리자 / 서비스 계정탭

서비스 계정 탭에 들어간 후, '서비스 계정 만들기' 버튼을 클릭합니다.

 

 

5) 서비스 계정 만들기 상세

서비스 계정 세부정보에 대충 계정 이름, ID를 넣습니다.

 

 

 

6) 서비스 계정 접속

만들어진 서비스 계정에 접속합니다.

 

7) 서비스 계정의 키 생성하기

 

8) 계정 키 다운로드

 

 

중요한 credentials의 모든 정보를 얻었습니다.

 

9) 위 키를 credentials.json 파일로 리눅스 서버에 저장

이 파일의 내용을 Linux 서버에 credentials.json 로 저장합니다.

 

 

 

 

 

2. Python 패키지 설치

 

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

 

 

 

3. Google Drive Folder id 찾기

Python으로 접근하고자 하는 폴더 ID 를 찾아냅니다.

 

 

 

4. Python code 실행

 

첫번째로 살펴볼 코드는 파일의 조회입니다.

 

 

중요한 변수는 다음과 같습니다.

SERVICE_ACCOUNT_FILE: credentials.json의 경로를 입력

folder_id: 위 3번에서 찾은 folder id를 str로 입력

pageSize=500: 최대 500개의 파일을 가져옵니다. 파일의 수가 더 많다면 더 크게 설정

 

 

 
from googleapiclient.discovery import build
from google.oauth2 import service_account

########################################################
##### 서비스 계정 JSON 키 파일의 경로를 지정합니다. #####
########################################################
SERVICE_ACCOUNT_FILE = 'credentials.json' # <- 서비스 키 파일

# Google Drive API에 접근하기 위한 서비스 계정 인증 정보를 생성합니다.
creds = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=['https://www.googleapis.com/auth/drive'])

# Google Drive API 서비스 인스턴스를 생성합니다.
service = build('drive', 'v3', credentials=creds)

###############################################################
##### 조회하고자 하는 Google Drive 폴더의 ID를 지정합니다. #####
###############################################################
folder_id = '1TqcjhaiaIUCHIPCHACI_CASC123asdasdNiR8Yf5' # 이부분 수정하셔야 합니다.

# 폴더 내 파일 목록을 조회하기 위한 쿼리 문자열을 구성합니다.
query = f"'{folder_id}' in parents"

# Google Drive API를 통해 폴더 내의 파일 목록을 조회합니다.
# 'pageSize'는 한 번의 요청으로 반환받을 최대 파일 수를 지정합니다.
# 'fields'는 반환받을 정보의 범위를 지정합니다.
results = service.files().list(q=query, pageSize=500, fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
 

조회에 성공한 화면 결과

 

 

 

두번째로 살펴볼 코드는 파일의 다운로드입니다.

위 조회 코드에서 연결되는 부분입니다.

 


from googleapiclient.http import MediaIoBaseDownload
import io

file_idx = 0
file_id = items[file_idx]['id']
file_name = items[file_idx]['name']

request = service.files().get_media(fileId=file_id)
fh = io.BytesIO()
# 파일 다운로드를 위한 다운로더 객체를 생성합니다.
downloader = MediaIoBaseDownload(fh, request)

done = False
while not done:
    status, done = downloader.next_chunk()
    print(f"Download {int(status.progress() * 100)}%.")

# 다운로드된 파일을 로컬 시스템에 저장합니다.
with open(file_name, 'wb') as f:
    fh.seek(0)
    f.write(fh.read())
 

 

 

실제로 다운받아진 파일.

 

간단하게 python의 for loop로 모든 파일을 다운받으실 수 있습니다.

 

file_idx 변수를 아래와 같이 for loop로 바꾸면 전체 파일을 받으실 수 있습니다.

for file_idx in range(len(items)):

 

그리고 nohup으로 background에 켜놓으면 한 이틀이면 받아지지 않을까요.. 합니다. ^^

 nohup python ./file_download.py &