karakeep-python-api 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {karakeep_python_api-0.2.1/karakeep_python_api.egg-info → karakeep_python_api-0.2.3}/PKG-INFO +7 -2
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/README.md +6 -1
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/karakeep_api.py +81 -55
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3/karakeep_python_api.egg-info}/PKG-INFO +7 -2
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/setup.py +1 -1
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/tests/test_karakeep_api.py +2 -4
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/LICENSE +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/MANIFEST.in +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/__init__.py +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/__main__.py +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/datatypes.py +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/openapi_reference.json +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/SOURCES.txt +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/dependency_links.txt +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/entry_points.txt +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/requires.txt +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/top_level.txt +0 -0
- {karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/setup.cfg +0 -0
{karakeep_python_api-0.2.1/karakeep_python_api.egg-info → karakeep_python_api-0.2.3}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: karakeep_python_api
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Community python client for the Karakeep API.
|
|
5
5
|
Home-page: https://github.com/thiswillbeyourgithub/karakeep_python_api/
|
|
6
6
|
License: GPLv3
|
|
@@ -243,7 +243,12 @@ except Exception as e:
|
|
|
243
243
|
|
|
244
244
|
Examples of the API being used can be found in the [`./examples`](./examples) folder. Don't hesitate to submit yours!
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
| Example Script | Description | Documentation |
|
|
247
|
+
|----------------|-------------|---------------|
|
|
248
|
+
| **Add Time-to-Read Tags** | Automatically adds time-to-read tags (`0-5m`, `5-10m`, etc.) to bookmarks based on content length analysis. | [`README.md`](./examples/add_time_to_read_tag/README.md) |
|
|
249
|
+
| **List to Tag Converter** | Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list. | [`README.md`](./examples/list_to_tag/README.md) |
|
|
250
|
+
| **Omnivore Archiving Status Updater** | Fixes the archived status of bookmarks imported from Omnivore by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/omnivore_archiving_status_updater/README.md) |
|
|
251
|
+
| **Pocket Archiving Status Updater** | Fixes the archived status of bookmarks imported from Pocket by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/pocket_archiving_status_updater/README.md) |
|
|
247
252
|
|
|
248
253
|
## Development
|
|
249
254
|
|
|
@@ -208,7 +208,12 @@ except Exception as e:
|
|
|
208
208
|
|
|
209
209
|
Examples of the API being used can be found in the [`./examples`](./examples) folder. Don't hesitate to submit yours!
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
| Example Script | Description | Documentation |
|
|
212
|
+
|----------------|-------------|---------------|
|
|
213
|
+
| **Add Time-to-Read Tags** | Automatically adds time-to-read tags (`0-5m`, `5-10m`, etc.) to bookmarks based on content length analysis. | [`README.md`](./examples/add_time_to_read_tag/README.md) |
|
|
214
|
+
| **List to Tag Converter** | Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list. | [`README.md`](./examples/list_to_tag/README.md) |
|
|
215
|
+
| **Omnivore Archiving Status Updater** | Fixes the archived status of bookmarks imported from Omnivore by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/omnivore_archiving_status_updater/README.md) |
|
|
216
|
+
| **Pocket Archiving Status Updater** | Fixes the archived status of bookmarks imported from Pocket by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/pocket_archiving_status_updater/README.md) |
|
|
212
217
|
|
|
213
218
|
## Development
|
|
214
219
|
|
|
@@ -85,7 +85,7 @@ class KarakeepAPI:
|
|
|
85
85
|
"""
|
|
86
86
|
|
|
87
87
|
# Version reflects the client library version, updated by bumpver
|
|
88
|
-
VERSION: str = "0.2.
|
|
88
|
+
VERSION: str = "0.2.3"
|
|
89
89
|
|
|
90
90
|
def __init__(
|
|
91
91
|
self,
|
|
@@ -955,16 +955,18 @@ class KarakeepAPI:
|
|
|
955
955
|
|
|
956
956
|
@optional_typecheck
|
|
957
957
|
def attach_tags_to_a_bookmark(
|
|
958
|
-
self,
|
|
958
|
+
self,
|
|
959
|
+
bookmark_id: str,
|
|
960
|
+
tag_ids: Optional[List[str]] = None,
|
|
961
|
+
tag_names: Optional[List[str]] = None,
|
|
959
962
|
) -> Dict[str, Any]:
|
|
960
963
|
"""
|
|
961
964
|
Attach one or more tags to a bookmark. Corresponds to POST /bookmarks/{bookmarkId}/tags.
|
|
962
965
|
|
|
963
966
|
Args:
|
|
964
967
|
bookmark_id: The ID (string) of the bookmark.
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
Example: `{"tags": [{"tagId": "existing_tag_id"}, {"tagName": "new_or_existing_tag_name"}]}`
|
|
968
|
+
tag_ids: List of existing tag IDs to attach (optional).
|
|
969
|
+
tag_names: List of tag names to attach (will create tags if they don't exist) (optional).
|
|
968
970
|
|
|
969
971
|
Returns:
|
|
970
972
|
dict: A dictionary containing the list of attached tag IDs under the key "attached".
|
|
@@ -972,38 +974,49 @@ class KarakeepAPI:
|
|
|
972
974
|
Validation is not performed on this response type by default.
|
|
973
975
|
|
|
974
976
|
Raises:
|
|
975
|
-
ValueError: If
|
|
977
|
+
ValueError: If no tags are provided or if arguments are invalid.
|
|
976
978
|
APIError: If the API request fails (e.g., 404 bookmark not found).
|
|
977
979
|
"""
|
|
978
|
-
# Validate
|
|
979
|
-
if not
|
|
980
|
-
raise ValueError("
|
|
980
|
+
# Validate that at least one tag source is provided
|
|
981
|
+
if not tag_ids and not tag_names:
|
|
982
|
+
raise ValueError("At least one of 'tag_ids' or 'tag_names' must be provided")
|
|
981
983
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
+
# Validate input types
|
|
985
|
+
if tag_ids is not None and not isinstance(tag_ids, list):
|
|
986
|
+
raise ValueError("'tag_ids' must be a list of strings")
|
|
984
987
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
raise ValueError("The 'tags' value must be a list")
|
|
988
|
+
if tag_names is not None and not isinstance(tag_names, list):
|
|
989
|
+
raise ValueError("'tag_names' must be a list of strings")
|
|
988
990
|
|
|
989
|
-
# Validate
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
991
|
+
# Validate individual elements
|
|
992
|
+
if tag_ids:
|
|
993
|
+
for i, tag_id in enumerate(tag_ids):
|
|
994
|
+
if not isinstance(tag_id, str) or not tag_id.strip():
|
|
995
|
+
raise ValueError(f"Tag ID at index {i} must be a non-empty string")
|
|
993
996
|
|
|
994
|
-
|
|
995
|
-
|
|
997
|
+
if tag_names:
|
|
998
|
+
for i, tag_name in enumerate(tag_names):
|
|
999
|
+
if not isinstance(tag_name, str) or not tag_name.strip():
|
|
1000
|
+
raise ValueError(f"Tag name at index {i} must be a non-empty string")
|
|
996
1001
|
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1002
|
+
# Construct the tags_data dict in the format expected by the API
|
|
1003
|
+
tags_list = []
|
|
1004
|
+
|
|
1005
|
+
if tag_ids:
|
|
1006
|
+
for tag_id in tag_ids:
|
|
1007
|
+
tags_list.append({"tagId": tag_id.strip()})
|
|
1008
|
+
|
|
1009
|
+
if tag_names:
|
|
1010
|
+
for tag_name in tag_names:
|
|
1011
|
+
tags_list.append({"tagName": tag_name.strip()})
|
|
1001
1012
|
|
|
1002
|
-
|
|
1003
|
-
raise ValueError(f"Tag at index {i}: 'tagId' must be a string")
|
|
1013
|
+
tags_data = {"tags": tags_list}
|
|
1004
1014
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1015
|
+
# Optional validation using Tag datatype if validation is enabled
|
|
1016
|
+
if not self.disable_response_validation:
|
|
1017
|
+
# Validate the constructed structure matches expected format
|
|
1018
|
+
# This is primarily for development/debugging purposes
|
|
1019
|
+
logger.debug("Validating constructed tags_data structure")
|
|
1007
1020
|
|
|
1008
1021
|
endpoint = f"bookmarks/{bookmark_id}/tags"
|
|
1009
1022
|
response_data = self._call("POST", endpoint, data=tags_data)
|
|
@@ -1013,16 +1026,18 @@ class KarakeepAPI:
|
|
|
1013
1026
|
|
|
1014
1027
|
@optional_typecheck
|
|
1015
1028
|
def detach_tags_from_a_bookmark(
|
|
1016
|
-
self,
|
|
1029
|
+
self,
|
|
1030
|
+
bookmark_id: str,
|
|
1031
|
+
tag_ids: Optional[List[str]] = None,
|
|
1032
|
+
tag_names: Optional[List[str]] = None,
|
|
1017
1033
|
) -> Dict[str, Any]:
|
|
1018
1034
|
"""
|
|
1019
1035
|
Detach one or more tags from a bookmark. Corresponds to DELETE /bookmarks/{bookmarkId}/tags.
|
|
1020
1036
|
|
|
1021
1037
|
Args:
|
|
1022
1038
|
bookmark_id: The ID (string) of the bookmark.
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
Example: `{"tags": [{"tagId": "tag_id_to_remove"}, {"tagName": "tag_name_to_remove"}]}`
|
|
1039
|
+
tag_ids: List of existing tag IDs to detach (optional).
|
|
1040
|
+
tag_names: List of tag names to detach (optional).
|
|
1026
1041
|
|
|
1027
1042
|
Returns:
|
|
1028
1043
|
dict: A dictionary containing the list of detached tag IDs under the key "detached".
|
|
@@ -1030,38 +1045,49 @@ class KarakeepAPI:
|
|
|
1030
1045
|
Validation is not performed on this response type by default.
|
|
1031
1046
|
|
|
1032
1047
|
Raises:
|
|
1033
|
-
ValueError: If
|
|
1048
|
+
ValueError: If no tags are provided or if arguments are invalid.
|
|
1034
1049
|
APIError: If the API request fails (e.g., 404 bookmark not found).
|
|
1035
1050
|
"""
|
|
1036
|
-
# Validate
|
|
1037
|
-
if not
|
|
1038
|
-
raise ValueError("
|
|
1051
|
+
# Validate that at least one tag source is provided
|
|
1052
|
+
if not tag_ids and not tag_names:
|
|
1053
|
+
raise ValueError("At least one of 'tag_ids' or 'tag_names' must be provided")
|
|
1039
1054
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1055
|
+
# Validate input types
|
|
1056
|
+
if tag_ids is not None and not isinstance(tag_ids, list):
|
|
1057
|
+
raise ValueError("'tag_ids' must be a list of strings")
|
|
1042
1058
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
raise ValueError("The 'tags' value must be a list")
|
|
1059
|
+
if tag_names is not None and not isinstance(tag_names, list):
|
|
1060
|
+
raise ValueError("'tag_names' must be a list of strings")
|
|
1046
1061
|
|
|
1047
|
-
# Validate
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1062
|
+
# Validate individual elements
|
|
1063
|
+
if tag_ids:
|
|
1064
|
+
for i, tag_id in enumerate(tag_ids):
|
|
1065
|
+
if not isinstance(tag_id, str) or not tag_id.strip():
|
|
1066
|
+
raise ValueError(f"Tag ID at index {i} must be a non-empty string")
|
|
1051
1067
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1068
|
+
if tag_names:
|
|
1069
|
+
for i, tag_name in enumerate(tag_names):
|
|
1070
|
+
if not isinstance(tag_name, str) or not tag_name.strip():
|
|
1071
|
+
raise ValueError(f"Tag name at index {i} must be a non-empty string")
|
|
1054
1072
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1073
|
+
# Construct the tags_data dict in the format expected by the API
|
|
1074
|
+
tags_list = []
|
|
1075
|
+
|
|
1076
|
+
if tag_ids:
|
|
1077
|
+
for tag_id in tag_ids:
|
|
1078
|
+
tags_list.append({"tagId": tag_id.strip()})
|
|
1079
|
+
|
|
1080
|
+
if tag_names:
|
|
1081
|
+
for tag_name in tag_names:
|
|
1082
|
+
tags_list.append({"tagName": tag_name.strip()})
|
|
1059
1083
|
|
|
1060
|
-
|
|
1061
|
-
raise ValueError(f"Tag at index {i}: 'tagId' must be a string")
|
|
1084
|
+
tags_data = {"tags": tags_list}
|
|
1062
1085
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1086
|
+
# Optional validation using Tag datatype if validation is enabled
|
|
1087
|
+
if not self.disable_response_validation:
|
|
1088
|
+
# Validate the constructed structure matches expected format
|
|
1089
|
+
# This is primarily for development/debugging purposes
|
|
1090
|
+
logger.debug("Validating constructed tags_data structure")
|
|
1065
1091
|
|
|
1066
1092
|
endpoint = f"bookmarks/{bookmark_id}/tags"
|
|
1067
1093
|
response_data = self._call("DELETE", endpoint, data=tags_data)
|
{karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3/karakeep_python_api.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: karakeep_python_api
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Community python client for the Karakeep API.
|
|
5
5
|
Home-page: https://github.com/thiswillbeyourgithub/karakeep_python_api/
|
|
6
6
|
License: GPLv3
|
|
@@ -243,7 +243,12 @@ except Exception as e:
|
|
|
243
243
|
|
|
244
244
|
Examples of the API being used can be found in the [`./examples`](./examples) folder. Don't hesitate to submit yours!
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
| Example Script | Description | Documentation |
|
|
247
|
+
|----------------|-------------|---------------|
|
|
248
|
+
| **Add Time-to-Read Tags** | Automatically adds time-to-read tags (`0-5m`, `5-10m`, etc.) to bookmarks based on content length analysis. | [`README.md`](./examples/add_time_to_read_tag/README.md) |
|
|
249
|
+
| **List to Tag Converter** | Converts a Karakeep list into tags by adding a specified tag to all bookmarks within that list. | [`README.md`](./examples/list_to_tag/README.md) |
|
|
250
|
+
| **Omnivore Archiving Status Updater** | Fixes the archived status of bookmarks imported from Omnivore by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/omnivore_archiving_status_updater/README.md) |
|
|
251
|
+
| **Pocket Archiving Status Updater** | Fixes the archived status of bookmarks imported from Pocket by reading export data and updating Karakeep accordingly. | [`README.md`](./examples/pocket_archiving_status_updater/README.md) |
|
|
247
252
|
|
|
248
253
|
## Development
|
|
249
254
|
|
|
@@ -7,7 +7,7 @@ with open("README.md", "r") as readme:
|
|
|
7
7
|
|
|
8
8
|
setup(
|
|
9
9
|
name="karakeep_python_api",
|
|
10
|
-
version="0.2.
|
|
10
|
+
version="0.2.3",
|
|
11
11
|
description="Community python client for the Karakeep API.", # Simplified description
|
|
12
12
|
long_description=long_description,
|
|
13
13
|
long_description_content_type="text/markdown",
|
|
@@ -530,9 +530,8 @@ def test_tag_lifecycle_on_bookmark(karakeep_client: KarakeepAPI, managed_bookmar
|
|
|
530
530
|
try:
|
|
531
531
|
# 1. Attach a new tag by name to the bookmark
|
|
532
532
|
logger.info(f"\nAttempting to attach tag '{initial_tag_name}' to bookmark {bookmark_id}")
|
|
533
|
-
attach_payload = {"tags": [{"tagName": initial_tag_name}]}
|
|
534
533
|
attach_response = karakeep_client.attach_tags_to_a_bookmark(
|
|
535
|
-
bookmark_id=bookmark_id,
|
|
534
|
+
bookmark_id=bookmark_id, tag_names=[initial_tag_name]
|
|
536
535
|
)
|
|
537
536
|
assert "attached" in attach_response and len(attach_response["attached"]) == 1, \
|
|
538
537
|
"Failed to attach tag or response format incorrect"
|
|
@@ -563,9 +562,8 @@ def test_tag_lifecycle_on_bookmark(karakeep_client: KarakeepAPI, managed_bookmar
|
|
|
563
562
|
|
|
564
563
|
# 4. Detach the tag from the bookmark
|
|
565
564
|
logger.info(f"\nAttempting to detach tag {tag_id_to_manage} from bookmark {bookmark_id}")
|
|
566
|
-
detach_payload = {"tags": [{"tagId": tag_id_to_manage}]}
|
|
567
565
|
detach_response = karakeep_client.detach_tags_from_a_bookmark(
|
|
568
|
-
bookmark_id=bookmark_id,
|
|
566
|
+
bookmark_id=bookmark_id, tag_ids=[tag_id_to_manage]
|
|
569
567
|
)
|
|
570
568
|
assert "detached" in detach_response and tag_id_to_manage in detach_response["detached"], \
|
|
571
569
|
"Failed to detach tag or response format incorrect"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api/openapi_reference.json
RENAMED
|
File without changes
|
{karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/requires.txt
RENAMED
|
File without changes
|
{karakeep_python_api-0.2.1 → karakeep_python_api-0.2.3}/karakeep_python_api.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|