{"id":13612184,"url":"https://github.com/bachya/aiolinkding","last_synced_at":"2025-04-14T07:07:50.701Z","repository":{"id":39569667,"uuid":"493408717","full_name":"bachya/aiolinkding","owner":"bachya","description":"A Python3, async interface to the linkding REST API","archived":false,"fork":false,"pushed_at":"2025-02-04T20:29:41.000Z","size":1536,"stargazers_count":21,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"dev","last_synced_at":"2025-04-14T07:07:44.037Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bachya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-17T20:46:06.000Z","updated_at":"2025-04-13T22:21:26.000Z","dependencies_parsed_at":"2023-10-20T17:41:38.444Z","dependency_job_id":"69b40a48-6276-476d-a314-723c7d81ccfc","html_url":"https://github.com/bachya/aiolinkding","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":"bachya/pypi-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bachya%2Faiolinkding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bachya%2Faiolinkding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bachya%2Faiolinkding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bachya%2Faiolinkding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bachya","download_url":"https://codeload.github.com/bachya/aiolinkding/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248837280,"owners_count":21169374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T20:00:24.153Z","updated_at":"2025-04-14T07:07:50.670Z","avatar_url":"https://github.com/bachya.png","language":"Python","funding_links":["https://www.buymeacoffee.com/bachya1208P"],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"# 🔖 aiolinkding: a Python3, async library to the linkding REST API\n\n[![CI][ci-badge]][ci]\n[![PyPI][pypi-badge]][pypi]\n[![Version][version-badge]][version]\n[![License][license-badge]][license]\n[![Code Coverage][codecov-badge]][codecov]\n[![Maintainability][maintainability-badge]][maintainability]\n\n\u003ca href=\"https://www.buymeacoffee.com/bachya1208P\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/default-orange.png\" alt=\"Buy Me A Coffee\" height=\"41\" width=\"174\"\u003e\u003c/a\u003e\n\n`aiolinkding` is a Python3, async library that interfaces with [linkding][linkding]\ninstances. It is intended to be a reasonably light wrapper around the linkding API\n(meaning that instead of drowning the user in custom objects/etc., it focuses on\nreturning JSON straight from the API).\n\n- [Installation](#installation)\n- [Python Versions](#python-versions)\n- [Usage](#usage)\n  - [Creating a Client](#creating-a-client)\n  - [Working with Bookmarks](#working-with-bookmarks)\n    - [Getting All Bookmarks](#getting-all-bookmarks)\n    - [Getting Archived Bookmarks](#getting-archived-bookmarks)\n    - [Getting a Single Bookmark](#getting-a-single-bookmark-by-id)\n    - [Creating a New Bookmark](#creating-a-new-bookmark)\n    - [Updating an Existing Bookmark by ID](#updating-an-existing-bookmark-by-id)\n    - [Archiving/Unarchiving a Bookmark](#archivingunarchiving-a-bookmark)\n    - [Deleting a Bookmark](#deleting-a-bookmark)\n  - [Working with Tags](#working-with-tags)\n    - [Getting All Tags](#getting-all-tags)\n    - [Getting a Single Tag](#getting-a-single-tag-by-id)\n    - [Creating a New Tag](#creating-a-new-Tag)\n  - [Working with User Data](#working-with-user-data)\n    - [Getting Profile Info](#getting-profile-info)\n  - [Connection Pooling](#connection-pooling)\n- [Contributing](#contributing)\n\n# Installation\n\n```bash\npip install aiolinkding\n```\n\n# Python Versions\n\n`aiolinkding` is currently supported on:\n\n- Python 3.11\n- Python 3.12\n- Python 3.13\n\n# Usage\n\n## Creating a Client\n\nIt's easy to create an API client for a linkding instance. All you need are two\nparameters:\n\n1. A URL to a linkding instance\n2. A linkding API token\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n\nasyncio.run(main())\n```\n\n## Working with Bookmarks\n\n### Getting All Bookmarks\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get all bookmarks:\n    bookmarks = await client.bookmarks.async_get_all()\n    # \u003e\u003e\u003e { \"count\": 100, \"next\": null, \"previous\": null, \"results\": [...] }\n\n\nasyncio.run(main())\n```\n\n`client.bookmarks.async_get_all()` takes three optional parameters:\n\n- `query`: a string query to filter the returned bookmarks\n- `limit`: the maximum number of results that should be returned\n- `offset`: the index from which to return results (e.g., `5` starts at the fifth bookmark)\n\n### Getting Archived Bookmarks\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get all archived bookmarks:\n    bookmarks = await client.bookmarks.async_get_archived()\n    # \u003e\u003e\u003e { \"count\": 100, \"next\": null, \"previous\": null, \"results\": [...] }\n\n\nasyncio.run(main())\n```\n\n`client.bookmarks.async_get_archived()` takes three optional parameters:\n\n- `query`: a string query to filter the returned bookmarks\n- `limit`: the maximum number of results that should be returned\n- `offset`: the index from which to return results (e.g., `5` starts at the fifth bookmark)\n\n### Getting a Single Bookmark by ID\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get a single bookmark:\n    bookmark = await client.bookmarks.async_get_single(37)\n    # \u003e\u003e\u003e { \"id\": 37, \"url\": \"https://example.com\", \"title\": \"Example title\", ... }\n\n\nasyncio.run(main())\n```\n\n### Creating a New Bookmark\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Create a new bookmark:\n    created_bookmark = await client.bookmarks.async_create(\n        \"https://example.com\",\n        title=\"Example title\",\n        description=\"Example description\",\n        tag_names=[\n            \"tag1\",\n            \"tag2\",\n        ],\n    )\n    # \u003e\u003e\u003e { \"id\": 37, \"url\": \"https://example.com\", \"title\": \"Example title\", ... }\n\n\nasyncio.run(main())\n```\n\n`client.bookmarks.async_create()` takes four optional parameters:\n\n- `title`: the bookmark's title\n- `description`: the bookmark's description\n- `notes`: Markdown notes to add to the bookmark\n- `tag_names`: the tags to assign to the bookmark (represented as a list of strings)\n- `is_archived`: whether the newly-created bookmark should automatically be archived\n- `unread`: whether the newly-created bookmark should be marked as unread\n- `shared`: whether the newly-created bookmark should be shareable with other linkding users\n\n### Updating an Existing Bookmark by ID\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Update an existing bookmark:\n    updated_bookmark = await client.bookmarks.async_update(\n        37,\n        url=\"https://different-example.com\",\n        title=\"Different example title\",\n        description=\"Different example description\",\n        tag_names=[\n            \"tag1\",\n            \"tag2\",\n        ],\n    )\n    # \u003e\u003e\u003e { \"id\": 37, \"url\": \"https://different-example.com\", ... }\n\n\nasyncio.run(main())\n```\n\n`client.bookmarks.async_update()` takes four optional parameters (inclusion of any parameter\nwill change that value for the existing bookmark):\n\n- `url`: the bookmark's URL\n- `title`: the bookmark's title\n- `description`: the bookmark's description\n- `notes`: Markdown notes to add to the bookmark\n- `tag_names`: the tags to assign to the bookmark (represented as a list of strings)\n- `unread`: whether the bookmark should be marked as unread\n- `shared`: whether the bookmark should be shareable with other linkding users\n\n### Archiving/Unarchiving a Bookmark\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Archive a bookmark by ID:\n    await client.bookmarks.async_archive(37)\n\n    # ...and unarchive it:\n    await client.bookmarks.async_unarchive(37)\n\n\nasyncio.run(main())\n```\n\n### Deleting a Bookmark\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Delete a bookmark by ID:\n    await client.bookmarks.async_delete(37)\n\n\nasyncio.run(main())\n```\n\n## Working with Tags\n\n### Getting All Tags\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get all tags:\n    tags = await client.tags.async_get_all()\n    # \u003e\u003e\u003e { \"count\": 100, \"next\": null, \"previous\": null, \"results\": [...] }\n\n\nasyncio.run(main())\n```\n\n`client.tags.async_get_all()` takes two optional parameters:\n\n- `limit`: the maximum number of results that should be returned\n- `offset`: the index from which to return results (e.g., `5` starts at the fifth bookmark)\n\n### Getting a Single Tag by ID\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get a single tag:\n    tag = await client.tags.async_get_single(22)\n    # \u003e\u003e\u003e { \"id\": 22, \"name\": \"example-tag\", ... }\n\n\nasyncio.run(main())\n```\n\n### Creating a New Tag\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Create a new tag:\n    created_tag = await client.tags.async_create(\"example-tag\")\n    # \u003e\u003e\u003e { \"id\": 22, \"name\": \"example-tag\", ... }\n\n\nasyncio.run(main())\n```\n\n## Working with User Data\n\n### Getting Profile Info\n\n```python\nimport asyncio\n\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    client = await async_get_client(\"http://127.0.0.1:8000\", \"token_abcde12345\")\n\n    # Get all tags:\n    tags = await client.user.async_get_profile()\n    # \u003e\u003e\u003e { \"theme\": \"auto\", \"bookmark_date_display\": \"relative\", ... }\n\n\nasyncio.run(main())\n```\n\n## Connection Pooling\n\nBy default, the library creates a new connection to linkding with each coroutine. If you\nare calling a large number of coroutines (or merely want to squeeze out every second of\nruntime savings possible), an [`aiohttp`][aiohttp] `ClientSession` can be used for\nconnection pooling:\n\n```python\nimport asyncio\n\nfrom aiohttp import async_get_clientSession\nfrom aiolinkding import async_get_client\n\n\nasync def main() -\u003e None:\n    \"\"\"Use aiolinkding for fun and profit.\"\"\"\n    async with ClientSession() as session:\n        client = await async_get_client(\n            \"http://127.0.0.1:8000\", \"token_abcde12345\", session=session\n        )\n\n        # Get to work...\n\n\nasyncio.run(main())\n```\n\n# Contributing\n\nThanks to all of [our contributors][contributors] so far!\n\n1. [Check for open features/bugs][issues] or [initiate a discussion on one][new-issue].\n2. [Fork the repository][fork].\n3. (_optional, but highly recommended_) Create a virtual environment: `python3 -m venv .venv`\n4. (_optional, but highly recommended_) Enter the virtual environment: `source ./.venv/bin/activate`\n5. Install the dev environment: `script/setup`\n6. Code your new feature or bug fix on a new branch.\n7. Write tests that cover your new functionality.\n8. Run tests and ensure 100% code coverage: `poetry run pytest --cov aiolinkding tests`\n9. Update `README.md` with any new documentation.\n10. Submit a pull request!\n\n[aiohttp]: https://github.com/aio-libs/aiohttp\n[linkding]: https://github.com/sissbruecker/linkding\n[ci-badge]: https://img.shields.io/github/actions/workflow/status/bachya/aiolinkding/test.yml\n[ci]: https://github.com/bachya/aiolinkding/actions\n[codecov-badge]: https://codecov.io/gh/bachya/aiolinkding/branch/dev/graph/badge.svg\n[codecov]: https://codecov.io/gh/bachya/aiolinkding\n[contributors]: https://github.com/bachya/aiolinkding/graphs/contributors\n[fork]: https://github.com/bachya/aiolinkding/fork\n[issues]: https://github.com/bachya/aiolinkding/issues\n[license-badge]: https://img.shields.io/pypi/l/aiolinkding.svg\n[license]: https://github.com/bachya/aiolinkding/blob/main/LICENSE\n[maintainability-badge]: https://api.codeclimate.com/v1/badges/189379773edd4035a612/maintainability\n[maintainability]: https://codeclimate.com/github/bachya/aiolinkding/maintainability\n[new-issue]: https://github.com/bachya/aiolinkding/issues/new\n[new-issue]: https://github.com/bachya/aiolinkding/issues/new\n[pypi-badge]: https://img.shields.io/pypi/v/aiolinkding.svg\n[pypi]: https://pypi.python.org/pypi/aiolinkding\n[version-badge]: https://img.shields.io/pypi/pyversions/aiolinkding.svg\n[version]: https://pypi.python.org/pypi/aiolinkding\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbachya%2Faiolinkding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbachya%2Faiolinkding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbachya%2Faiolinkding/lists"}