44many docstrings are borrowed from the underlying library.
55"""
66
7- from typing import Optional
7+ from typing import List , Optional
88
99import requests
1010from google .auth import identity_pool
1111from google .cloud import storage
12- from replit .storage .config import REPLIT_ADC , REPLIT_DEFAULT_BUCKET_URL
13- from replit .storage .errors import DefaultBucketError
12+ from google .cloud .exceptions import NotFound
13+ from replit .object_storage .config import REPLIT_ADC , REPLIT_DEFAULT_BUCKET_URL
14+ from replit .object_storage .errors import (
15+ DefaultBucketError ,
16+ ObjectNotFoundError ,
17+ google_error_handler ,
18+ )
19+ from replit .object_storage .object import Object
1420
1521
1622class Client :
@@ -39,14 +45,41 @@ def __init__(self, bucket_id: Optional[str] = None):
3945 self .__gcs_client = storage .Client (credentials = creds , project = "" )
4046 self .__gcs_bucket_handle = None
4147
42- def delete (self , object_name : str ) -> None :
48+ @google_error_handler
49+ def copy (self , object_name : str , dest_object_name : str ) -> None :
50+ """Copies the specified object within the same bucket.
51+
52+ If an object exists in the same location, it will be overwritten.
53+
54+ Args:
55+ object_name: The full path of the object to be copied.
56+ dest_object_name: The full path to copy the object to.
57+ """
58+ source_object = self .__object (object_name )
59+ bucket = self .__bucket ()
60+ bucket .copy_blob (
61+ source_object ,
62+ bucket ,
63+ dest_object_name ,
64+ )
65+
66+ @google_error_handler
67+ def delete (self , object_name : str , ignore_not_found : bool = False ) -> None :
4368 """Deletes an object from Object Storage.
4469
4570 Args:
4671 object_name: The name of the object to be deleted.
72+ ignore_not_found: Whether an error should be raised if the object does not
73+ exist.
4774 """
48- return self .__object (object_name ).delete ()
75+ try :
76+ return self .__object (object_name ).delete ()
77+ except NotFound as err :
78+ if ignore_not_found :
79+ return
80+ raise ObjectNotFoundError ("The requested object could not be found." ) from err
4981
82+ @google_error_handler
5083 def download_as_bytes (self , object_name : str ) -> bytes :
5184 """Download the contents an object as a bytes object.
5285
@@ -55,23 +88,16 @@ def download_as_bytes(self, object_name: str) -> bytes:
5588 """
5689 return self .__object (object_name ).download_as_bytes ()
5790
58- def download_as_string (self , object_name : str ) -> str :
91+ @google_error_handler
92+ def download_as_text (self , object_name : str ) -> str :
5993 """Download the contents an object as a string.
6094
6195 Args:
6296 object_name: The name of the object to be downloaded.
6397 """
6498 return self .__object (object_name ).download_as_text ()
6599
66- def download_to_file (self , object_name : str , dest_file ) -> None :
67- """Download the contents an object into a file-like object.
68-
69- Args:
70- object_name: The name of the object to be downloaded.
71- dest_file: A file-like object.
72- """
73- return self .__object (object_name ).download_to_file (dest_file )
74-
100+ @google_error_handler
75101 def download_to_filename (self , object_name : str , dest_filename : str ) -> None :
76102 """Download the contents an object into a file on the local disk.
77103
@@ -81,6 +107,7 @@ def download_to_filename(self, object_name: str, dest_filename: str) -> None:
81107 """
82108 return self .__object (object_name ).download_to_filename (dest_filename )
83109
110+ @google_error_handler
84111 def exists (self , object_name : str ) -> bool :
85112 """Checks if an object exist.
86113
@@ -89,15 +116,42 @@ def exists(self, object_name: str) -> bool:
89116 """
90117 return self .__object (object_name ).exists ()
91118
92- def upload_from_file (self , dest_object_name : str , src_file ) -> None :
93- """Uploads the contents of a file-like object.
119+ @google_error_handler
120+ def list (
121+ self ,
122+ end_offset : Optional [str ] = None ,
123+ match_glob : Optional [str ] = None ,
124+ max_results : Optional [int ] = None ,
125+ prefix : Optional [str ] = None ,
126+ start_offset : Optional [str ] = None ,
127+ ) -> List [Object ]:
128+ """Lists objects in the bucket.
94129
95130 Args:
96- dest_object_name: The name of the object to be uploaded.
97- src_file: A file-like object.
131+ end_offset: Filter results to objects whose names are lexicographically
132+ before end_offset. If start_offset is also set, the objects listed
133+ have names between start_offset (inclusive) and end_offset
134+ (exclusive).
135+ match_glob: Glob pattern used to filter results, for example foo*bar.
136+ max_results: The maximum number of results that can be returned in the
137+ response.
138+ prefix: Filter results to objects who names have the specified prefix.
139+ start_offset: Filter results to objects whose names are
140+ lexicographically equal to or after start_offset. If endOffset is
141+ also set, the objects listed have names between start_offset
142+ (inclusive) and end_offset (exclusive).
143+
98144 """
99- self .__object (dest_object_name ).upload_from_file (src_file )
100-
145+ iter = self .__bucket ().list_blobs (
146+ end_offset = end_offset ,
147+ match_glob = match_glob ,
148+ max_results = max_results ,
149+ prefix = prefix ,
150+ start_offset = start_offset ,
151+ )
152+ return [Object (name = object .name ) for object in iter ]
153+
154+ @google_error_handler
101155 def upload_from_filename (self , dest_object_name : str ,
102156 src_filename : str ) -> None :
103157 """Upload an object from a file on the local disk.
@@ -108,7 +162,8 @@ def upload_from_filename(self, dest_object_name: str,
108162 """
109163 self .__object (dest_object_name ).upload_from_filename (src_filename )
110164
111- def upload_from_string (self , dest_object_name : str , src_data : str ) -> None :
165+ @google_error_handler
166+ def upload_from_text (self , dest_object_name : str , src_data : str ) -> None :
112167 """Upload an object from a string.
113168
114169 Args:
@@ -117,11 +172,13 @@ def upload_from_string(self, dest_object_name: str, src_data: str) -> None:
117172 """
118173 self .__object (dest_object_name ).upload_from_string (src_data )
119174
120- def __object (self , object_name : str ) -> storage .Blob :
175+ def __bucket (self ) -> storage .Bucket :
121176 if self .__gcs_bucket_handle is None :
122177 self .__gcs_bucket_handle = self .__get_bucket_handle ()
178+ return self .__gcs_bucket_handle
123179
124- return self .__gcs_bucket_handle .blob (object_name )
180+ def __object (self , object_name : str ) -> storage .Blob :
181+ return self .__bucket ().blob (object_name )
125182
126183 def __get_bucket_handle (self ) -> storage .Bucket :
127184 if self .__bucket_id is None :
0 commit comments