Skip to content

API Reference

gophient - Python library to browse the Gopherspace.

Its code is separated into submodules
  • gophient.const - Constant values like SEPARATOR or TYPES.
  • gophient.exc - Exceptions that derive from GopherError.
  • gophient.types - This submodule contains everything you usually work with.

types

gophient.types - Types that implement the main logic.

RequestType module-attribute

RequestType = Union[bytes, bytearray, str]

ResponseType module-attribute

ResponseType = Union[bytes, bytearray]

Gopher

Gopher(timeout=10, encoding='utf-8')

Gopher client.

Initialize a client.

Parameters:

Name Type Description Default
timeout int

Socket timeout

10
encoding str

Packet encoding

'utf-8'
Source code in gophient/types.py
def __init__(self, timeout: int = 10, encoding: str = 'utf-8'):
    """Initialize a client.

    Args:
        timeout (int): Socket timeout
        encoding (str): Packet encoding
    """
    self.timeout = timeout
    """Socket timeout. Defaults to `10`."""
    self.encoding = encoding
    """Packet encoding. Defaults to `'utf-8'`."""

encoding instance-attribute

encoding = encoding

Packet encoding. Defaults to 'utf-8'.

timeout instance-attribute

timeout = timeout

Socket timeout. Defaults to 10.

parse_response

parse_response(resp)

Parse the server response.

Parameters:

Name Type Description Default
resp ResponseType

Server response

required

Returns:

Type Description
Union[List[Item], ResponseType]

A list of Item (can be empty) or resp

Source code in gophient/types.py
def parse_response(self, resp: 'ResponseType') -> Union[List[Item], 'ResponseType']:
    """Parse the server response.

    Args:
        resp (ResponseType): Server response

    Returns:
        A list of `Item` (can be empty) or `resp`
    """
    pretty_resp = []
    for item in resp.split(const.EOL):
        item = Item.parse(self, item)
        if not item:
            continue

        if item.raw_type == '':
            # Received raw data
            return resp

        if item.raw_type == 'i' and pretty_resp:
            if pretty_resp[-1].raw_type == 'i':
                pretty_resp[-1].merge_messages(item)
                continue

        pretty_resp.append(item)

    return pretty_resp

request

request(host, path='/', port=70, query='')

Request an address.

Parameters:

Name Type Description Default
host str

Server domain or IP address

required
path str

Request path

'/'
port int

Server port

70
query RequestType

Query

''

Returns:

Type Description
Union[list[Item], bytes]

A list of Item (can be empty) or a server response

