Source code for ab.api.endpoints.contacts
"""Contacts API endpoints (12 routes)."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from ab.api.models.contacts import (
ContactDetailedInfo,
ContactEditRequest,
ContactGraphData,
ContactHistory,
ContactHistoryAggregated,
ContactHistoryCreateRequest,
ContactMergePreview,
ContactMergeRequest,
ContactPrimaryDetails,
ContactSearchRequest,
ContactSimple,
SearchContactEntityResult,
)
from ab.api.base import BaseEndpoint
from ab.api.route import Route
from ab.cache import CodeResolver
_GET = Route("GET", "/contacts/{id}", response_model="ContactSimple")
_GET_DETAILS = Route("GET", "/contacts/{contactId}/editdetails", response_model="ContactDetailedInfo")
_UPDATE_DETAILS = Route(
"PUT", "/contacts/{contactId}/editdetails",
request_model="ContactEditRequest", params_model="ContactEditParams",
)
_CREATE = Route(
"POST", "/contacts/editdetails",
request_model="ContactEditRequest", params_model="ContactEditParams",
)
_SEARCH = Route(
"POST", "/contacts/v2/search",
request_model="ContactSearchRequest", response_model="List[SearchContactEntityResult]",
)
_PRIMARY_DETAILS = Route("GET", "/contacts/{contactId}/primarydetails", response_model="ContactPrimaryDetails")
_CURRENT_USER = Route("GET", "/contacts/user", response_model="ContactSimple")
# Extended contact routes (008)
_POST_HISTORY = Route(
"POST", "/contacts/{contactId}/history",
request_model="ContactHistoryCreateRequest", response_model="ContactHistory",
)
_GET_HISTORY_AGGREGATED = Route(
"GET", "/contacts/{contactId}/history/aggregated",
params_model="ContactHistoryParams", response_model="ContactHistoryAggregated",
)
_GET_HISTORY_GRAPH_DATA = Route(
"GET", "/contacts/{contactId}/history/graphdata",
params_model="ContactHistoryParams", response_model="ContactGraphData",
)
_MERGE_PREVIEW = Route(
"POST", "/contacts/{mergeToId}/merge/preview",
request_model="ContactMergeRequest", response_model="ContactMergePreview",
)
_MERGE = Route("PUT", "/contacts/{mergeToId}/merge", request_model="ContactMergeRequest")
[docs]
class ContactsEndpoint(BaseEndpoint):
"""Operations on contacts (ACPortal API)."""
def __init__(self, client: Any, resolver: CodeResolver) -> None:
super().__init__(client)
self._resolver = resolver
[docs]
def get(self, contact_id: str) -> ContactSimple:
"""GET /contacts/{id}
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get.html
Response model: ContactSimple
"""
return self._request(_GET.bind(id=contact_id))
[docs]
def get_did(self, contact_did: str | int) -> ContactSimple:
"""Resolve a contact display ID through CodeResolver, then GET /contacts/{id}."""
return self.get(self._resolver.resolve(str(contact_did)))
[docs]
def get_details(self, contact_id: str) -> ContactDetailedInfo:
"""GET /contacts/{contactId}/editdetails
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get_details.html
Response model: ContactDetailedInfo
"""
return self._request(_GET_DETAILS.bind(contactId=contact_id))
[docs]
def update_details(
self,
contact_id: str,
*,
data: ContactEditRequest | dict,
franchisee_id: str | None = None,
) -> None:
"""PUT /contacts/{contactId}/editdetails.
Args:
contact_id: Contact identifier.
data: Contact edit payload with name, email, phone, addresses.
Accepts a :class:`ContactEditRequest` instance or a dict.
franchisee_id: Franchisee UUID filter (query param).
Request model: :class:`ContactEditRequest`
Params model: :class:`ContactEditParams`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/update_details.html
Request model: ContactEditRequest
Query params: ContactEditParams
"""
params = dict(franchisee_id=franchisee_id)
return self._request(
_UPDATE_DETAILS.bind(contactId=contact_id), json=data, params=params,
)
[docs]
def create(
self,
*,
data: ContactEditRequest | dict,
franchisee_id: str | None = None,
) -> None:
"""POST /contacts/editdetails.
Args:
data: Contact creation payload with name, email, phone, addresses.
Accepts a :class:`ContactEditRequest` instance or a dict.
franchisee_id: Franchisee UUID filter (query param).
Request model: :class:`ContactEditRequest`
Params model: :class:`ContactEditParams`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/create.html
Request model: ContactEditRequest
Query params: ContactEditParams
"""
params = dict(franchisee_id=franchisee_id)
return self._request(_CREATE, json=data, params=params)
[docs]
def search(self, *, data: ContactSearchRequest | dict) -> list[SearchContactEntityResult]:
"""POST /contacts/v2/search.
Args:
data: Search payload with search_text, page, and page_size.
Accepts a :class:`ContactSearchRequest` instance or a dict.
Request model: :class:`ContactSearchRequest`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/search.html
Request model: ContactSearchRequest
Response model: List[SearchContactEntityResult]
"""
return self._request(_SEARCH, json=data)
[docs]
def get_primary_details(self, contact_id: str) -> ContactPrimaryDetails:
"""GET /contacts/{contactId}/primarydetails
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get_primary_details.html
Response model: ContactPrimaryDetails
"""
return self._request(_PRIMARY_DETAILS.bind(contactId=contact_id))
[docs]
def get_current_user(self) -> ContactSimple:
"""GET /contacts/user
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get_current_user.html
Response model: ContactSimple
"""
return self._request(_CURRENT_USER)
# ---- Extended (008) ---------------------------------------------------
[docs]
def post_history(self, contact_id: str, *, data: ContactHistoryCreateRequest | dict) -> ContactHistory:
"""POST /contacts/{contactId}/history.
Args:
contact_id: Contact identifier.
data: History creation payload.
Accepts a :class:`ContactHistoryCreateRequest` instance or a dict.
Request model: :class:`ContactHistoryCreateRequest`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/post_history.html
Request model: ContactHistoryCreateRequest
Response model: ContactHistory
"""
return self._request(_POST_HISTORY.bind(contactId=contact_id), json=data)
[docs]
def get_history_aggregated(self, contact_id: str) -> ContactHistoryAggregated:
"""GET /contacts/{contactId}/history/aggregated
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get_history_aggregated.html
Query params: ContactHistoryParams
Response model: ContactHistoryAggregated
"""
return self._request(_GET_HISTORY_AGGREGATED.bind(contactId=contact_id))
[docs]
def get_history_graph_data(self, contact_id: str) -> ContactGraphData:
"""GET /contacts/{contactId}/history/graphdata
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/get_history_graph_data.html
Query params: ContactHistoryParams
Response model: ContactGraphData
"""
return self._request(_GET_HISTORY_GRAPH_DATA.bind(contactId=contact_id))
[docs]
def merge_preview(self, merge_to_id: str, *, data: ContactMergeRequest | dict) -> ContactMergePreview:
"""POST /contacts/{mergeToId}/merge/preview.
Args:
merge_to_id: Target contact to merge into.
data: Merge preview request payload.
Accepts a :class:`ContactMergeRequest` instance or a dict.
Request model: :class:`ContactMergeRequest`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/merge_preview.html
Request model: ContactMergeRequest
Response model: ContactMergePreview
"""
return self._request(_MERGE_PREVIEW.bind(mergeToId=merge_to_id), json=data)
[docs]
def merge(self, merge_to_id: str, *, data: ContactMergeRequest | dict) -> None:
"""PUT /contacts/{mergeToId}/merge.
Args:
merge_to_id: Target contact to merge into.
data: Merge request payload.
Accepts a :class:`ContactMergeRequest` instance or a dict.
Request model: :class:`ContactMergeRequest`
Docs: https://ab-sdk.readthedocs.io/en/latest/api/contacts/merge.html
Request model: ContactMergeRequest
"""
return self._request(_MERGE.bind(mergeToId=merge_to_id), json=data)