Skip to main content

Cursers

A minimal threaded wrapper for Python curses that simplifies terminal user interface development with built-in threading support and lifecycle management.

Features

  • Simple context manager for curses applications
  • Built-in update loop with configurable FPS
  • Lifecycle hooks for application logic
  • Threaded version for running updates in separate thread
  • Text drawing utilities with styling support

Installation

pip install cursers

Quick Start

Basic App

import cursers


class MyApp(cursers.App):
    # Called when entering the application context
    def on_enter(self):
        self.draw_text(0, 0, "Hello, World!", bold=True)

    # Called each frame with the current key input
    def on_update(self, key):
        if key == 27:  # ESC key
            self.exit()


# Run the application
with MyApp() as app:
    while app.is_running():
        app.update()

Threaded App

import cursers
import time


class MyThreadedApp(cursers.ThreadedApp):
    def on_enter(self):
        self.draw_text(0, 0, "Running in background thread!")

    def on_update(self, key):
        if key == 27:  # ESC key
            self.exit()


# Run in background thread
with MyThreadedApp() as app:
    while app.is_running():
        time.sleep(0.1)  # Do other work

API Reference

App Class

The main application class that provides a context manager for curses applications.

Constructor

App(fps=30)
  • fps: Target frames per second (default: 30)

Methods

  • is_running(): Returns True if the application is running
  • update(): Updates the application state and handles input (call in main loop)
  • exit(): Signals the application to exit
  • draw_text(y, x, text, bold=False, underline=False): Draw text at position

Lifecycle Hooks

Override these methods in your subclass:

  • on_enter(): Called when entering the context
  • on_update(key): Called every frame with key input (-1 if no key pressed)
  • on_exit(): Called when exiting the context

ThreadedApp Class

Extends App to run the update loop in a separate thread.

class MyThreadedApp(cursers.ThreadedApp):
    def on_update(self, key):
        # Handle input and drawing
        pass


with MyThreadedApp() as app:
    # Update loop runs automatically in background thread
    while app.is_running():
        # Main thread is free for other tasks
        time.sleep(0.1)

Thread Class

Basic threading context manager for custom threading needs.

class MyThread(cursers.Thread):
    def run(self):
        # Your thread code here
        pass


with MyThread() as thread:
    # Thread runs automatically
    pass

Examples

Check out the examples/ directory for complete working examples:

Development

Setup

# Clone the repository
git clone https://github.com/threeal/cursers.git
cd cursers

# Install development dependencies
uv sync

# Install Git hooks
uv run lefthook install

Code Quality

# Format code
dprint fmt

# Run linter
uv run ruff check --fix

License

This project is licensed under the terms of the MIT License.

Copyright © 2025 Alfi Maulana

Metadata

Release files for cursers 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cursers 0.1.0
File Size Uploaded
cursers-0.1.0.tar.gz 4.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cursers 0.1.0
File Interpreter ABI Platform
cursers-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 9.4 kB

Release files / cursers-0.1.0.tar.gz

Download URL cursers-0.1.0.tar.gz
Size 4.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6682c9c8c38b0a45f8f2a3a624cd63e7dce71a08cfa36b4bceae6c8b76dd0294
BLAKE2b-256 checksum
How to use checksums
fba0ec548c5308ae43c39460005e90f104ab262a05d0a22a57c36be6dc143bb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.13

Release files / cursers-0.1.0-py3-none-any.whl

Download URL cursers-0.1.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0a14236891664b3c42ac5fd1e825cc457e10f13baaced59acb73e04d4e01502
BLAKE2b-256 checksum
How to use checksums
6b9792cd79c4391f0a19e89a7c66a0de004fc5e7963e77e5851b335a8322a619
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page