Skip to content

gportal.sftp

download(target, local_dir='.', username=None, password=None)

Downloads files to a local directory via SFTP.

Parameters:

Name Type Description Default
target Union[str, Product, Iterable[Union[str, Product]]]

Remote path, Product object, or a list of them.

required
local_dir str

Local directory to download to.

'.'
username Optional[str]

G-Portal username. If not provided, the value of gportal.username is used.

None
password Optional[str]

G-Portal password. If not provided, the value of gportal.password is used.

None

Returns:

Type Description
Union[str, list[str]]

A local path of the downloaded file when target is a single path or Product object.

Union[str, list[str]]

A list of local paths of the downloaded files when target is a list of paths or Product objects.

Source code in gportal/sftp.py
def download(
    target: Union[str, Product, Iterable[Union[str, Product]]],
    local_dir: str = ".",
    username: Optional[str] = None,
    password: Optional[str] = None,
) -> Union[str, list[str]]:
    """Downloads files to a local directory via SFTP.

    Args:
        target: Remote path, Product object, or a list of them.
        local_dir: Local directory to download to.
        username: G-Portal username. If not provided, the value of `gportal.username` is used.
        password: G-Portal password. If not provided, the value of `gportal.password` is used.

    Returns:
        A local path of the downloaded file when `target` is a single path or Product object.
        A list of local paths of the downloaded files when `target` is a list of paths or Product objects.
    """
    with SFTP.connect(username, password) as sftp:
        return sftp.download(target, local_dir)

SFTP

Wrapper of the G-Portal SFTP interface.

Attributes:

Name Type Description
client SFTPClient

An instance of paramiko.SFTPClient.

Source code in gportal/sftp.py
class SFTP:
    """Wrapper of the G-Portal SFTP interface.

    Attributes:
        client: An instance of [`paramiko.SFTPClient`][paramiko.sftp_client.SFTPClient].
    """

    HOST = "ftp.gportal.jaxa.jp"
    PORT = 2051

    def __init__(self, sftp_client: SFTPClient):
        self.client: SFTPClient = sftp_client

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.close()

    @classmethod
    def connect(cls, username: Optional[str] = None, password: Optional[str] = None) -> "SFTP":
        """Opens an SFTP session with G-Portal.

        Args:
            username: G-Portal username. If not provided, the value of `gportal.username` is used.
            password: G-Portal password. If not provided, the value of `gportal.password` is used.

        Returns:
            An instance of [`SFTP`][gportal.sftp.SFTP].
        """
        username = username or gportal.username
        password = password or gportal.password

        if username is None or password is None:
            raise ValueError("username and password are required")

        transport = Transport((cls.HOST, cls.PORT))
        transport.connect(username=username, password=password)

        sftp_client = transport.open_sftp_client()
        if sftp_client is None:  # will never happen
            raise RuntimeError("Failed to open SFTP session")

        return cls(sftp_client)

    def close(self) -> None:
        """Closes the SFTP session."""
        self.client.close()

    def listdir(self, path: str = "/", /, filter_pattern: Optional[str] = None, fullpath: bool = False) -> list[str]:
        """Returns a list containing the names of the entries in the given path.

        Wraps [`paramiko.SFTPClient.listdir`][paramiko.sftp_client.SFTPClient.listdir].

        Args:
            path: Remote path to list. It must be absolute.
            filter_pattern: Regular expression to filter the entries.
            fullpath: If `True`, the returned list contains full paths of the entries.

        Returns:
            A list containing the names of the entries.
        """
        self._reset_cwd()
        entries = self.client.listdir(path)

        if filter_pattern:
            entries = [entry for entry in entries if re.search(filter_pattern, entry)]

        if fullpath:
            return [os.path.join(path, entry) for entry in entries]
        else:
            return entries

    @overload
    def download(self, target: Union[str, Product], local_dir: str) -> str:
        ...

    @overload
    def download(self, target: Iterable[Union[str, Product]], local_dir: str) -> list[str]:
        ...

    def download(
        self, target: Union[str, Product, Iterable[Union[str, Product]]], local_dir: str
    ) -> Union[str, list[str]]:
        """Downloads files to a local directory.

        Args:
            target: Remote path, Product object, or a list of them.
            local_dir: Local directory to download to.

        Returns:
            A local path of the downloaded file when `target` is a single path or Product object.
            A list of local paths of the downloaded files when `target` is a list of paths or Product objects.
        """
        self._reset_cwd()

        if isinstance(target, Iterable) and not isinstance(target, str):
            return [self._download_single(t, local_dir) for t in target]
        else:
            return self._download_single(target, local_dir)

    def _download_single(self, target: Union[str, Product], local_dir: str) -> str:
        if isinstance(target, Product):
            if target.data_path is None:
                raise ValueError(f"Product {target.id} has no URL to download")

            target = target.data_path

        elif target.startswith("https://gportal.jaxa.jp/download/"):
            target = target.replace("https://gportal.jaxa.jp/download/", "", 1)

        local_path = os.path.join(local_dir, os.path.basename(target))
        self.client.get(target, local_path)
        return local_path

    def _reset_cwd(self) -> None:
        self.client.chdir()

