google_storage_util.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import io
  2. import json
  3. import logging
  4. import os
  5. from app.config import settings
  6. from app.util.file_util import generate_unique_filename
  7. logger = logging.getLogger(__name__)
  8. def upload_file(
  9. local_path: str,
  10. gcs_key: str,
  11. project_id: str | None = None,
  12. bucket_name: str | None = None,
  13. credentials_json: str | None = None,
  14. ) -> str | None:
  15. if not local_path or not gcs_key:
  16. logger.error("Local file path or GCS key is blank.")
  17. return None
  18. if not os.path.isfile(local_path):
  19. logger.error("Local file does not exist: %s", local_path)
  20. return None
  21. pid = project_id or settings.gcs_project_id
  22. bn = bucket_name or settings.gcs_bucket_name
  23. cred = credentials_json or settings.gcs_credentials_json
  24. if not cred and settings.gcs_credentials_file:
  25. try:
  26. with open(settings.gcs_credentials_file, "r", encoding="utf-8") as f:
  27. cred = f.read()
  28. except Exception as e:
  29. logger.error("Failed to read GCS credentials file: %s", e)
  30. try:
  31. from google.cloud import storage as gcs_storage
  32. from google.oauth2 import service_account
  33. if cred:
  34. info = json.loads(cred)
  35. credentials = service_account.Credentials.from_service_account_info(info)
  36. client = gcs_storage.Client(project=pid, credentials=credentials)
  37. else:
  38. client = gcs_storage.Client(project=pid)
  39. bucket = client.bucket(bn)
  40. blob = bucket.blob(gcs_key)
  41. blob.upload_from_filename(local_path)
  42. gcs_url = f"https://storage.googleapis.com/{bn}/{gcs_key}"
  43. logger.debug("Successfully uploaded: %s", gcs_url)
  44. return gcs_url
  45. except Exception as e:
  46. logger.error("Failed to upload file to GCS: %s -> %s, %s", local_path, gcs_key, e)
  47. return None
  48. def upload_files(
  49. local_paths: list[str],
  50. gcs_prefix: str,
  51. project_id: str | None = None,
  52. bucket_name: str | None = None,
  53. credentials_json: str | None = None,
  54. ) -> list[str]:
  55. uploaded: list[str] = []
  56. if not local_paths:
  57. return uploaded
  58. if not gcs_prefix:
  59. gcs_prefix = "uploads/"
  60. if not gcs_prefix.endswith("/"):
  61. gcs_prefix += "/"
  62. for path in local_paths:
  63. try:
  64. name = generate_unique_filename(os.path.basename(path))
  65. key = gcs_prefix + name
  66. url = upload_file(path, key, project_id, bucket_name, credentials_json)
  67. if url:
  68. uploaded.append(url)
  69. except Exception as e:
  70. logger.error("Failed to upload file: %s, %s", path, e)
  71. return uploaded