UglierPTY - A Really Ugly PyQt6-based SSH Terminal
Project description
PyQt6 SSH Terminal Widget: UglierPTY
Overview
UglierPTY is a very functional proof-of-concept (POC) application created to construct a fully functional SSH Terminal Widget using PyQt6. This POC is inspired by its sister project, UglyPTY, a full-featured SSH client that utilizes xterm.js. The aim is to offer a similar, if not superior, feature set without relying on browser technologies or JavaScript, resulting in a more streamlined and resource-efficient solution.
This is a work in progress, but feel free to give it a try! REPO: https://github.com/scottpeterman/UglierPTY
A Note About UglyPTY
If your interested in the PyQt6/XTerm.js version of this application take a look here: https://github.com/scottpeterman/UglyPTY
Features
- Fully functional SSH terminal built with PyQt6
- Credentials manager for easy login
- Portable session files in YAML (Compatible with UglyPTY)
- Terminal history and screen ratio control via pyte
- Terminal screen render via QPaint
- Modular design for easy embedding into other PyQt6 projects
- Pure Python - Free of Web technology (no xterm.js)
Architecture
- Python 3.x
- PyQt6
- Paramiko
- pyte
- SQLAlchemy
- PyYaml
Screenshots
Here are some snapshots of Uglier in action:
Installation
-
Clone the repository:
git clone https://github.com/scottpeterman/UglierPTY
-
Navigate into the project directory:
cd UglierPTY
-
Install the required Python packages:
pip install -r requirements.txt
Usage
The primary entry point for this POC is the uglierpty.py
script. To launch the application:
If you cloned the repo
python run_test.py
If you installed via PIP
python -m uglierpty
or
pythonw -m uglierpty
SSH Terminal Flow
<title>SSH Terminal Flow</title>SSH Terminal Flow
+--------------------+ +-------------------+ +-------------------+ +------------+ +------------------+ | SSHTerminalWidget | | SSHLib Class | | Communication | | pyte | | Remote SSH Host | | | | | | | | | | | | keyPressEvent() |------>| write(data) |------>| sendDataToSSH() |------>| |------>| Shell Process | | | | | | | | | | | +--------------------+ +-------------------+ +-------------------+ +------------+ +------------------+ ^ ^ ^ ^ | | | | | | | | | | | | | | | | +--------------------+ +-------------------+ +-------------------+ +------------+ +------------------+ | SSHTerminalWidget | | SSHLib Class | | Communication | | pyte | | Remote SSH Host | | | | | | | | | | | | paintEvent() |<------| read() |<------| receiveDataFromSSH() |<------| feed() |<------| Shell Process | | | | | | | | stream.attach(screen) | | | +--------------------+ +-------------------+ +-------------------+ +------------+ +------------------+
Step-by-Step Explanation:
- Keystroke in SSHTerminalWidget: The
keyPressEvent()
function captures the keystroke and sends it to theSSHLib
class viawrite(data)
. - Sending to SSH Channel: The
write()
method sends the data through an SSH channel, probably utilizingparamiko.SSHClient
. This is done inCommunication.sendDataToSSH()
. - SSH to Remote Host: The keystroke reaches the shell process running on the remote SSH host.
- Remote Host to pyte: Once the shell process echoes the output, it's read by
Communication.receiveDataFromSSH()
and fed to pyte'sStream
object viafeed()
inSSHLib.read()
. - pyte to GUI: The
Stream
object updates theScreen
object, which theSSHTerminalWidget.paintEvent()
method uses to draw on the GUI, completing the round trip.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.