portinspector 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- portinspector-0.1.0/.github/workflows/ci.yml +77 -0
- portinspector-0.1.0/.github/workflows/release.yml +38 -0
- portinspector-0.1.0/.gitignore +54 -0
- portinspector-0.1.0/AGENTS.md +85 -0
- portinspector-0.1.0/CHANGELOG.md +26 -0
- portinspector-0.1.0/CONTRIBUTING.md +83 -0
- portinspector-0.1.0/LICENSE +21 -0
- portinspector-0.1.0/PKG-INFO +239 -0
- portinspector-0.1.0/README.md +207 -0
- portinspector-0.1.0/pyproject.toml +80 -0
- portinspector-0.1.0/src/portinspector/__init__.py +6 -0
- portinspector-0.1.0/src/portinspector/__main__.py +10 -0
- portinspector-0.1.0/src/portinspector/checker.py +215 -0
- portinspector-0.1.0/src/portinspector/cli.py +261 -0
- portinspector-0.1.0/src/portinspector/formatter.py +137 -0
- portinspector-0.1.0/src/portinspector/kill.py +147 -0
- portinspector-0.1.0/src/portinspector/models.py +67 -0
- portinspector-0.1.0/src/portinspector/platform/__init__.py +33 -0
- portinspector-0.1.0/src/portinspector/platform/base.py +31 -0
- portinspector-0.1.0/src/portinspector/platform/linux.py +352 -0
- portinspector-0.1.0/src/portinspector/platform/macos.py +265 -0
- portinspector-0.1.0/src/portinspector/platform/windows.py +513 -0
- portinspector-0.1.0/src/portinspector/watch.py +126 -0
- portinspector-0.1.0/tests/__init__.py +1 -0
- portinspector-0.1.0/tests/conftest.py +115 -0
- portinspector-0.1.0/tests/test_checker.py +77 -0
- portinspector-0.1.0/tests/test_cli.py +133 -0
- portinspector-0.1.0/tests/test_json.py +98 -0
- portinspector-0.1.0/tests/test_kill.py +76 -0
- portinspector-0.1.0/tests/test_parsing.py +100 -0
- portinspector-0.1.0/tests/test_platform.py +135 -0
- portinspector-0.1.0/tests/test_watch.py +141 -0
- portinspector-0.1.0/uv.lock +8 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Lint & Format Check
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout repository
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
version: "latest"
|
|
25
|
+
|
|
26
|
+
- name: Set up Python 3.12
|
|
27
|
+
run: uv python install 3.12
|
|
28
|
+
|
|
29
|
+
- name: Run Ruff Lint
|
|
30
|
+
run: uv run --with ruff ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Run Ruff Format Check
|
|
33
|
+
run: uv run --with ruff ruff format --check .
|
|
34
|
+
|
|
35
|
+
test:
|
|
36
|
+
name: Test (${{ matrix.os }} - Py ${{ matrix.python-version }})
|
|
37
|
+
runs-on: ${{ matrix.os }}
|
|
38
|
+
strategy:
|
|
39
|
+
fail-fast: false
|
|
40
|
+
matrix:
|
|
41
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
42
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
43
|
+
steps:
|
|
44
|
+
- name: Checkout repository
|
|
45
|
+
uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Install uv
|
|
48
|
+
uses: astral-sh/setup-uv@v5
|
|
49
|
+
with:
|
|
50
|
+
version: "latest"
|
|
51
|
+
|
|
52
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
53
|
+
run: uv python install ${{ matrix.python-version }}
|
|
54
|
+
|
|
55
|
+
- name: Run Pytest
|
|
56
|
+
run: uv run --python ${{ matrix.python-version }} --with pytest pytest -v
|
|
57
|
+
|
|
58
|
+
build-check:
|
|
59
|
+
name: Build & Package Validation
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- name: Checkout repository
|
|
63
|
+
uses: actions/checkout@v4
|
|
64
|
+
|
|
65
|
+
- name: Install uv
|
|
66
|
+
uses: astral-sh/setup-uv@v5
|
|
67
|
+
with:
|
|
68
|
+
version: "latest"
|
|
69
|
+
|
|
70
|
+
- name: Set up Python 3.12
|
|
71
|
+
run: uv python install 3.12
|
|
72
|
+
|
|
73
|
+
- name: Build distributions
|
|
74
|
+
run: uv build
|
|
75
|
+
|
|
76
|
+
- name: Validate distribution metadata
|
|
77
|
+
run: uv run --with twine twine check dist/*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
name: Build and Publish to PyPI
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment:
|
|
13
|
+
name: pypi
|
|
14
|
+
url: https://pypi.org/p/portinspector
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write # Mandatory for PyPI Trusted Publishing
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v5
|
|
25
|
+
with:
|
|
26
|
+
version: "latest"
|
|
27
|
+
|
|
28
|
+
- name: Set up Python 3.12
|
|
29
|
+
run: uv python install 3.12
|
|
30
|
+
|
|
31
|
+
- name: Build distributions
|
|
32
|
+
run: uv build
|
|
33
|
+
|
|
34
|
+
- name: Verify distribution archives
|
|
35
|
+
run: uv run --with twine twine check dist/*
|
|
36
|
+
|
|
37
|
+
- name: Publish package distributions to PyPI
|
|
38
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# Virtual environments
|
|
30
|
+
.env
|
|
31
|
+
.venv
|
|
32
|
+
env/
|
|
33
|
+
venv/
|
|
34
|
+
ENV/
|
|
35
|
+
env.bak/
|
|
36
|
+
venv.bak/
|
|
37
|
+
test_env/
|
|
38
|
+
|
|
39
|
+
# IDE files
|
|
40
|
+
.idea/
|
|
41
|
+
.vscode/
|
|
42
|
+
*.swp
|
|
43
|
+
*.swo
|
|
44
|
+
|
|
45
|
+
# Testing / coverage
|
|
46
|
+
.pytest_cache/
|
|
47
|
+
.coverage
|
|
48
|
+
.coverage.*
|
|
49
|
+
htmlcov/
|
|
50
|
+
.ruff_cache/
|
|
51
|
+
|
|
52
|
+
# Local OS files
|
|
53
|
+
.DS_Store
|
|
54
|
+
Thumbs.db
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# AGENTS.md - PortInspector Contributor Guide for AI Agents
|
|
2
|
+
|
|
3
|
+
This document provides architectural context, development constraints, and design principles for AI coding agents modifying or extending PortInspector.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Principles & Constraints
|
|
8
|
+
|
|
9
|
+
1. **Zero Runtime Dependencies**:
|
|
10
|
+
- The production package must remain dependency-free (`dependencies = []` in `pyproject.toml`).
|
|
11
|
+
- Use Python standard library modules (`ctypes`, `socket`, `subprocess`, `argparse`, `dataclasses`, `json`, etc.).
|
|
12
|
+
- Do not add packages like `click`, `typer`, `psutil`, or `rich` to core dependencies.
|
|
13
|
+
|
|
14
|
+
2. **Cross-Platform Architecture**:
|
|
15
|
+
- Platform implementations are strictly isolated inside `src/portinspector/platform/`:
|
|
16
|
+
- `windows.py`: IP Helper API (`iphlpapi.dll`) via `ctypes` + `netstat -ano` fallback.
|
|
17
|
+
- `linux.py`: `/proc/net/tcp`, `/proc/net/udp` + `/proc/<pid>/fd` procfs inspection + `ss` fallback.
|
|
18
|
+
- `macos.py`: `lsof -nP` + BSD `netstat -anv` fallback.
|
|
19
|
+
- `base.py`: Abstract `PlatformProvider` interface.
|
|
20
|
+
- `__init__.py`: Dynamic dispatcher returning provider instance based on `sys.platform`.
|
|
21
|
+
- Never assume Unix-only commands (`lsof`, `ss`) are available on all machines.
|
|
22
|
+
- Always handle `PermissionError`, missing files, and unreadable PIDs gracefully. Read-only commands must never crash when permissions are restricted.
|
|
23
|
+
|
|
24
|
+
3. **Safety First**:
|
|
25
|
+
- `--kill PORT` must never terminate a process automatically unless `--yes` / `-y` is provided.
|
|
26
|
+
- Always display process details and a prominent warning banner prior to the confirmation prompt.
|
|
27
|
+
|
|
28
|
+
4. **Testing Constraints**:
|
|
29
|
+
- **Never hardcode static ports** (e.g. 8000, 3000, 5000) as assumed free or occupied in tests.
|
|
30
|
+
- **Use ephemeral sockets** (`sock.bind(("127.0.0.1", 0))`) in pytest fixtures to test active and available detection deterministically.
|
|
31
|
+
- **No external network calls**: Tests must pass completely offline.
|
|
32
|
+
- When testing platform-specific modules on other host operating systems, mock file access or OS calls.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Repository Layout
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
src/portinspector/
|
|
40
|
+
├── __init__.py # __version__ export
|
|
41
|
+
├── __main__.py # Entrypoint for python -m portinspector
|
|
42
|
+
├── cli.py # Argument parser and command routing
|
|
43
|
+
├── models.py # PortInfo, ProcessInfo, ScanSummary
|
|
44
|
+
├── checker.py # Single-port inspection, range scanning, port availability
|
|
45
|
+
├── kill.py # Process termination with safety confirmation
|
|
46
|
+
├── watch.py # Periodic port monitoring
|
|
47
|
+
├── formatter.py # Table, detail, summary, and JSON formatters
|
|
48
|
+
└── platform/
|
|
49
|
+
├── __init__.py # Platform detector and provider factory
|
|
50
|
+
├── base.py # PlatformProvider interface
|
|
51
|
+
├── windows.py # Windows ctypes IP Helper + netstat
|
|
52
|
+
├── linux.py # Linux procfs + ss
|
|
53
|
+
└── macos.py # macOS lsof + netstat
|
|
54
|
+
tests/
|
|
55
|
+
├── conftest.py # Shared fixtures (ephemeral test sockets, mock providers)
|
|
56
|
+
├── test_cli.py # CLI integration tests
|
|
57
|
+
├── test_parsing.py # Port and port range input parsing tests
|
|
58
|
+
├── test_checker.py # Port availability, range scanning, and inspection tests
|
|
59
|
+
├── test_platform.py # Windows, Linux, and macOS provider tests
|
|
60
|
+
├── test_json.py # JSON schema tests across all commands
|
|
61
|
+
├── test_kill.py # Termination confirmation and safety tests
|
|
62
|
+
└── test_watch.py # Event monitoring and diff detection tests
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Verification Commands
|
|
68
|
+
|
|
69
|
+
Before concluding any work, always execute:
|
|
70
|
+
```bash
|
|
71
|
+
# Run test suite
|
|
72
|
+
uv run --with pytest pytest -v
|
|
73
|
+
|
|
74
|
+
# Run linting
|
|
75
|
+
uv run --with ruff ruff check .
|
|
76
|
+
|
|
77
|
+
# Run formatting checks
|
|
78
|
+
uv run --with ruff ruff format --check .
|
|
79
|
+
|
|
80
|
+
# Build package
|
|
81
|
+
uv build
|
|
82
|
+
|
|
83
|
+
# Validate package distribution
|
|
84
|
+
uv run --with twine twine check dist/*
|
|
85
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-09-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of `portinspector`, a lightweight cross-platform CLI developer utility for inspecting local ports and processes.
|
|
12
|
+
- Default command `portinspector` to list all currently active and listening local ports with protocol, address, status, PID, and process name.
|
|
13
|
+
- Single port inspection `portinspector PORT` clearly reporting `ACTIVE/LISTENING` or `AVAILABLE` status.
|
|
14
|
+
- Filter flag `portinspector --active` to display active/listening ports.
|
|
15
|
+
- Range scanner `portinspector --scan START-END` to quickly scan and summarize active vs available ports.
|
|
16
|
+
- Port finder `portinspector --find` and `portinspector --find PORT` to find next available local ports.
|
|
17
|
+
- Process inspector `portinspector --process PORT` to display executable path, command line, status, and parent PID.
|
|
18
|
+
- Process termination `portinspector --kill PORT` with mandatory interactive confirmation and `--yes` automation flag.
|
|
19
|
+
- Real-time watch mode `portinspector --watch` with configurable polling interval `--interval SECONDS`.
|
|
20
|
+
- Structured JSON output `portinspector --json` across all query and inspection commands.
|
|
21
|
+
- Isolated platform implementations:
|
|
22
|
+
- Windows: IP Helper API (`iphlpapi.dll`) via `ctypes` and `netstat -ano` fallback.
|
|
23
|
+
- Linux: procfs `/proc/net/{tcp,tcp6,udp,udp6}` and `/proc/<pid>/fd` with `ss` fallback.
|
|
24
|
+
- macOS: `lsof` and BSD `netstat -anv` with `ps` fallback.
|
|
25
|
+
- Comprehensive test suite with ephemeral test socket fixtures.
|
|
26
|
+
- GitHub Actions multi-OS CI and PyPI release workflows.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Contributing to PortInspector
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to PortInspector! We welcome bug fixes, documentation improvements, and platform enhancements.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Development Setup
|
|
8
|
+
|
|
9
|
+
PortInspector requires **Python 3.10+** and has zero runtime dependencies. We recommend using [uv](https://github.com/astral-sh/uv) for development.
|
|
10
|
+
|
|
11
|
+
### 1. Clone the Repository
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/ramalingamthangamani/PortCheck.git
|
|
14
|
+
cd PortCheck
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 2. Set Up Virtual Environment & Dependencies
|
|
18
|
+
Using `uv`:
|
|
19
|
+
```bash
|
|
20
|
+
uv venv
|
|
21
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
22
|
+
uv pip install -e ".[dev]" pytest ruff build twine
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or using standard `venv` and `pip`:
|
|
26
|
+
```bash
|
|
27
|
+
python -m venv .venv
|
|
28
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
29
|
+
pip install -e .
|
|
30
|
+
pip install pytest ruff build twine
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Running the Test Suite
|
|
36
|
+
|
|
37
|
+
Run all unit and integration tests:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
uv run --with pytest pytest -v
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Test Design Guidelines
|
|
44
|
+
- **No hardcoded machine ports**: Never assume ports like 8000 or 3000 are free or busy. Use the shared test socket fixtures (`ephemeral_port`, `bound_socket`) which bind to port `0` or loopback addresses.
|
|
45
|
+
- **No external network calls**: Tests must not make network requests to external hosts or APIs. All tests must be self-contained and run completely offline.
|
|
46
|
+
- **Platform isolation**: When writing platform-specific tests (e.g. for Windows ctypes, Linux procfs, or macOS lsof), mock or isolate the operating system calls so test suites pass consistently across any host OS.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Code Quality & Linting
|
|
51
|
+
|
|
52
|
+
We use [Ruff](https://github.com/astral-sh/ruff) for linting and code formatting:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Check code style and rules
|
|
56
|
+
uv run --with ruff ruff check .
|
|
57
|
+
|
|
58
|
+
# Check formatting
|
|
59
|
+
uv run --with ruff ruff format --check .
|
|
60
|
+
|
|
61
|
+
# Automatically apply formatting
|
|
62
|
+
uv run --with ruff ruff format .
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Building and Checking the Distribution
|
|
68
|
+
|
|
69
|
+
Validate package packaging and PyPI metadata:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
uv build
|
|
73
|
+
uv run --with twine twine check dist/*
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Submitting Pull Requests
|
|
79
|
+
|
|
80
|
+
1. Create a feature branch: `git checkout -b feature/my-enhancement`.
|
|
81
|
+
2. Ensure all tests pass and Ruff checks succeed.
|
|
82
|
+
3. Keep commits focused, descriptive, and atomic.
|
|
83
|
+
4. Submit a Pull Request targeting the `main` branch.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PortInspector contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: portinspector
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Lightweight cross-platform CLI developer utility for inspecting network ports and processes
|
|
5
|
+
Project-URL: Homepage, https://github.com/ramalingamthangamani/PortCheck
|
|
6
|
+
Project-URL: Documentation, https://github.com/ramalingamthangamani/PortCheck#readme
|
|
7
|
+
Project-URL: Issues, https://github.com/ramalingamthangamani/PortCheck/issues
|
|
8
|
+
Project-URL: Repository, https://github.com/ramalingamthangamani/PortCheck.git
|
|
9
|
+
Author: PortInspector Contributors
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,developer-tools,lsof,netstat,network,port,portcheck,portinspector,process
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
+
Classifier: Topic :: System :: Networking :: Monitoring
|
|
29
|
+
Classifier: Topic :: Utilities
|
|
30
|
+
Requires-Python: >=3.10
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# PortInspector
|
|
34
|
+
|
|
35
|
+
[](https://github.com/ramalingamthangamani/PortCheck/actions/workflows/ci.yml)
|
|
36
|
+
[](https://pypi.org/project/portinspector/)
|
|
37
|
+
[](https://pypi.org/project/portinspector/)
|
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
|
39
|
+
|
|
40
|
+
**PortInspector** is a lightweight, cross-platform developer utility for inspecting local network ports and the processes using them.
|
|
41
|
+
|
|
42
|
+
Built with pure Python standard library primitives, PortInspector requires **zero runtime dependencies**, installs instantly, and works across **Windows**, **Linux**, and **macOS**.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Key Features
|
|
47
|
+
|
|
48
|
+
- **Instant Visibility**: See all active and listening ports, addresses, PIDs, and process names in milliseconds.
|
|
49
|
+
- **Port Inspection**: Quickly check if a specific port is `ACTIVE/LISTENING` or `AVAILABLE`.
|
|
50
|
+
- **Port Finder**: Find the next available local port for web servers and microservices.
|
|
51
|
+
- **Fast Range Scanning**: Scan thousands of ports in milliseconds using OS connection caching.
|
|
52
|
+
- **Process Inspection**: View detailed process metadata (PID, executable path, command line, parent PID).
|
|
53
|
+
- **Safe Process Termination**: Kill hung processes with mandatory interactive confirmation and `--yes` automation support.
|
|
54
|
+
- **Continuous Watch Mode**: Real-time port monitoring that alerts when ports open or close.
|
|
55
|
+
- **Structured JSON Output**: Full `--json` support across commands for CI/CD pipelines, dev tooling, and scripts.
|
|
56
|
+
- **Zero Dependencies**: Pure Python with native platform integrations. No heavy C extensions or compilation required.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install portinspector
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Or using [uv](https://github.com/astral-sh/uv):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
uv tool install portinspector
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Quick Reference
|
|
75
|
+
|
|
76
|
+
| Command | Description |
|
|
77
|
+
| :--- | :--- |
|
|
78
|
+
| `portinspector` | Show all active/listening local ports with process details |
|
|
79
|
+
| `portinspector 8000` | Inspect port 8000 (status, process, PID, protocol, address) |
|
|
80
|
+
| `portinspector --active` | Show only active/listening ports |
|
|
81
|
+
| `portinspector --scan 3000-9000` | Scan a port range and summarize active vs available ports |
|
|
82
|
+
| `portinspector --find` | Find an available local port (defaults to starting at 8000) |
|
|
83
|
+
| `portinspector --find 8000` | Start at port 8000 and find the next available port |
|
|
84
|
+
| `portinspector --process 8000` | Show detailed process information for the process on port 8000 |
|
|
85
|
+
| `portinspector --kill 8000` | Terminate the process using port 8000 (interactive confirmation) |
|
|
86
|
+
| `portinspector --kill 8000 --yes` | Terminate the process using port 8000 without prompting |
|
|
87
|
+
| `portinspector --watch` | Continuously monitor ports and report opened/closed events |
|
|
88
|
+
| `portinspector --watch --interval 2` | Monitor ports with a custom polling interval in seconds |
|
|
89
|
+
| `portinspector --json` | Output structured JSON suitable for scripts and automation |
|
|
90
|
+
| `portinspector --version` | Display version number |
|
|
91
|
+
| `portinspector --help` | Display help and usage manual |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Usage Examples
|
|
96
|
+
|
|
97
|
+
### 1. List Active & Listening Ports
|
|
98
|
+
```bash
|
|
99
|
+
$ portinspector
|
|
100
|
+
PORT PROTO ADDRESS STATUS PID PROCESS
|
|
101
|
+
----- ----- ------------------------- ------ ----- ---------------
|
|
102
|
+
22 TCP 0.0.0.0 LISTEN 7104 sshd.exe
|
|
103
|
+
80 TCP 0.0.0.0 LISTEN 1234 nginx
|
|
104
|
+
3000 TCP 127.0.0.1 LISTEN 9821 node.exe
|
|
105
|
+
8000 TCP 127.0.0.1 LISTEN 4218 python.exe
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 2. Inspect a Specific Port
|
|
109
|
+
```bash
|
|
110
|
+
$ portinspector 8000
|
|
111
|
+
Port 8000:
|
|
112
|
+
Status: ACTIVE/LISTENING
|
|
113
|
+
Protocol: TCP
|
|
114
|
+
Address: 127.0.0.1
|
|
115
|
+
Process: python.exe
|
|
116
|
+
PID: 4218
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If the port is free:
|
|
120
|
+
```bash
|
|
121
|
+
$ portinspector 8001
|
|
122
|
+
Port 8001:
|
|
123
|
+
Status: AVAILABLE
|
|
124
|
+
Message: Port 8001 is available for use.
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 3. Find Next Available Port
|
|
128
|
+
Useful for configuring dev servers or automated tests:
|
|
129
|
+
```bash
|
|
130
|
+
$ portinspector --find 8000
|
|
131
|
+
Port 8000 is ACTIVE/LISTENING. Next available port is 8001.
|
|
132
|
+
|
|
133
|
+
$ portinspector --find 8000 --json
|
|
134
|
+
{
|
|
135
|
+
"start_port": 8000,
|
|
136
|
+
"available_port": 8001,
|
|
137
|
+
"is_available": true
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### 4. Scan a Port Range
|
|
142
|
+
```bash
|
|
143
|
+
$ portinspector --scan 3000-3005
|
|
144
|
+
Port Scan Summary (3000-3005):
|
|
145
|
+
Total Scanned: 6
|
|
146
|
+
Active Ports: 2
|
|
147
|
+
Available Ports: 4
|
|
148
|
+
|
|
149
|
+
Active Ports:
|
|
150
|
+
PORT PROTO ADDRESS STATUS PID PROCESS
|
|
151
|
+
----- ----- --------- ------ ----- -------
|
|
152
|
+
3000 TCP 127.0.0.1 LISTEN 9821 node.exe
|
|
153
|
+
3001 TCP 127.0.0.1 LISTEN 9822 vite.exe
|
|
154
|
+
|
|
155
|
+
Available Ports:
|
|
156
|
+
3002, 3003, 3004, 3005
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 5. Detailed Process Information
|
|
160
|
+
```bash
|
|
161
|
+
$ portinspector --process 8000
|
|
162
|
+
Process Details (Port 8000):
|
|
163
|
+
PID: 4218
|
|
164
|
+
Name: python.exe
|
|
165
|
+
Status: running
|
|
166
|
+
Executable: C:\Users\developer\AppData\Local\Programs\Python\Python310\python.exe
|
|
167
|
+
Command: python -m http.server 8000
|
|
168
|
+
Parent PID: 1024
|
|
169
|
+
Ports Used: 8000
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 6. Terminate a Process Using a Port
|
|
173
|
+
PortInspector prioritizes safety. Process termination always prompts for explicit confirmation unless `--yes` is passed:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
$ portinspector --kill 8000
|
|
177
|
+
============================================================
|
|
178
|
+
WARNING: DANGEROUS OPERATION - PROCESS TERMINATION
|
|
179
|
+
============================================================
|
|
180
|
+
Terminating this process will immediately close its network sockets
|
|
181
|
+
and may cause unsaved data loss or crash dependent applications.
|
|
182
|
+
|
|
183
|
+
Port: 8000
|
|
184
|
+
PID: 4218
|
|
185
|
+
Process Name: python.exe
|
|
186
|
+
Path: C:\Users\developer\AppData\Local\Programs\Python\Python310\python.exe
|
|
187
|
+
Command: python -m http.server 8000
|
|
188
|
+
============================================================
|
|
189
|
+
Are you sure you want to terminate process 4218 (python.exe)? [y/N]: y
|
|
190
|
+
Successfully terminated process 4218 (python.exe) on port 8000.
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
For non-interactive scripts:
|
|
194
|
+
```bash
|
|
195
|
+
portinspector --kill 8000 --yes
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 7. Real-Time Watch Mode
|
|
199
|
+
Monitor ports dynamically as services spin up or shut down:
|
|
200
|
+
```bash
|
|
201
|
+
$ portinspector --watch --interval 1.5
|
|
202
|
+
[13:30:00] Monitoring listening ports every 1.5s (Press Ctrl+C to stop)...
|
|
203
|
+
[13:30:00] Initial state: 18 listening ports detected.
|
|
204
|
+
[13:30:04] [OPENED] Port 5173 (TCP) on 127.0.0.1 by vite (PID: 14205)
|
|
205
|
+
[13:30:22] [CLOSED] Port 5173 (TCP) (was vite (PID: 14205))
|
|
206
|
+
^C
|
|
207
|
+
[13:30:30] Monitoring stopped.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Platform Support & Architecture
|
|
213
|
+
|
|
214
|
+
PortInspector implements isolated, native OS providers:
|
|
215
|
+
|
|
216
|
+
- **Windows (`src/portinspector/platform/windows.py`)**:
|
|
217
|
+
- Leverages the Windows IP Helper API (`iphlpapi.dll`) via `ctypes` (`GetExtendedTcpTable`, `GetExtendedUdpTable`).
|
|
218
|
+
- Fetches complete TCP and UDP connection tables directly in-memory without spawning slow subprocesses.
|
|
219
|
+
- Fallback parser for `netstat -ano`.
|
|
220
|
+
- Process queries via `kernel32` (`QueryFullProcessImageNameW`) and WMI.
|
|
221
|
+
- **Linux (`src/portinspector/platform/linux.py`)**:
|
|
222
|
+
- Reads `/proc/net/tcp`, `/proc/net/tcp6`, `/proc/net/udp`, `/proc/net/udp6`.
|
|
223
|
+
- Resolves socket inodes to PIDs via `/proc/<pid>/fd/*`.
|
|
224
|
+
- Fallback parser for `ss` or `netstat`.
|
|
225
|
+
- Reads `/proc/<pid>/comm`, `cmdline`, `status`, and `exe`.
|
|
226
|
+
- **macOS (`src/portinspector/platform/macos.py`)**:
|
|
227
|
+
- Built-in `lsof` parser with fallback to BSD `netstat -anv`.
|
|
228
|
+
- Process metadata via `ps`.
|
|
229
|
+
|
|
230
|
+
### Permissions
|
|
231
|
+
- **Read-Only Inspection**: Administrator/root privileges are **never required** for normal scanning.
|
|
232
|
+
- **Permission Handling**: When a process is owned by another user or system account, PortInspector still reports the active port, protocol, and address gracefully while noting when PID details are restricted by OS security boundaries.
|
|
233
|
+
- **Process Termination**: Terminating processes owned by other users or system services requires elevated privileges.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## License
|
|
238
|
+
|
|
239
|
+
This project is licensed under the terms of the [MIT License](LICENSE).
|