Source code for gigl.common.types.uri.uri
from __future__ import annotations
import os
from pathlib import Path
from typing import Any, Union
from typing_extensions import Self
[docs]
class Uri(object):
    """
    A URI; currently supports GCS ('gs://foo/bar'), HTTP ('http://abc.com/xyz') or local ('/foo/bar').
    """
    @property
[docs]
    def uri(self):
        return self.__uri 
    def __init__(self, uri: _URI_LIKE):
        self.__uri = self._token_to_string(uri)
    @staticmethod
    def _token_to_string(token: _URI_LIKE) -> str:
        if isinstance(token, str):
            return token
        elif isinstance(token, Uri):
            return token.uri
        elif isinstance(token, Path):
            return str(token)
        return ""
    # TODO(kmonte): You should not be able to join a Uri with a Uri of a different type.
    # *or* join HTTP on HTTP or GCS on GCS.
    # This is not backwards compatible, so come around to this later.
    @classmethod
[docs]
    def join(cls, token: _URI_LIKE, *tokens: _URI_LIKE) -> Self:
        """
        Join multiple tokens to create a new Uri instance.
        Args:
            token: The first token to join.
            tokens: Additional tokens to join.
        Returns:
            A new Uri instance representing the joined URI.
        """
        token = cls._token_to_string(token)
        token_strs: list[str] = [cls._token_to_string(token) for token in tokens]
        joined_tmp_path = os.path.join(token, *token_strs)
        joined_path = cls(joined_tmp_path)
        return joined_path 
    @classmethod
[docs]
    def is_valid(cls, uri: _URI_LIKE, raise_exception: bool = False) -> bool:
        """
        Check if the given URI is valid.
        Args:
            uri: The URI to check.
            raise_exception: Whether to raise an exception if the URI is invalid.
        Returns:
            bool: True if the URI is valid, False otherwise.
        """
        raise NotImplementedError(
            f"Subclasses of {cls.__name__} are responsible"
            f" for implementing custom is_valid logic."
        ) 
[docs]
    def get_basename(self) -> str:
        """
        The base name is the final component of the path, effectively extracting the file or directory name from a full path string.
        i.e. get_basename("/foo/bar.txt") -> bar.txt
        get_basename("gs://bucket/foo") -> foo
        """
        return self.uri.split("/")[-1] 
    def __repr__(self) -> str:
        return self.uri
    def __hash__(self) -> int:
        return hash(self.uri)
    def __eq__(self, other: Any) -> bool:
        if isinstance(other, Uri):
            return self.uri == other.uri
        return False
    def __truediv__(self, other: _URI_LIKE) -> Self:
        if isinstance(other, Uri) and not isinstance(other, type(self)):
            raise TypeError(
                f"Cannot use '/' operator to join {type(self).__name__} with {type(other).__name__}"
            )
        return self.join(self, other) 
_URI_LIKE = Union[str, Path, Uri]