Skip to main content

lunatask-api-python - Python API for Lunatask

Lunatask logo with Python's logo superimposed.

A Python version of Lunatask's API, plus a script to pull task data from Todoist and import it into Lunatask.

I wanted to try out Lunatask without copying and pasting my existing Todoist tasks over; Todoist only lets you export to CSV, and Lunatask doesn't have any import abilities yet, so here we are.

Requirements

Installation

  • pip install lunatask-api-python from PyPI
  • uv build to build from source; this gives you:
    • dist/lunatask_api_python-0.1.0-py3-none-any.whl - A Python wheel you can install.
    • .venv/bin/todoist2lunatask - The Todoist importer script.

Generate Docs

# Generate documentation in wiki/*.md:
uv tool install pydoc-markdown
uv tool run pydoc-markdown

# Optionally fix up invalid Markdown:
perl -pi -e 'BEGIN{undef $/;} s/(<a id="[^"]+"><\\/a>)\\n\\n(.*)/#\2 \1\n/mg;' wiki/docs/*.md

Before You Import

Before using the todoist2lunatask script, you need to create a todoist2lunatask.config from the todoist2lunatask.config.template (click to download a copy). This config file controls the import process.

NOTE: Lunatask doesn't currently have public APIs for creating Areas of Life (aka Projects) or Goals (which I was going to use to replicate Todoist Labels).

There are three items you need to specify in the config before you can begin:

  • lunatask_api_token - In the Luntask desktop application:
    1. Click the Settings icon ⚙️ in the top left.
    2. Click "Access tokens" in the Preferences list on the lef.
    3. Click the "Create access token" button. Rename it to something like "Todoist Import" so you don't forget what it's for. You should revoke the token when you're done importing from Todoist.
    4. Click the "Copy to clipboard" button and paste it into your config file.
  • todoist_api_token - Your Todoist API token.
  • todoist_default_area - The default Area of Life; if you haven't set up a mapping between your Todoist projects and Lunatask Areas of Life, imported tasks will be created in here.

To put imported tasks in specific Areas of Life, you must create one or more Areas to receive the imported Todoist tasks and list them in the todoist2lunatask.config file's todoist_project_map. It's tedious (especially if you have a lof of Projects in Todoist), but easy. Instructions are in the config file.

todoist2lunatask Usage

To import your Todoist Tasks into Lunatask:

  1. Copy the todoist2lunatask.config-template to todoist2lunatask.config.
  2. Edit the todoist2lunatask.config file using your favourite text editor (hopefully one that does syntax highlighting for TOML, but it's not required).
  3. Add your Todoist API token:
    1. In Todoist's settings under Integrations, go to the Developer tab.
    2. Click Copy API Token.
    3. Paste your Todoist API token in todoist2lunatask.config so it replaces TODOIST_API_TOKEN_GOES_HERE.
  4. Add your Lunatask API token:
    1. In Lunatask's settings under Access tokens, click Create access token and optionally rename it "Todoist Import" so you'll remember what it was for.
    2. Click Copy to clipboard.
    3. Paste your Lunatask API token in todoist2lunatask.config so it replaces LUNATASK_API_TOKEN_GOES_HERE.
  5. Paste the Area ID for your default Lunatask Area of Life in todoist_default_area.
  6. Optionally create Areas of Life to duplicate your Todoist Projects, then paste the Todoist Project names and Luntask Area IDs in the todoist_project_map.

Now you're ready to go:

  1. Run todoist2lunatask --check to make sure your API tokens are correct. This will also warn you if there are Todoist Projects that don't have a corresponding Lunatask Area of Life. Note that this doesn't verify your Area of Life IDs. The --check doesn't make any changes to your Lunatask data.
  2. Run todoist2lunatask --import to import all of your Todoist tasks. Warnings will let you know about any problems.

Details

Todoist's features don't map directly into Lunatask; here's how the import adjusts things:

  • Deadlines are prepended to the task title as [Deadline: date].
  • Todoist's Priority has four levels, be default these map to the following Lunatask priorities (you can change this in the config file):
    • P1 -> Highest
    • P2 -> High
    • P3 -> Normal
    • P4 -> Low
  • Imported tasks will have Todoist as their source and (optionally) the original Todoist task ID as the source_id. These are available in the API, but not in the desktop apps.
  • Collaborators (Task creators, or assignees) are created as People in Lunatask with the Relationship set by todoist_collaborator_relationship in the config.

Todoist features not supported:

  • Assignee, Assigner, Creator - There's no way to get user info from Todoist via the REST API.
  • Attachments - Added to the Note section as a link to the Todoist task.
  • Sections - Added to the Note section of the imported Lunatask Task.

Detailed Details

Here's the detailed mapping between data in a Todoist Task object to a Lunatask Task.

A 🙅 indicates that the Todoist field isn't replicated in Lunatask.

Todoist Lunatask Notes
assignee_id 🙅
assigner_id 🙅
comment_count note 2
content name 1, 2
created_at note 2
creator_id 🙅
deadline note 2, 4
description note 2
due note 2, 6
duration estimate
id 🙅
is_completed status
labels goal_id 2, 3
order 🙅
parent_id 7
priority priority 5
project_id area_id
section_id 2, 8
url note 2

Notes:

  1. Todoist's Content field is a big free-form text area that supports Markdown; Lunatask's Name field is a single line without formatting.
  2. This information gets formatted into the Lunatask Task's Note section.
  3. Areas that have imported Tasks that originally had Labels in Todoist get a new Task listing those tasks and their labels, so you can recreate them via Goals inside the Areas if you wish.
  4. Deadline format is controlled by the todoist_deadline_* settings in the config file.
  5. Todoist priorities are mapped to Lunatask priorities according to the todoist_priority setting in the config file.
  6. There's no way to set recurrence in the Lunatask API; you can by recreate this after the import: https://lunatask.app/docs/features/tasks/recurring-tasks
  7. Todoist Tasks with a parent_id are Subtasks; they'll be recreated as Lunatask Tasks with notes referring to their parent. The parent will list its sub-tasks.
  8. Project sections are ignored, Task sections are added to the task note.

License

todoist2lunatask is currently licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International by Chris Herborth. Contact me if that doesn't work for you.

Metadata

Release files for lunatask-api-python 1.0.0

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

Source distribution (sdist)

Source distribution for lunatask-api-python 1.0.0
File Size Uploaded Provenance
lunatask_api_python-1.0.0.tar.gz 44.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lunatask-api-python 1.0.0
File Interpreter ABI Platform
lunatask_api_python-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 65.1 kB

Release files / lunatask_api_python-1.0.0.tar.gz

Download URL lunatask_api_python-1.0.0.tar.gz
Size 44.4 kB
Tags Source
SHA-256 checksum
How to use checksums
38862e3696390c65a687bf450dd41618142ee7000d25d0982c3b8ba5a5a94591
BLAKE2b-256 checksum
How to use checksums
bea7d03f4df1f393290026cc5e2bec7d4d5a9d7581f60ffbd7fa55be66256a75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.9

Release files / lunatask_api_python-1.0.0-py3-none-any.whl

Download URL lunatask_api_python-1.0.0-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1231c467d84ed6dc15c90c3827fe1c14ab757779a5df88af8cdf58d0e0934e0
BLAKE2b-256 checksum
How to use checksums
18618215162499e2724892636e49bcb936e5ec762c9fad931bdc321a32ed3e0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.9

Security for lunatask-api-python 1.0.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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