Skip to main content

A lean Python library for representing goals, tasks, relationships, priority, evolution, and history.

Project description

taskatlas

PyPI version Python versions License: MIT CI

A lean Python library for representing goals, tasks, relationships, priority, evolution, and history.


What is this?

taskatlas gives you a clean, Pythonic object model for tracking work. It sits in the space between a simple task list and an enterprise issue tracker — expressive enough to model real project structure, lightweight enough to feel like writing regular Python.

An Atlas is a navigable world of:

  • Goals — intended outcomes (what you're trying to achieve)
  • Tasks — actionable work (what needs to be done)
  • Relationships — typed links between entities (dependencies, blockers, support)
  • History — automatic event records of every meaningful change
  • Views — board, tree, queue, and summary representations of the current state

The library has zero external dependencies. It runs on Python 3.10+ using only the standard library.


Install

pip install taskatlas

For development (includes pytest):

git clone https://github.com/jrolf/taskatlas.git
cd taskatlas
pip install -e ".[dev]"

Quick Example

import taskatlas as ta

# Create an atlas
atlas = ta.Atlas({"name": "My Project"})

# Define a goal — an intended outcome
goal = ta.Goal({
    "title": "Launch the public API",
    "summary": "Ship a stable, documented v1.",
    "status": "active",
    "priority": "high",
    "tags": ["api", "launch"],
})
atlas.add_goal(goal)

# Add tasks — actionable work
design = goal.add_task({
    "title": "Design endpoint schema",
    "stage": "active",
    "priority": "high",
})

tests = goal.add_task({
    "title": "Write integration tests",
    "stage": "ready",
    "priority": "high",
})

# Decompose complex tasks into subtasks
design.add_task({"title": "Define auth endpoints", "stage": "done"})
design.add_task({"title": "Define data endpoints", "stage": "active"})

# Model dependencies with typed links
tests.link(design, kind="depends_on")

# Move tasks through stages
design.move("review", reason="Implementation complete")

# Add notes to capture context
design.note("Using OpenAPI 3.1 for all endpoint specs.")

# Check goal progress
print(goal.progress())
# {'goal_id': 'g-...', 'task_count': 2, 'by_stage': {'review': 1, 'ready': 1},
#  'done_count': 0, 'done_ratio': 0.0, ...}

# View the board
print(atlas.board())

# Inspect history — every mutation is recorded automatically
for event in atlas.recent(limit=5):
    print(f"{event.event_type}: {event.reason or ''}")

# Save the entire atlas to JSON
atlas.save("project.json")

# Reload it later — everything is preserved
atlas2 = ta.Atlas.load("project.json")

Core Concepts

Atlas

The root container. It owns all goals, tasks, links, and events. It's the single object you serialize and restore.

atlas = ta.Atlas({"name": "Q3 Roadmap"})

Goal

A higher-order intended outcome. Goals have statuses: proposed, active, paused, achieved, archived.

goal = ta.Goal({"title": "Improve reliability", "status": "active", "priority": "high"})
atlas.add_goal(goal)

Task

An actionable work unit. Tasks have stages: inbox, ready, active, blocked, review, done, archived.

task = ta.Task({"title": "Add retry logic", "stage": "ready", "priority": "high"})
atlas.add_task(task)

Containment vs. Links

These are two distinct relationship types that are never conflated:

Containment is structural nesting — subtasks under tasks, subgoals under goals, tasks attached to goals:

goal.add_task(task)         # attach task to goal
task.add_task(subtask)      # nest subtask under task
goal.add_goal(subgoal)      # nest subgoal under goal

Links are typed cross-references — dependencies, blockers, and other semantic relationships:

task_a.link(task_b, kind="depends_on")
task_c.link(task_d, kind="blocks")
goal.link(other_goal, kind="supports")

Available link kinds: depends_on, blocks, relates_to, supports, duplicates, derived_from, conflicts_with.

Notes

Append-only, timestamped annotations on any goal or task:

task.note("Switched approach after profiling showed the bottleneck.")
task.note("Results look good.", meta={"runtime_ms": 340})

Automatic History

Every mutation generates an Event — stage changes, status changes, priority changes, notes, links, attachments. You never manually log history; the library does it.

task.history()                    # per-entity, newest first
atlas.get_events(limit=20)        # global, newest first
atlas.recent(limit=10)            # shortcut for recent activity

Filtering and Retrieval

Simple keyword arguments, conjunctive (AND) logic:

atlas.get_tasks(stage="active", priority="high")
atlas.get_tasks(tags=["backend"], order_by="priority")
atlas.get_tasks(goal_id=goal.id, blocked=True)
atlas.get_tasks(title_contains="auth")

atlas.get_goals(status="active")
atlas.get_goals(priority="high", tags=["core"])

Archived items are excluded by default. Use archived=True to query them explicitly.


Views

Four built-in views return structured Python data (dicts and lists), ready for rendering however you need:

Method Returns Purpose
atlas.board() Tasks grouped by stage Kanban-style workflow view
atlas.tree() Nested goal/task hierarchy Structural overview
atlas.queue() Priority-sorted actionable tasks "What should I do next?"
atlas.summary() Aggregate counts and recent events Dashboard / status check

Each goal and task also has a .context() method that returns a focused situational summary:

task.context()              # compact: id, title, stage, priority, latest note
task.context(mode="full")   # everything: links, notes, events, parent/children
goal.context(mode="full")   # includes progress snapshot

Serialization

Full round-trip serialization to JSON files or JSON-compatible dicts:

# File-based (recommended)
atlas.save("atlas.json")
atlas = ta.Atlas.load("atlas.json")

# Dict-based
payload = atlas.to_dict()           # atlas → dict
atlas = ta.Atlas.from_dict(payload) # dict → atlas

Everything is preserved: IDs, relationships, notes, links, events, timestamps, metadata.


Project Structure

taskatlas/
├── __init__.py        # Public API: Atlas, Goal, Task, Link, Event
├── _atlas.py          # Atlas container and registry
├── _goal.py           # Goal class
├── _task.py           # Task class
├── _base.py           # Shared WorkItem base class
├── _link.py           # Typed relationship model
├── _event.py          # Historical event model
├── _filtering.py      # Query and sort helpers
├── _views.py          # Board, tree, queue, summary renderers
├── _identity.py       # ID generation
└── _types.py          # Constants and defaults

Tutorials

The tutorials/ directory contains detailed walkthroughs:

  1. Quickstart — Your first atlas, goals, tasks, and board
  2. Modeling a Real Project — End-to-end example with a data platform
  3. Relationships and Structure — Containment vs. links in depth
  4. History and Evolution — Automatic events and audit trails
  5. Views and Context — Board, tree, queue, summary, and context()
  6. Persistence and Programmatic Use — Serialization, agents, and automation
  7. Filtering and Retrieval — Every filter option with examples

Running Tests

pytest

The test suite contains 213 tests covering all modules, relationships, history, views, and serialization round-trips.


Design Philosophy

  • Goals are not tasks. Goals represent intended outcomes. Tasks represent work. They have different lifecycles and different semantics.
  • Containment is not linking. Subtask nesting is structural. Dependencies and blockers are cross-references. These are kept separate.
  • History is automatic. Every meaningful mutation creates an event. You never have to manually log what happened.
  • Retrieval returns context, not rows. The library should feel like asking a colleague, not querying a database.
  • The board is a view, not the ontology. Tasks may move through stages, but the underlying reality is richer than columns on a board.
  • Stay lean. Zero dependencies. Small API surface. No enterprise ceremony.

Contributing

Contributions are welcome. Please read CONTRIBUTING.md for the branch model, how to run tests, and PR guidelines.


License

MIT

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

taskatlas-0.0.2.tar.gz (34.0 kB view details)

Uploaded Source

Built Distribution

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

taskatlas-0.0.2-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file taskatlas-0.0.2.tar.gz.

File metadata

  • Download URL: taskatlas-0.0.2.tar.gz
  • Upload date:
  • Size: 34.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for taskatlas-0.0.2.tar.gz
Algorithm Hash digest
SHA256 5bedba4395868b81894c6388af802dd3b0f7946ff343527e9495664cef7b2f15
MD5 07c2f37480854b477be410ada61022eb
BLAKE2b-256 57fd76650692ed7836bb0703d8a832b0f22c6ae8035a7e4d22368877b5dada84

See more details on using hashes here.

File details

Details for the file taskatlas-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: taskatlas-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for taskatlas-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 24577e163c4a3a7d3a2890b4231b2874a6f5b6ec1564c95df13534acacf85231
MD5 48283a922dbffdf04c495f69c0d4b273
BLAKE2b-256 cab663eeb24910756d508a0df7d0781eb76a999c27bca71770e45a338b963cce

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