Spaces:
Running
Running
| from pathlib import Path | |
| import boto3 | |
| from supabase import Client | |
| class SupabaseStorage: | |
| """Storage adapter backed by Supabase Storage. Same interface as R2Storage.""" | |
| def __init__(self, *, client: Client, bucket: str, public_base_url: str): | |
| self.bucket = bucket | |
| self.public_base_url = public_base_url.rstrip("/") | |
| self._client = client | |
| def upload(self, data: bytes, key: str, *, content_type: str = "application/octet-stream") -> None: | |
| self._client.storage.from_(self.bucket).upload( | |
| path=key, file=data, | |
| file_options={"content-type": content_type, "upsert": "true"}, | |
| ) | |
| def upload_file(self, path: Path, key: str, *, content_type: str = "audio/mpeg") -> None: | |
| with open(path, "rb") as f: | |
| self._client.storage.from_(self.bucket).upload( | |
| path=key, file=f.read(), | |
| file_options={"content-type": content_type, "upsert": "true"}, | |
| ) | |
| def delete(self, key: str) -> None: | |
| self._client.storage.from_(self.bucket).remove([key]) | |
| def public_url(self, key: str) -> str: | |
| return f"{self.public_base_url}/{key}" | |
| class R2Storage: | |
| def __init__(self, *, account_id: str, access_key: str, secret_key: str, | |
| bucket: str, public_base_url: str): | |
| self.bucket = bucket | |
| self.public_base_url = public_base_url.rstrip("/") | |
| self._s3 = boto3.client( | |
| "s3", | |
| endpoint_url=f"https://{account_id}.r2.cloudflarestorage.com", | |
| aws_access_key_id=access_key, | |
| aws_secret_access_key=secret_key, | |
| region_name="auto", | |
| ) | |
| def upload(self, data: bytes, key: str, *, content_type: str = "application/octet-stream") -> None: | |
| self._s3.put_object(Bucket=self.bucket, Key=key, Body=data, ContentType=content_type) | |
| def upload_file(self, path: Path, key: str, *, content_type: str = "audio/mpeg") -> None: | |
| self._s3.upload_file( | |
| Filename=str(path), Bucket=self.bucket, Key=key, | |
| ExtraArgs={"ContentType": content_type}, | |
| ) | |
| def delete(self, key: str) -> None: | |
| self._s3.delete_object(Bucket=self.bucket, Key=key) | |
| def public_url(self, key: str) -> str: | |
| return f"{self.public_base_url}/{key}" | |