karakeep-python-api 1.3.0__tar.gz → 1.3.1__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.
Files changed (18) hide show
  1. {karakeep_python_api-1.3.0/karakeep_python_api.egg-info → karakeep_python_api-1.3.1}/PKG-INFO +1 -1
  2. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api/karakeep_api.py +4 -2
  3. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1/karakeep_python_api.egg-info}/PKG-INFO +1 -1
  4. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/setup.py +1 -1
  5. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/tests/test_karakeep_api.py +93 -93
  6. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/LICENSE +0 -0
  7. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/MANIFEST.in +0 -0
  8. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/README.md +0 -0
  9. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api/__init__.py +0 -0
  10. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api/__main__.py +0 -0
  11. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api/datatypes.py +0 -0
  12. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api/openapi_reference.json +0 -0
  13. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api.egg-info/SOURCES.txt +0 -0
  14. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api.egg-info/dependency_links.txt +0 -0
  15. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api.egg-info/entry_points.txt +0 -0
  16. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api.egg-info/requires.txt +0 -0
  17. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/karakeep_python_api.egg-info/top_level.txt +0 -0
  18. {karakeep_python_api-1.3.0 → karakeep_python_api-1.3.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: karakeep_python_api
3
- Version: 1.3.0
3
+ Version: 1.3.1
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
@@ -85,7 +85,7 @@ class KarakeepAPI:
85
85
  """
86
86
 
87
87
  # Version reflects the client library version, updated by bumpver
88
- VERSION: str = "1.3.0"
88
+ VERSION: str = "1.3.1"
89
89
 
90
90
  def __init__(
91
91
  self,
@@ -932,7 +932,9 @@ class KarakeepAPI:
932
932
 
933
933
  @optional_typecheck
934
934
  def get_a_single_bookmark(
935
- self, bookmark_id: str, include_content: bool = True # Default from spec
935
+ self,
936
+ bookmark_id: str,
937
+ include_content: bool = True, # Default from spec
936
938
  ) -> Union[datatypes.Bookmark, Dict[str, Any], List[Any]]:
937
939
  """
938
940
  Get a single bookmark by its ID. Corresponds to GET /bookmarks/{bookmarkId}.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: karakeep_python_api
3
- Version: 1.3.0
3
+ Version: 1.3.1
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
@@ -7,7 +7,7 @@ with open("README.md", "r") as readme:
7
7
 
8
8
  setup(
9
9
  name="karakeep_python_api",
10
- version="1.3.0",
10
+ version="1.3.1",
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",
@@ -21,9 +21,9 @@ def test_get_all_bookmarks_paginated(karakeep_client: KarakeepAPI):
21
21
  try:
22
22
  # Get the first page
23
23
  page1 = karakeep_client.get_all_bookmarks(limit=2)
24
- assert isinstance(
25
- page1, datatypes.PaginatedBookmarks
26
- ), "Response should be PaginatedBookmarks model"
24
+ assert isinstance(page1, datatypes.PaginatedBookmarks), (
25
+ "Response should be PaginatedBookmarks model"
26
+ )
27
27
  assert isinstance(page1.bookmarks, list), "Bookmarks attribute should be a list"
28
28
  assert len(page1.bookmarks) <= 2, "Should return at most 'limit' bookmarks"
29
29
  logger.info(f"✓ Retrieved first page with {len(page1.bookmarks)} bookmarks.")
@@ -42,9 +42,9 @@ def test_get_all_bookmarks_paginated(karakeep_client: KarakeepAPI):
42
42
  )
43
43
  # Ensure bookmarks are different from page 1 (simple check)
44
44
  if page1.bookmarks and page2.bookmarks:
45
- assert (
46
- page1.bookmarks[0].id != page2.bookmarks[0].id
47
- ), "Bookmarks on page 1 and 2 should differ"
45
+ assert page1.bookmarks[0].id != page2.bookmarks[0].id, (
46
+ "Bookmarks on page 1 and 2 should differ"
47
+ )
48
48
  else:
49
49
  logger.info(" No next cursor found, pagination test ends.")
50
50
 
@@ -83,9 +83,9 @@ def test_get_all_lists(karakeep_client: KarakeepAPI):
83
83
  lists = karakeep_client.get_all_lists()
84
84
  assert isinstance(lists, list), "Response should be a list"
85
85
  if lists: # Only check elements if the list is not empty
86
- assert all(
87
- isinstance(item, datatypes.ListModel) for item in lists
88
- ), "All items should be ListModel instances"
86
+ assert all(isinstance(item, datatypes.ListModel) for item in lists), (
87
+ "All items should be ListModel instances"
88
+ )
89
89
  logger.info(f"✓ Successfully retrieved {len(lists)} lists.")
90
90
  except (APIError, AuthenticationError) as e:
91
91
  pytest.fail(f"API error during list retrieval: {e}")
@@ -118,15 +118,15 @@ def test_get_all_tags(karakeep_client: KarakeepAPI):
118
118
  """Test retrieving all tags."""
119
119
  try:
120
120
  tags = karakeep_client.get_all_tags()
121
- assert isinstance(
122
- tags, datatypes.PaginatedTags
123
- ), "Response should be of type PaginatedTags"
121
+ assert isinstance(tags, datatypes.PaginatedTags), (
122
+ "Response should be of type PaginatedTags"
123
+ )
124
124
  tags = tags.tags
125
125
  assert isinstance(tags, list), "tags var should be of type list at this point"
126
126
  if tags: # Only check elements if the list is not empty
127
- assert all(
128
- isinstance(item, datatypes.Tag) for item in tags
129
- ), "All items should be Tag instances"
127
+ assert all(isinstance(item, datatypes.Tag) for item in tags), (
128
+ "All items should be Tag instances"
129
+ )
130
130
  logger.info(f"✓ Successfully retrieved {len(tags)} tags.")
131
131
  except (APIError, AuthenticationError) as e:
132
132
  pytest.fail(f"API error during tag retrieval: {e}")
@@ -160,12 +160,12 @@ def test_get_all_highlights_paginated(karakeep_client: KarakeepAPI):
160
160
  try:
161
161
  # Get the first page
162
162
  page1 = karakeep_client.get_all_highlights(limit=3)
163
- assert isinstance(
164
- page1, datatypes.PaginatedHighlights
165
- ), "Response should be PaginatedHighlights model"
166
- assert isinstance(
167
- page1.highlights, list
168
- ), "Highlights attribute should be a list"
163
+ assert isinstance(page1, datatypes.PaginatedHighlights), (
164
+ "Response should be PaginatedHighlights model"
165
+ )
166
+ assert isinstance(page1.highlights, list), (
167
+ "Highlights attribute should be a list"
168
+ )
169
169
  assert len(page1.highlights) <= 3, "Should return at most 'limit' highlights"
170
170
  logger.info(f"✓ Retrieved first page with {len(page1.highlights)} highlights.")
171
171
 
@@ -183,9 +183,9 @@ def test_get_all_highlights_paginated(karakeep_client: KarakeepAPI):
183
183
  )
