abs_client.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import httpx
  2. from typing import List, Dict, Any
  3. from app.config import get_settings
  4. class AudiobookshelfClient:
  5. """Client for interacting with Audiobookshelf API."""
  6. def __init__(self, abs_url: str, api_token: str):
  7. """
  8. Initialize Audiobookshelf client with credentials.
  9. Args:
  10. abs_url: Base URL of Audiobookshelf server
  11. api_token: API token for authentication (unencrypted)
  12. """
  13. self.base_url = abs_url.rstrip("/")
  14. self.api_token = api_token
  15. self.headers = {"Authorization": f"Bearer {self.api_token}"}
  16. async def get_libraries(self) -> List[Dict[str, Any]]:
  17. """Get all libraries from Audiobookshelf."""
  18. async with httpx.AsyncClient() as client:
  19. response = await client.get(
  20. f"{self.base_url}/api/libraries", headers=self.headers
  21. )
  22. response.raise_for_status()
  23. return response.json().get("libraries", [])
  24. async def get_library_items(self, library_id: str) -> List[Dict[str, Any]]:
  25. """Get all items in a library."""
  26. async with httpx.AsyncClient() as client:
  27. response = await client.get(
  28. f"{self.base_url}/api/libraries/{library_id}/items",
  29. headers=self.headers,
  30. )
  31. response.raise_for_status()
  32. return response.json().get("results", [])
  33. async def get_user_listening_sessions(self) -> List[Dict[str, Any]]:
  34. """Get user's listening sessions."""
  35. async with httpx.AsyncClient() as client:
  36. response = await client.get(
  37. f"{self.base_url}/api/me/listening-sessions", headers=self.headers
  38. )
  39. response.raise_for_status()
  40. return response.json().get("sessions", [])
  41. async def get_user_progress(self) -> List[Dict[str, Any]]:
  42. """Get user's items in progress."""
  43. async with httpx.AsyncClient() as client:
  44. response = await client.get(
  45. f"{self.base_url}/api/me/items-in-progress", headers=self.headers
  46. )
  47. response.raise_for_status()
  48. # The response is an array of library items with progress
  49. result = response.json()
  50. return result.get("libraryItems", result if isinstance(result, list) else [])
  51. async def get_item_details(self, item_id: str) -> Dict[str, Any]:
  52. """Get detailed information about a specific library item."""
  53. async with httpx.AsyncClient() as client:
  54. response = await client.get(
  55. f"{self.base_url}/api/items/{item_id}", headers=self.headers
  56. )
  57. response.raise_for_status()
  58. return response.json()
  59. async def get_user_info(self) -> Dict[str, Any]:
  60. """Get current user information."""
  61. async with httpx.AsyncClient() as client:
  62. response = await client.get(
  63. f"{self.base_url}/api/me", headers=self.headers
  64. )
  65. response.raise_for_status()
  66. return response.json()
  67. def get_abs_client(user) -> AudiobookshelfClient:
  68. """
  69. Create an Audiobookshelf client for a specific user.
  70. Args:
  71. user: User model instance with abs_url and abs_api_token
  72. Returns:
  73. Configured AudiobookshelfClient instance
  74. """
  75. from app.auth import decrypt_token
  76. # Decrypt the user's API token
  77. decrypted_token = decrypt_token(user.abs_api_token)
  78. return AudiobookshelfClient(
  79. abs_url=user.abs_url,
  80. api_token=decrypted_token
  81. )