From 8ed901232f0df7015fa8bb75a122dc2776f8900d Mon Sep 17 00:00:00 2001 From: sumanth-manchala Date: Sat, 7 Feb 2026 17:15:39 +0530 Subject: [PATCH 1/4] Accept PUT as a valid http method --- pyiceberg/catalog/rest/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyiceberg/catalog/rest/__init__.py b/pyiceberg/catalog/rest/__init__.py index 802be28565..40fc05dbf2 100644 --- a/pyiceberg/catalog/rest/__init__.py +++ b/pyiceberg/catalog/rest/__init__.py @@ -88,6 +88,7 @@ class HttpMethod(str, Enum): HEAD = "HEAD" POST = "POST" DELETE = "DELETE" + PUT = "PUT" class Endpoint(IcebergBaseModel): From 354f1481a4daeb5e888f5b20043744ef868fa5db Mon Sep 17 00:00:00 2001 From: sumanth-manchala Date: Tue, 17 Feb 2026 12:35:02 +0530 Subject: [PATCH 2/4] Add all valid Http Methods --- pyiceberg/catalog/rest/__init__.py | 4 ++++ tests/catalog/test_rest.py | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/pyiceberg/catalog/rest/__init__.py b/pyiceberg/catalog/rest/__init__.py index 40fc05dbf2..69b1c17b95 100644 --- a/pyiceberg/catalog/rest/__init__.py +++ b/pyiceberg/catalog/rest/__init__.py @@ -89,6 +89,10 @@ class HttpMethod(str, Enum): POST = "POST" DELETE = "DELETE" PUT = "PUT" + CONNECT = "CONNECT" + OPTIONS = "OPTIONS" + TRACE = "TRACE" + PATCH = "PATCH" class Endpoint(IcebergBaseModel): diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py index 9fb1fa9af5..fe69f46a48 100644 --- a/tests/catalog/test_rest.py +++ b/tests/catalog/test_rest.py @@ -35,6 +35,8 @@ OAUTH2_SERVER_URI, SNAPSHOT_LOADING_MODE, Capability, + Endpoint, + HttpMethod, RestCatalog, ) from pyiceberg.exceptions import ( @@ -2351,3 +2353,28 @@ def test_table_uuid_check_on_refresh(rest_mock: Mocker, example_table_metadata_v assert "Table UUID does not match" in str(exc_info.value) assert f"current={original_uuid}" in str(exc_info.value) assert f"refreshed={different_uuid}" in str(exc_info.value) + + +@pytest.mark.parametrize( + "raw_string, http_method, path", + [ + ("GET /v1/resource", HttpMethod.GET, "/v1/resource"), + ("HEAD /v1/resource", HttpMethod.HEAD, "/v1/resource"), + ("POST /v1/resource", HttpMethod.POST, "/v1/resource"), + ("DELETE /v1/resource", HttpMethod.DELETE, "/v1/resource"), + ("PUT /v1/resource", HttpMethod.PUT, "/v1/resource"), + ("CONNECT /v1/resource", HttpMethod.CONNECT, "/v1/resource"), + ("OPTIONS /v1/resource", HttpMethod.OPTIONS, "/v1/resource"), + ("TRACE /v1/resource", HttpMethod.TRACE, "/v1/resource"), + ("PATCH /v1/resource", HttpMethod.PATCH, "/v1/resource"), + ], +) +def test_endpoint_parsing_from_string_with_valid_http_method(raw_string: str, http_method: str, path: str) -> None: + endpoint = Endpoint.from_string(raw_string) + assert endpoint.http_method == http_method + assert endpoint.path == path + + +def test_endpoint_parsing_from_string_with_invalid_http_method() -> None: + with pytest.raises(ValueError, match="not a valid HttpMethod"): + Endpoint.from_string("INVALID /v1/resource") From dbe6d01a3f171df5be73f0b331ff11896f7f0772 Mon Sep 17 00:00:00 2001 From: Sumanth <33193748+sumanth-manchala@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:44:40 +0530 Subject: [PATCH 3/4] Fix types Co-authored-by: geruh --- tests/catalog/test_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py index fe69f46a48..12baca8090 100644 --- a/tests/catalog/test_rest.py +++ b/tests/catalog/test_rest.py @@ -2369,7 +2369,7 @@ def test_table_uuid_check_on_refresh(rest_mock: Mocker, example_table_metadata_v ("PATCH /v1/resource", HttpMethod.PATCH, "/v1/resource"), ], ) -def test_endpoint_parsing_from_string_with_valid_http_method(raw_string: str, http_method: str, path: str) -> None: +def test_endpoint_parsing_from_string_with_valid_http_method(raw_string: str, http_method: HttpMethod, path: str) -> None: endpoint = Endpoint.from_string(raw_string) assert endpoint.http_method == http_method assert endpoint.path == path From 2a15bc5b088fb0f3e36481295c94d4da8ee1c6de Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Tue, 17 Feb 2026 12:59:55 -0800 Subject: [PATCH 4/4] Update tests/catalog/test_rest.py --- tests/catalog/test_rest.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py index 12baca8090..4225d30d93 100644 --- a/tests/catalog/test_rest.py +++ b/tests/catalog/test_rest.py @@ -2355,9 +2355,8 @@ def test_table_uuid_check_on_refresh(rest_mock: Mocker, example_table_metadata_v assert f"refreshed={different_uuid}" in str(exc_info.value) -@pytest.mark.parametrize( - "raw_string, http_method, path", - [ +def test_endpoint_parsing_from_string_with_valid_http_method() -> None: + test_cases = [ ("GET /v1/resource", HttpMethod.GET, "/v1/resource"), ("HEAD /v1/resource", HttpMethod.HEAD, "/v1/resource"), ("POST /v1/resource", HttpMethod.POST, "/v1/resource"), @@ -2367,12 +2366,12 @@ def test_table_uuid_check_on_refresh(rest_mock: Mocker, example_table_metadata_v ("OPTIONS /v1/resource", HttpMethod.OPTIONS, "/v1/resource"), ("TRACE /v1/resource", HttpMethod.TRACE, "/v1/resource"), ("PATCH /v1/resource", HttpMethod.PATCH, "/v1/resource"), - ], -) -def test_endpoint_parsing_from_string_with_valid_http_method(raw_string: str, http_method: HttpMethod, path: str) -> None: - endpoint = Endpoint.from_string(raw_string) - assert endpoint.http_method == http_method - assert endpoint.path == path + ] + + for raw_string, http_method, path in test_cases: + endpoint = Endpoint.from_string(raw_string) + assert endpoint.http_method == http_method + assert endpoint.path == path def test_endpoint_parsing_from_string_with_invalid_http_method() -> None: