-
Notifications
You must be signed in to change notification settings - Fork 0
2.4.0 - Experiemental: Websocket UI #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces an experimental WebSocket interface for LANscape, enabling real-time network scanning capabilities with a standalone async WebSocket server. The implementation provides a comprehensive API for scan management, port list operations, and utility functions with delta-based updates for efficient real-time data synchronization.
Changes:
- Added complete WebSocket server infrastructure with protocol definitions, handlers, and delta tracking
- Integrated WebSocket server mode into the main application with new command-line arguments (
--ws-server,--ws-port) - Implemented comprehensive test coverage with 940 lines of unit and integration tests
- Added dependencies:
websockets>=12.0,<14.0andpytest-asyncio>=0.23for async testing
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_websocket.py |
Comprehensive test suite covering protocol, handlers, delta tracking, and integration scenarios |
pyproject.toml |
Added WebSocket and async testing dependencies |
lanscape/ui/ws/server.py |
Core WebSocket server with async connection handling, message routing, and real-time scan updates |
lanscape/ui/ws/protocol.py |
Pydantic-based message protocol definitions (request, response, error, event) |
lanscape/ui/ws/handlers/tools.py |
Handler for subnet validation, network listing, and configuration queries |
lanscape/ui/ws/handlers/scan.py |
Handler for scan operations including start, subscribe, and delta updates |
lanscape/ui/ws/handlers/port.py |
Handler for port list CRUD operations |
lanscape/ui/ws/handlers/base.py |
Base handler class with action registration and async/sync handler support |
lanscape/ui/ws/handlers/__init__.py |
Handler module exports |
lanscape/ui/ws/delta.py |
Delta tracking system using MD5 hashing for efficient change detection |
lanscape/ui/ws/__init__.py |
WebSocket module exports |
lanscape/ui/main.py |
Integration of WebSocket server startup with port validation logic |
lanscape/core/runtime_args.py |
New runtime arguments for WebSocket server mode and port configuration |
examples/local_scan_reliability.py |
Example demonstrating network scan reliability testing |
examples/local_example.py |
Basic example of library usage |
examples/__init__.py |
Path setup for examples |
.gitpod.yml |
Removed Gitpod configuration file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 29 out of 32 changed files in this pull request and generated 11 comments.
Comments suppressed due to low confidence (1)
lanscape/ui/blueprints/api/scan.py:102
- The
terminate_scanendpoint doesn't check if the scan exists before callingscan.terminate(). Ifscan_manager.get_scan(scan_id)returnsNone, this will raise anAttributeError. The endpoint should check forNoneand return a 404 error, consistent with theget_scanandget_scan_summaryendpoints.
@api_bp.route('/api/scan/<scan_id>/terminate', methods=['GET'])
def terminate_scan(scan_id):
"""Terminate a running scan.
Args:
scan_id (str): Unique identifier for the scan
Returns:
JSON response indicating success or failure
"""
scan = scan_manager.get_scan(scan_id)
scan.terminate()
return jsonify({'success': True})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 33 out of 36 changed files in this pull request and generated 9 comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 36 out of 38 changed files in this pull request and generated 10 comments.
| DEFAULT_HOST = 'localhost' | ||
| DEFAULT_PORT = 8766 | ||
|
|
||
| def __init__(self, host: str = DEFAULT_HOST, port: int = DEFAULT_PORT): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| Subclasses should register their handlers in __init__. | ||
| """ | ||
|
|
||
| def __init__(self): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| - port.delete: Delete a port list | ||
| """ | ||
|
|
||
| def __init__(self, port_manager: Optional[PortManager] = None): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| Clients receive only the changed portions of scan results. | ||
| """ | ||
|
|
||
| def __init__(self): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| def __init__( | ||
| self, | ||
| initial_multiplier: float = 1.0, | ||
| decrease_percent: float = 0.25, | ||
| debounce_sec: float = 5.0, | ||
| min_multiplier: float = 0.1, | ||
| on_warning: Optional[Callable[[str, dict], None]] = None | ||
| ): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| def __init__( | ||
| self, | ||
| max_workers: int, | ||
| retry_config: RetryConfig, | ||
| multiplier_controller: MultiplierController, | ||
| thread_name_prefix: str = "RetryPool", | ||
| on_job_error: Optional[Callable[[Any, Exception, str], None]] = None | ||
| ): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| if not self.running: | ||
| self.results.end_time = time() | ||
|
|
||
| def _handle_warning(self, warning_type: str, warning_data: dict): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method _handle_warning is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| - scan.unsubscribe: Unsubscribe from scan updates | ||
| """ | ||
|
|
||
| def __init__(self, scan_manager: Optional[ScanManager] = None): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
| - tools.arp_supported: Check if ARP is supported on this system | ||
| """ | ||
|
|
||
| def __init__(self): |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init method is missing a return type hint. According to the coding guidelines, type hints are required for all functions and methods. Add -> None as the return type.
examples/__init__.py
Outdated
| @@ -0,0 +1,4 @@ | |||
| import lanscape | |||
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import statement import lanscape on line 1 is not used in this module. This import should either be removed or have a comment explaining why it's needed (e.g., if it's required for module initialization). The other imports on lines 2-4 suggest this might be unnecessary.
| import lanscape |
Build out the websocket UI for the new dedicated lanscape app