Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions google/cloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ def list_blobs(
page_token=None,
prefix=None,
delimiter=None,
match_glob=None,
Comment thread
cojenco marked this conversation as resolved.
Outdated
start_offset=None,
end_offset=None,
include_trailing_delimiter=None,
Expand Down Expand Up @@ -1314,6 +1315,12 @@ def list_blobs(
:param delimiter: (Optional) Delimiter, used with ``prefix`` to
emulate hierarchy.

:type match_glob: str
:param match_glob:
(Optional) A glob pattern used to filter results (for example, foo*bar).
The string value must be UTF-8 encoded. See:
https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob

:type start_offset: str
:param start_offset:
(Optional) Filter results to objects whose names are
Expand Down Expand Up @@ -1376,6 +1383,7 @@ def list_blobs(
page_token=page_token,
prefix=prefix,
delimiter=delimiter,
match_glob=match_glob,
start_offset=start_offset,
end_offset=end_offset,
include_trailing_delimiter=include_trailing_delimiter,
Expand Down
9 changes: 9 additions & 0 deletions google/cloud/storage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,7 @@ def list_blobs(
page_token=None,
prefix=None,
delimiter=None,
match_glob=None,
start_offset=None,
end_offset=None,
include_trailing_delimiter=None,
Expand Down Expand Up @@ -1154,6 +1155,11 @@ def list_blobs(
(Optional) Delimiter, used with ``prefix`` to
emulate hierarchy.

match_glob (str):
(Optional) A glob pattern used to filter results (for example, foo*bar).
The string value must be UTF-8 encoded. See:
https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob

start_offset (str):
(Optional) Filter results to objects whose names are
lexicographically equal to or after ``startOffset``. If
Expand Down Expand Up @@ -1231,6 +1237,9 @@ def list_blobs(
if delimiter is not None:
extra_params["delimiter"] = delimiter

if match_glob is not None:
extra_params["matchGlob"] = match_glob

if start_offset is not None:
extra_params["startOffset"] = start_offset

Expand Down
32 changes: 32 additions & 0 deletions tests/system/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,38 @@ def test_bucket_list_blobs_hierarchy_w_include_trailing_delimiter(
assert iterator.prefixes == expected_prefixes


@_helpers.retry_failures
def test_bucket_list_blobs_w_match_glob(
storage_client,
buckets_to_delete,
blobs_to_delete,
):
bucket_name = _helpers.unique_name("w-matchglob")
bucket = _helpers.retry_429_503(storage_client.create_bucket)(bucket_name)
buckets_to_delete.append(bucket)

payload = b"helloworld"
blob_names = ["foo/bar", "foo/baz", "foo/foobar", "foobar"]
for name in blob_names:
blob = bucket.blob(name)
blob.upload_from_string(payload)
blobs_to_delete.append(blob)

match_glob_results = {
"foo*bar": ["foobar"],
"foo**bar": ["foo/bar", "foo/foobar", "foobar"],
"**/foobar": ["foo/foobar", "foobar"],
"*/ba[rz]": ["foo/bar", "foo/baz"],
"*/ba[!a-y]": ["foo/baz"],
"**/{foobar,baz}": ["foo/baz", "foo/foobar", "foobar"],
"foo/{foo*,*baz}": ["foo/baz", "foo/foobar"],
}
for match_glob, expected_names in match_glob_results.items():
blob_iter = bucket.list_blobs(match_glob=match_glob)
blobs = list(blob_iter)
assert [blob.name for blob in blobs] == expected_names


def test_bucket_w_retention_period(
storage_client,
buckets_to_delete,
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,7 @@ def test_list_blobs_w_defaults(self):
expected_max_results = None
expected_prefix = None
expected_delimiter = None
expected_match_glob = None
expected_start_offset = None
expected_end_offset = None
expected_include_trailing_delimiter = None
Expand All @@ -1155,6 +1156,7 @@ def test_list_blobs_w_defaults(self):
page_token=expected_page_token,
prefix=expected_prefix,
delimiter=expected_delimiter,
match_glob=expected_match_glob,
start_offset=expected_start_offset,
end_offset=expected_end_offset,
include_trailing_delimiter=expected_include_trailing_delimiter,
Expand All @@ -1171,6 +1173,7 @@ def test_list_blobs_w_explicit(self):
page_token = "ABCD"
prefix = "subfolder"
delimiter = "/"
match_glob = "**txt"
start_offset = "c"
end_offset = "g"
include_trailing_delimiter = True
Expand All @@ -1188,6 +1191,7 @@ def test_list_blobs_w_explicit(self):
page_token=page_token,
prefix=prefix,
delimiter=delimiter,
match_glob=match_glob,
start_offset=start_offset,
end_offset=end_offset,
include_trailing_delimiter=include_trailing_delimiter,
Expand All @@ -1205,6 +1209,7 @@ def test_list_blobs_w_explicit(self):
expected_max_results = max_results
expected_prefix = prefix
expected_delimiter = delimiter
expected_match_glob = match_glob
expected_start_offset = start_offset
expected_end_offset = end_offset
expected_include_trailing_delimiter = include_trailing_delimiter
Expand All @@ -1217,6 +1222,7 @@ def test_list_blobs_w_explicit(self):
page_token=expected_page_token,
prefix=expected_prefix,
delimiter=expected_delimiter,
match_glob=expected_match_glob,
start_offset=expected_start_offset,
end_offset=expected_end_offset,
include_trailing_delimiter=expected_include_trailing_delimiter,
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,7 @@ def test_list_blobs_w_explicit_w_user_project(self):
page_token = "ABCD"
prefix = "subfolder"
delimiter = "/"
match_glob = "**txt"
start_offset = "c"
end_offset = "g"
include_trailing_delimiter = True
Expand All @@ -1953,6 +1954,7 @@ def test_list_blobs_w_explicit_w_user_project(self):
page_token=page_token,
prefix=prefix,
delimiter=delimiter,
match_glob=match_glob,
start_offset=start_offset,
end_offset=end_offset,
include_trailing_delimiter=include_trailing_delimiter,
Expand All @@ -1976,6 +1978,7 @@ def test_list_blobs_w_explicit_w_user_project(self):
"projection": projection,
"prefix": prefix,
"delimiter": delimiter,
"matchGlob": match_glob,
"startOffset": start_offset,
"endOffset": end_offset,
"includeTrailingDelimiter": include_trailing_delimiter,
Expand Down