YUDA't

읽지 않아도 되는 서론;

구글 시트를 업데이트하려면 당연히 별도의 인증절차가 필요하다. 업데이트하려는 자가 그 시트에 대한 접근 권한이 있는지 알아야 하기 때문이다. 이건 시트 공유 설정을 '링크가 있는 모든 사용자가 수정할 수 있음'으로 해도 마찬가지다. 

 

한편 구글에서 제공한 Python Quickstart를 보면 OAuth 2.0 클라이언트 인증을 사용하는데, 이렇게 하면 유저가 구글 로그인을 해서 권한을 얻어 시트를 열거나 수정할 수 있다. 다만 내 시트를 내가 수정하는 경우 이 방법을 사용하면 매우 귀찮다는 생각이 든다. 유저 정보가 필요한 게 아니고 내 애플리케이션을 가지고 작업하는 거니까. 물론 별도의 작업을 거쳐 OAuth 클라이언트로도 로그인 없이 작업을 수행할 수 있지만 약간 번거롭다.

 

그래서 로그인 절차 없이 내 애플리케이션(시트)에 접근할 수 있는 서비스 계정 키를 사용했다. 서비스 계정이란 '특정 유저가 아닌 애플리케이션에 속한 특별한 유형의 Google 계정'인데, 나도 처음 써봐서 좀 헷갈렸지만 그냥 쉽게 로봇 계정이라 생각하면 된다. 어느 때에 OAuth 2.0 클라이언트를 사용하고 서비스 계정을 사용하는지 궁금하다면 스택오버플로 답변을 참고하자.

그럼 시작!!

 



0) GCP 콘솔에서 새로운 프로젝트를 생성한다.

GCP 콘솔에 들어가 프로젝트를 생성한다. 무료 계정이어도 20개까진가 생성 가능하다.

 

1) 프로젝트에서 Google Sheets API를 활성화한다.

왼쪽 탭의 API 및 서비스 > 라이브러리에 들어가서 Google Sheets를 검색한다.


그럼 아래와 같이 나오는데 '사용 설정' 버튼을 눌러 Google Sheets API를 활성화한다.

2) 프로젝트의 서비스 계정 키 생성

프로젝트를 생성하고 API도 활성화했으니 이제 서비스 계정을 만들어야 한다. 왼쪽 탭을 열어 'API 및 서비스' > '사용자 인증 정보' 클릭한다.

 

'사용자 인증 정보 만들기'에서 '서비스 계정 키'를 선택한다.


'새 서비스 계정'을 선택한 뒤 이름과 ID를 적당히 적어준다. 시트 편집을 시킬 거니 역할은 프로젝트 편집자로 설정했다. 키 유형은 JSON으로 한다. 다 입력하고 '생성' 버튼을 누르면 json 파일이 다운로드될 텐데 이걸 credential로 사용해야 하니 소중히 여기자.

이제 Google Sheets API 관리 페이지에서 '사용자 인증 정보'를 보면 방금 만든 사용자 계정이 보일 것이다.


2) 사용자 계정과 구글 시트 공유

사용자 계정을 만들 때 다운로드한 json 파일에서 "client_email"의 값을 복사한다.

{
  "type": "service_account",
  "project_id": "my-python-project-237605",
  "private_key_id": "",
  "private_key": "",
  "client_email": "python-client@my-python-project-237605.iam.gserviceaccount.com",
  "client_id": "",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/bizform-practice%40bizform-practice.iam.gserviceaccount.com"
}

이게 바로 서비스 계정의 이메일인데, 내가 수정하려는 구글 시트에서 이 이메일에 수정 권한을 공유해준다. 그럼 이제 구글 쪽 준비는 끝났다.


3) 파이썬 코드로 구글 시트 업데이트

pip으로 필요한 라이브러리들을 설치한다.

pip install --upgrade google-api-python-client oauth2client


전체 코드는 이렇다.

from httplib2 import Http
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

# Google API 요청 시 필요한 권한 유형
SCOPES = ['https://www.googleapis.com/auth/spreadsheets'] 
# 구글 시트 ID
SPREADSHEET_ID = '1T1o7XxzrIznXCsF5ZYsM6IN74-cVn2_eYrebY-aBf0s'

def main():
    values = [
        ['이건', '첫 번째', '행입니다.'],
        ['첫 번째'],
        ['열입니다.'],
    ]
    body = {
        'values': values
    }
    # json 파일로 서비스 계정 credential 정의
    credentials = ServiceAccountCredentials.from_json_keyfile_name('My Python Project-13f8199aebe1.json', SCOPES)
    http_auth = credentials.authorize(Http())
    service = build('sheets', 'v4', http=http_auth)
    # 업데이트 요청 및 실행
    request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID, 
                                                     range='시트1!A1:D3',  # 2
                                                     valueInputOption='RAW', 
                                                     body=body)
    request.execute()

if __name__ == '__main__':
    main()

 

실행하고 나면 시트에 값이 들어가 있을 것이다.


+ 구글 시트 id는 시트 url에서 /spreadsheets/d/ 뒤의 문자열이다.

+ 구글 시트의 range는 A1 표기법을 따라야 한다.

 


참고 & 읽을거리

Google Sheets Python Quickstart

구글 서비스 계정 이해

Introduction to the Google Sheets API

What's the difference between api key, client id and service account?