184
184
  # Ensure highlights are different from page 1 (simple check)
185
185
  if page1.highlights and page2.highlights:
186
- assert (
187
- page1.highlights[0].id != page2.highlights[0].id
188
- ), "Highlights on page 1 and 2 should differ"
186
+ assert page1.highlights[0].id != page2.highlights[0].id, (
187
+ "Highlights on page 1 and 2 should differ"
188
+ )
189
189
  else:
190
190
  logger.info(" No next cursor found, pagination test ends.")
191
191
 
@@ -228,9 +228,9 @@ def test_openapi_spec_accessible(karakeep_client: KarakeepAPI):
228
228
  assert spec is not None, "openapi_spec attribute should not be None"
229
229
  assert isinstance(spec, dict), "openapi_spec should be a dictionary"
230
230
  # Check for a top-level key expected in an OpenAPI spec
231
- assert (
232
- "openapi" in spec
233
- ), "openapi_spec should contain the 'openapi' version key"
231
+ assert "openapi" in spec, (
232
+ "openapi_spec should contain the 'openapi' version key"
233
+ )
234
234
  logger.info(
235
235
  f"✓ Successfully accessed openapi_spec attribute. Version: {spec.get('openapi', 'N/A')}"
236
236
  )
@@ -288,9 +288,9 @@ def test_create_and_delete_list(karakeep_client: KarakeepAPI):
288
288
  created_list = karakeep_client.create_a_new_list(
289
289
  name=list_name, icon=list_icon, list_type="manual"
290
290
  )
291
- assert isinstance(
292
- created_list, datatypes.ListModel
293
- ), "Response should be a ListModel"
291
+ assert isinstance(created_list, datatypes.ListModel), (
292
+ "Response should be a ListModel"
293
+ )
294
294
  assert created_list.name == list_name, "Created list name should match"
