Portend
Portend is a Python library for TCP port monitoring and discovery. It provides routines to wait for a port to become free or occupied, check the current state of a port, or identify a suitable port available for binding locally. The library is currently at version 3.2.1 and is actively maintained with a stable release cadence.
Warnings
- gotcha When running `portend` directly as a module (e.g., `python -m portend localhost:8080 occupied`), it exits with a status of 0 on success and 1 on failure. This is standard for command-line tools but important to note for scripting.
- gotcha The `portend.assert_free()` function will raise a `portend.PortNotFree` exception if the specified host/port combination is already occupied by a bound listener. Ensure proper exception handling if you intend to assert a port's availability.
- deprecated In older versions (specifically v1.2), there were 'original names' that were kept as aliases. While the current primary API (`portend.occupied`, `portend.free`, etc.) appears stable, relying on undocumented or historical aliases might lead to issues in future major versions.
- breaking No significant breaking changes for the core `portend` API (like `portend.occupied` or `portend.free`) between v2 and v3 are explicitly documented in the official GitHub repository or PyPI project description. Users migrating across these major versions are unlikely to encounter API breakage for core functionalities, but should review the release notes for any minor adjustments or behavioral changes.
Install
-
pip install portend
Imports
- portend
import portend
Quickstart
import portend
import socket
import time
def demo_port_usage():
# Example: Wait for an occupied port (e.g., a simple server)
# Start a dummy server in a separate thread/process for this to work
# For demonstration, we'll simulate a server binding/unbinding
# Find a free port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 0))
port = s.getsockname()[1]
s.close()
print(f"Found a free port: {port}")
# Simulate a process binding to the port
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', port))
server_socket.listen(1)
print(f"Server bound to localhost:{port}")
# Use portend to wait for the port to be occupied
print(f"Waiting for localhost:{port} to be occupied (max 5s)...")
try:
portend.occupied('localhost', port, timeout=5)
print(f"Success: localhost:{port} is occupied.")
except portend.Timeout: # Removed the direct import for Timeout as it's an attribute of portend module and was causing an error.
print(f"Error: Timeout waiting for localhost:{port} to be occupied.")
finally:
server_socket.close()
print(f"Server unbound from localhost:{port}")
# Use portend to wait for the port to be free
print(f"Waiting for localhost:{port} to be free (max 5s)...")
try:
portend.free('localhost', port, timeout=5)
print(f"Success: localhost:{port} is free.")
except portend.Timeout:
print(f"Error: Timeout waiting for localhost:{port} to be free.")
demo_port_usage()