Package: taskwarrior
Taskwarrior bindings for PythonInteract with your local taskwarrior task list from Python.This is heavily inspired by@ralphbean'staskw library(that I'm also a contributor to), but breaks with many past decisions so as to have a cleaner internal API, a saner method of interacting with Taskwarrior itself, type annotations, and much improved maintainability.Installationpip install taskwarriorYou can also install the in-development version with:pip install https://github.com/coddingtonbear/taskwarrior/archive/master.zipQuickstart>>>fromtaskwarriorimportClient>>>client=Client()>>>tasks=client.filter(status='pending')[Task(annotations=None,depends=None,description='Wake up',due=None,end=None,entry=datetime.datetime(2022,1,24,4,28,11,tzinfo=tzutc()),id=1,imask=None,mask=None,modified=datetime.datetime(2022,1,24,4,28,51,tzinfo=tzutc()),parent=None,project=None,recur=None,scheduled=None,start=None,status='pending',tags=['alarm'],until=None,urgency=0.8,uuid=UUID('a39ea0fa-682a-4815-9556-8b6785ee301c'),wait=None)]>>>ExamplesFinding TasksThefiltermethod is used for finding tasks:>>>fromtaskwarriorimportClient>>>client=Client()>>>client.filter(status='pending')[Task(annotations=None,depends=None,description='Wake up',due=None,end=None,entry=datetime.datetime(2023,1,24,4,28,11,tzinfo=tzutc()),id=1,imask=None,mask=None,modified=datetime.datetime(2022,1,24,4,28,51,tzinfo=tzutc()),parent=None,project=None,recur=None,scheduled=None,start=None,status='pending',tags=['alarm'],until=None,urgency=0.8,uuid=UUID('a39ea0fa-682a-4815-9556-8b6785ee301c'),wait=None)]It accepts as parameters any of the following:Any number of keyword arguments:Example of filter keyword arguments include:status='pending'description__contains='Some string'due__after='yesterday'Double-underscores are transformed into a.when sending the filter to Taskwarrior so as to allow you to use filters likedescription.containsordue.after.Any number of filter dictionaries:These work much the same way as keyword arguments described above, but allow you to specify these as raw dictionaries instead.Any number of raw strings:E.g. for filtering to tasks having only a certain tag, you can provide as a value+mytag.Any number ofQobjects:You can useQobjects to perform complexorandandqueries using exactly the same keyword arguments, filter dictionaries, or string values descrribed above.See "Using Q Objects" below for more information.Each of these parameters areand-ed together should more than one parameter be provided.  If you need to useorexpressions, see "Using Q Objects" below.If you are expecting to retrieve just a single task, you can use the.getmethod, too:>>>fromtaskwarriorimportClient>>>client=Client()>>>client.get(uuid="a39ea0fa-682a-4815-9556-8b6785ee301c")Task(annotations=None,depends=None,description='Wake up',due=None,end=None,entry=datetime.datetime(2023,1,24,4,28,11,tzinfo=tzutc()),id=1,imask=None,mask=None,modified=datetime.datetime(2022,1,24,4,28,51,tzinfo=tzutc()),parent=None,project=None,recur=None,scheduled=None,start=None,status='pending',tags=['alarm'],until=None,urgency=0.8,uuid=UUID('a39ea0fa-682a-4815-9556-8b6785ee301c'),wait=None)if either zero or more than one task is returned from your query, an exception will be raised.Retrieving tasks>>>fromtaskwarriorimportClient>>>client=Client()>>>client.get(uuid="a39ea0fa-682a-4815-9556-8b6785ee301c")Task(annotations=None,depends=None,description='Wake up',due=None,end=None,entry=datetime.datetime(2023,1,24,4,28,11,tzinfo=tzutc()),id=1,imask=None,mask=None,modified=datetime.datetime(2022,1,24,4,28,51,tzinfo=tzutc()),parent=None,project=None,recur=None,scheduled=None,start=None,status='pending',tags=['alarm'],until=None,urgency=0.8,uuid=UUID('a39ea0fa-682a-4815-9556-8b6785ee301c'),wait=None)See "Finding Tasks" for more details -- this allows all of the functionality described there, except that it asserts that only a single task be returned.  Note that you can use any combination of fields you might like for retrieving your single task, butuuidandidare the ones most likely to be of use to you.Counting tasks>>>fromtaskwarriorimportClient>>>client=Client()>>>client.count(status='pending')1This allows all of the same filtering logic that you can find described in "Finding tasks" above; see that section for more details.Adding Tasks>>>fromtaskwarriorimportClient,Task>>>client=Client()>>>task=Task(description="my new task")>>>client.add(task)>>>task.uuidUUID('29d06231-525f-4a62-9e9f-dd0f680aaaff')'Changing tasks>>>fromtaskwarriorimportClient>>>importpytz>>>client=Client()>>>task=client.get(uuid="a39ea0fa-682a-4815-9556-8b6785ee301c")>>>task.due=datetime.datetime(2029,1,1,10,0,tzinfo=pytz.timezone('America/Los_Angeles'))>>>client.modify(task)Just alter the fields on the object directly using native python datatypes and pass your altered object tomodifyand your task will be updated immediately.Being Flexible>>>fromtaskwarriorimportClient>>>client=Client(config_filename="/path/to/my/taskrc",config_overrides={"some":{"config":"values",}},task_bin="/path/to/bin/task",)You can provide the following parameters when instantiating your client:config_filename: (Default:~/.taskrc) The path of thetaskrcfile to use.config_overrides: A dictionary object representing configuration overrides to use when interacting with Taskwarrior.  Nested dictionaries will be encoded into dotted configuration paths using the key name in their parent dictionary.task_bin: The path to thetaskbinary to use.Using Q ObjectsQ objects (inspired byDjango's objects of the same namecan be used for building complex logical queries for filtering your tasks.Q objects accept all of the same parameter types described in "Finding tasks" above, but can also beororand-ed together using|or&:>>>fromtaskwarriorimportClient,Q>>>importpytz>>>client=Client()>>>client.filter(Q(status='pending')|Q(status='waiting',due__before=pytz.timezone('America/Los_Angeles').localize(datetime.datetime.utcnow()+datetime.timedelta(days=7))))How does this differ fromtaskw?This is a much younger library and may still have bugs.This interacts with Taskwarrior over itsexportandimport("plumbing") interfaces instead of interacting with its "porcelain" interfaces likemodify.  This makes this library internally a lot simpler and less likely to break as Taskwarrior's command-line API is changed in the future.This has far fewer options and controls.  Mostly: those options and controls are of limited value and high maintenance cost anyway, so it's likely you won't even notice.This has much more sophisticated filtering capabilities.This uses a slightly simpler API for retrieving tasks -- rather than handing you a 2-tuple of values(id, {data})this just hands you a data object (or list of them).This uses a third-party library (Pydantic) for data serialization/deserialization so as to remove those responsibilities from the library itself (and hopefully make it somewhat easier to maintain).This supports only modern versions of Taskwarrior.  Specifically: only versions of Taskwarrior newer than 2.5.1 are supported.This supports only currently supported versions of Python.  Specifically: only versions of Python currently receiving security updates are supported -- that means Python 3.7+ at the moment.