Skip to main content

pytodo-qt

CI codecov Python 3.11+ License: GPL v3 Ruff Code style: black basedpyright

A cross-platform to-do list manager with encrypted peer-to-peer synchronization.

Features

  • Multiple lists - Organize tasks into separate lists with private/shared control
  • Priority levels - High, normal, and low priority with color coding
  • Due dates - Date picker with overdue highlighting and filtering
  • Search and filter - Real-time filtering of todo items
  • Undo/redo - Full undo/redo for all operations
  • Encrypted sync - AES-256-GCM encryption with Ed25519 key exchange
  • Device management - Track peers by fingerprint with trust levels (normal/trusted/blocked)
  • Sync groups - Organize devices into groups and control which lists sync where
  • Auto-sync - Debounced push after changes and periodic full sync on configurable timers
  • Offline queue - Queue syncs for offline devices, auto-execute when they come online
  • Auto-discovery - Find other instances on your network via mDNS/Zeroconf
  • Dark/light themes - WCAG AA contrast-compliant themes with system-following
  • Cross-platform - Linux, macOS, and Windows support

Requirements

  • Python 3.11 or later
  • PyQt6

Installation

Pre-built Binaries

Download the latest release for your platform from the Releases page.

macOS

  1. Download pytodo-qt-VERSION-macos-arm64.zip (Apple Silicon) or pytodo-qt-VERSION-macos-x86_64.zip (Intel)
  2. Extract the zip file
  3. Move pytodo-qt.app to /Applications or ~/Applications
  4. First run only: Right-click the app and select "Open" to bypass Gatekeeper
    • Alternatively, run: xattr -rd com.apple.quarantine /Applications/pytodo-qt.app
  5. After the first run, you can open normally by double-clicking

Note: The app is ad-hoc signed (not notarized with an Apple Developer ID), so macOS will show an "unidentified developer" warning on first launch. This is normal for open-source software distributed outside the App Store.

Linux

  1. Download pytodo-qt-VERSION-linux-x86_64.tar.gz or pytodo-qt-VERSION-linux-arm64.tar.gz
  2. Extract: tar -xzf pytodo-qt-VERSION-linux-*.tar.gz
  3. Run the install script: cd pytodo-qt-*/ && ./install.sh
  4. Or run directly: ./pytodo-qt

The install script places the binary in ~/.local/bin/ and creates a desktop entry.

To uninstall: ~/.local/lib/pytodo-qt/uninstall.sh (or run ./uninstall.sh from the extracted archive)

Windows

  1. Download pytodo-qt-VERSION-windows-x86_64.zip
  2. Extract the zip file
  3. Run pytodo-qt.exe

From PyPI

pipx install pytodo-qt    # recommended
pip install pytodo-qt     # alternative

From source

git clone https://github.com/berrym/pytodo-qt.git
cd pytodo-qt
pip install .

Development install

pip install -e ".[dev]"

Usage

pytodo-qt

Command-line options

Server Options:
  -s, --server {yes,no}    enable/disable network server
  --pull {yes,no}          allow remote pull requests
  --push {yes,no}          allow remote push requests
  -i, --ip IP              server bind address
  -p, --port PORT          server port

Discovery Options:
  -d, --discovery {yes,no} enable/disable mDNS discovery

Appearance Options:
  -t, --theme {light,dark,system}

Configuration

Configuration is stored in XDG-compliant locations:

Platform Config Data
Linux ~/.config/pytodo-qt/ ~/.local/share/pytodo-qt/
macOS ~/Library/Application Support/pytodo-qt/ same
Windows %APPDATA%\pytodo-qt\ same

config.toml

[database]
active_list = ""
sort_key = "priority"
reverse_sort = false

[server]
enabled = true
address = "0.0.0.0"
port = 5364
allow_pull = true
allow_push = true

[discovery]
enabled = true
service_name = ""  # defaults to pytodo-{hostname}
auto_sync_trusted = false  # auto-sync when trusted devices come online
auto_sync_delay = 0  # seconds to debounce before auto-push (0 = disabled)
auto_sync_interval = 0  # minutes between periodic full syncs (0 = disabled)

[appearance]
theme = "system"  # light, dark, system

Synchronization

pytodo-qt uses a secure peer-to-peer protocol for syncing between instances:

  1. Discovery - Instances advertise themselves via mDNS (_pytodo._tcp.local.)
  2. Key exchange - Ed25519 identity keys with X25519 ephemeral session keys
  3. Encryption - All data encrypted with AES-256-GCM
  4. Merge - Last-write-wins conflict resolution with UUID-based items
  5. Device management - Track peers with trust levels and organize into sync groups
  6. Sync rules - Control which lists sync to which device groups
  7. Auto-sync - Debounced push after changes, periodic full sync, and sync on trusted device discovery
  8. Offline queue - Queue syncs for offline devices, auto-execute when they come online

Identity keys are stored in your system keyring (GNOME Keyring, macOS Keychain, Windows Credential Locker).

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Lint and format
ruff check src/ tests/
ruff format src/ tests/

# Type check
basedpyright src/

License

GPLv3 or later. See COPYING for details.

Copyright 2024-2026 Michael Berry trismegustis@gmail.com

Release files for pytodo-qt 0.3.10

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

Source distribution (sdist)

Source distribution for pytodo-qt 0.3.10
File Size Uploaded
pytodo_qt-0.3.10.tar.gz 1.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytodo-qt 0.3.10
File Interpreter ABI Platform
pytodo_qt-0.3.10-py3-none-any.whl Python 3 none any Details

Total release size: 2.1 MB

Release files / pytodo_qt-0.3.10.tar.gz

Download URL pytodo_qt-0.3.10.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
191cdb2c0e2640dac65149c219650ea0882222b574ef1766857095c3bd8591e0
BLAKE2b-256 checksum
How to use checksums
22723a2e7b033c3939ca1a7a444cca16180de1393720ad44a8508cc16ce08d45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 2, 2026.

Transparency log

Release files / pytodo_qt-0.3.10-py3-none-any.whl

Download URL pytodo_qt-0.3.10-py3-none-any.whl
Size 1.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
0974c7264c71bb756107bfe20e245e47bf33421abd71868d9fd78179067e0685
BLAKE2b-256 checksum
How to use checksums
0f15ddd2b97d5c4bb60a7d5a1845341537492191128f9735aae429e65e7b85c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.10 This release

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

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