Coverage for src/mcp_atlassian/confluence/search.py: 93%

29 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-10 03:26 +0900

1"""Module for Confluence search operations.""" 

2 

3import logging 

4 

5import requests 

6 

7from ..document_types import Document 

8from .client import ConfluenceClient 

9 

10logger = logging.getLogger("mcp-atlassian") 

11 

12 

13class SearchMixin(ConfluenceClient): 

14 """Mixin for Confluence search operations.""" 

15 

16 def search(self, cql: str, limit: int = 10) -> list[Document]: 

17 """ 

18 Search content using Confluence Query Language (CQL). 

19 

20 Args: 

21 cql: Confluence Query Language string 

22 limit: Maximum number of results to return 

23 

24 Returns: 

25 List of Document objects containing search results 

26 """ 

27 try: 

28 results = self.confluence.cql(cql=cql, limit=limit) 

29 documents = [] 

30 

31 for result in results.get("results", []): 

32 content = result.get("content", {}) 

33 if content.get("type") == "page": 

34 metadata = { 

35 "page_id": content["id"], 

36 "title": result["title"], 

37 "space": result.get("resultGlobalContainer", {}).get("title"), 

38 "url": f"{self.config.url}{result['url']}", 

39 "last_modified": result.get("lastModified"), 

40 "type": content["type"], 

41 } 

42 

43 # Use the excerpt as page_content since it's already a good summary 

44 documents.append( 

45 Document( 

46 page_content=result.get("excerpt", ""), metadata=metadata 

47 ) 

48 ) 

49 

50 return documents 

51 except KeyError as e: 

52 logger.error(f"Missing key in search results: {str(e)}") 

53 return [] 

54 except requests.RequestException as e: 

55 logger.error(f"Network error during search: {str(e)}") 

56 return [] 

57 except (ValueError, TypeError) as e: 

58 logger.error(f"Error processing search results: {str(e)}") 

59 return [] 

60 except Exception as e: # noqa: BLE001 - Intentional fallback with logging 

61 logger.error(f"Unexpected error during search: {str(e)}") 

62 logger.debug("Full exception details for search:", exc_info=True) 

63 return []