Add your description here
Project description
termlit
Termlit converts a plain Python script into an interactive SSH experience.
Write terminal flows with welcome, input, and post helpers, then expose
them over SSH via termlit run app.py.
Features
- SSH server with ready-to-use credentials (or anonymous mode)
- Built-in Rich welcome panels and simple text helpers
- Rich-powered spinners that lock user input while background work is running
- Request/response helpers (
termlit.post) powered byrequests - Password-masked input via
termlit.input(..., hidden=True) - Session-scoped stdout redirection so
print()just works - Upload helpers (
termlit.upload_file(s)) that copy generated files into anupload_files/directory so you can retrieve them easily - Download helpers (
termlit.download_cmd) that generate ready-to-run scp commands or temporary HTTP links for your end users
Quick start
-
Install the package (editable mode during development is fine):
pip install -e .
or, if you prefer uv:
curl -LsSf https://astral.sh/uv/install.sh | sh # install uv (once) uv pip install -e .
-
Create a script, e.g.
app.py:import termlit termlit.welcome( title="Welcome~", subtitle="version 1.0.0", description="This is a note", ) while True: prompt = termlit.input("User question: ") if prompt.lower() in {"quit", "exit"}: termlit.goodbye("Goodbye! See you next time") break with termlit.spinner("dots", "Processing your question..."): response = termlit.post( url="https://httpbin.org/post", json={"question": prompt}, log=False, # Suppress automatic POST summary ) termlit.write("Answer: " + str(response.json()))
termlit.spinnerblocks input by default, so users cannot queue input during wait. By defaulttermlit.inputignores empty input, allow withallow_empty=True。 需要輸入Password時可使用termlit.input("input password: ", hidden=True)for password input masked with*. -
Serve it over SSH:
termlit run app.py --host 0.0.0.0 --port 2222 --reload
Add
--auth none可讓使用者免Password登入(預設為--auth ssh需輸入Password)。 -
Connect from any SSH client (default credentials
admin/password123):ssh admin@127.0.0.1 -p 2222
CLI flags
--user name=secret: add/override login credentials (repeatable).--auth {ssh,none}: choose between password-protected (ssh) or passwordless (none) sessions.--allow-anonymous: accept any username/password combo.--reload: watch the target script and restart the SSH server whenever it changes (development helper).--host/--port: where the SSH server listens.--version: display the installed Termlit version and exit.
Streaming output
When you already have a generator/iterable that yields text chunks (for example,
tailing logs or chunked API responses), call termlit.write(..., stream=True)
to forward each chunk immediately without buffering:
def stream_logs():
for line in follow_log_file():
yield line
termlit.write(stream_logs(), stream=True)
Strings/bytes are still treated as a single chunk, so you can safely switch the flag on even when a function sometimes returns plain text and sometimes returns an iterator.
Programmatic usage
You can also embed Termlit inside a Python process:
import termlit
def app():
termlit.welcome("Inline app")
termlit.write("Hello there!")
termlit.goodbye()
if __name__ == "__main__":
termlit.run(app, host="127.0.0.1", port=2222)
需要免Password體驗時, 可傳入
auth_mode="none"給termlit.run.
Uploading files
Use the upload_files/upload_file helpers when your script needs to drop
artifacts (reports, logs, etc.) into a directory that you can fetch later:
import termlit
# Copy a single file to ./upload_files (or $TERMLIT_UPLOAD_DIR) with progress
termlit.upload_files("build/output/report.pdf", show_progress=True)
# Copy multiple files and grab the resulting server-side paths
uploaded = termlit.upload_file(
["app.log", r"C:\temp\screenshot.png"],
show_progress=True,
)
termlit.write("Saved files to:")
for path in uploaded:
termlit.write(f" - {path}")
# Provide ready-to-run scp commands for the client
cmd = termlit.download_cmd(
"report.pdf",
source_dir="upload_files",
)
termlit.write("Run command locally to download:")
termlit.write(cmd)
# Or host a temporary HTTP download link
http_links = termlit.download_cmd(
"report.pdf",
source_dir="upload_files",
type="http",
)
termlit.write("Or open in browser:")
termlit.write(http_links)
All files are copied into upload_files/ relative to where termlit run was
executed (override via the TERMLIT_UPLOAD_DIR environment variable or the
destination_dir argument). Pass show_progress=True to stream simple
percentage updates back to the SSH client while a file is being copied. Use
replace=True when you want to overwrite same-named files instead of letting
Termlit append _1, _2, ... suffixes (the default collision-avoidance
behaviour). Use
termlit.download_cmd(...) to generate the scp command your users should run
locally, pass source_dir="upload_files" when you want to specify the hosting
folder, or set type="http" to spin up a temporary http.server over the
target folder. Set TERMLIT_DOWNLOAD_HOST, TERMLIT_DOWNLOAD_PORT,
TERMLIT_DOWNLOAD_USER, or TERMLIT_HTTP_PORT when the defaults are
insufficient.
Downloading files
Once your script calls termlit.upload_file(...), you have two convenient ways
to guide end users through downloading the artifacts:
- scp 指令 – 呼叫
termlit.download_cmd("report.pdf", source_dir="upload_files")generates string likescp -P 2222 admin@<host>:/abs/path/report.pdf ./. Copy this command to user to run locally. Adjust host/port/user via env varsTERMLIT_DOWNLOAD_HOST,TERMLIT_DOWNLOAD_PORT,TERMLIT_DOWNLOAD_USERor override usinghost=,port=,username=,destination=。 - HTTP 下載 – 傳入
type="http", e.g.termlit.download_cmd("report.pdf", source_dir="upload_files", type="http"), startshttp.server(default port8765useTERMLIT_HTTP_PORT覆寫), 並回傳http://<host>:8765/report.pdfURL. User downloads via browser; server access log is 自動抑制, 避免干擾 SSH 介面。
HTTP 模式要求所有檔案在同一個資料夾, 可將檔案集中到
upload_files/then generate link. Remind user to close temp HTTP server (restart app or custom cmd) for security.
Repository layout
termlit/session.py– public helper implementations.termlit/runtime.py– SSH server + script runner.termlit/cli.py– command line interface (termlit run).scripts/ssh_server_plain.py,scripts/telnet_server.py– original demo servers (optional utilities; they call an external FastAPI backend that you must run yourself).scripts/start_services.py– helper script that starts the Telnet/SSH demos and forwards the--fastapi-urlyou provide.
Happy terminal building!
Developer Overview
termlit/__init__.py: 集中 re-export Termlit 公開 API(welcome、input、upload_file...), 也在匯入時載入版本資訊與 thread-local session 綁定。termlit/session.py: Session 層主程式, 實作所有對外 helper(UI、HTTP、上傳/下載等), 並維護_current_session, file copy, HTTP download service details.termlit/runtime.py: 啟動/管理 SSH 伺服器與 ScriptRunner, 並提供serve_script_with_reloaderwatchdog flow; handles Paramiko server interface and stdout redirection.termlit/cli.py:termlit指令的進入點, 解析termlit runflags, manages auth settings and calls runtime.example_app.py: 內建範例, 展示如何建立 Termlit 流程、上傳檔案以及和 HTTP API 互動。scripts/ssh_server_plain.py/scripts/telnet_server.py: 較早期的互動式 demo 伺服器, 提供自建命令列介面並透過外部 FastAPI 後端提供應答。scripts/start_services.py: 方便一次啟動 telnet/ssh demo 並將--fastapi-urlto both.tests/: 單元/整合測試樣本;新增功能時請補上覆蓋相關 helper 或 runtime 的測試。upload_files/: 預設的伺服器端上傳輸出資料夾(可透過TERMLIT_UPLOAD_DIR覆寫), 便於從本機取得 Termlit Session 中產生的檔案。
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file termlit-0.2.0.tar.gz.
File metadata
- Download URL: termlit-0.2.0.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1563c35f61421316af36bf96eeee6db44c3e0859430ba15e093668fb02a2f327
|
|
| MD5 |
2443a6e03b2e54da393cd26343fed2c7
|
|
| BLAKE2b-256 |
23951d0742cf4960b37836ea967799d2030fac7751986ac8b7dd28ece1cf5bca
|
File details
Details for the file termlit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: termlit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 26.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3450df898fc093fc814f30ce3476bde37b5a34f5ae5088c3606769c20efdec66
|
|
| MD5 |
9138af14f0d126086598165d4f3f3eda
|
|
| BLAKE2b-256 |
209dbeb766b7bd19093e57adc22e6220476820e0010b8a53a2788e058db6801a
|