advanced-port-scanner 0.3.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.
Files changed (52) hide show
  1. advanced_port_scanner-0.3.0/LICENSE +21 -0
  2. advanced_port_scanner-0.3.0/PKG-INFO +503 -0
  3. advanced_port_scanner-0.3.0/README.md +488 -0
  4. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/PKG-INFO +503 -0
  5. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/SOURCES.txt +50 -0
  6. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/dependency_links.txt +1 -0
  7. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/entry_points.txt +2 -0
  8. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/requires.txt +7 -0
  9. advanced_port_scanner-0.3.0/advanced_port_scanner.egg-info/top_level.txt +2 -0
  10. advanced_port_scanner-0.3.0/pyproject.toml +28 -0
  11. advanced_port_scanner-0.3.0/scanner/__init__.py +23 -0
  12. advanced_port_scanner-0.3.0/scanner/analytics.py +46 -0
  13. advanced_port_scanner-0.3.0/scanner/auth.py +42 -0
  14. advanced_port_scanner-0.3.0/scanner/config.py +96 -0
  15. advanced_port_scanner-0.3.0/scanner/cve.py +143 -0
  16. advanced_port_scanner-0.3.0/scanner/history.py +82 -0
  17. advanced_port_scanner-0.3.0/scanner/html_report.py +74 -0
  18. advanced_port_scanner-0.3.0/scanner/jobs.py +187 -0
  19. advanced_port_scanner-0.3.0/scanner/metrics.py +27 -0
  20. advanced_port_scanner-0.3.0/scanner/profiles.py +39 -0
  21. advanced_port_scanner-0.3.0/scanner/reporting.py +19 -0
  22. advanced_port_scanner-0.3.0/scanner/retention.py +28 -0
  23. advanced_port_scanner-0.3.0/scanner/scanner.py +165 -0
  24. advanced_port_scanner-0.3.0/scanner/security.py +73 -0
  25. advanced_port_scanner-0.3.0/scanner/service_detection.py +71 -0
  26. advanced_port_scanner-0.3.0/scanner/utils.py +103 -0
  27. advanced_port_scanner-0.3.0/scanner/version.py +3 -0
  28. advanced_port_scanner-0.3.0/scanner/vuln_hints.py +64 -0
  29. advanced_port_scanner-0.3.0/setup.cfg +4 -0
  30. advanced_port_scanner-0.3.0/tests/test_analytics.py +48 -0
  31. advanced_port_scanner-0.3.0/tests/test_api_v1_contract.py +28 -0
  32. advanced_port_scanner-0.3.0/tests/test_auth.py +17 -0
  33. advanced_port_scanner-0.3.0/tests/test_cli.py +55 -0
  34. advanced_port_scanner-0.3.0/tests/test_cve.py +23 -0
  35. advanced_port_scanner-0.3.0/tests/test_cve_api.py +41 -0
  36. advanced_port_scanner-0.3.0/tests/test_docker_compose.py +13 -0
  37. advanced_port_scanner-0.3.0/tests/test_docker_runtime.py +21 -0
  38. advanced_port_scanner-0.3.0/tests/test_html_report.py +36 -0
  39. advanced_port_scanner-0.3.0/tests/test_jobs.py +62 -0
  40. advanced_port_scanner-0.3.0/tests/test_metrics.py +43 -0
  41. advanced_port_scanner-0.3.0/tests/test_metrics_api.py +15 -0
  42. advanced_port_scanner-0.3.0/tests/test_profiles.py +18 -0
  43. advanced_port_scanner-0.3.0/tests/test_profiles_web.py +17 -0
  44. advanced_port_scanner-0.3.0/tests/test_retention.py +45 -0
  45. advanced_port_scanner-0.3.0/tests/test_runtime_regressions.py +131 -0
  46. advanced_port_scanner-0.3.0/tests/test_scanner.py +61 -0
  47. advanced_port_scanner-0.3.0/tests/test_security.py +84 -0
  48. advanced_port_scanner-0.3.0/tests/test_service_detection.py +28 -0
  49. advanced_port_scanner-0.3.0/tests/test_utils.py +29 -0
  50. advanced_port_scanner-0.3.0/tests/test_web.py +14 -0
  51. advanced_port_scanner-0.3.0/web/api_v1.py +190 -0
  52. advanced_port_scanner-0.3.0/web/app.py +349 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 hack2ai
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,503 @@
1
+ Metadata-Version: 2.4
2
+ Name: advanced-port-scanner
3
+ Version: 0.3.0
4
+ Summary: Professional defensive network discovery scanner
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: flask<4,>=3.0
9
+ Requires-Dist: gunicorn<24,>=22
10
+ Requires-Dist: rich<15,>=13.7
11
+ Requires-Dist: tqdm<5,>=4.66
12
+ Provides-Extra: syn
13
+ Requires-Dist: scapy<3,>=2.5; extra == "syn"
14
+ Dynamic: license-file
15
+
16
+ # Advanced Port Scanner
17
+
18
+ <p align="center">
19
+ <strong>Professional defensive network discovery for authorized security testing.</strong><br>
20
+ Fast local CLI • Flask dashboard • Versioned API • Persistent history • Reports • Analytics • Operational metrics • Controlled CVE enrichment
21
+ </p>
22
+
23
+ <p align="center">
24
+ <a href="https://github.com/hack2ai/advanced-port-scanner/actions/workflows/ci.yml"><img src="https://github.com/hack2ai/advanced-port-scanner/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
25
+ <a href="https://github.com/hack2ai/advanced-port-scanner/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
26
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
27
+ <img src="https://img.shields.io/badge/release-0.3.0-informational.svg" alt="v0.3.0">
28
+ </p>
29
+
30
+ > **Authorized use only.** Scan systems you own or have explicit permission to assess.
31
+
32
+ ## Overview
33
+
34
+ Advanced Port Scanner is a Python-based network discovery platform designed for controlled, authorized security assessment. It combines a focused command-line interface with a Flask dashboard and versioned REST API.
35
+
36
+ The project is built around predictable resource controls, persistent scan history, cooperative job cancellation, structured reporting, operational metrics, controlled CVE enrichment, and security-conscious deployment defaults.
37
+
38
+ ## Why this project
39
+
40
+ - **One scanner, multiple interfaces** — use the CLI for focused work or the dashboard/API for repeatable operations.
41
+ - **Bounded by design** — target, port, concurrency, timeout, queue, and retention limits keep workloads predictable.
42
+ - **Operationally useful** — scans persist to SQLite, exports can be generated as JSON/CSV/TXT/HTML, analytics are derived from stored results, and operational metrics expose current workload and historical outcomes.
43
+ - **Security-aware** — authentication, RBAC, CSRF protection, rate limiting, security headers, non-root containers, and dropped Linux capabilities are included.
44
+ - **Transparent results** — service and risk metadata are presented as observations and guidance, not as proof of vulnerabilities.
45
+
46
+ ## Features
47
+
48
+ ### Scanning
49
+
50
+ - Concurrent TCP connect scanning with bounded worker usage
51
+ - Optional SYN mode for controlled lab environments
52
+ - IPv4/IPv6 connection handling
53
+ - Lightweight banner collection
54
+ - Service/product/version fingerprinting with confidence metadata
55
+ - Heuristic TTL/OS indication
56
+ - Configurable socket and banner timeouts
57
+ - Reusable scan profiles
58
+
59
+ ### Job management
60
+
61
+ - Bounded asynchronous scan queue
62
+ - Live progress reporting
63
+ - Cooperative cancellation
64
+ - Accurate terminal status and elapsed time
65
+ - Persistent history for completed, failed, and cancelled jobs
66
+ - Configurable history retention
67
+
68
+ ### Reporting, analytics & metrics
69
+
70
+ - Versioned JSON report model
71
+ - CSV and TXT exports
72
+ - HTML reports with scan metadata and findings
73
+ - Persistent scan history in SQLite
74
+ - Configurable report retention
75
+ - Analytics for scan volume, unique targets, open ports, high-risk findings, duration, risk distribution, and top services
76
+ - Operational metrics for active/queued/running jobs, retained history, completed/failed/cancelled scans, average duration, and total open ports
77
+
78
+ ### CVE enrichment
79
+
80
+ - Separate from heuristic port-risk hints
81
+ - Explicit modes: `off`, `offline`, and `online`
82
+ - Operator-supplied offline JSON feeds
83
+ - Optional NVD API lookup in online mode
84
+ - Source-aware CVE records with severity, score, summary, and URL metadata
85
+ - Enrichment failures are non-critical to scan execution
86
+
87
+ ### Web & API
88
+
89
+ - Responsive Flask dashboard
90
+ - Versioned `/api/v1` endpoints
91
+ - Request IDs for API responses
92
+ - Session authentication with `viewer`, `operator`, and `admin` roles
93
+ - Login and scan rate limiting
94
+ - CSRF protection for protected mutations
95
+ - Security response headers
96
+ - Trusted-proxy support only when explicitly enabled
97
+
98
+ ### Deployment & distribution
99
+
100
+ - Installable Python package with an `aps` console command
101
+ - Gunicorn-compatible web deployment
102
+ - Non-root Docker execution
103
+ - `no-new-privileges` and dropped capabilities in Compose
104
+ - Persistent Docker storage for SQLite data, reports, and logs
105
+ - CI across Python 3.11, 3.12, and 3.13
106
+ - Tag-driven PyPI publishing workflow using GitHub OIDC trusted publishing
107
+
108
+ ## Architecture
109
+
110
+ ```text
111
+ ┌─────────────────────┐
112
+ │ CLI / Web UI │
113
+ └──────────┬──────────┘
114
+ │
115
+ ▼
116
+ ┌─────────────────────┐
117
+ │ Input validation & │
118
+ │ target resolution │
119
+ └──────────┬──────────┘
120
+ │
121
+ ▼
122
+ ┌─────────────────────┐
123
+ │ Job Manager │
124
+ │ queue • progress • │
125
+ │ cancellation │
126
+ └──────────┬──────────┘
127
+ │
128
+ ▼
129
+ ┌─────────────────────┐
130
+ │ Scan Engine │
131
+ │ TCP • SYN • banner │
132
+ │ service detection │
133
+ └───────┬─────┬───────┘
134
+ │ │
135
+ ┌───────────┘ └────────────┐
136
+ ▼ ▼
137
+ ┌─────────────────┐ ┌─────────────────┐
138
+ │ SQLite history │ │ JSON/CSV/TXT/ │
139
+ │ + analytics │ │ HTML reports │
140
+ └────────┬────────┘ └─────────────────┘
141
+ │
142
+ ▼
143
+ ┌─────────────────┐
144
+ │ Operational │
145
+ │ metrics + CVE │
146
+ │ enrichment │
147
+ └─────────────────┘
148
+ ```
149
+
150
+ ## Project layout
151
+
152
+ ```text
153
+ advanced-port-scanner/
154
+ ├── scanner/
155
+ │ ├── analytics.py
156
+ │ ├── auth.py
157
+ │ ├── config.py
158
+ │ ├── cve.py
159
+ │ ├── history.py
160
+ │ ├── jobs.py
161
+ │ ├── metrics.py
162
+ │ ├── profiles.py
163
+ │ ├── reporting.py
164
+ │ ├── retention.py
165
+ │ ├── scanner.py
166
+ │ ├── security.py
167
+ │ ├── service_detection.py
168
+ │ ├── utils.py
169
+ │ ├── version.py
170
+ │ └── vuln_hints.py
171
+ ├── web/
172
+ │ ├── api_v1.py
173
+ │ ├── app.py
174
+ │ └── templates/
175
+ ├── tests/
176
+ ├── docs/
177
+ ├── data/
178
+ ├── reports/
179
+ ├── logs/
180
+ ├── .github/workflows/
181
+ │ ├── ci.yml
182
+ │ └── pypi.yml
183
+ ├── Dockerfile
184
+ ├── docker-compose.yml
185
+ ├── main.py
186
+ ├── pyproject.toml
187
+ ├── requirements.txt
188
+ ├── CHANGELOG.md
189
+ └── README.md
190
+ ```
191
+
192
+ ## Requirements
193
+
194
+ - Python 3.11 or newer
195
+ - For normal TCP scanning: standard Python runtime plus project dependencies
196
+ - Optional Scapy installation for SYN mode
197
+ - Docker and Docker Compose for container deployment
198
+
199
+ ## Installation
200
+
201
+ ### From source
202
+
203
+ ```bash
204
+ git clone https://github.com/hack2ai/advanced-port-scanner.git
205
+ cd advanced-port-scanner
206
+ python -m venv .venv
207
+ ```
208
+
209
+ Activate the environment and install the project:
210
+
211
+ ```bash
212
+ python -m pip install -e .
213
+ ```
214
+
215
+ Optional SYN support:
216
+
217
+ ```bash
218
+ python -m pip install -e '.[syn]'
219
+ ```
220
+
221
+ Verify the installation:
222
+
223
+ ```bash
224
+ aps --version
225
+ aps --help
226
+ ```
227
+
228
+ ## CLI usage
229
+
230
+ List available profiles:
231
+
232
+ ```bash
233
+ aps profiles
234
+ ```
235
+
236
+ Run a small authorized local/lab scan:
237
+
238
+ ```bash
239
+ aps scan 127.0.0.1 --profile quick
240
+ ```
241
+
242
+ Use the standard profile:
243
+
244
+ ```bash
245
+ aps scan 127.0.0.1 --profile standard
246
+ ```
247
+
248
+ Specify an explicit range:
249
+
250
+ ```bash
251
+ aps scan 127.0.0.1 --ports 1-1024
252
+ ```
253
+
254
+ Disable banner collection:
255
+
256
+ ```bash
257
+ aps scan 127.0.0.1 --profile standard --no-banner
258
+ ```
259
+
260
+ Save reports:
261
+
262
+ ```bash
263
+ aps scan 127.0.0.1 --profile standard \
264
+ --save-json --save-csv --save-txt \
265
+ --output-dir reports
266
+ ```
267
+
268
+ The CLI and web API both enforce `MAX_TARGETS` and `MAX_PORTS` safety limits. Profiles cannot bypass those controls.
269
+
270
+ ## Dashboard
271
+
272
+ Start the Flask application locally:
273
+
274
+ ```bash
275
+ python web/app.py
276
+ ```
277
+
278
+ Open:
279
+
280
+ ```text
281
+ http://127.0.0.1:5000
282
+ ```
283
+
284
+ For a production-style process, use Gunicorn as described in [`docs/installation.md`](docs/installation.md).
285
+
286
+ ## API v1
287
+
288
+ The preferred machine-readable interface is `/api/v1`.
289
+
290
+ | Method | Endpoint | Description |
291
+ | --- | --- | --- |
292
+ | `GET` | `/api/v1/health` | Service health |
293
+ | `GET` | `/api/v1/profiles` | Available profiles |
294
+ | `POST` | `/api/v1/scans` | Queue an authorized scan |
295
+ | `GET` | `/api/v1/scans/<job_id>` | Read scan status/results |
296
+ | `POST` | `/api/v1/scans/<job_id>/cancel` | Request cancellation |
297
+ | `GET` | `/api/v1/jobs` | List recent jobs |
298
+ | `GET` | `/api/v1/history` | List persisted history |
299
+ | `GET` | `/api/v1/history/<job_id>` | Read stored scan details |
300
+ | `GET` | `/api/v1/reports/<job_id>/html` | Render an HTML report |
301
+ | `GET` | `/api/v1/analytics` | Read persisted analytics |
302
+ | `GET` | `/api/v1/metrics` | Read operational metrics |
303
+ | `GET` | `/api/v1/cve/lookup` | Lookup CVE enrichment for an observed product/version |
304
+
305
+ The metrics response currently includes:
306
+
307
+ ```json
308
+ {
309
+ "data": {
310
+ "active_jobs": 0,
311
+ "queued_jobs": 0,
312
+ "running_jobs": 0,
313
+ "retained_history": 0,
314
+ "completed_scans": 0,
315
+ "failed_scans": 0,
316
+ "cancelled_scans": 0,
317
+ "average_duration_seconds": 0.0,
318
+ "total_open_ports": 0
319
+ },
320
+ "request_id": "..."
321
+ }
322
+ ```
323
+
324
+ CVE lookup example:
325
+
326
+ ```text
327
+ GET /api/v1/cve/lookup?product=OpenSSH&version=9.8
328
+ ```
329
+
330
+ CVE enrichment is controlled by the configured mode and is `off` by default.
331
+
332
+ Successful JSON responses use a request-aware envelope:
333
+
334
+ ```json
335
+ {
336
+ "data": {},
337
+ "request_id": "..."
338
+ }
339
+ ```
340
+
341
+ Errors use a structured form:
342
+
343
+ ```json
344
+ {
345
+ "error": {
346
+ "code": "...",
347
+ "message": "..."
348
+ },
349
+ "request_id": "..."
350
+ }
351
+ ```
352
+
353
+ Legacy `/api/...` endpoints remain available for compatibility.
354
+
355
+ ## Scan profiles
356
+
357
+ | Profile | Range | Intended use |
358
+ | --- | --- | --- |
359
+ | `quick` | `1-100` | Fast first-pass discovery |
360
+ | `standard` | `1-1024` | General-purpose discovery |
361
+ | `extended` | `1-10000` | Broader service discovery |
362
+ | `full` | `1-65535` | Full TCP port coverage when explicitly permitted |
363
+
364
+ The effective range is always subject to the configured `MAX_PORTS` limit.
365
+
366
+ ## Configuration
367
+
368
+ Configuration is centralized in `scanner/config.py` and can be overridden using environment variables.
369
+
370
+ Key controls include:
371
+
372
+ | Variable | Default | Purpose |
373
+ | --- | ---: | --- |
374
+ | `HOST` | `127.0.0.1` | Bind address |
375
+ | `PORT` | `5000` | Web port |
376
+ | `MAX_CONCURRENT_JOBS` | `2` | Concurrent queued scans |
377
+ | `MAX_TARGETS` | `16` | Maximum targets per request |
378
+ | `MAX_PORTS` | `4096` | Maximum ports per scan |
379
+ | `SOCKET_TIMEOUT` | `0.5` | TCP connection timeout |
380
+ | `BANNER_TIMEOUT` | `0.75` | Banner probe timeout |
381
+ | `HISTORY_RETENTION` | `100` | Stored history records |
382
+ | `REPORT_RETENTION` | `100` | Stored report groups |
383
+ | `AUTH_ENABLED` | `false` | Enable session authentication |
384
+ | `SECURE_COOKIES` | `false` | Mark cookies Secure |
385
+ | `TRUST_PROXY_HEADERS` | `false` | Trust `X-Forwarded-For` when behind a configured proxy |
386
+ | `CVE_MODE` | `off` | CVE enrichment mode: `off`, `offline`, or `online` |
387
+ | `CVE_FEED` | empty | Operator-supplied offline CVE JSON feed |
388
+ | `CVE_TIMEOUT` | `5.0` | Online CVE request timeout |
389
+ | `CVE_API_URL` | NVD v2 API | Online CVE provider endpoint |
390
+
391
+ See [`docs/configuration.md`](docs/configuration.md) for authentication, password hashing, rate limits, CVE enrichment, and deployment guidance.
392
+
393
+ ## Docker
394
+
395
+ Build and start the stack:
396
+
397
+ ```bash
398
+ docker compose up --build
399
+ ```
400
+
401
+ The Compose configuration:
402
+
403
+ - runs the application as a non-root user
404
+ - drops Linux capabilities
405
+ - enables `no-new-privileges`
406
+ - persists data, reports, and logs using Docker-managed volumes
407
+ - keeps SYN/raw-packet capability disabled by default
408
+
409
+ The container intentionally uses one Gunicorn worker with multiple threads because scan job state and rate-limit state are process-local. Multi-process scaling requires a shared job/rate-limit backend.
410
+
411
+ For authorized lab environments that require SYN mode, review the commented capability configuration in `docker-compose.yml` and enable it deliberately.
412
+
413
+ ## CVE enrichment
414
+
415
+ CVE enrichment is intentionally separate from the scanner's heuristic risk hints. A reachable port is not a CVE finding.
416
+
417
+ Modes:
418
+
419
+ - **off** — no external or local CVE lookup
420
+ - **offline** — search an operator-supplied JSON feed
421
+ - **online** — query the configured NVD API endpoint
422
+
423
+ Example environment configuration:
424
+
425
+ ```bash
426
+ export CVE_MODE=offline
427
+ export CVE_FEED=data/cve-feed.json
428
+ ```
429
+
430
+ The online mode must be explicitly enabled. Network errors return an empty enrichment result rather than causing an otherwise valid scan to fail.
431
+
432
+ ## Security model
433
+
434
+ Authentication is disabled by default for local development. For controlled deployments, enable authentication and configure a strong secret, credentials, and appropriate cookie settings.
435
+
436
+ Roles:
437
+
438
+ - **viewer** — read-only access to jobs, history, analytics, reports, metrics, and CVE lookup
439
+ - **operator** — viewer access plus scan and cancellation operations
440
+ - **admin** — operator access plus administrative capability reserved for future expansion
441
+
442
+ Additional protections include CSRF validation, login/scan rate limiting, response security headers, bounded workloads, and explicit trusted-proxy configuration.
443
+
444
+ ### Important limitations
445
+
446
+ - Open ports indicate network reachability, not vulnerability.
447
+ - Risk labels are informational guidance, not a substitute for vulnerability research.
448
+ - CVE enrichment depends on accurate product/version identification and the selected data source; a keyword match is not proof that a specific host is vulnerable.
449
+ - Service fingerprinting is heuristic and reports confidence rather than certainty.
450
+ - TTL/OS identification is heuristic and can be influenced by routing devices.
451
+ - Banner collection is intentionally lightweight.
452
+ - Operational metrics are derived from process-local jobs and retained history, not a long-term telemetry system.
453
+ - Before exposing the dashboard/API outside a trusted environment, use authentication, TLS, and network access controls.
454
+
455
+ ## Reports & history
456
+
457
+ A completed scan can produce a structured report with:
458
+
459
+ - schema and scanner version
460
+ - scan time and duration
461
+ - scan type and profile
462
+ - selected port range
463
+ - target-level results
464
+ - service/version/banner observations
465
+ - risk guidance
466
+
467
+ The HTML report is designed for human review, while JSON is the preferred structured format for automation.
468
+
469
+ Persisted history is stored in SQLite and is bounded by `HISTORY_RETENTION`. Generated report groups are bounded by `REPORT_RETENTION`.
470
+
471
+ ## Testing & development
472
+
473
+ Run the complete test suite locally:
474
+
475
+ ```bash
476
+ python -m pytest -q
477
+ ```
478
+
479
+ The repository CI validates the project across Python 3.11, 3.12, and 3.13.
480
+
481
+ Recommended development loop:
482
+
483
+ ```bash
484
+ python -m pytest -q
485
+ aps --help
486
+ aps profiles
487
+ ```
488
+
489
+ When changing API or deployment behavior, add or update regression coverage in `tests/`.
490
+
491
+ ## Release
492
+
493
+ Current application version: **0.3.0**.
494
+
495
+ See [`CHANGELOG.md`](CHANGELOG.md) and [`docs/v0.3-release.md`](docs/v0.3-release.md) for release details.
496
+
497
+ ## License
498
+
499
+ This project is licensed under the MIT License. See [`LICENSE`](LICENSE).
500
+
501
+ ## Responsible use
502
+
503
+ Use Advanced Port Scanner only on systems and networks you are authorized to assess. The project is intended for defensive discovery, validation, and security testing—not credential attacks, exploitation, stealth, or evasion.