import json from typing import Any import boto3 from botocore.exceptions import ClientError from download_spotify_charts import config class Client: def __init__(self): self.session = boto3.Session(region_name=config.AWS_DEFAULT_REGION) self.s3_resource = self.session.resource("s3") self.bucket = self.s3_resource.Bucket(config.AWS_S3_BUCKET_NAME) def _get_path(self, s3_key: str) -> str: """Generate path within S3 bucket. Args: s3_key: Related path in S3. Returns: Absolute path in S3. """ return f"{config.BUCKET_BASE_PATH}/{s3_key}" def get(self, s3_key: str, default_value: Any = None) -> Any: """Get text file from S3. Args: s3_key: Related path in S3. default_value: Default value if not found. """ try: obj = self.s3_resource.Object(config.AWS_S3_BUCKET_NAME, self._get_path(s3_key)) return obj.get()["Body"].read().decode() except ClientError: return default_value def put(self, s3_key: str, data: str, content_type: str = "text/plain"): """Update text file. Args: s3_key: Related path in S3. data: Data to save content_type: Content type. """ self.bucket.put_object(Key=self._get_path(s3_key), Body=data.encode(), ContentType=content_type) def upload_csv(self, s3_key: str, data): """Upload csv to S3 bucket. Args: s3_key: Related path in S3. data: Data to upload. """ self.bucket.upload_fileobj(data, self._get_path(s3_key), ExtraArgs={"ContentType": "text/csv"}) def put_json(self, s3_key: str, data: dict): """Update json config. Args: s3_key: Related path in S3. data: Data to save """ self.put(s3_key, json.dumps(data), "text/json") def get_json(self, s3_key: str, default_value: dict or None = None) -> dict: """Get json config from S3. Args: s3_key: Related path in S3. default_value: Default value if not found. """ value = self.get(s3_key, default_value) return json.loads(value) if value else default_value