Skip to main content

Pytrilium

Python SDK (wrapper, whatever you want to call it) for interacting with Trilium's ETAPI. The exact OpenAPI spec definition file that I'm trying to match can be found here.

You can use either your password or an ETAPI token to authenticate to the Trilium instance.

🖥 Installation

pip install pytrilium

Examples

🔐 Authenticating (via ETAPI token or password)

Token:

from pytrilium.PyTrilium import PyTrilium

pytrilium_client = PyTrilium("https://trilium.example.com", token="TTDaTeG3sadffy2_eOtgqvZoI6xHvga/6vhz61ezke1RpoX47vPI93zs5qs=")

print(pytrilium_client.get_note_content_by_id("MLDQ3EGWsU8e"))

Password:

from pytrilium.PyTrilium import PyTrilium

pytrilium_client = PyTrilium("https://trilium.example.com", password="thisisabadpassword1")

print(pytrilium_client.get_note_content_by_id("MLDQ3EGWsU8e"))

📒 Basic Use Case

This will just print out the contents of a note, as one large string. Trilium's API returns it in the HTML format.

from pytrilium.PyTrilium import PyTrilium

pytrilium_client = PyTrilium("https://trilium.example.com", token="TTDaTeG3sadffy2_eOtgqvZoI6xHvga/6vhz61ezke1RpoX47vPI93zs5qs=")

print(pytrilium_client.get_note_content_by_id("MLDQ3EGWsU8e"))

Export a note to a file

from pytrilium.PyTrilium import PyTrilium

test_client = PyTrilium("https://trilium.example.com", token="TTDaTeG3sadffy2_eOtgqvZoI6xHvga/6vhz61ezke1RpoX47vPI93zs5qs=")

print(test_client.get_note_content_by_id("MLDQ3EGWsU8e"))

test_client.export_note_by_id("MLDQ3EGWsU8e", "./test.zip")

📎 Working with Attachments

Create and manage attachments:

from pytrilium.PyTrilium import PyTrilium

pytrilium_client = PyTrilium("https://trilium.example.com", token="TTDaTeG3sadffy2_eOtgqvZoI6xHvga/6vhz61ezke1RpoX47vPI93zs5qs=")

# Create an attachment
attachment_data = '{"role": "file", "mime": "image/png", "title": "my-image.png"}'
attachment = pytrilium_client.create_attachment(attachment_data)
attachment_id = attachment['attachmentId']

# Get attachment metadata
attachment_info = pytrilium_client.get_attachment_by_id(attachment_id)

# Get attachment content (binary data)
attachment_content = pytrilium_client.get_attachment_content_by_id(attachment_id)

# Update attachment content
with open("new-image.png", "rb") as f:
    new_content = f.read()
pytrilium_client.put_attachment_content_by_id(attachment_id, new_content)

# Update attachment metadata
update_data = '{"title": "updated-image.png"}'
pytrilium_client.patch_attachment_by_id(attachment_id, update_data)

# Delete attachment
pytrilium_client.delete_attachment_by_id(attachment_id)

🧠 More Advanced

If I'm braindead or this just doesn't do what you want it to, you can still use the underlying requests.Session that I've set up so that you can still interact with the API. This way you can still make manual requests if you would like to, and do whatever you would like with them.

To print out a Note's content without using other helpers -

from pytrilium.PyTrilium import PyTrilium

pytrilium_client = PyTrilium("https://trilium.example.com", token="TTDaTeG3sadffy2_eOtgqvZoI6xHvga/6vhz61ezke1RpoX47vPI93zs5qs=")

resp = pytrilium_client.make_request('notes/<noteid>/content')
print(resp.text)

Currently implemented functions

attempt_basic_call
auth_login
auth_logout
clean_url
create_attachment
create_note
create_note_revision
delete_attachment_by_id
delete_attribute_by_id
delete_branch_by_id
delete_note_by_id
export_note_by_id
get_app_info
get_attachment_by_id
get_attachment_content_by_id
get_attribute_by_id
get_branch_by_id
get_days_note
get_inbox_note
get_months_note
get_note_by_id
get_note_content_by_id
get_weeks_note
get_year_note
make_request
make_requests_session
patch_attachment_by_id
patch_attribute_by_id
patch_branch_by_id
patch_note_by_id
post_attribute
post_branch
print_custom_functions
put_attachment_content_by_id
put_note_content_by_id
refresh_note_ordering
search
set_session_auth
valid_response_codes

Development

Installing for Development

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

Running Tests

# Format code
black pytrilium/

# Check imports
isort pytrilium/

# Lint code  
flake8 pytrilium/

# Test imports
python -c "from pytrilium.PyTrilium import PyTrilium; print('✅ Import successful')"

Releasing

See RELEASE.md for the complete release process. Quick version:

# Update version and create tag
python scripts/bump_version.py 1.3.2 --create-tag --push-tag

# Push to trigger automated release
git push origin main

Misc

To get a quick list of currently available paths from the OpenAPI spec (doesn't always mean what's in this package or not):

curl https://raw.githubusercontent.com/zadam/trilium/master/src/etapi/etapi.openapi.yaml 2>/dev/null | yq -e ".paths | keys"

Metadata

Release files for PyTrilium 1.3.5

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

Source distribution (sdist)

Source distribution for PyTrilium 1.3.5
File Size Uploaded
pytrilium-1.3.5.tar.gz 10.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for PyTrilium 1.3.5
File Interpreter ABI Platform
pytrilium-1.3.5-py3-none-any.whl Python 3 none any Details

Total release size: 24.8 kB

Release files / pytrilium-1.3.5.tar.gz

Download URL pytrilium-1.3.5.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
407621508c43b610874c6b077cdb3225f0f55ad84042d9abbcced93cc1e90ea2
BLAKE2b-256 checksum
How to use checksums
ca1429f8a59a399e7ba1fc1b28a6b13f48616b1ef2070d501f1f47c2fcb8cdbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Release files / pytrilium-1.3.5-py3-none-any.whl

Download URL pytrilium-1.3.5-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
adc03b8caf31f74255a4a541df7cd78cf8a061189ccda249174f7c5ef1e998b9
BLAKE2b-256 checksum
How to use checksums
06d93b2f604df6122b55094da127912a407a3e6494b57eeda246fa3ada0a003d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Release history Release notifications | RSS feed

This release

1.3.5 This release

2 release files

1.3.1

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.4

2 release files

1.0.1

2 release files

1.0.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