java_client.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import httpx
  2. from typing import Optional
  3. from app.config import settings
  4. import logging
  5. logger = logging.getLogger(__name__)
  6. class JavaClient:
  7. """Java 后端 HTTP 客户端 (单例, 复用连接池)"""
  8. _instance: Optional["JavaClient"] = None
  9. def __new__(cls):
  10. if cls._instance is None:
  11. cls._instance = super().__new__(cls)
  12. cls._instance._client = None
  13. cls._instance._base_url = settings.java_base_url
  14. return cls._instance
  15. async def _get_client(self) -> httpx.AsyncClient:
  16. if self._client is None:
  17. limits = httpx.Limits(
  18. max_connections=10,
  19. max_keepalive_connections=5,
  20. keepalive_expiry=30,
  21. )
  22. self._client = httpx.AsyncClient(
  23. base_url=self._base_url,
  24. timeout=httpx.Timeout(10.0, connect=3.0),
  25. limits=limits,
  26. )
  27. return self._client
  28. async def close(self):
  29. if self._client:
  30. await self._client.aclose()
  31. self._client = None
  32. JavaClient._instance = None
  33. async def get_published_articles(self) -> list[dict]:
  34. client = await self._get_client()
  35. resp = await client.post("/api/article/list", json={"status": "published", "limit": 1000})
  36. data = resp.json()
  37. if data.get("code") == 200:
  38. return data.get("data", [])
  39. return []
  40. async def search_products(self, keyword: str, limit: int = 5) -> list[dict]:
  41. client = await self._get_client()
  42. resp = await client.post("/api/product/search", json={
  43. "keyword": keyword, "status": "上架", "limit": limit
  44. })
  45. data = resp.json()
  46. if data.get("code") == 200:
  47. return data.get("data", [])
  48. return []
  49. async def search_activities(self, keyword: str, limit: int = 5) -> list[dict]:
  50. client = await self._get_client()
  51. resp = await client.post("/api/activity/search", json={
  52. "keyword": keyword, "status": "published", "limit": limit
  53. })
  54. data = resp.json()
  55. if data.get("code") == 200:
  56. return data.get("data", [])
  57. return []
  58. async def search_articles(self, keyword: str, limit: int = 5) -> list[dict]:
  59. client = await self._get_client()
  60. resp = await client.post("/api/article/search", json={
  61. "keyword": keyword, "status": "published", "limit": limit
  62. })
  63. data = resp.json()
  64. if data.get("code") == 200:
  65. return data.get("data", [])
  66. return []
  67. async def get_user_context(self, user_id: int, params: Optional[dict] = None) -> dict:
  68. client = await self._get_client()
  69. resp = await client.post(settings.effective_java_context_url, json={
  70. "user_id": str(user_id),
  71. "params": params or {},
  72. })
  73. data = resp.json()
  74. if data.get("code") == 200:
  75. return data.get("data", {})
  76. return {}