Skip to main content

A minimal threaded wrapper for Python curses

Project description

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

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

cursers-0.1.0.tar.gz (4.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cursers-0.1.0-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file cursers-0.1.0.tar.gz.

File metadata

  • Download URL: cursers-0.1.0.tar.gz
  • Upload date:
  • Size: 4.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for cursers-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6682c9c8c38b0a45f8f2a3a624cd63e7dce71a08cfa36b4bceae6c8b76dd0294
MD5 62a4e90f3a1955981d93df9ac67295ee
BLAKE2b-256 fba0ec548c5308ae43c39460005e90f104ab262a05d0a22a57c36be6dc143bb8

See more details on using hashes here.

File details

Details for the file cursers-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cursers-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for cursers-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f0a14236891664b3c42ac5fd1e825cc457e10f13baaced59acb73e04d4e01502
MD5 15e6926087f8e26eaf4306bbd659f2b5
BLAKE2b-256 6b9792cd79c4391f0a19e89a7c66a0de004fc5e7963e77e5851b335a8322a619

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page