Source code for pihole_lib.lists

"""Pi-hole Lists API client."""

from pihole_lib.base import BasePiHoleAPIClient
from pihole_lib.models.lists import (
    AddListRequest,
    BatchDeleteItem,
    ListsResponse,
    ListType,
    PiHoleList,
    UpdateListRequest,
)
from pihole_lib.models.search import SearchResponse
from pihole_lib.utils import check_api_errors, make_pihole_request


[docs] class PiHoleLists(BasePiHoleAPIClient): """Pi-hole Lists API client. Handles domain list operations for blocklists and allowlists. Examples:: from pihole_lib import PiHoleClient, ListType with PiHoleClient("http://192.168.1.100", password="secret") as client: # Get all lists all_lists = client.lists.get_lists() # Add a blocklist client.lists.add_list( address="https://example.com/domains.txt", list_type=ListType.BLOCK, comment="Ad servers" ) # Search for domains results = client.lists.search_domains("example.com") """ BASE_URL = "/api/lists"
[docs] def get_lists( self, list_name: str | None = None, list_type: ListType | None = None, ) -> list[PiHoleList]: """Get Pi-hole domain lists. Args: list_name: Optional specific list name to retrieve. list_type: Optional list type filter (allow or block). Returns: List of PiHoleList objects. """ endpoint = f"{self.BASE_URL}/{list_name}" if list_name else self.BASE_URL params = {"type": list_type.value} if list_type else None response = make_pihole_request( self._client, "GET", endpoint, params=params, ) return ListsResponse.model_validate(response.json()).lists
[docs] def add_list( self, address: str, list_type: ListType, comment: str | None = None, groups: list[int] | None = None, enabled: bool = True, ) -> list[PiHoleList]: """Add a new domain list to Pi-hole. Args: address: Address of the list. list_type: Type of list (ALLOW or BLOCK). comment: Optional comment for this list. groups: Group IDs to assign (defaults to [0]). enabled: Whether the list should be enabled (defaults to True). Returns: List of PiHoleList objects containing the created list. """ request_data = AddListRequest( address=address, comment=comment, groups=groups or [0], enabled=enabled, ) response = make_pihole_request( self._client, "POST", self.BASE_URL, params={"type": list_type.value}, json=request_data.model_dump(exclude_none=True), ) response_data = response.json() check_api_errors(response_data, address, "add list") return ListsResponse.model_validate(response_data).lists
[docs] def delete_list(self, address: str, list_type: ListType) -> bool: """Delete a domain list from Pi-hole. Args: address: Address of the list to delete. list_type: Type of list (ALLOW or BLOCK). Returns: True if the list was successfully deleted. """ response = make_pihole_request( self._client, "DELETE", f"{self.BASE_URL}/{address}", params={"type": list_type.value}, ) return bool(response.status_code == 204)
[docs] def batch_delete_lists(self, items: list[BatchDeleteItem]) -> bool: """Delete multiple domain lists from Pi-hole. Args: items: List of BatchDeleteItem objects specifying lists to delete. Returns: True if all lists were successfully deleted. """ items_data = [item.model_dump() for item in items] response = make_pihole_request( self._client, "POST", f"{self.BASE_URL}:batchDelete", json=items_data, ) return bool(response.status_code == 204)
[docs] def update_list( self, address: str, list_type: ListType, comment: str | None = None, groups: list[int] | None = None, enabled: bool = True, ) -> ListsResponse: """Update an existing domain list in Pi-hole. Args: address: Address of the list to update. list_type: Type of list (ALLOW or BLOCK). comment: Optional comment for this list. groups: Group IDs to assign (defaults to [0]). enabled: Whether the list should be enabled (defaults to True). Returns: ListsResponse with the updated list and processing results. """ request_data = UpdateListRequest( comment=comment, type=list_type, groups=groups or [0], enabled=enabled, ) response = make_pihole_request( self._client, "PUT", f"{self.BASE_URL}/{address}", params={"type": list_type.value}, json=request_data.model_dump(exclude_none=True), ) response_data = response.json() check_api_errors(response_data, address, "update list") return ListsResponse.model_validate(response_data)
[docs] def search_domains( self, domain: str, partial: bool = False, max_results: int = 20, debug: bool = False, ) -> SearchResponse: """Search for domains in Pi-hole's lists. Args: domain: Domain (or part of domain) to search for. partial: Whether to enable partial matching (defaults to False). max_results: Maximum number of results (defaults to 20). debug: Whether to include debug information (defaults to False). Returns: SearchResponse with search results and metadata. """ params = {"partial": partial, "N": max_results, "debug": debug} response = make_pihole_request( self._client, "GET", f"/api/search/{domain}", params=params, ) return SearchResponse.model_validate(response.json())