@@ -111,6 +111,40 @@ def does_object_exist(path: str, boto3_session: Optional[boto3.Session] = None)
111111 raise ex # pragma: no cover
112112
113113
114+ def list_directories (path : str , boto3_session : Optional [boto3 .Session ] = None ) -> List [str ]:
115+ """List Amazon S3 objects from a prefix.
116+
117+ Parameters
118+ ----------
119+ path : str
120+ S3 path (e.g. s3://bucket/prefix).
121+ boto3_session : boto3.Session(), optional
122+ Boto3 Session. The default boto3 session will be used if boto3_session receive None.
123+
124+ Returns
125+ -------
126+ List[str]
127+ List of objects paths.
128+
129+ Examples
130+ --------
131+ Using the default boto3 session
132+
133+ >>> import awswrangler as wr
134+ >>> wr.s3.list_objects('s3://bucket/prefix/')
135+ ['s3://bucket/prefix/dir0', 's3://bucket/prefix/dir1', 's3://bucket/prefix/dir2']
136+
137+ Using a custom boto3 session
138+
139+ >>> import boto3
140+ >>> import awswrangler as wr
141+ >>> wr.s3.list_objects('s3://bucket/prefix/', boto3_session=boto3.Session())
142+ ['s3://bucket/prefix/dir0', 's3://bucket/prefix/dir1', 's3://bucket/prefix/dir2']
143+
144+ """
145+ return _list_objects (path = path , delimiter = "/" , boto3_session = boto3_session )
146+
147+
114148def list_objects (path : str , boto3_session : Optional [boto3 .Session ] = None ) -> List [str ]:
115149 """List Amazon S3 objects from a prefix.
116150
@@ -142,20 +176,37 @@ def list_objects(path: str, boto3_session: Optional[boto3.Session] = None) -> Li
142176 ['s3://bucket/prefix0', 's3://bucket/prefix1', 's3://bucket/prefix2']
143177
144178 """
179+ return _list_objects (path = path , delimiter = None , boto3_session = boto3_session )
180+
181+
182+ def _list_objects (
183+ path : str , delimiter : Optional [str ] = None , boto3_session : Optional [boto3 .Session ] = None
184+ ) -> List [str ]:
145185 client_s3 : boto3 .client = _utils .client (service_name = "s3" , session = boto3_session )
146186 paginator = client_s3 .get_paginator ("list_objects_v2" )
147187 bucket : str
148188 prefix : str
149189 bucket , prefix = _utils .parse_path (path = path )
150- response_iterator = paginator .paginate (Bucket = bucket , Prefix = prefix , PaginationConfig = {"PageSize" : 1000 })
190+ args : Dict [str , Any ] = {"Bucket" : bucket , "Prefix" : prefix , "PaginationConfig" : {"PageSize" : 1000 }}
191+ if delimiter is not None :
192+ args ["Delimiter" ] = delimiter
193+ response_iterator = paginator .paginate (** args )
151194 paths : List [str ] = []
152195 for page in response_iterator :
153- contents : Optional [List ] = page .get ("Contents" )
154- if contents is not None :
155- for content in contents :
156- if (content is not None ) and ("Key" in content ):
157- key : str = content ["Key" ]
158- paths .append (f"s3://{ bucket } /{ key } " )
196+ if delimiter is None :
197+ contents : Optional [List [Optional [Dict [str , str ]]]] = page .get ("Contents" )
198+ if contents is not None :
199+ for content in contents :
200+ if (content is not None ) and ("Key" in content ):
201+ key : str = content ["Key" ]
202+ paths .append (f"s3://{ bucket } /{ key } " )
203+ else :
204+ prefixes : Optional [List [Optional [Dict [str , str ]]]] = page .get ("CommonPrefixes" )
205+ if prefixes is not None :
206+ for pfx in prefixes :
207+ if (pfx is not None ) and ("Prefix" in pfx ):
208+ key = pfx ["Prefix" ]
209+ paths .append (f"s3://{ bucket } /{ key } " )
159210 return paths
160211
161212
0 commit comments