Skip to main content

Port70: Async Gopher Protocol Client Library

Port70 is an async-first, fully type-hinted Python client library for the Gopher protocol (RFC 1436 / RFC 4266).

Features

  • Async First: Built on top of Python's standard asyncio networking loop.
  • RFC 1436 & RFC 4266 Support: Full support for standard Gopher item types, selectors, search queries, and URIs.
  • Type Safe: Fully typed API passing strict static type checking (mypy --strict).
  • GopherURI Representation: Rich URI class to parse, inspect, validate, manipulate, and resolve Gopher URIs and query targets.
  • Zero Dependencies: Built entirely on Python's standard library.
  • CLI Utility: Includes a port70 command-line interface out of the box.

Installation

port70 requires Python 3.12 or later and can be installed with your package manager of choice.

With pip:

pip install port70

With uv:

uv add port70

Quick Start

1. Make a Simple Request

Use Client with standard async context managers to query a Gopher server:

import asyncio
from port70 import Client, Port70Error

async def main():
    async with Client() as client:
        try:
            # Query a Gopher menu or document
            response = await client.request("gopher://gopher.floodgap.com/")

            print(f"Target host: {response.uri.host}")
            print(f"Item type: {response.item_type}")
            print(f"Content length: {len(response.content)} bytes")
            print("--- Response Text ---")
            print(response.text)
        except Port70Error as error:
            print(f"Request failed: {error}")

if __name__ == "__main__":
    asyncio.run(main())

2. Working with GopherURI

The GopherURI class parses both full URI strings (gopher://host/1/selector) and target format strings:

from port70 import GopherURI

# Parse from Gopher URI string
uri = GopherURI.from_string("gopher://gopher.floodgap.com/7/v2/vs?python")

print(uri.host)        # 'gopher.floodgap.com'
print(uri.port)        # 70
print(uri.item_type)   # '7'
print(uri.selector)    # '/v2/vs'
print(uri.query)       # 'python'
print(uri.is_search)   # True

# Create modified copies
custom_port_uri = uri.with_port(7070)
parent_uri = uri.parent
root_uri = uri.root

3. Search Queries and Response Inspection

You can issue search queries for item type 7 search engines or inspect item types on responses:

async with Client() as client:
    # Send a search request with query terms
    response = await client.request(
        "gopher://gopher.floodgap.com/7/v2/vs",
        query_terms="python",
    )
    assert response.is_text

    # Access text response split into lines
    for line in response.lines[:5]:
        print(line)

Command Line Interface (CLI)

port70 includes a command-line client:

# Query a Gopher target (defaults to gopher://gopher.floodgap.com/)
uv run port70 gopher://gopher.floodgap.com/

# Perform a search request
uv run port70 -q python gopher://gopher.floodgap.com/7/v2/vs

# Query on a custom port
uv run port70 -p 7070 gopher://example.com/1/

# Output raw binary content to stdout
uv run port70 -r gopher://gopher.floodgap.com/0/gopher/readdata

# Display CLI help
uv run port70 --help

Licence

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

port70-0.1.2.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

port70-0.1.2-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file port70-0.1.2.tar.gz.

File metadata

  • Download URL: port70-0.1.2.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for port70-0.1.2.tar.gz
Algorithm Hash digest
SHA256 242fd5fdbb210fd76197d0a637aa7ddffa9a7271ddf5d007dfbc4547e8d28ecd
MD5 3797d5ccb7aa35a1cf8160ece54b67d3
BLAKE2b-256 41fbec745b7e9a422f6acb0cb0778f8706af8b4d6a6d03c477e716bda0da7f92

See more details on using hashes here.

File details

Details for the file port70-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: port70-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for port70-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7207f8b00a39ac22cb062474303161962dac5dcd98581d01964fbf2f543e14e5
MD5 5f9b8470ac38d01a723e52e0af3f860a
BLAKE2b-256 5712b63115abb8c38f351e3b88a4f3a32575a143eb01ed1cf28fc8cb4c969127

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page