This is an automated email from the ASF dual-hosted git repository.

yuzelin pushed a commit to branch release-1.4
in repository https://gitbox.apache.org/repos/asf/paimon.git

commit 861252a7028fce664dc9583beacc6bca6ee94731
Author: XiaoHongbo <[email protected]>
AuthorDate: Wed Apr 1 11:10:33 2026 +0800

    [python] Fix REST signature mismatch by encoding query param values (#7568)
    
    Requests with special characters in query parameters (e.g.
    functionNamePattern=func%) fail with `401 NotAuthorizedException:
    "accessKeyId validate failed with error message: current signature xxx
    not match"`. This PR fixes above issue by encoding query param values
---
 paimon-python/pypaimon/api/typedef.py                | 17 +++++++++++++++--
 paimon-python/pypaimon/tests/rest/dlf_signer_test.py |  7 +++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/paimon-python/pypaimon/api/typedef.py 
b/paimon-python/pypaimon/api/typedef.py
index 893b199b4b..3d05cb2fb6 100644
--- a/paimon-python/pypaimon/api/typedef.py
+++ b/paimon-python/pypaimon/api/typedef.py
@@ -15,15 +15,28 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-from dataclasses import dataclass
+from dataclasses import dataclass, field
 from typing import Dict, TypeVar
+from urllib.parse import quote
 
 T = TypeVar("T")
 
 
+def _encode_string(value: str) -> str:
+    if value is None:
+        return value
+    return quote(str(value), safe='')
+
+
 @dataclass
 class RESTAuthParameter:
     method: str
     path: str
     data: str
-    parameters: Dict[str, str]
+    parameters: Dict[str, str] = field(default_factory=dict)
+
+    def __post_init__(self):
+        if self.parameters:
+            self.parameters = {
+                k: _encode_string(v) for k, v in self.parameters.items()
+            }
diff --git a/paimon-python/pypaimon/tests/rest/dlf_signer_test.py 
b/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
index a2e72f599e..9109f5d619 100644
--- a/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
+++ b/paimon-python/pypaimon/tests/rest/dlf_signer_test.py
@@ -131,6 +131,13 @@ class DLFSignerTest(unittest.TestCase):
         self.assertIn("Content-MD5", header)
         self.assertEqual("UNSIGNED-PAYLOAD", 
header.get("x-dlf-content-sha256"))
 
+    def test_rest_auth_parameter_encodes_values(self):
+        param = RESTAuthParameter(
+            method="GET", path="/test",
+            data="", parameters={"functionNamePattern": "func%"})
+        self.assertEqual(
+            param.parameters["functionNamePattern"], "func%25")
+
     def test_parse_signing_algo_from_uri(self):
         parse = DLFAuthProviderFactory.parse_signing_algo_from_uri
 

Reply via email to