{"id":28087465,"url":"https://github.com/thiswillbeyourgithub/karakeep_python_api","last_synced_at":"2026-02-22T21:17:43.322Z","repository":{"id":291602542,"uuid":"978124008","full_name":"thiswillbeyourgithub/karakeep_python_api","owner":"thiswillbeyourgithub","description":"Community-driven Python client \u0026 CLI for the Karakeep API.","archived":false,"fork":false,"pushed_at":"2025-11-30T00:46:12.000Z","size":374,"stargazers_count":23,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-02T04:29:04.066Z","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":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thiswillbeyourgithub.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-05T14:03:06.000Z","updated_at":"2025-11-30T00:43:18.000Z","dependencies_parsed_at":"2025-05-05T16:04:32.526Z","dependency_job_id":"cc4d06a7-ab70-437d-9449-ab87a25ad5ab","html_url":"https://github.com/thiswillbeyourgithub/karakeep_python_api","commit_stats":null,"previous_names":["thiswillbeyourgithub/karakeep_python_api"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/thiswillbeyourgithub/karakeep_python_api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiswillbeyourgithub%2Fkarakeep_python_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiswillbeyourgithub%2Fkarakeep_python_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiswillbeyourgithub%2Fkarakeep_python_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiswillbeyourgithub%2Fkarakeep_python_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thiswillbeyourgithub","download_url":"https://codeload.github.com/thiswillbeyourgithub/karakeep_python_api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thiswillbeyourgithub%2Fkarakeep_python_api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29727313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T20:09:16.275Z","status":"ssl_error","status_checked_at":"2026-02-22T20:09:13.750Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2025-05-13T11:32:05.472Z","updated_at":"2026-02-22T21:17:43.309Z","avatar_url":"https://github.com/thiswillbeyourgithub.png","language":"Python","readme":"# Karakeep Python API Client\n\n[![PyPI version](https://badge.fury.io/py/karakeep-python-api.svg)](https://badge.fury.io/py/karakeep-python-api)\n\nA community-developed Python client for the [Karakeep](https://karakeep.app/) API.\n\n**Disclaimer:** This is an unofficial, community-driven project. The developers of Karakeep were not consulted during its creation. Use at your own discretion.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Current Status \u0026 Caveats](#current-status--caveats)\n- [API Method Coverage](#api-method-coverage)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Environment Variables](#environment-variables)\n  - [Command Line Interface (CLI)](#command-line-interface-cli)\n  - [Python Library](#python-library)\n- [Community Scripts](#community-scripts)\n- [Development](#development)\n\n## Overview\n\nThis library provides a Python interface (both a class and a command-line tool) to interact with a Karakeep instance's API. The author also developed [freshrss_to_karakeep](https://github.com/thiswillbeyourgithub/freshrss_to_karakeep), a Python script that periodically sends FreshRSS \"favourite\" articles to Karakeep (a bookmarking and read-it-later app, see [Karakeep on GitHub](https://github.com/karakeep-app/karakeep)).\n\nThe development process involved:\n\n1.  Starting with the official Karakeep OpenAPI specification: [karakeep-openapi-spec.json](https://github.com/karakeep-app/karakeep/blob/main/packages/open-api/karakeep-openapi-spec.json).\n2.  Generating Pydantic data models from the specification using [datamodel-code-generator](https://koxudaxi.github.io/datamodel-code-generator/).\n3.  Using [aider.chat](https://aider.chat), an AI pair programming tool, to write the `KarakeepAPI` client class, the Click-based CLI, and the initial Pytest suite.\n\n## Current Status \u0026 Caveats\n\n*   **Experimental Methods:** The included Pytest suite currently only covers a subset of the available API methods (primarily 'get all' endpoints and client initialization). Methods *not* explicitly tested should be considered **experimental**.\n*   **Ongoing Development:** The author intends to improve and validate methods as they are needed for personal use cases. Contributions and bug reports are welcome!\n* **Updating process**: I have local scripts that downloads the latest OpenAPI specs from karakeep's repo. I then visually inspect the diff, stage a few changes into git, then run `aider --read karakeep_python_api/openapi_reference.json karakeep_python_api/karakeep_api.py karakeep_python_api/datatypes.py --message \"As you can see from the git diff output, there was a small update to the openapi reference json file. Please update the python code to match this new update. Here is the git output: $(git --no-pager diff --staged) \"`.\n\n## API Method Coverage\n\nThe following table lists the public methods available in the `KarakeepAPI` class.\n*   The \"Pytest\" column indicates whether the Python library method is covered by the automated test suite (`tests/test_karakeep_api.py`).\n*   The \"CLI\" column indicates whether the corresponding CLI command for that method is tested within the Pytest suite (typically via `subprocess`).\nMethods or CLI commands marked with ❌ should be used with caution as their behavior has not been automatically verified within the test suite.\n\n| Method Name                      | Pytest | CLI  | Remarks                                      |\n| -------------------------------- | :----: | :--: | -------------------------------------------- |\n| `get_all_bookmarks`              |   ✅   |  ✅  | Tested with pagination.                      |\n| `create_a_new_bookmark`          |   ✅   |  ❌  | Pytest for `type=\"link\"` via fixture and `type=\"asset\"` via PDF test. CLI not directly tested. |\n| `search_bookmarks`               |   ✅   |  ✅  | Seems to be nondeterministic and fails if using more than 3 words        |\n| `get_a_single_bookmark`          |   ✅   |  ❌  |  |\n| `delete_a_bookmark`              |   ✅   |  ❌  |  |\n| `update_a_bookmark`              |   ✅   |  ✅  | Tested for title updates.                    |\n| `summarize_a_bookmark`           |   ❌   |  ❌  |                                              |\n| `attach_tags_to_a_bookmark`      |   ✅   |  ❌  |  |\n| `detach_tags_from_a_bookmark`    |   ✅   |  ❌  |  |\n| `get_highlights_of_a_bookmark`   |   ❌   |  ❌  | Works from the CLI; not yet added to Pytest. |\n| `attach_asset`                   |   ❌   |  ❌  |                                              |\n| `replace_asset`                  |   ❌   |  ❌  |                                              |\n| `detach_asset`                   |   ❌   |  ❌  |                                              |\n| `get_all_lists`                  |   ✅   |  ✅  |                                              |\n| `create_a_new_list`              |   ✅   |  ❌  | |\n| `get_a_single_list`              |   ✅   |  ❌  | |\n| `delete_a_list`                  |   ✅   |  ❌  | |\n| `update_a_list`                  |   ❌   |  ❌  |                                              |\n| `get_bookmarks_in_the_list`      |   ❌   |  ❌  |                                              |\n| `add_a_bookmark_to_a_list`       |   ❌   |  ❌  |                                              |\n| `remove_a_bookmark_from_a_list`  |   ❌   |  ❌  |                                              |\n| `get_all_tags`                   |   ✅   |  ✅  |                                              |\n| `create_a_new_tag`               |   ❌   |  ❌  |                                              |\n| `get_a_single_tag`               |   ✅   |  ❌  |  |\n| `delete_a_tag`                   |   ✅   |  ❌  |  |\n| `update_a_tag`                   |   ✅   |  ❌  |  No output validation due to [server bug](https://github.com/karakeep-app/karakeep/issues/1365). |\n| `get_bookmarks_with_the_tag`   |   ❌   |  ❌  |                                              |\n| `get_all_highlights`             |   ✅   |  ✅  | Tested with pagination.                      |\n| `create_a_new_highlight`         |   ❌   |  ❌  |                                              |\n| `get_a_single_highlight`         |   ❌   |  ❌  |                                              |\n| `delete_a_highlight`             |   ❌   |  ❌  | Works from the CLI; not yet added to Pytest. |\n| `update_a_highlight`             |   ❌   |  ❌  |                                              |\n| `upload_a_new_asset`             |   ✅   |  ❌  | Tested in PDF asset lifecycle test.         |\n| `get_a_single_asset`             |   ✅   |  ❌  | Tested in PDF asset lifecycle test.         |\n| `get_current_user_info`          |   ✅   |  ❌  | Pytest: Tested indirectly during client init. CLI not directly tested. |\n| `get_current_user_stats`         |   ✅   |  ✅  |                                              |\n| `update_user`                    |   ❌   |  ❌  |                                              |\n| `get_all_backups`                |   ✅   |  ✅  | Tested in backup lifecycle test.            |\n| `trigger_a_new_backup`           |   ✅   |  ❌  | Tested in backup lifecycle test.            |\n| `get_a_single_backup`            |   ✅   |  ❌  | Tested in backup lifecycle test.            |\n| `delete_a_backup`                |   ✅   |  ❌  | Tested in backup lifecycle test.            |\n| `download_a_backup`              |   ✅   |  ❌  | Tested in backup lifecycle test.            |\n\n## Installation\n\nIt is recommended to use `uv` for faster installation:\n\n```bash\nuv pip install karakeep-python-api\n```\n\nAlternatively, use standard `pip`:\n\n```bash\npip install karakeep-python-api\n```\n\n## Usage\n\nThis package can be used as a Python library or as a command-line interface (CLI).\n\n### Environment Variables\n\nThe client can be configured using the following environment variables:\n\n*   `KARAKEEP_PYTHON_API_ENDPOINT`: **Required**. The full URL of your Karakeep API, including the `/api/v1/` path (e.g., `https://karakeep.domain.com/api/v1/` or `https://try.karakeep.app/api/v1/`).\n*   `KARAKEEP_PYTHON_API_KEY`: **Required**. Your Karakeep API key (Bearer token).\n*   `KARAKEEP_PYTHON_API_VERIFY_SSL`: Set to `false` to disable SSL certificate verification (default: `true`).\n*   `KARAKEEP_PYTHON_API_VERBOSE`: Set to `true` to enable verbose debug logging for the client and CLI (default: `false`).\n*   `KARAKEEP_PYTHON_API_DISABLE_RESPONSE_VALIDATION`: Set to `true` to disable Pydantic validation of API responses. The client will return raw dictionary/list data instead of Pydantic models (default: `false`).\n*   `KARAKEEP_PYTHON_API_ENSURE_ASCII`: Set to `true` to escape non-ASCII characters in the JSON output (default: `false`, which means Unicode characters are kept).\n\n### Command Line Interface (CLI)\n\nThe CLI dynamically generates commands based on the API methods. You need to provide your API key and endpoint either via environment variables (recommended) or command-line options.\n\n**Basic Structure:**\n\n```bash\npython -m karakeep_python_api [GLOBAL_OPTIONS] \u003cCOMMAND\u003e [COMMAND_OPTIONS]\n```\n\n**Getting Help:**\n\n```bash\n# General help and list of commands\npython -m karakeep_python_api --help\n\n# Help for a specific command\npython -m karakeep_python_api get-all-bookmarks --help\n```\n\n**Examples:**\n\n```bash\n# List all tags (requires env vars set)\npython -m karakeep_python_api get-all-tags\n\n# Get the first page of bookmarks with a limit, overriding env vars if needed\n# Note: The /api/v1/ path will be automatically appended if not present\npython -m karakeep_python_api --base-url https://karakeep.domain.com/api/v1/ --api-key YOUR_API_KEY get-all-bookmarks --limit 10\n\n# Get all lists and pipe the JSON output to jq to extract the first list\npython -m karakeep_python_api get-all-lists | jq '.[0]'\n\n# Create a new bookmark from a link (body provided as JSON string)\npython -m karakeep_python_api create-a-new-bookmark --data '{\"type\": \"link\", \"url\": \"https://example.com\"}'\n\n# Get all tags and ensure ASCII output (e.g., for compatibility with systems that don't handle Unicode well)\npython -m karakeep_python_api --ascii get-all-tags\n\n# Dump the raw OpenAPI spec used by the client\npython -m karakeep_python_api --dump-openapi-specification\n```\n\n### Python Library\n\nImport the `KarakeepAPI` class and instantiate it.\n\n```python\nimport os\nfrom karakeep_python_api import KarakeepAPI, APIError, AuthenticationError, datatypes\n\n# Ensure required environment variables are set\n# Example: os.environ[\"KARAKEEP_PYTHON_API_ENDPOINT\"] = \"https://karakeep.domain.com/api/v1/\"\n# Example: os.environ[\"KARAKEEP_PYTHON_API_KEY\"] = \"your_secret_api_key\"\n\ntry:\n    # Initialize the client (reads from env vars by default)\n    client = KarakeepAPI(\n        # Optionally override env vars:\n        # api_endpoint=\"https://karakeep.domain.com/api/v1/\",\n        # api_key=\"another_key\",\n        # verbose=True,\n        # disable_response_validation=False\n    )\n\n    # Example: Get all lists\n    all_lists = client.get_all_lists()\n    if all_lists:\n        print(f\"Retrieved {len(all_lists)} lists.\")\n        # Access list properties (uses Pydantic models by default)\n        print(f\"First list name: {all_lists[0].name}\")\n        print(f\"First list ID: {all_lists[0].id}\")\n    else:\n        print(\"No lists found.\")\n\n    # Example: Get first page of bookmarks\n    bookmarks_page = client.get_all_bookmarks(limit=5)\n    print(f\"\\nRetrieved {len(bookmarks_page.bookmarks)} bookmarks.\")\n    if bookmarks_page.bookmarks:\n        print(f\"First bookmark title: {bookmarks_page.bookmarks[0].title}\")\n    if bookmarks_page.nextCursor:\n        print(f\"Next page cursor: {bookmarks_page.nextCursor}\")\n\n\nexcept AuthenticationError as e:\n    print(f\"Authentication failed: {e}\")\nexcept APIError as e:\n    print(f\"An API error occurred: {e}\")\nexcept ValueError as e:\n    # Handles missing API key/endpoint during initialization\n    print(f\"Configuration error: {e}\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\n\n```\n\n## Community Scripts\n\nCommunity Scripts are a bunch of scripts made to solve specific issues. They are made by the community so don't hesitate to submit yours or open an issue if you have a bug. They also serve as example of how to use the API.\n\nThey can be found in the [./community_scripts](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts) folder. Don't hesitate to submit yours, the contribution guidelines are in the community_scripts directory README.md file.\n\n| Community Script | Description                                                                                                |\n|----------------|--------------------------------------------------------------------------------------------------------------|\n| [Karakeep-Time-Tagger](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/karakeep-time-tagger) | Automatically adds time-to-read tags (`0-5m`, `5-10m`, etc.) to bookmarks based on content length analysis. Includes systemd service and timer files for automated periodic execution. |\n| [Karakeep-List-To-Tag](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/karakeep-list-to-tag) | Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list.                                                                                        |\n| [Omnivore2Karakeep-Highlights](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/omnivore2karakeep-highlights) | Imports highlights from Omnivore export data to Karakeep, with intelligent position detection and bookmark matching. Supports dry-run mode for testing.                                |\n| [Omnivore2Karakeep-Archived](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/omnivore2karakeep-archived) | (Should not be needed anymore) Fixes the archived status of bookmarks imported from Omnivore by reading export data and updating Karakeep accordingly.                                 |\n| [pocket2karakeep-archived](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/pocket2karakeep-archived) by [@youenchene](https://github.com/youenchene) | (Should not be needed anymore) Fixes the archived status of bookmarks imported from Pocket by reading export data and updating Karakeep accordingly.                                   |\n| [Karakeep-Archive-Before-Date](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/karakeep-archive-before-date) by [@youenchene](https://github.com/youenchene) | Allow you to archive all not archived post before a given date                                                                                                                         |\n| [Freshrss-To-Karakeep](https://github.com/thiswillbeyourgithub/freshrss_to_karakeep)  |  Syncs some links from Freshrss to Karakeep      |\n| [Karanki (WIP)](https://github.com/thiswillbeyourgithub/Karanki)  |  Bidirectional sync between anki notes and highlights      |\n| [Karakeep-remove-ai-tags](https://github.com/thiswillbeyourgithub/karakeep_python_api/tree/main/community_scripts/karakeep-remove-ai-tags)  by [@youenchene](https://github.com/youenchene)                                                   | Remove all tags attached by AI and not human attached       |\n\n## Development\n\n1.  Clone the repository.\n2.  Create a virtual environment and activate it.\n3.  Install dependencies, including development tools (using `uv` recommended):\n\n    ```bash\n    uv pip install -e \".[dev]\"\n    ```\n4.  Set the required environment variables (`KARAKEEP_PYTHON_API_ENDPOINT`, `KARAKEEP_PYTHON_API_KEY`) for running tests against a live instance.\n5.  Run tests:\n\n    ```bash\n    pytest\n    ```\n\n\n---\n\n*This README was generated with assistance from [aider.chat](https://aider.chat).*\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthiswillbeyourgithub%2Fkarakeep_python_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthiswillbeyourgithub%2Fkarakeep_python_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthiswillbeyourgithub%2Fkarakeep_python_api/lists"}