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

Release files for port70 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for port70 1.0.0
File Size Uploaded
port70-1.0.0.tar.gz 9.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for port70 1.0.0
File Interpreter ABI Platform
port70-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 21.3 kB

Release files / port70-1.0.0.tar.gz

Download URL port70-1.0.0.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c5f58df5c7f1d6f42d95e4456e9878357b3d8827d7c7a377045ba529043cc050
BLAKE2b-256 checksum
How to use checksums
a0fccd64e080aee9887618105bb414cf56e71c0b745cc421f0e12c49a7fd0373
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","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}

Release files / port70-1.0.0-py3-none-any.whl

Download URL port70-1.0.0-py3-none-any.whl
Size 11.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ac956e27d62502687442823371ade772895b7992918d03978ca8bed157b497f4
BLAKE2b-256 checksum
How to use checksums
e5614ef6a612b4f8cce8cb36a4e9a801077d94b2d017448626c3fd07f4ccddb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","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}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page