ReceiptSplitAI / google_drive_client.py
valentynliubchenko
merging
eba303d
import os
import tempfile
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from googleapiclient.errors import HttpError
class GoogleDriveClient:
def __init__(self, json_key_path=None, json_key_env_var='GOOGLE_SERVICE_ACCOUNT_KEY'):
"""
Initializes the Google Drive client.
:param json_key_path: Path to the JSON file (optional)
:param json_key_env_var: Environment variable name containing the JSON key (default 'GOOGLE_SERVICE_ACCOUNT_KEY')
"""
self.json_key_path = json_key_path
self.json_key_env_var = json_key_env_var
self.service = self._authenticate_google_drive()
def _authenticate_google_drive(self):
"""
Authenticates using the JSON key from a file or environment variable.
:return: Google Drive API service object
"""
if self.json_key_path and os.path.isfile(self.json_key_path):
# Authenticate using the file
creds = service_account.Credentials.from_service_account_file(
self.json_key_path,
scopes=['https://www.googleapis.com/auth/drive.file']
)
else:
# Get JSON key from environment variable
json_key = os.getenv(self.json_key_env_var)
if not json_key:
raise ValueError(f"Environment variable {self.json_key_env_var} is not set.")
# Save JSON key to a temporary file
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_file.write(json_key.encode('utf-8'))
temp_file_path = temp_file.name
# Create credentials object
creds = service_account.Credentials.from_service_account_file(
temp_file_path,
scopes=['https://www.googleapis.com/auth/drive.file']
)
# Remove the temporary file after creating the credentials object
os.remove(temp_file_path)
# Create and return the Google Drive API service object
return build('drive', 'v3', credentials=creds)
def upload_file(self, file_path, folder_id):
"""
Uploads a file to Google Drive.
:param file_path: Path to the local file
:param folder_id: ID of the folder on Google Drive
:return: URL of the uploaded file or error message
"""
try:
file_metadata = {
'name': os.path.basename(file_path),
'parents': [folder_id] # ID of the folder to upload the file to
}
media = MediaFileUpload(file_path, mimetype='application/octet-stream')
# Upload the file
file = self.service.files().create(body=file_metadata, media_body=media, fields='id').execute()
# Get the file ID and construct the URL
file_id = file.get('id')
file_link = f'https://drive.google.com/file/d/{file_id}/view?usp=drive_link'
return file_link
except HttpError as error:
return f"An error occurred: {error}"
# Example usage
if __name__ == '__main__':
# Path to the local file
file_path = './file.txt'
# ID of the folder on Google Drive
# folder_id = '19yiqYX_Z1rbHDxnFLJTvji0VcbhSO9cq'
folder_id = '10qtum6ykbGTyu7vvw59i3h1XSY3-lRpo'
# Initialize the client and upload the file
client = GoogleDriveClient(json_key_path='secrets/GOOGLE_SERVICE_DRIVE_KEY_435817.json')
file_link = client.upload_file(file_path, folder_id)
print(f'File upload result: {file_link}')