Source code in gophient/types.py
def request(
    self, host: str, path: str = '/', port: int = 70, query: 'RequestType' = '',
) -> Union[list[Item], bytes]:
    """Request an address.

    Args:
        host (str): Server domain or IP address
        path (str): Request path
        port (int): Server port
        query (RequestType): Query

    Returns:
        A list of `Item` (can be empty) or a server response
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    with sock:
        socket.timeout(self.timeout)
        sock.connect((host, port))
        payload = self._prepare_payload(path, query)
        sock.sendall(payload)

        resp = bytes()
        packet = b'init'
        while packet:
            packet = sock.recv(1024)
            resp += packet

    return self.parse_response(resp)

Item dataclass

Item of a server response.

desc class-attribute instance-attribute

desc = ''

The item description.

host class-attribute instance-attribute

host = ''

The IP address or the domain name of a server that this item is pointing to.

path class-attribute instance-attribute

path = ''

The path on a server that this item is pointing to.

port class-attribute instance-attribute

port = 70

The port of a server that this item is pointing to.

pretty_type class-attribute instance-attribute

pretty_type = field(hash=False, compare=False)

The human-readable item type. Possible values are const.TYPES values.

raw_type class-attribute instance-attribute

raw_type = field(repr=False)

The item type. Possible values are const.TYPES keys.

__str__

__str__()

Return a string representation of Item.

Returns:

Type Description
str

str

Source code in gophient/types.py
def __str__(self) -> str:
    """Return a string representation of `Item`.

    Returns:
        str
    """
    if self.raw_type == 'i':
        return self.desc
    if self.raw_type == '':
        return f'File {self.path} on {self.host}:{self.port}'

    return f'{self.desc} ({self.pretty_type}) - {self.path} on {self.host}:{self.port}'

follow

follow()

Follow the link.

Returns:

Type Description
Union[List[Item], bytes]

A list of Item or a server response

Source code in gophient/types.py
def follow(self) -> Union[List['Item'], bytes]:
    """Follow the link.

    Returns:
        A list of `Item` or a server response
    """
    return self._client.request(self.host, self.path, self.port, self._client.encoding)

merge_messages

merge_messages(item)

Merge two informational messages.

Parameters:

Name Type Description Default
item Item

Item

required

Raises:

Type Description
TypeMismatchError

Can't merge items with wrong types

Source code in gophient/types.py
def merge_messages(self, item: 'Item') -> None:
    """Merge two informational messages.

    Args:
        item (Item): Item

    Raises:
        TypeMismatchError: Can't merge items with wrong types
    """
    if self.raw_type == 'i' and item.raw_type == 'i':
        self.desc += const.EOL.decode(self._client.encoding) + item.desc
    else:
        raise exc.TypeMismatchError(item.pretty_type, self.pretty_type)

parse classmethod

parse(client, raw)

Parse a raw ByteString.

Parameters:

Name Type Description Default
client Gopher

Related client

required
raw ByteString

Data to parse

required

Returns:

Type Description
Union[Item, None]

Union[Item, None]

Source code in gophient/types.py
@classmethod
def parse(cls, client: 'Gopher', raw: 'ResponseType') -> Union['Item', None]:
    """Parse a raw `ByteString`.

    Args:
        client (Gopher): Related client
        raw (ByteString): Data to parse

    Returns:
        Union[Item, None]
    """
    if raw == b'.' or raw == b'':
        return None  # Optional part of the specification

    try:
        encoded = raw.decode(client.encoding)
        parts = encoded[1:].split(const.SEPARATOR)
        if len(parts) < 4:
            # Received raw data
            raise ValueError
    except ValueError:  # UnicodeDecodeError is a subclass of ValueError
        return cls(client, '', const.TYPES.get('', 'Unknown'))

    return cls(
        _client=client,
        raw_type=encoded[0],
        pretty_type=const.TYPES.get(encoded[0], 'Unknown'),
        desc=parts[0],
        path=parts[1],
        host=parts[2],
        port=int(parts[3]),
    )

exc

gophient.exc - Client exceptions.

GopherError

Bases: Exception

Base exception for gophient.

TypeMismatchError

TypeMismatchError(got, expected)

Bases: GopherError

Items' types mismatch.

Initialize an exception.

Parameters:

Name Type Description Default
got str

Item type

required
expected str

Expected type

required
Source code in gophient/exc.py
def __init__(self, got: str, expected: str):
    """Initialize an exception.

    Args:
        got (str): Item type
        expected (str): Expected type
    """
    super().__init__()
    self.got = got
    self.expected = expected
    self.message = f'Expected {self.expected!r} (got {self.got!r}).'

expected instance-attribute

expected = expected

got instance-attribute

got = got

message instance-attribute

message = f'Expected {expected} (got {got}).'

__repr__

__repr__()

Return an object representation.

Returns:

Type Description
str

str

Source code in gophient/exc.py
def __repr__(self) -> str:
    """Return an object representation.

    Returns:
        str
    """
    return f'<TypeMismatchError message={self.message!r}>'

__str__

__str__()

Return a string representation of an exception.

Returns:

Type Description
str

str

Source code in gophient/exc.py
def __str__(self) -> str:
    """Return a string representation of an exception.

    Returns:
        str
    """
    return self.message