connect(username=None, password=None) classmethod

Opens an SFTP session with G-Portal.

Parameters:

Name Type Description Default
username Optional[str]

G-Portal username. If not provided, the value of gportal.username is used.

None
password Optional[str]

G-Portal password. If not provided, the value of gportal.password is used.

None

Returns:

Type Description
SFTP

An instance of SFTP.

Source code in gportal/sftp.py
@classmethod
def connect(cls, username: Optional[str] = None, password: Optional[str] = None) -> "SFTP":
    """Opens an SFTP session with G-Portal.

    Args:
        username: G-Portal username. If not provided, the value of `gportal.username` is used.
        password: G-Portal password. If not provided, the value of `gportal.password` is used.

    Returns:
        An instance of [`SFTP`][gportal.sftp.SFTP].
    """
    username = username or gportal.username
    password = password or gportal.password

    if username is None or password is None:
        raise ValueError("username and password are required")

    transport = Transport((cls.HOST, cls.PORT))
    transport.connect(username=username, password=password)

    sftp_client = transport.open_sftp_client()
    if sftp_client is None:  # will never happen
        raise RuntimeError("Failed to open SFTP session")

    return cls(sftp_client)

close()

Closes the SFTP session.

Source code in gportal/sftp.py
def close(self) -> None:
    """Closes the SFTP session."""
    self.client.close()

listdir(path='/', /, filter_pattern=None, fullpath=False)

Returns a list containing the names of the entries in the given path.

Wraps paramiko.SFTPClient.listdir.

Parameters:

Name Type Description Default
path str

Remote path to list. It must be absolute.

'/'
filter_pattern Optional[str]

Regular expression to filter the entries.

None
fullpath bool

If True, the returned list contains full paths of the entries.

False

Returns:

Type Description
list[str]

A list containing the names of the entries.

Source code in gportal/sftp.py
def listdir(self, path: str = "/", /, filter_pattern: Optional[str] = None, fullpath: bool = False) -> list[str]:
    """Returns a list containing the names of the entries in the given path.

    Wraps [`paramiko.SFTPClient.listdir`][paramiko.sftp_client.SFTPClient.listdir].

    Args:
        path: Remote path to list. It must be absolute.
        filter_pattern: Regular expression to filter the entries.
        fullpath: If `True`, the returned list contains full paths of the entries.

    Returns:
        A list containing the names of the entries.
    """
    self._reset_cwd()
    entries = self.client.listdir(path)

    if filter_pattern:
        entries = [entry for entry in entries if re.search(filter_pattern, entry)]

    if fullpath:
        return [os.path.join(path, entry) for entry in entries]
    else:
        return entries

download(target, local_dir)

Downloads files to a local directory.

Parameters:

Name Type Description Default
target Union[str, Product, Iterable[Union[str, Product]]]

Remote path, Product object, or a list of them.

required
local_dir str

Local directory to download to.

required

Returns:

Type Description
Union[str, list[str]]

A local path of the downloaded file when target is a single path or Product object.

Union[str, list[str]]

A list of local paths of the downloaded files when target is a list of paths or Product objects.

Source code in gportal/sftp.py
def download(
    self, target: Union[str, Product, Iterable[Union[str, Product]]], local_dir: str
) -> Union[str, list[str]]:
    """Downloads files to a local directory.

    Args:
        target: Remote path, Product object, or a list of them.
        local_dir: Local directory to download to.

    Returns:
        A local path of the downloaded file when `target` is a single path or Product object.
        A list of local paths of the downloaded files when `target` is a list of paths or Product objects.
    """
    self._reset_cwd()

    if isinstance(target, Iterable) and not isinstance(target, str):
        return [self._download_single(t, local_dir) for t in target]
    else:
        return self._download_single(target, local_dir)