You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

google_cloud_storage.py 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import base64
  2. import io
  3. import json
  4. from collections.abc import Generator
  5. from contextlib import closing
  6. from flask import Flask
  7. from google.cloud import storage as google_cloud_storage
  8. from extensions.storage.base_storage import BaseStorage
  9. class GoogleCloudStorage(BaseStorage):
  10. """Implementation for Google Cloud storage."""
  11. def __init__(self, app: Flask):
  12. super().__init__(app)
  13. app_config = self.app.config
  14. self.bucket_name = app_config.get("GOOGLE_STORAGE_BUCKET_NAME")
  15. service_account_json_str = app_config.get("GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64")
  16. # if service_account_json_str is empty, use Application Default Credentials
  17. if service_account_json_str:
  18. service_account_json = base64.b64decode(service_account_json_str).decode("utf-8")
  19. # convert str to object
  20. service_account_obj = json.loads(service_account_json)
  21. self.client = google_cloud_storage.Client.from_service_account_info(service_account_obj)
  22. else:
  23. self.client = google_cloud_storage.Client()
  24. def save(self, filename, data):
  25. bucket = self.client.get_bucket(self.bucket_name)
  26. blob = bucket.blob(filename)
  27. with io.BytesIO(data) as stream:
  28. blob.upload_from_file(stream)
  29. def load_once(self, filename: str) -> bytes:
  30. bucket = self.client.get_bucket(self.bucket_name)
  31. blob = bucket.get_blob(filename)
  32. data = blob.download_as_bytes()
  33. return data
  34. def load_stream(self, filename: str) -> Generator:
  35. def generate(filename: str = filename) -> Generator:
  36. bucket = self.client.get_bucket(self.bucket_name)
  37. blob = bucket.get_blob(filename)
  38. with closing(blob.open(mode="rb")) as blob_stream:
  39. while chunk := blob_stream.read(4096):
  40. yield chunk
  41. return generate()
  42. def download(self, filename, target_filepath):
  43. bucket = self.client.get_bucket(self.bucket_name)
  44. blob = bucket.get_blob(filename)
  45. blob.download_to_filename(target_filepath)
  46. def exists(self, filename):
  47. bucket = self.client.get_bucket(self.bucket_name)
  48. blob = bucket.blob(filename)
  49. return blob.exists()
  50. def delete(self, filename):
  51. bucket = self.client.get_bucket(self.bucket_name)
  52. bucket.delete_blob(filename)