feat: Google Drive API 인증 및 에러 처리 개선

This commit is contained in:
2025-08-28 11:58:36 +09:00
parent 59d213ab4a
commit f0ddc5aebe
4 changed files with 66 additions and 15 deletions

View File

@@ -6,13 +6,13 @@
- Hugging Face 모델 (jxm/gpt-oss-20b-base)을 사용하여 AI 에이전트 실행
- 웹 크롤링을 통한 정보 수집
- 수집된 데이터의 Google Drive 저장
- 수집된 데이터의 Google Drive 저장 (마운트 방식 기본, API 선택)
- Colab Pro 환경에서 A100 GPU 활용
## 요구사항
- Python 3.8 이상
- Google Drive API 인증 파일 (credentials.json)
- (옵션) Google Drive API 인증 파일 (credentials.json)
- Colab Pro 계정 (A100 GPU 지원)
## 설치 방법
@@ -23,15 +23,18 @@ pip install -r requirements.txt
## 설정
1. `config.json` 파일에서 다음 항목들을 설정하세요:
- `google_drive_folder_id`: 데이터를 저장할 Google Drive 폴더 ID
- `google_credentials_path`: Google API 인증 파일 경로
1. `config.json` 파일 설정:
- `data_storage.drive_mount_path`: 기본 저장 경로 (마운트 방식)
- (옵션) `google_drive_folder_id`: Google Drive API 업로드 대상 폴더 ID
- (옵션) `google_credentials_path`: Google API 인증 파일 경로
2. Google Drive API 설정:
2. (옵션) Google Drive API 설정:
- Google Cloud Console에서 Drive API 활성화
- OAuth 2.0 클라이언트 ID 생성
- credentials.json 파일 다운로드
credentials.json 또는 folder_id가 없으면 API 업로드는 자동 비활성화되고, 마운트 방식 저장만 사용됩니다.
## 실행 방법
자세한 실행 방법은 `run_guide.md` 파일을 참고하세요.

View File

@@ -28,9 +28,28 @@ class AIAgent:
# 도구들 초기화
self.web_scraper = WebScraper(config_path)
self.drive_uploader = GoogleDriveUploader(config_path)
self.simple_saver = SimpleDriveSaver(self.config['data_storage']['drive_mount_path'])
# Google Drive API는 선택 사항: 자격증명 파일이 존재할 때만 활성화
self.drive_uploader = None
try:
drive_folder_id = self.config.get('google_drive_folder_id', '').strip()
creds_path = self.config.get('google_credentials_path', '').strip()
has_valid_folder = bool(drive_folder_id) and drive_folder_id != 'YOUR_GOOGLE_DRIVE_FOLDER_ID'
has_creds_file = bool(creds_path) and __import__('os').path.isfile(creds_path)
if has_valid_folder and has_creds_file:
self.drive_uploader = GoogleDriveUploader(config_path)
else:
reason = []
if not has_valid_folder:
reason.append('folder_id 미설정')
if not has_creds_file:
reason.append('credentials 파일 없음')
print(f"Google Drive API 비활성화 ({', '.join(reason)}) — SimpleDriveSaver만 사용")
except Exception as e:
# 어떤 이유로든 초기화 실패 시 API 도구는 비활성화하고 계속 진행
print(f"Google Drive API 초기화 실패: {e} — SimpleDriveSaver만 사용")
# LangChain 도구 정의
self.tools = [
Tool(
@@ -38,11 +57,6 @@ class AIAgent:
func=self.scrape_web,
description="웹사이트에서 정보를 수집합니다. URL을 입력하세요."
),
Tool(
name="GoogleDriveUploader",
func=self.upload_to_drive_api,
description="Google Drive API를 사용하여 데이터를 업로드합니다. 데이터와 파일명을 입력하세요."
),
Tool(
name="SimpleDriveSaver",
func=self.save_to_drive_simple,
@@ -50,6 +64,16 @@ class AIAgent:
)
]
# Google Drive API 도구는 사용 가능할 때만 추가
if self.drive_uploader is not None:
self.tools.append(
Tool(
name="GoogleDriveUploader",
func=self.upload_to_drive_api,
description="Google Drive API를 사용하여 데이터를 업로드합니다. 데이터(JSON)|파일명 형식으로 입력하세요."
)
)
# 메모리
self.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

View File

@@ -22,10 +22,18 @@ class GoogleDriveUploader:
"""
Google Drive API 인증
"""
# 자격증명 파일 존재 여부 확인 (명시적으로 친절한 메시지 제공)
if not self.creds_path or not os.path.isfile(self.creds_path):
raise FileNotFoundError(
f"Google Drive API 자격증명 파일을 찾을 수 없습니다: {self.creds_path}.\n"
f"config.json의 'google_credentials_path'를 올바른 credentials.json 경로로 설정하거나, API 업로드를 사용하지 마세요."
)
token_path = os.path.join(os.path.dirname(self.creds_path) or '.', 'token.json')
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', self.scopes)
if os.path.exists(token_path):
creds = Credentials.from_authorized_user_file(token_path, self.scopes)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
@@ -35,7 +43,7 @@ class GoogleDriveUploader:
self.creds_path, self.scopes)
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token:
with open(token_path, 'w') as token:
token.write(creds.to_json())
self.service = build('drive', 'v3', credentials=creds)
@@ -44,6 +52,9 @@ class GoogleDriveUploader:
"""
파일을 Google Drive에 업로드
"""
if self.service is None:
raise RuntimeError('Google Drive API가 초기화되지 않았습니다. credentials.json과 folder_id를 설정하세요.')
if file_name is None:
file_name = os.path.basename(file_path)
@@ -87,6 +98,9 @@ class GoogleDriveUploader:
"""
폴더 내 파일 목록 조회
"""
if self.service is None:
raise RuntimeError('Google Drive API가 초기화되지 않았습니다. credentials.json과 folder_id를 설정하세요.')
try:
results = self.service.files().list(
q=f"'{self.folder_id}' in parents",

View File

@@ -194,6 +194,16 @@ os.environ["HF_TOKEN"] = "hf_********************************"
```
또는 양자화된/경량화된 공개 모델을 사용하면 메모리 요구량이 크게 줄어듭니다.
### 6.4 Google Drive API 인증 오류 (credentials.json 없음)
- 기본 동작은 Google Drive 마운트 기반 저장(SimpleDriveSaver)입니다. 이 방법은 API 자격증명이 필요하지 않습니다.
- `config.json``google_credentials_path`가 가리키는 `credentials.json` 파일이 없거나, `google_drive_folder_id`가 기본값이라면 Google Drive API 업로드 도구는 자동으로 비활성화되고, 마운트 저장만 사용합니다.
- Google Drive API 업로드가 필요하다면:
1) Google Cloud Console에서 OAuth 2.0 클라이언트 ID(데스크톱)를 만들고 JSON을 다운로드
2) 프로젝트가 접근 가능한 경로에 파일을 두고 `config.json``google_credentials_path`를 해당 경로로 설정
3) 업로드 대상 폴더의 ID를 `google_drive_folder_id`에 설정
4) 첫 실행 시 브라우저 인증을 완료하면 `token.json`이 같은 폴더에 생성됩니다.
## 7. 확장 및 커스터마이징
### 7.1 새로운 도구 추가