Port79: Async Finger Protocol Client Library
Port79 is an async-first, fully type-hinted Python client library for the Finger User Information Protocol (RFC 1288).
Features
- Async First: Built on top of Python's standard
asyncionetworking loop. - RFC 1288 Support: Full support for standard system queries, user queries, verbose (
/W) requests, and remote host forwarding. - Type Safe: Fully typed API passing strict static type checking (
mypy --strict). - FingerURI Representation: Rich URI class to parse, inspect, validate, and manipulate Finger URIs and query targets.
- Zero Dependencies: Built entirely on Python's standard library.
- CLI Utility: Includes a
port79command-line interface out of the box.
Installation
port79 requires Python 3.12 or later and can be installed with your package manager of choice.
With pip:
pip install port79
With uv:
uv add port79
Quick Start
1. Make a Simple Request
Use Client with standard async context managers to query a Finger server:
import asyncio
from port79 import Client, Port79Error
async def main():
async with Client() as client:
try:
# Query a user at a target host
response = await client.request("davep@plan.cat")
print(f"Target host: {response.target_host}")
print(f"Query kind: {response.query_kind.name}")
print(f"Latency: {response.latency:.3f}s")
print("--- Response Text ---")
print(response.text)
except Port79Error as e:
print(f"Request failed: {e}")
if __name__ == "__main__":
asyncio.run(main())
2. Working with FingerURI
The FingerURI class parses both URI strings (finger://host/user) and target format strings (user@host, /W user@host, @host):
from port79 import FingerURI
# Parse from email-style target or full URI
uri = FingerURI.from_string("/W davep@plan.cat")
print(uri.host) # 'plan.cat'
print(uri.username) # 'davep'
print(uri.is_verbose) # True
print(uri.raw_query) # '/W davep\r\n'
# Create modified copies
custom_port_uri = uri.with_port(7979)
system_uri = uri.with_username(None)
resolved_uri = uri.resolve("alice")
3. Verbose and System Queries
You can issue verbose queries or system-wide logged-in user listings:
async with Client() as client:
# System query (requests logged-in user list)
system_response = await client.request("plan.cat")
assert system_response.is_system_query
# Verbose user query
verbose_response = await client.request("finger://plan.cat/davep?W")
assert verbose_response.is_verbose
Command Line Interface (CLI)
port79 includes a command-line client:
# Query a user
uv run port79 davep@plan.cat
# Request verbose output
uv run port79 -w davep@plan.cat
# Query system user list on a custom port
uv run port79 -p 7979 plan.cat
# Display CLI help
uv run port79 --help
Licence
MIT
Release files for port79 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| port79-1.1.0.tar.gz | 10.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| port79-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.1 kB
Release files / port79-1.1.0.tar.gz
| Download URL | port79-1.1.0.tar.gz |
|---|---|
| Size | 10.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
19580cec81dbbdae05668d6cd5f98b22ecc38f2cfa596e457b942ad5eee362cf
|
|
BLAKE2b-256 checksum How to use checksums |
710086159a02077c71a1cfb1a95ba88fbb83c51301bad003cfabdf4ec96dc45f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","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 / port79-1.1.0-py3-none-any.whl
| Download URL | port79-1.1.0-py3-none-any.whl |
|---|---|
| Size | 13.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c07fc61f3035c1ee1b0c35fd22696fcdfea412cd1ec468189b2a2fccbb02d901
|
|
BLAKE2b-256 checksum How to use checksums |
45672b60273f14dc6867e779b880a59520a451e9992fb4cf010c289ae2f64c8e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","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}
|