295
295
  assert created_list.icon == list_icon, "Created list icon should match"
296
296
  assert created_list.id, "Created list must have an ID"
@@ -299,12 +299,12 @@ def test_create_and_delete_list(karakeep_client: KarakeepAPI):
299
299
 
300
300
  # 4. Verify the list appears in get_all_lists
301
301
  current_lists_after_create = karakeep_client.get_all_lists()
302
- assert (
303
- len(current_lists_after_create) == initial_list_count + 1
304
- ), "List count should increase by one after creation"
305
- assert any(
306
- lst.id == created_list_id for lst in current_lists_after_create
307
- ), "Created list should be present in the list of all lists"
302
+ assert len(current_lists_after_create) == initial_list_count + 1, (
303
+ "List count should increase by one after creation"
304
+ )
305
+ assert any(lst.id == created_list_id for lst in current_lists_after_create), (
306
+ "Created list should be present in the list of all lists"
307
+ )
308
308
  logger.info(f" List count after creation: {len(current_lists_after_create)}")
309
309
  logger.info(f"✓ Verified list {created_list_id} is present in get_all_lists.")
310
310
 
@@ -335,21 +335,21 @@ def test_create_and_delete_list(karakeep_client: KarakeepAPI):
335
335
  f"List with ID {created_list_id} should not exist after deletion, but get_a_single_list succeeded."
336
336
  )
337
337
  except APIError as e:
338
- assert (
339
- e.status_code == 404
340
- ), f"Expected 404 Not Found when getting deleted list, but got status {e.status_code}"
338
+ assert e.status_code == 404, (
339
+ f"Expected 404 Not Found when getting deleted list, but got status {e.status_code}"
340
+ )
341
341
  logger.info(
342
342
  f"✓ Confirmed list {created_list_id} is deleted (received 404)."
343
343
  )
344
344
 
345
345
  # 8. Verify list count decreased (optional check)
346
346
  final_lists = karakeep_client.get_all_lists()
347
- assert (
348
- len(final_lists) == initial_list_count
349
- ), "List count should return to initial count after deletion"
350
- assert not any(
351
- lst.id == created_list_id for lst in final_lists
352
- ), "Deleted list should not be present in the final list of all lists"
347
+ assert len(final_lists) == initial_list_count, (
348
+ "List count should return to initial count after deletion"
349
+ )
350
+ assert not any(lst.id == created_list_id for lst in final_lists), (
351
+ "Deleted list should not be present in the final list of all lists"
352
+ )
353
353
  logger.info(f" Final list count: {len(final_lists)}")
354
354
 
355
355
  except (APIError, AuthenticationError) as e:
