From 511f9706d5133dbc660faa65184bb241f9989f18 Mon Sep 17 00:00:00 2001
From: Maxim Zhiltsov <zhiltsov.max35@gmail.com>
Date: Sun, 9 Oct 2022 10:01:46 +0300
Subject: [PATCH] Allow trailing slashes in SDK client url (#5057)

---
 CHANGELOG.md                     |  2 ++
 cvat-sdk/cvat_sdk/core/client.py |  6 ++++--
 tests/python/sdk/test_client.py  | 13 +++++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a5a93625512..94c100c31ee1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,8 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
 - Fixed cvat-core ESlint problems (<https://github.com/opencv/cvat/pull/5027>)
 - Fixed task creation with non-local files via the SDK/CLI
   (<https://github.com/opencv/cvat/issues/4962>)
+- A trailing slash in hostname does't allow SDK to send some requests
+  (<https://github.com/opencv/cvat/pull/5057>)
 
 ### Security
 - TDB
diff --git a/cvat-sdk/cvat_sdk/core/client.py b/cvat-sdk/cvat_sdk/core/client.py
index f4e5d84eca02..4f772d7b9b33 100644
--- a/cvat-sdk/cvat_sdk/core/client.py
+++ b/cvat-sdk/cvat_sdk/core/client.py
@@ -98,6 +98,8 @@ def _validate_and_prepare_url(cls, url: str) -> str:
             schema = ""
             base_url = url
 
+        base_url = base_url.rstrip("/")
+
         if schema and schema not in cls.ALLOWED_SCHEMAS:
             raise InvalidHostException(
                 f"Invalid url schema '{schema}', expected "
@@ -279,7 +281,7 @@ class CVAT_API_V2:
     """Build parameterized API URLs"""
 
     def __init__(self, host: str):
-        self.host = host
+        self.host = host.rstrip("/")
         self.base = self.host + "/api/"
         self.git = self.host + "/git/repository/"
 
@@ -308,7 +310,7 @@ def make_endpoint_url(
 def make_client(
     host: str, *, port: Optional[int] = None, credentials: Optional[Tuple[int, int]] = None
 ) -> Client:
-    url = host
+    url = host.rstrip("/")
     if port:
         url = f"{url}:{port}"
 
diff --git a/tests/python/sdk/test_client.py b/tests/python/sdk/test_client.py
index 7fdf70eee650..6c6af23a8630 100644
--- a/tests/python/sdk/test_client.py
+++ b/tests/python/sdk/test_client.py
@@ -58,6 +58,19 @@ def test_can_get_server_version(self):
         assert (version.major, version.minor) >= (2, 0)
 
 
+def test_can_strip_trailing_slash_in_hostname_in_make_client(admin_user: str):
+    host, port = BASE_URL.split("://", maxsplit=1)[1].rsplit(":", maxsplit=1)
+
+    with make_client(host=host + "/", port=port, credentials=(admin_user, USER_PASS)) as client:
+        assert client.api_map.host == BASE_URL
+
+
+def test_can_strip_trailing_slash_in_hostname_in_client_ctor(admin_user: str):
+    with Client(url=BASE_URL + "/") as client:
+        client.login((admin_user, USER_PASS))
+        assert client.api_map.host == BASE_URL
+
+
 def test_can_detect_server_schema_if_not_provided():
     host, port = BASE_URL.split("://", maxsplit=1)[1].rsplit(":", maxsplit=1)
     client = make_client(host=host, port=int(port))