Awesome
🔖 aiolinkding: a Python3, async library to the linkding REST API
<a href="https://www.buymeacoffee.com/bachya1208P" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
aiolinkding
is a Python3, async library that interfaces with linkding
instances. It is intended to be a reasonably light wrapper around the linkding API
(meaning that instead of drowning the user in custom objects/etc., it focuses on
returning JSON straight from the API).
- Installation
- Python Versions
- Usage
- Contributing
Installation
pip install aiolinkding
Python Versions
aiolinkding
is currently supported on:
- Python 3.10
- Python 3.11
- Python 3.12
Usage
Creating a Client
It's easy to create an API client for a linkding instance. All you need are two parameters:
- A URL to a linkding instance
- A linkding API token
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
asyncio.run(main())
Working with Bookmarks
Getting All Bookmarks
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get all bookmarks:
bookmarks = await client.bookmarks.async_get_all()
# >>> { "count": 100, "next": null, "previous": null, "results": [...] }
asyncio.run(main())
client.bookmarks.async_get_all()
takes three optional parameters:
query
: a string query to filter the returned bookmarkslimit
: the maximum number of results that should be returnedoffset
: the index from which to return results (e.g.,5
starts at the fifth bookmark)
Getting Archived Bookmarks
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get all archived bookmarks:
bookmarks = await client.bookmarks.async_get_archived()
# >>> { "count": 100, "next": null, "previous": null, "results": [...] }
asyncio.run(main())
client.bookmarks.async_get_archived()
takes three optional parameters:
query
: a string query to filter the returned bookmarkslimit
: the maximum number of results that should be returnedoffset
: the index from which to return results (e.g.,5
starts at the fifth bookmark)
Getting a Single Bookmark by ID
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get a single bookmark:
bookmark = await client.bookmarks.async_get_single(37)
# >>> { "id": 37, "url": "https://example.com", "title": "Example title", ... }
asyncio.run(main())
Creating a New Bookmark
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Create a new bookmark:
created_bookmark = await client.bookmarks.async_create(
"https://example.com",
title="Example title",
description="Example description",
tag_names=[
"tag1",
"tag2",
],
)
# >>> { "id": 37, "url": "https://example.com", "title": "Example title", ... }
asyncio.run(main())
client.bookmarks.async_create()
takes four optional parameters:
title
: the bookmark's titledescription
: the bookmark's descriptionnotes
: Markdown notes to add to the bookmarktag_names
: the tags to assign to the bookmark (represented as a list of strings)is_archived
: whether the newly-created bookmark should automatically be archivedunread
: whether the newly-created bookmark should be marked as unreadshared
: whether the newly-created bookmark should be shareable with other linkding users
Updating an Existing Bookmark by ID
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Update an existing bookmark:
updated_bookmark = await client.bookmarks.async_update(
37,
url="https://different-example.com",
title="Different example title",
description="Different example description",
tag_names=[
"tag1",
"tag2",
],
)
# >>> { "id": 37, "url": "https://different-example.com", ... }
asyncio.run(main())
client.bookmarks.async_update()
takes four optional parameters (inclusion of any parameter
will change that value for the existing bookmark):
url
: the bookmark's URLtitle
: the bookmark's titledescription
: the bookmark's descriptionnotes
: Markdown notes to add to the bookmarktag_names
: the tags to assign to the bookmark (represented as a list of strings)unread
: whether the bookmark should be marked as unreadshared
: whether the bookmark should be shareable with other linkding users
Archiving/Unarchiving a Bookmark
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Archive a bookmark by ID:
await client.bookmarks.async_archive(37)
# ...and unarchive it:
await client.bookmarks.async_unarchive(37)
asyncio.run(main())
Deleting a Bookmark
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Delete a bookmark by ID:
await client.bookmarks.async_delete(37)
asyncio.run(main())
Working with Tags
Getting All Tags
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get all tags:
tags = await client.tags.async_get_all()
# >>> { "count": 100, "next": null, "previous": null, "results": [...] }
asyncio.run(main())
client.tags.async_get_all()
takes two optional parameters:
limit
: the maximum number of results that should be returnedoffset
: the index from which to return results (e.g.,5
starts at the fifth bookmark)
Getting a Single Tag by ID
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get a single tag:
tag = await client.tags.async_get_single(22)
# >>> { "id": 22, "name": "example-tag", ... }
asyncio.run(main())
Creating a New Tag
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Create a new tag:
created_tag = await client.tags.async_create("example-tag")
# >>> { "id": 22, "name": "example-tag", ... }
asyncio.run(main())
Working with User Data
Getting Profile Info
import asyncio
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
client = await async_get_client("http://127.0.0.1:8000", "token_abcde12345")
# Get all tags:
tags = await client.user.async_get_profile()
# >>> { "theme": "auto", "bookmark_date_display": "relative", ... }
asyncio.run(main())
Connection Pooling
By default, the library creates a new connection to linkding with each coroutine. If you
are calling a large number of coroutines (or merely want to squeeze out every second of
runtime savings possible), an aiohttp
ClientSession
can be used for
connection pooling:
import asyncio
from aiohttp import async_get_clientSession
from aiolinkding import async_get_client
async def main() -> None:
"""Use aiolinkding for fun and profit."""
async with ClientSession() as session:
client = await async_get_client(
"http://127.0.0.1:8000", "token_abcde12345", session=session
)
# Get to work...
asyncio.run(main())
Contributing
Thanks to all of our contributors so far!
- Check for open features/bugs or initiate a discussion on one.
- Fork the repository.
- (optional, but highly recommended) Create a virtual environment:
python3 -m venv .venv
- (optional, but highly recommended) Enter the virtual environment:
source ./.venv/bin/activate
- Install the dev environment:
script/setup
- Code your new feature or bug fix on a new branch.
- Write tests that cover your new functionality.
- Run tests and ensure 100% code coverage:
poetry run pytest --cov aiolinkding tests
- Update
README.md
with any new documentation. - Submit a pull request!