feat(espocrm): Implement automatic pagination for related records and enforce API max page size
This commit is contained in:
@@ -331,6 +331,9 @@ class EspoCRMAPI:
|
||||
params=self._flatten_params(search_params)
|
||||
)
|
||||
|
||||
# EspoCRM API-User limit: maxSize ≥ 500 → 403 Access forbidden
|
||||
ESPOCRM_MAX_PAGE_SIZE = 200
|
||||
|
||||
async def list_related(
|
||||
self,
|
||||
entity_type: str,
|
||||
@@ -343,9 +346,11 @@ class EspoCRMAPI:
|
||||
offset: int = 0,
|
||||
max_size: int = 50
|
||||
) -> Dict[str, Any]:
|
||||
# Clamp max_size to avoid 403 from EspoCRM permission limit
|
||||
safe_size = min(max_size, self.ESPOCRM_MAX_PAGE_SIZE)
|
||||
search_params: Dict[str, Any] = {
|
||||
'offset': offset,
|
||||
'maxSize': max_size,
|
||||
'maxSize': safe_size,
|
||||
}
|
||||
if where:
|
||||
search_params['where'] = where
|
||||
@@ -362,6 +367,39 @@ class EspoCRMAPI:
|
||||
params=self._flatten_params(search_params)
|
||||
)
|
||||
|
||||
async def list_related_all(
|
||||
self,
|
||||
entity_type: str,
|
||||
entity_id: str,
|
||||
link: str,
|
||||
where: Optional[List[Dict]] = None,
|
||||
select: Optional[str] = None,
|
||||
order_by: Optional[str] = None,
|
||||
order: Optional[str] = None,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""Fetch ALL related records via automatic pagination (safe page size)."""
|
||||
page_size = self.ESPOCRM_MAX_PAGE_SIZE
|
||||
offset = 0
|
||||
all_records: List[Dict[str, Any]] = []
|
||||
|
||||
while True:
|
||||
result = await self.list_related(
|
||||
entity_type, entity_id, link,
|
||||
where=where, select=select,
|
||||
order_by=order_by, order=order,
|
||||
offset=offset, max_size=page_size
|
||||
)
|
||||
page = result.get('list', [])
|
||||
all_records.extend(page)
|
||||
total = result.get('total', len(all_records))
|
||||
|
||||
if len(all_records) >= total or len(page) < page_size:
|
||||
break
|
||||
offset += page_size
|
||||
|
||||
self._log(f"list_related_all {entity_type}/{entity_id}/{link}: {len(all_records)}/{total} records")
|
||||
return all_records
|
||||
|
||||
async def create_entity(
|
||||
self,
|
||||
entity_type: str,
|
||||
|
||||
Reference in New Issue
Block a user