s3_service.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import uuid
  2. import boto3
  3. from botocore.config import Config
  4. from botocore.exceptions import ClientError
  5. from decouple import config
  6. from loguru import logger
  7. from werkzeug.exceptions import InternalServerError
  8. from constants import NOT_AVAILABLE
  9. class S3Service:
  10. """ S3 Service """
  11. def __init__(self):
  12. self.key = config("AWS_ACCESS_KEY")
  13. self.secret = config("AWS_SECRET")
  14. self.bucket_name = config("AWS_BUCKET")
  15. self.region = config("AWS_REGION")
  16. self.s3 = boto3.client(
  17. "s3",
  18. aws_access_key_id=self.key,
  19. aws_secret_access_key=self.secret,
  20. region_name=self.region,
  21. config=Config(signature_version="s3v4"),
  22. )
  23. def __generate_pre_signed_url(
  24. self, expiration_time, object_name, key_prefix, operation_name="get_object"
  25. ):
  26. """
  27. Generate a presigned URL for the S3 object
  28. :param expiration_time:
  29. :param object_name:
  30. :param key_prefix:
  31. :param operation_name:
  32. :return: url
  33. """
  34. url = self.s3.generate_presigned_url(
  35. operation_name,
  36. Params={"Bucket": self.bucket_name, "Key": f"{key_prefix}/{object_name}"},
  37. ExpiresIn=expiration_time,
  38. )
  39. return url
  40. def upload_object(self, file_name, object_name, expiration_time):
  41. """
  42. Upload a file to an S3 bucket
  43. :param file_name:
  44. :param object_name:
  45. :param expiration_time:
  46. :return: url as string of the presigned url
  47. """
  48. try:
  49. key_prefix = str(uuid.uuid4())
  50. self.s3.upload_file(
  51. file_name, self.bucket_name, f"{key_prefix}/{object_name}",
  52. )
  53. return self.__generate_pre_signed_url(
  54. expiration_time, object_name, key_prefix
  55. )
  56. except ClientError as client_error:
  57. logger.exception(
  58. NOT_AVAILABLE, client_error,
  59. )
  60. raise InternalServerError(NOT_AVAILABLE)
  61. def get_upload_url(self, expiration_time, object_name):
  62. """
  63. Get a presigned url to upload an object
  64. :param expiration_time:
  65. :param object_name:
  66. :return: url as string of the presigned url
  67. """
  68. try:
  69. key_prefix = str(uuid.uuid4())
  70. return self.__generate_pre_signed_url(
  71. expiration_time, object_name, key_prefix, "put_object"
  72. )
  73. except ClientError as client_error:
  74. logger.exception(
  75. NOT_AVAILABLE, client_error,
  76. )
  77. raise InternalServerError(NOT_AVAILABLE)