Skip to content

urls

normalize_url(url)

S3- aware URL normalization. For local paths, this is just os.path.normpath. For S3 URLs, this just strips trailing slashes. Notably, we do NOT want to collapse :// into :/.

Source code in fractal_server/urls.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def normalize_url(url: str) -> str:
    """S3- aware URL normalization.
    For local paths, this is just `os.path.normpath`.
    For S3 URLs, this just strips trailing slashes. Notably, we do NOT want to
    collapse `://` into `:/`."""
    url = url.strip()
    if url.startswith("/"):
        return normpath(url)
    elif url.startswith("s3://"):
        return url.rstrip("/")
    else:
        raise ValueError("URLs must begin with '/' or 's3://'.")

url_is_relative_to(*, url, base)

S3-aware replacement for Path(url).is_relative_to(base).

Source code in fractal_server/urls.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def url_is_relative_to(*, url: str, base: str) -> bool:
    """
    S3-aware replacement for `Path(url).is_relative_to(base)`.
    """
    url = normalize_url(url)
    base = normalize_url(base)

    url_is_s3 = url.startswith("s3://")
    base_is_s3 = base.startswith("s3://")

    if url_is_s3 != base_is_s3:
        return False  # mixed s3/local

    if url_is_s3:
        url = url[5:]
        base = base[5:]

    return PurePosixPath(url).is_relative_to(base)

url_join(base, *parts)

S3-aware replacement for os.path.join.

Source code in fractal_server/urls.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def url_join(base: str, *parts: str) -> str:
    """
    S3-aware replacement for `os.path.join`.
    """
    is_s3 = base.startswith("s3://")
    # Strip scheme before joining to protect "://" from normpath
    if is_s3:
        base = base[len("s3://") :]

    # common for both local and S3 URLs
    joined = os_path_join(base, *parts)

    if is_s3:
        # Re-add scheme
        return "s3://" + joined

    return normpath(joined)