pytaskwarrior 0.4.9__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytaskwarrior-1.0.0/PKG-INFO +84 -0
- pytaskwarrior-1.0.0/PYPI_README.md +59 -0
- pytaskwarrior-1.0.0/README.md +341 -0
- pytaskwarrior-1.0.0/pyproject.toml +96 -0
- pytaskwarrior-1.0.0/src/__init__.py +0 -0
- pytaskwarrior-1.0.0/src/pytaskwarrior.egg-info/PKG-INFO +84 -0
- pytaskwarrior-1.0.0/src/pytaskwarrior.egg-info/SOURCES.txt +30 -0
- {pytaskwarrior-0.4.9 → pytaskwarrior-1.0.0}/src/pytaskwarrior.egg-info/requires.txt +0 -1
- {pytaskwarrior-0.4.9 → pytaskwarrior-1.0.0}/src/pytaskwarrior.egg-info/top_level.txt +0 -2
- pytaskwarrior-1.0.0/src/taskwarrior/__init__.py +65 -0
- pytaskwarrior-1.0.0/src/taskwarrior/adapters/__init__.py +1 -0
- pytaskwarrior-1.0.0/src/taskwarrior/adapters/taskwarrior_adapter.py +491 -0
- pytaskwarrior-1.0.0/src/taskwarrior/dto/__init__.py +5 -0
- pytaskwarrior-1.0.0/src/taskwarrior/dto/annotation_dto.py +53 -0
- pytaskwarrior-1.0.0/src/taskwarrior/dto/context_dto.py +37 -0
- pytaskwarrior-1.0.0/src/taskwarrior/dto/task_dto.py +345 -0
- pytaskwarrior-1.0.0/src/taskwarrior/dto/uda_dto.py +80 -0
- pytaskwarrior-1.0.0/src/taskwarrior/enums.py +98 -0
- pytaskwarrior-1.0.0/src/taskwarrior/exceptions.py +57 -0
- pytaskwarrior-1.0.0/src/taskwarrior/main.py +484 -0
- pytaskwarrior-1.0.0/src/taskwarrior/py.typed +0 -0
- pytaskwarrior-1.0.0/src/taskwarrior/registry/__init__.py +0 -0
- pytaskwarrior-1.0.0/src/taskwarrior/registry/uda_registry.py +168 -0
- pytaskwarrior-1.0.0/src/taskwarrior/services/__init__.py +0 -0
- pytaskwarrior-1.0.0/src/taskwarrior/services/context_service.py +189 -0
- pytaskwarrior-1.0.0/src/taskwarrior/services/uda_service.py +84 -0
- pytaskwarrior-1.0.0/src/taskwarrior/utils/__init__.py +0 -0
- pytaskwarrior-1.0.0/src/taskwarrior/utils/conversions.py +46 -0
- pytaskwarrior-1.0.0/src/taskwarrior/utils/dto_converter.py +39 -0
- pytaskwarrior-0.4.9/PKG-INFO +0 -44
- pytaskwarrior-0.4.9/PYPI_README.md +0 -31
- pytaskwarrior-0.4.9/README.md +0 -50
- pytaskwarrior-0.4.9/pyproject.toml +0 -19
- pytaskwarrior-0.4.9/src/__init__.py +0 -12
- pytaskwarrior-0.4.9/src/ii.py +0 -7
- pytaskwarrior-0.4.9/src/pytaskwarrior.egg-info/PKG-INFO +0 -44
- pytaskwarrior-0.4.9/src/pytaskwarrior.egg-info/SOURCES.txt +0 -14
- pytaskwarrior-0.4.9/src/taskwarrior.py +0 -274
- pytaskwarrior-0.4.9/src/twmodels.py +0 -326
- pytaskwarrior-0.4.9/tests/test_warrior.py +0 -202
- {pytaskwarrior-0.4.9 → pytaskwarrior-1.0.0}/LICENSE +0 -0
- {pytaskwarrior-0.4.9 → pytaskwarrior-1.0.0}/setup.cfg +0 -0
- {pytaskwarrior-0.4.9 → pytaskwarrior-1.0.0}/src/pytaskwarrior.egg-info/dependency_links.txt +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytaskwarrior
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Taskwarrior wrapper python module
|
|
5
|
+
Author-email: sznicolas <sznicolas@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sznicolas/pytaskwarrior/
|
|
8
|
+
Project-URL: Repository, https://github.com/sznicolas/pytaskwarrior/
|
|
9
|
+
Project-URL: Issues, https://github.com/sznicolas/pytaskwarrior/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/sznicolas/pytaskwarrior/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: taskwarrior,task,productivity,cli
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: pydantic>=2.11.7
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# pytaskwarrior
|
|
27
|
+
|
|
28
|
+
[](https://www.python.org/downloads/)
|
|
29
|
+
[](https://opensource.org/licenses/MIT)
|
|
30
|
+
[](https://github.com/astral-sh/ruff)
|
|
31
|
+
[](https://github.com/sznicolas/pytaskwarrior/actions)
|
|
32
|
+
[](https://github.com/sznicolas/pytaskwarrior)
|
|
33
|
+
[](https://pypi.org/project/pytaskwarrior/)
|
|
34
|
+
|
|
35
|
+
A modern Python wrapper for [TaskWarrior](https://taskwarrior.org/), the command-line task management tool.
|
|
36
|
+
|
|
37
|
+
**v1.0.0**: Production-ready with 132 tests (96% coverage), strict type checking, and professional-grade code quality. Zero linting errors, full async-safe subprocess handling, and PEP 561 type hints for IDE support.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- ✅ Full CRUD operations for tasks
|
|
42
|
+
- ✅ Type-safe with Pydantic models
|
|
43
|
+
- ✅ Context management
|
|
44
|
+
- ✅ UDA (User Defined Attributes) support
|
|
45
|
+
- ✅ Recurring tasks and annotations
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- Python 3.12+
|
|
50
|
+
- TaskWarrior 3.4+ installed
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install pytaskwarrior
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from taskwarrior import TaskWarrior, TaskInputDTO, Priority
|
|
62
|
+
|
|
63
|
+
tw = TaskWarrior()
|
|
64
|
+
|
|
65
|
+
# Create a task
|
|
66
|
+
task = TaskInputDTO(
|
|
67
|
+
description="Important meeting",
|
|
68
|
+
priority=Priority.HIGH,
|
|
69
|
+
project="work",
|
|
70
|
+
due="friday"
|
|
71
|
+
)
|
|
72
|
+
added = tw.add_task(task)
|
|
73
|
+
|
|
74
|
+
# Get all pending tasks
|
|
75
|
+
for t in tw.get_tasks():
|
|
76
|
+
print(f"[{t.priority or '-'}] {t.description}")
|
|
77
|
+
|
|
78
|
+
# Complete a task
|
|
79
|
+
tw.done_task(added.uuid)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Documentation
|
|
83
|
+
|
|
84
|
+
Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# pytaskwarrior
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/astral-sh/ruff)
|
|
6
|
+
[](https://github.com/sznicolas/pytaskwarrior/actions)
|
|
7
|
+
[](https://github.com/sznicolas/pytaskwarrior)
|
|
8
|
+
[](https://pypi.org/project/pytaskwarrior/)
|
|
9
|
+
|
|
10
|
+
A modern Python wrapper for [TaskWarrior](https://taskwarrior.org/), the command-line task management tool.
|
|
11
|
+
|
|
12
|
+
**v1.0.0**: Production-ready with 132 tests (96% coverage), strict type checking, and professional-grade code quality. Zero linting errors, full async-safe subprocess handling, and PEP 561 type hints for IDE support.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- ✅ Full CRUD operations for tasks
|
|
17
|
+
- ✅ Type-safe with Pydantic models
|
|
18
|
+
- ✅ Context management
|
|
19
|
+
- ✅ UDA (User Defined Attributes) support
|
|
20
|
+
- ✅ Recurring tasks and annotations
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- Python 3.12+
|
|
25
|
+
- TaskWarrior 3.4+ installed
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install pytaskwarrior
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from taskwarrior import TaskWarrior, TaskInputDTO, Priority
|
|
37
|
+
|
|
38
|
+
tw = TaskWarrior()
|
|
39
|
+
|
|
40
|
+
# Create a task
|
|
41
|
+
task = TaskInputDTO(
|
|
42
|
+
description="Important meeting",
|
|
43
|
+
priority=Priority.HIGH,
|
|
44
|
+
project="work",
|
|
45
|
+
due="friday"
|
|
46
|
+
)
|
|
47
|
+
added = tw.add_task(task)
|
|
48
|
+
|
|
49
|
+
# Get all pending tasks
|
|
50
|
+
for t in tw.get_tasks():
|
|
51
|
+
print(f"[{t.priority or '-'}] {t.description}")
|
|
52
|
+
|
|
53
|
+
# Complete a task
|
|
54
|
+
tw.done_task(added.uuid)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Documentation
|
|
58
|
+
|
|
59
|
+
Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# pytaskwarrior
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://github.com/astral-sh/ruff)
|
|
6
|
+
[](https://github.com/sznicolas/pytaskwarrior/actions)
|
|
7
|
+
[](https://github.com/sznicolas/pytaskwarrior)
|
|
8
|
+
[](https://pypi.org/project/pytaskwarrior/)
|
|
9
|
+
|
|
10
|
+
A modern Python wrapper for [TaskWarrior](https://taskwarrior.org/) v3.4, the command-line task management tool.
|
|
11
|
+
|
|
12
|
+
**v1.0.0**: Production-ready with 132 tests (96% coverage), strict type checking, and professional-grade code quality. Zero linting errors, full async-safe subprocess handling, and PEP 561 type hints for IDE support.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- ✅ **Full CRUD operations** - Create, read, update, delete tasks
|
|
17
|
+
- ✅ **Type-safe** - Pydantic models with full type hints
|
|
18
|
+
- ✅ **Context management** - Define, apply, and switch contexts
|
|
19
|
+
- ✅ **UDA support** - User Defined Attributes
|
|
20
|
+
- ✅ **Recurring tasks** - Full recurrence support
|
|
21
|
+
- ✅ **Annotations** - Add notes to tasks
|
|
22
|
+
- ✅ **Date calculations** - Use TaskWarrior's date expressions
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
- Python 3.12+
|
|
27
|
+
- TaskWarrior 3.4+ installed and accessible via `task` command
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install pytaskwarrior==1.0.0
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or install from source:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/sznicolas/pytaskwarrior.git
|
|
39
|
+
cd pytaskwarrior
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
### Running the bundled examples in isolation
|
|
46
|
+
|
|
47
|
+
The examples in the examples/ directory are designed to be independent of your personal TaskWarrior configuration. They use the bundled examples/taskrc_example and examples/task_data so they won't modify your default ~/.taskrc or TaskWarrior database.
|
|
48
|
+
|
|
49
|
+
To run an example script (from the repository root):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python examples/example_1_basic.py
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
To run the task CLI manually with the same resources (from the repository root):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
task rc:examples/taskrc_example rc.data.location=examples/task_data <command>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Replace the relative paths with absolute paths (for example, $(pwd)/examples/taskrc_example) if you prefer.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from taskwarrior import TaskWarrior, TaskInputDTO, Priority
|
|
66
|
+
|
|
67
|
+
# Initialize TaskWarrior (uses default ~/.taskrc)
|
|
68
|
+
tw = TaskWarrior()
|
|
69
|
+
|
|
70
|
+
# Create a simple task
|
|
71
|
+
task = TaskInputDTO(description="Buy groceries")
|
|
72
|
+
added_task = tw.add_task(task)
|
|
73
|
+
print(f"Created task #{added_task.index}: {added_task.uuid}")
|
|
74
|
+
|
|
75
|
+
# Create a task with more details
|
|
76
|
+
urgent_task = TaskInputDTO(
|
|
77
|
+
description="Finish project report",
|
|
78
|
+
priority=Priority.HIGH,
|
|
79
|
+
project="work",
|
|
80
|
+
tags=["urgent", "report"],
|
|
81
|
+
due="friday", # TaskWarrior date expressions work!
|
|
82
|
+
)
|
|
83
|
+
tw.add_task(urgent_task)
|
|
84
|
+
|
|
85
|
+
# Get all pending tasks
|
|
86
|
+
tasks = tw.get_tasks()
|
|
87
|
+
for t in tasks:
|
|
88
|
+
print(f"[{t.priority or '-'}] {t.description}")
|
|
89
|
+
|
|
90
|
+
# Complete a task
|
|
91
|
+
tw.done_task(added_task.uuid)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API Reference
|
|
95
|
+
|
|
96
|
+
### TaskWarrior
|
|
97
|
+
|
|
98
|
+
The main class for interacting with TaskWarrior.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from taskwarrior import TaskWarrior
|
|
102
|
+
|
|
103
|
+
# With defaults (uses ~/.taskrc)
|
|
104
|
+
tw = TaskWarrior()
|
|
105
|
+
|
|
106
|
+
# With custom configuration
|
|
107
|
+
tw = TaskWarrior(
|
|
108
|
+
taskrc_file="/path/to/.taskrc",
|
|
109
|
+
data_location="/path/to/task/data",
|
|
110
|
+
task_cmd="task" # Path to task binary
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Task Operations
|
|
115
|
+
|
|
116
|
+
| Method | Description |
|
|
117
|
+
|--------|-------------|
|
|
118
|
+
| `add_task(task: TaskInputDTO)` | Create a new task |
|
|
119
|
+
| `get_task(uuid)` | Get a single task by UUID or ID |
|
|
120
|
+
| `get_tasks(filter_args="")` | Get tasks matching filter |
|
|
121
|
+
| `modify_task(task: TaskInputDTO, uuid)` | Modify an existing task |
|
|
122
|
+
| `delete_task(uuid)` | Mark task as deleted |
|
|
123
|
+
| `purge_task(uuid)` | Permanently remove task |
|
|
124
|
+
| `done_task(uuid)` | Mark task as completed |
|
|
125
|
+
| `start_task(uuid)` | Start working on task |
|
|
126
|
+
| `stop_task(uuid)` | Stop working on task |
|
|
127
|
+
| `annotate_task(uuid, annotation)` | Add annotation to task |
|
|
128
|
+
|
|
129
|
+
#### Context Operations
|
|
130
|
+
|
|
131
|
+
| Method | Description |
|
|
132
|
+
|--------|-------------|
|
|
133
|
+
| `define_context(name, filter)` | Create a context with filter |
|
|
134
|
+
| `apply_context(name)` | Activate a context |
|
|
135
|
+
| `unset_context()` | Deactivate current context |
|
|
136
|
+
| `get_contexts()` | List all contexts |
|
|
137
|
+
| `get_current_context()` | Get active context name |
|
|
138
|
+
| `delete_context(name)` | Remove a context |
|
|
139
|
+
| `has_context(name)` | Check if context exists |
|
|
140
|
+
|
|
141
|
+
### Data Models
|
|
142
|
+
|
|
143
|
+
#### TaskInputDTO
|
|
144
|
+
|
|
145
|
+
Used for creating and modifying tasks.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from taskwarrior import TaskInputDTO, Priority, RecurrencePeriod
|
|
149
|
+
|
|
150
|
+
task = TaskInputDTO(
|
|
151
|
+
description="Task description", # Required
|
|
152
|
+
priority=Priority.HIGH, # H, M, L or None
|
|
153
|
+
project="project.subproject",
|
|
154
|
+
tags=["tag1", "tag2"],
|
|
155
|
+
due="2024-12-31", # ISO date or TW expression
|
|
156
|
+
scheduled="monday",
|
|
157
|
+
wait="tomorrow",
|
|
158
|
+
until="2025-01-01",
|
|
159
|
+
recur=RecurrencePeriod.WEEKLY, # daily, weekly, monthly, yearly
|
|
160
|
+
depends=[uuid1, uuid2], # Task dependencies
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### TaskOutputDTO
|
|
165
|
+
|
|
166
|
+
Returned when retrieving tasks. Includes all input fields plus:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
task = tw.get_task(uuid)
|
|
170
|
+
|
|
171
|
+
task.uuid # Task UUID
|
|
172
|
+
task.index # Task ID number
|
|
173
|
+
task.status # TaskStatus.PENDING, COMPLETED, DELETED, etc.
|
|
174
|
+
task.entry # Creation datetime
|
|
175
|
+
task.modified # Last modification datetime
|
|
176
|
+
task.urgency # Calculated urgency score
|
|
177
|
+
task.annotations # List of annotations
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Enums
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from taskwarrior import Priority, TaskStatus, RecurrencePeriod
|
|
184
|
+
|
|
185
|
+
# Priority levels
|
|
186
|
+
Priority.HIGH # "H"
|
|
187
|
+
Priority.MEDIUM # "M"
|
|
188
|
+
Priority.LOW # "L"
|
|
189
|
+
|
|
190
|
+
# Task statuses
|
|
191
|
+
TaskStatus.PENDING
|
|
192
|
+
TaskStatus.COMPLETED
|
|
193
|
+
TaskStatus.DELETED
|
|
194
|
+
TaskStatus.WAITING
|
|
195
|
+
TaskStatus.RECURRING
|
|
196
|
+
|
|
197
|
+
# Recurrence periods
|
|
198
|
+
RecurrencePeriod.DAILY
|
|
199
|
+
RecurrencePeriod.WEEKLY
|
|
200
|
+
RecurrencePeriod.MONTHLY
|
|
201
|
+
RecurrencePeriod.YEARLY
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
> **Custom recurrence periods**: TaskWarrior supports any recurrence expression beyond the enum values. Pass a raw string directly to `recur` for periods like `"2weeks"`, `"10days"`, or `"6months"`:
|
|
205
|
+
> ```python
|
|
206
|
+
> task = TaskInputDTO(description="Bi-weekly review", recur="2weeks", due="monday")
|
|
207
|
+
> ```
|
|
208
|
+
|
|
209
|
+
## Advanced Examples
|
|
210
|
+
|
|
211
|
+
### Working with Contexts
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# Define contexts for different workflows
|
|
215
|
+
tw.define_context("work", "project:work or +urgent")
|
|
216
|
+
tw.define_context("home", "project:home or project:personal")
|
|
217
|
+
|
|
218
|
+
# Switch to work context
|
|
219
|
+
tw.apply_context("work")
|
|
220
|
+
|
|
221
|
+
# Now get_tasks() only returns work-related tasks
|
|
222
|
+
work_tasks = tw.get_tasks()
|
|
223
|
+
|
|
224
|
+
# Switch back to no context
|
|
225
|
+
tw.unset_context()
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Recurring Tasks
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from taskwarrior import TaskInputDTO, RecurrencePeriod
|
|
232
|
+
|
|
233
|
+
# Create a weekly recurring task
|
|
234
|
+
weekly_review = TaskInputDTO(
|
|
235
|
+
description="Weekly project review",
|
|
236
|
+
due="monday",
|
|
237
|
+
recur=RecurrencePeriod.WEEKLY,
|
|
238
|
+
project="reviews",
|
|
239
|
+
)
|
|
240
|
+
tw.add_task(weekly_review)
|
|
241
|
+
|
|
242
|
+
# Get the parent recurring task
|
|
243
|
+
recurring = tw.get_recurring_task(task.uuid)
|
|
244
|
+
|
|
245
|
+
# Get all instances
|
|
246
|
+
instances = tw.get_recurring_instances(task.uuid)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Task Annotations
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
# Add notes to a task
|
|
253
|
+
task = tw.add_task(TaskInputDTO(description="Research topic"))
|
|
254
|
+
|
|
255
|
+
tw.annotate_task(task.uuid, "Found useful article at example.com")
|
|
256
|
+
tw.annotate_task(task.uuid, "Discussed with team, need more info")
|
|
257
|
+
|
|
258
|
+
# Annotations are included when retrieving tasks
|
|
259
|
+
task = tw.get_task(task.uuid)
|
|
260
|
+
for ann in task.annotations:
|
|
261
|
+
print(f"{ann.entry}: {ann.description}")
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Date Calculations
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
# Use TaskWarrior's date calculation
|
|
268
|
+
result = tw.task_calc("today + 2weeks")
|
|
269
|
+
print(result) # "2024-02-14T00:00:00"
|
|
270
|
+
|
|
271
|
+
# Validate a date expression
|
|
272
|
+
if tw.date_validator("next monday"):
|
|
273
|
+
print("Valid date expression")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Configuration
|
|
277
|
+
|
|
278
|
+
### Environment Variables
|
|
279
|
+
|
|
280
|
+
- `TASKRC` - Path to taskrc file (default: `~/.taskrc`)
|
|
281
|
+
- `TASKDATA` - Path to task data directory
|
|
282
|
+
|
|
283
|
+
### Automatic Configuration
|
|
284
|
+
|
|
285
|
+
If no `.taskrc` exists at the specified path, pytaskwarrior creates one with sensible defaults:
|
|
286
|
+
|
|
287
|
+
```ini
|
|
288
|
+
# Auto-generated by pytaskwarrior
|
|
289
|
+
rc.data.location=~/.task
|
|
290
|
+
rc.confirmation=off
|
|
291
|
+
rc.bulk=0
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Development
|
|
295
|
+
|
|
296
|
+
### Setup
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
git clone https://github.com/sznicolas/pytaskwarrior.git
|
|
300
|
+
cd pytaskwarrior
|
|
301
|
+
pip install -e ".[dev]"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Running Tests
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Run all tests
|
|
308
|
+
pytest
|
|
309
|
+
|
|
310
|
+
# With coverage
|
|
311
|
+
pytest --cov=src/taskwarrior --cov-report=term-missing
|
|
312
|
+
|
|
313
|
+
# Run specific test file
|
|
314
|
+
pytest tests/unit/test_dto.py -v
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Code Quality
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Linting and formatting
|
|
321
|
+
ruff check src/ tests/
|
|
322
|
+
ruff format src/ tests/
|
|
323
|
+
|
|
324
|
+
# Type checking
|
|
325
|
+
mypy src/taskwarrior
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## License
|
|
329
|
+
|
|
330
|
+
MIT License - see [LICENSE](LICENSE) file.
|
|
331
|
+
|
|
332
|
+
## Contributing
|
|
333
|
+
|
|
334
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
335
|
+
|
|
336
|
+
## Links
|
|
337
|
+
|
|
338
|
+
- [TaskWarrior](https://taskwarrior.org/) - The underlying task management tool
|
|
339
|
+
- [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
|
|
340
|
+
- [PyPI Package](https://pypi.org/project/pytaskwarrior/)
|
|
341
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pytaskwarrior"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Taskwarrior wrapper python module"
|
|
5
|
+
readme = "PYPI_README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
keywords = [ "taskwarrior", "task", "productivity", "cli" ]
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "sznicolas", email = "sznicolas@users.noreply.github.com" },
|
|
11
|
+
]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
19
|
+
"Topic :: Utilities",
|
|
20
|
+
"Typing :: Typed",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"pydantic>=2.11.7",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[dependency-groups]
|
|
27
|
+
dev = [
|
|
28
|
+
"pytest>=8.4.0",
|
|
29
|
+
"ruff>=0.8.0",
|
|
30
|
+
"mypy>=1.13.0",
|
|
31
|
+
"pytest-cov>=7.0.0",
|
|
32
|
+
]
|
|
33
|
+
docs = [
|
|
34
|
+
"mkdocs>=1.6.0",
|
|
35
|
+
"mkdocs-material>=9.5.0",
|
|
36
|
+
"mkdocstrings[python]>=0.27.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/sznicolas/pytaskwarrior/"
|
|
41
|
+
Repository = "https://github.com/sznicolas/pytaskwarrior/"
|
|
42
|
+
Issues = "https://github.com/sznicolas/pytaskwarrior/issues"
|
|
43
|
+
Changelog = "https://github.com/sznicolas/pytaskwarrior/blob/main/CHANGELOG.md"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
taskwarrior = ["py.typed"]
|
|
47
|
+
|
|
48
|
+
[build-system]
|
|
49
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
50
|
+
build-backend = "setuptools.build_meta"
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
# Target Python 3.12+
|
|
54
|
+
target-version = "py312"
|
|
55
|
+
line-length = 100
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint]
|
|
58
|
+
# Enable recommended rules + additional quality checks
|
|
59
|
+
select = [
|
|
60
|
+
"E", # pycodestyle errors
|
|
61
|
+
"W", # pycodestyle warnings
|
|
62
|
+
"F", # pyflakes
|
|
63
|
+
"I", # isort
|
|
64
|
+
"N", # pep8-naming
|
|
65
|
+
"UP", # pyupgrade
|
|
66
|
+
"B", # flake8-bugbear
|
|
67
|
+
"C4", # flake8-comprehensions
|
|
68
|
+
"SIM", # flake8-simplify
|
|
69
|
+
]
|
|
70
|
+
ignore = [
|
|
71
|
+
"E501", # Line too long (handled by formatter)
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[tool.ruff.lint.per-file-ignores]
|
|
75
|
+
"tests/**/*.py" = [
|
|
76
|
+
"N802", # Function name should be lowercase (allow test_* methods)
|
|
77
|
+
"SIM117", # Nested `with` statements in tests (patch + pytest.raises idiom)
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
[tool.mypy]
|
|
81
|
+
python_version = "3.12"
|
|
82
|
+
strict = true
|
|
83
|
+
warn_return_any = true
|
|
84
|
+
warn_unused_configs = true
|
|
85
|
+
disallow_untyped_defs = true
|
|
86
|
+
disallow_any_unimported = false
|
|
87
|
+
no_implicit_optional = true
|
|
88
|
+
warn_redundant_casts = true
|
|
89
|
+
warn_unused_ignores = true
|
|
90
|
+
warn_no_return = true
|
|
91
|
+
check_untyped_defs = true
|
|
92
|
+
strict_equality = true
|
|
93
|
+
|
|
94
|
+
[[tool.mypy.overrides]]
|
|
95
|
+
module = "tests.*"
|
|
96
|
+
disallow_untyped_defs = false
|
|
File without changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytaskwarrior
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Taskwarrior wrapper python module
|
|
5
|
+
Author-email: sznicolas <sznicolas@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sznicolas/pytaskwarrior/
|
|
8
|
+
Project-URL: Repository, https://github.com/sznicolas/pytaskwarrior/
|
|
9
|
+
Project-URL: Issues, https://github.com/sznicolas/pytaskwarrior/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/sznicolas/pytaskwarrior/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: taskwarrior,task,productivity,cli
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: pydantic>=2.11.7
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# pytaskwarrior
|
|
27
|
+
|
|
28
|
+
[](https://www.python.org/downloads/)
|
|
29
|
+
[](https://opensource.org/licenses/MIT)
|
|
30
|
+
[](https://github.com/astral-sh/ruff)
|
|
31
|
+
[](https://github.com/sznicolas/pytaskwarrior/actions)
|
|
32
|
+
[](https://github.com/sznicolas/pytaskwarrior)
|
|
33
|
+
[](https://pypi.org/project/pytaskwarrior/)
|
|
34
|
+
|
|
35
|
+
A modern Python wrapper for [TaskWarrior](https://taskwarrior.org/), the command-line task management tool.
|
|
36
|
+
|
|
37
|
+
**v1.0.0**: Production-ready with 132 tests (96% coverage), strict type checking, and professional-grade code quality. Zero linting errors, full async-safe subprocess handling, and PEP 561 type hints for IDE support.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- ✅ Full CRUD operations for tasks
|
|
42
|
+
- ✅ Type-safe with Pydantic models
|
|
43
|
+
- ✅ Context management
|
|
44
|
+
- ✅ UDA (User Defined Attributes) support
|
|
45
|
+
- ✅ Recurring tasks and annotations
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- Python 3.12+
|
|
50
|
+
- TaskWarrior 3.4+ installed
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install pytaskwarrior
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from taskwarrior import TaskWarrior, TaskInputDTO, Priority
|
|
62
|
+
|
|
63
|
+
tw = TaskWarrior()
|
|
64
|
+
|
|
65
|
+
# Create a task
|
|
66
|
+
task = TaskInputDTO(
|
|
67
|
+
description="Important meeting",
|
|
68
|
+
priority=Priority.HIGH,
|
|
69
|
+
project="work",
|
|
70
|
+
due="friday"
|
|
71
|
+
)
|
|
72
|
+
added = tw.add_task(task)
|
|
73
|
+
|
|
74
|
+
# Get all pending tasks
|
|
75
|
+
for t in tw.get_tasks():
|
|
76
|
+
print(f"[{t.priority or '-'}] {t.description}")
|
|
77
|
+
|
|
78
|
+
# Complete a task
|
|
79
|
+
tw.done_task(added.uuid)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Documentation
|
|
83
|
+
|
|
84
|
+
Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
PYPI_README.md
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
src/__init__.py
|
|
6
|
+
src/pytaskwarrior.egg-info/PKG-INFO
|
|
7
|
+
src/pytaskwarrior.egg-info/SOURCES.txt
|
|
8
|
+
src/pytaskwarrior.egg-info/dependency_links.txt
|
|
9
|
+
src/pytaskwarrior.egg-info/requires.txt
|
|
10
|
+
src/pytaskwarrior.egg-info/top_level.txt
|
|
11
|
+
src/taskwarrior/__init__.py
|
|
12
|
+
src/taskwarrior/enums.py
|
|
13
|
+
src/taskwarrior/exceptions.py
|
|
14
|
+
src/taskwarrior/main.py
|
|
15
|
+
src/taskwarrior/py.typed
|
|
16
|
+
src/taskwarrior/adapters/__init__.py
|
|
17
|
+
src/taskwarrior/adapters/taskwarrior_adapter.py
|
|
18
|
+
src/taskwarrior/dto/__init__.py
|
|
19
|
+
src/taskwarrior/dto/annotation_dto.py
|
|
20
|
+
src/taskwarrior/dto/context_dto.py
|
|
21
|
+
src/taskwarrior/dto/task_dto.py
|
|
22
|
+
src/taskwarrior/dto/uda_dto.py
|
|
23
|
+
src/taskwarrior/registry/__init__.py
|
|
24
|
+
src/taskwarrior/registry/uda_registry.py
|
|
25
|
+
src/taskwarrior/services/__init__.py
|
|
26
|
+
src/taskwarrior/services/context_service.py
|
|
27
|
+
src/taskwarrior/services/uda_service.py
|
|
28
|
+
src/taskwarrior/utils/__init__.py
|
|
29
|
+
src/taskwarrior/utils/conversions.py
|
|
30
|
+
src/taskwarrior/utils/dto_converter.py
|