@@ -414,12 +414,12 @@ def test_create_and_delete_bookmark(
414
414
  search_results = karakeep_client.search_bookmarks(
415
415
  q=search_query_component, limit=100, include_content=False
416
416
  )
417
- assert isinstance(
418
- search_results, datatypes.PaginatedBookmarks
419
- ), "Search response should be PaginatedBookmarks model"
420
- assert isinstance(
421
- search_results.bookmarks, list
422
- ), "Search results bookmarks attribute should be a list"
417
+ assert isinstance(search_results, datatypes.PaginatedBookmarks), (
418
+ "Search response should be PaginatedBookmarks model"
419
+ )
420
+ assert isinstance(search_results.bookmarks, list), (
421
+ "Search results bookmarks attribute should be a list"
422
+ )
423
423
 
424
424
  titles_in_search = [b.title for b in search_results.bookmarks]
425
425
  found_in_search = any(
@@ -429,9 +429,9 @@ def test_create_and_delete_bookmark(
429
429
  break
430
430
  else:
431
431
  time.sleep(3)
432
- assert (
433
- found_in_search
434
- ), f"Managed bookmark {created_bookmark_id} (Title: '{original_title}') not found in {trial + 1} different search results for '{search_query_component}'. Titles were: '{titles_in_search}'."
432
+ assert found_in_search, (
433
+ f"Managed bookmark {created_bookmark_id} (Title: '{original_title}') not found in {trial + 1} different search results for '{search_query_component}'. Titles were: '{titles_in_search}'."
434
+ )
435
435
  logger.info(
436
436
  f"✓ Found managed bookmark in search results for '{search_query_component}'."
437
437
  )
@@ -449,9 +449,9 @@ def test_create_and_delete_bookmark(
449
449
  capture_output=True,
450
450
  text=True,
451
451
  )
452
- assert (
453
- created_bookmark_id in search_cli_output.stdout
454
- ), f"Managed bookmark ID {created_bookmark_id} not found in CLI search output for '{search_query_component}'"
452
+ assert created_bookmark_id in search_cli_output.stdout, (
453
+ f"Managed bookmark ID {created_bookmark_id} not found in CLI search output for '{search_query_component}'"
454
+ )
455
455
  logger.info(
456
456
  "✓ CLI search command executed successfully and contained the bookmark ID."
457
457
  )
@@ -502,12 +502,12 @@ def test_update_bookmark_title(
502
502
  updated_bookmark_partial = karakeep_client.update_a_bookmark(
503
503
  bookmark_id=created_bookmark_id, update_data=update_payload_api
504
504
  )
505
- assert isinstance(
506
- updated_bookmark_partial, dict
507
- ), "Update response should be a dict"
508
- assert (
509
- updated_bookmark_partial.get("title") == target_api_title
510
- ), f"Partial response title '{updated_bookmark_partial.get('title')}' does not match target API title '{target_api_title}'"
505
+ assert isinstance(updated_bookmark_partial, dict), (
506
+ "Update response should be a dict"
507
+ )
508
+ assert updated_bookmark_partial.get("title") == target_api_title, (
509
+ f"Partial response title '{updated_bookmark_partial.get('title')}' does not match target API title '{target_api_title}'"
510
+ )
511
511
  logger.info(
512
512
  f"✓ API call to update_a_bookmark successful. Partial response title: '{updated_bookmark_partial.get('title')}'"
513
513
  )
@@ -520,9 +520,9 @@ def test_update_bookmark_title(
520
520
  bookmark_id=created_bookmark_id
521
521
  )
522
522
  assert isinstance(retrieved_bookmark_after_api_update, datatypes.Bookmark)
523
- assert (
524
- retrieved_bookmark_after_api_update.title == target_api_title
525
- ), f"Retrieved bookmark title '{retrieved_bookmark_after_api_update.title}' does not match expected API-updated title '{target_api_title}'"
523
+ assert retrieved_bookmark_after_api_update.title == target_api_title, (
524
+ f"Retrieved bookmark title '{retrieved_bookmark_after_api_update.title}' does not match expected API-updated title '{target_api_title}'"
525
+ )
526
526
  logger.info(
527
527
  f"✓ Successfully verified bookmark title updated by API to: '{retrieved_bookmark_after_api_update.title}'"
528
528
  )
@@ -553,9 +553,9 @@ def test_update_bookmark_title(
553
553
  bookmark_id=created_bookmark_id
554
554
  )
555
555
  assert isinstance(retrieved_bookmark_after_cli_update, datatypes.Bookmark)
556
- assert (
557
- retrieved_bookmark_after_cli_update.title == target_cli_title
558
- ), f"Retrieved bookmark title '{retrieved_bookmark_after_cli_update.title}' after CLI update does not match expected '{target_cli_title}'"
556
+ assert retrieved_bookmark_after_cli_update.title == target_cli_title, (
557
+ f"Retrieved bookmark title '{retrieved_bookmark_after_cli_update.title}' after CLI update does not match expected '{target_cli_title}'"
558
+ )
559
559
  logger.info(
560
560
  f"✓ Successfully verified bookmark title updated by CLI to: '{retrieved_bookmark_after_cli_update.title}'"
561
561
  )
@@ -621,9 +621,9 @@ def test_tag_lifecycle_on_bookmark(
621
621
  # assert isinstance(updated_tag, datatypes.Tag), "Update tag response should be Tag model"
622
622
  # assert updated_tag.name == updated_tag_name, "Tag name was not updated as expected"
623
623
  # logger.info(f"✓ Tag {tag_id_to_manage} updated to name '{updated_tag.name}'")
624
- assert (
625
- updated_tag["name"] == updated_tag_name
626
- ), "Tag name was not updated as expected"
624
+ assert updated_tag["name"] == updated_tag_name, (
625
+ "Tag name was not updated as expected"
626
+ )
627
627
  logger.info(f"✓ Tag {tag_id_to_manage} updated to name '{updated_tag['name']}'")
628
628
 
629
629
  # 3. Verify tag update by getting it directly
@@ -631,12 +631,12 @@ def test_tag_lifecycle_on_bookmark(
631
631
  f"\nFetching tag {tag_id_to_manage} to verify its name is '{updated_tag_name}'"
632
632
  )
633
633
  retrieved_tag = karakeep_client.get_a_single_tag(tag_id=tag_id_to_manage)
634
- assert isinstance(
635
- retrieved_tag, datatypes.Tag
636
- ), "Get single tag response should be Tag model"
637
- assert (
638
- retrieved_tag.name == updated_tag_name
639
- ), "Retrieved tag name does not match updated name"
634
+ assert isinstance(retrieved_tag, datatypes.Tag), (
635
+ "Get single tag response should be Tag model"
636
+ )
637
+ assert retrieved_tag.name == updated_tag_name, (
638
+ "Retrieved tag name does not match updated name"
639
+ )
640
640
  assert retrieved_tag.id == tag_id_to_manage, "Retrieved tag ID does not match"
641
641
  logger.info(
642
642
  f"✓ Verified tag {tag_id_to_manage} has name '{retrieved_tag.name}'"
@@ -674,9 +674,9 @@ def test_tag_lifecycle_on_bookmark(
674
674
  f"Tag {tag_id_to_manage} should not exist after deletion, but get_a_single_tag succeeded."
675
675
  )
676
676
  except APIError as e:
677
- assert (
678
- e.status_code == 404
679
- ), f"Expected 404 Not Found when getting deleted tag, but got status {e.status_code}"
677
+ assert e.status_code == 404, (
678
+ f"Expected 404 Not Found when getting deleted tag, but got status {e.status_code}"
679
+ )
680
680
  logger.info(
681
681
  f"✓ Confirmed tag {tag_id_to_manage} is deleted (received 404)."
682
682
  )
@@ -729,9 +729,9 @@ def test_cli_get_bookmarks_count_with_jq(karakeep_client: KarakeepAPI):
729
729
  logger.info(f"✓ Command returned {actual_count} bookmarks")
730
730
 
731
731
  # Check if we got exactly the requested number or fewer (if there aren't enough bookmarks)
732
- assert (
733
- actual_count <= test_limit
734
- ), f"Expected at most {test_limit} bookmarks, got {actual_count}"
732
+ assert actual_count <= test_limit, (
733
+ f"Expected at most {test_limit} bookmarks, got {actual_count}"
734
+ )
735
735
 
736
736
  # Check if we got any bookmarks at all (to ensure the test is meaningful)
737
737
  # This could fail if the account has no bookmarks
@@ -825,9 +825,9 @@ def test_asset_lifecycle_with_pdf(karakeep_client: KarakeepAPI):
825
825
  assert isinstance(uploaded_asset, datatypes.Asset)
826
826
  assert uploaded_asset.assetId, "Uploaded asset must have an ID"
827
827
  assert "pdf" in uploaded_asset.contentType.lower(), "Asset should be PDF type"
828
- assert (
829
- uploaded_asset.fileName == "PDF Bookmark Sample.pdf"
830
- ), "Asset filename should match the original file"
828
+ assert uploaded_asset.fileName == "PDF Bookmark Sample.pdf", (
829
+ "Asset filename should match the original file"
830
+ )
831
831
  uploaded_asset_id = uploaded_asset.assetId
832
832
  logger.info(f"✓ PDF uploaded with asset ID: {uploaded_asset_id}")
833
833
 
@@ -852,15 +852,15 @@ def test_asset_lifecycle_with_pdf(karakeep_client: KarakeepAPI):
852
852
  bookmark_id=created_bookmark_id
853
853
  )
854
854
  assert isinstance(retrieved_bookmark, datatypes.Bookmark)
855
- assert (
856
- len(retrieved_bookmark.assets) > 0
857
- ), "Bookmark should have at least one asset"
855
+ assert len(retrieved_bookmark.assets) > 0, (
856
+ "Bookmark should have at least one asset"
857
+ )
858
858
 
859
859
  # Check that our uploaded asset is among the bookmark's assets
860
860
  asset_ids = [asset.id for asset in retrieved_bookmark.assets]
861
- assert (
862
- uploaded_asset_id in asset_ids
863
- ), f"Uploaded asset {uploaded_asset_id} should be attached to bookmark"
861
+ assert uploaded_asset_id in asset_ids, (
862
+ f"Uploaded asset {uploaded_asset_id} should be attached to bookmark"
863
+ )
864
864
  logger.info(f"✓ Verified bookmark contains the PDF asset {uploaded_asset_id}")
865
865
 
866
866
  # 4. Retrieve and verify the asset content