Skip to content
This repository has been archived by the owner on Oct 3, 2020. It is now read-only.

Commit

Permalink
Join URL path components without os.path/posixpath (#59)
Browse files Browse the repository at this point in the history
* use posixpath for url

* remove unused import

* join URL path without os.path/posixpath

Co-authored-by: jbw <[email protected]>
  • Loading branch information
hjacobs and jbw authored Mar 31, 2020
1 parent 2ad94b3 commit efad2a8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
11 changes: 5 additions & 6 deletions pykube/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import datetime
import json
import os
import posixpath
import shlex
import subprocess
from typing import Optional
Expand All @@ -23,7 +22,7 @@
from urllib.parse import urlparse

from .exceptions import HTTPError
from .utils import jsonpath_installed, jsonpath_parse
from .utils import jsonpath_installed, jsonpath_parse, join_url_path
from .config import KubeConfig

from . import __version__
Expand Down Expand Up @@ -139,7 +138,9 @@ def _setup_request_auth(self, config, request, kwargs):
parsed_out = json.loads(output)
token = parsed_out["status"]["token"]
else:
raise NotImplementedError(f'auth exec api version {api_version} not implemented')
raise NotImplementedError(
f"auth exec api version {api_version} not implemented"
)

request.headers["Authorization"] = "Bearer {}".format(token)
return None
Expand Down Expand Up @@ -286,10 +287,8 @@ def get_kwargs(self, **kwargs) -> dict:
if namespace:
bits.extend(["namespaces", namespace])
url = kwargs.get("url", "")
if url.startswith("/"):
url = url[1:]
bits.append(url)
kwargs["url"] = self.url + posixpath.join(*bits)
kwargs["url"] = self.url + join_url_path(*bits, join_empty=True)
if "timeout" not in kwargs:
# apply default HTTP timeout
kwargs["timeout"] = self.timeout
Expand Down
7 changes: 3 additions & 4 deletions pykube/objects.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import copy
import json
import os.path as op
from inspect import getmro
from typing import Optional
from typing import Type
Expand All @@ -11,6 +10,7 @@
from .mixins import ReplicatedMixin
from .mixins import ScalableMixin
from .query import Query
from .utils import join_url_path
from .utils import obj_merge


Expand Down Expand Up @@ -96,9 +96,8 @@ def api_kwargs(self, **kwargs):
else:
subresource = kwargs.pop("subresource", None) or ""
operation = kwargs.pop("operation", "")
kw["url"] = op.normpath(
op.join(self.endpoint, self.name, subresource, operation)
)
kw["url"] = join_url_path(self.endpoint, self.name, subresource, operation)

params = kwargs.pop("params", None)
if params is not None:
query_string = urlencode(params)
Expand Down
25 changes: 25 additions & 0 deletions pykube/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
from typing import List

try:
from jsonpath_ng import parse as jsonpath
Expand Down Expand Up @@ -62,3 +63,27 @@ def repl(m):
return jsonpath(path).find(obj)[0].value

return re.sub(r"(\{([^\}]*)\})", repl, template)


def join_url_path(*components, join_empty: bool = False) -> str:
"""Join given URL path components and return absolute path starting with '/'."""
new_comps: List[str] = []
for comp in components:
comp = comp.strip("/")
if comp in ("", "."):
continue
else:
new_comps.append(comp)

if components and components[-1] == "" and join_empty:
trailing_slash = True
elif components and components[-1] == "/":
trailing_slash = True
else:
trailing_slash = False

if trailing_slash:
new_comps.append("")

path = "/".join(new_comps)
return "/" + path
14 changes: 14 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pykube.utils import join_url_path
from pykube.utils import obj_merge


Expand Down Expand Up @@ -28,3 +29,16 @@ def test_obj_merge():
assert obj_merge(
{"a": {"b": [1, 2]}}, {"a": {"b": [3, 4, 5], "c": [1, 2]}}, is_strategic=False
) == {"a": {"b": [1, 2]}}


def test_join_url_path():
assert join_url_path() == "/"
assert join_url_path("") == "/"
assert join_url_path("", "/") == "/"
assert join_url_path("first", "") == "/first"
assert join_url_path("first", "/") == "/first/"
assert join_url_path("first", "second") == "/first/second"
assert join_url_path("/first", "second/") == "/first/second"
assert join_url_path("first", "second", "") == "/first/second"
assert join_url_path("first", "/", "second", "", "") == "/first/second"
assert join_url_path("/first", "second", "", join_empty=True) == "/first/second/"

0 comments on commit efad2a8

Please sign in to comment.