{"library":"portend","title":"Portend","description":"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.","language":"python","status":"active","last_verified":"Sat May 16","install":{"commands":["pip install portend"],"cli":null},"imports":["import portend"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import portend\nimport socket\nimport time\n\ndef demo_port_usage():\n    # Example: Wait for an occupied port (e.g., a simple server)\n    # Start a dummy server in a separate thread/process for this to work\n    # For demonstration, we'll simulate a server binding/unbinding\n\n    # Find a free port\n    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    s.bind(('localhost', 0))\n    port = s.getsockname()[1]\n    s.close()\n    print(f\"Found a free port: {port}\")\n\n    # Simulate a process binding to the port\n    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    server_socket.bind(('localhost', port))\n    server_socket.listen(1)\n    print(f\"Server bound to localhost:{port}\")\n\n    # Use portend to wait for the port to be occupied\n    print(f\"Waiting for localhost:{port} to be occupied (max 5s)...\")\n    try:\n        portend.occupied('localhost', port, timeout=5)\n        print(f\"Success: localhost:{port} is occupied.\")\n    except portend.Timeout: # Removed the direct import for Timeout as it's an attribute of portend module and was causing an error.\n        print(f\"Error: Timeout waiting for localhost:{port} to be occupied.\")\n    finally:\n        server_socket.close()\n        print(f\"Server unbound from localhost:{port}\")\n\n    # Use portend to wait for the port to be free\n    print(f\"Waiting for localhost:{port} to be free (max 5s)...\")\n    try:\n        portend.free('localhost', port, timeout=5)\n        print(f\"Success: localhost:{port} is free.\")\n    except portend.Timeout:\n        print(f\"Error: Timeout waiting for localhost:{port} to be free.\")\n\ndemo_port_usage()","lang":"python","description":"This quickstart demonstrates how to use `portend.occupied` to wait for a port to become active and `portend.free` to wait for a port to be released. It includes a simple simulation of a server binding and unbinding a port.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-16","installed_version":"3.2.1","pypi_latest":"3.2.1","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":3,"avg_import_s":0.15,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.11,"mem_mb":4.7,"disk_size":"33.7M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.3,"import_time_s":0.08,"mem_mb":4.7,"disk_size":"34M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.24,"mem_mb":5.4,"disk_size":"37.3M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.5,"import_time_s":0.18,"mem_mb":5.3,"disk_size":"38M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.16,"mem_mb":5,"disk_size":"28.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.1,"import_time_s":0.19,"mem_mb":5,"disk_size":"29M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.16,"mem_mb":5.5,"disk_size":"28.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":3.1,"import_time_s":0.16,"mem_mb":5.5,"disk_size":"29M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.11,"mem_mb":4.5,"disk_size":"18.9M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"portend","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.08,"mem_mb":4.5,"disk_size":"19M"}]}}